Merge "Made BagOStuff::debug protected"
authorjenkins-bot <jenkins-bot@gerrit.wikimedia.org>
Thu, 12 Feb 2015 17:17:30 +0000 (17:17 +0000)
committerGerrit Code Review <gerrit@wikimedia.org>
Thu, 12 Feb 2015 17:17:30 +0000 (17:17 +0000)
239 files changed:
.jscsrc
Gruntfile.js
RELEASE-NOTES-1.25
autoload.php
composer.json
docs/extension.schema.json
docs/hooks.txt
img_auth.php
includes/CategoryViewer.php
includes/ChangeTags.php
includes/DefaultSettings.php
includes/Feed.php
includes/GlobalFunctions.php
includes/Import.php
includes/Linker.php
includes/MediaWiki.php
includes/Message.php
includes/Revision.php
includes/Sanitizer.php
includes/Status.php
includes/Title.php
includes/User.php
includes/UserRightsProxy.php
includes/actions/HistoryAction.php
includes/api/ApiMain.php
includes/api/ApiManageTags.php [new file with mode: 0644]
includes/api/ApiQuerySearch.php
includes/api/ApiQuerySiteinfo.php
includes/api/ApiQueryTags.php
includes/api/ApiQueryUserInfo.php
includes/api/i18n/awa.json [new file with mode: 0644]
includes/api/i18n/be-tarask.json
includes/api/i18n/bn.json [new file with mode: 0644]
includes/api/i18n/cs.json
includes/api/i18n/en.json
includes/api/i18n/es.json
includes/api/i18n/fr.json
includes/api/i18n/gl.json
includes/api/i18n/it.json
includes/api/i18n/ja.json
includes/api/i18n/ko.json
includes/api/i18n/lb.json
includes/api/i18n/nap.json [new file with mode: 0644]
includes/api/i18n/nds.json [new file with mode: 0644]
includes/api/i18n/pam.json [new file with mode: 0644]
includes/api/i18n/pl.json
includes/api/i18n/pt-br.json [new file with mode: 0644]
includes/api/i18n/pt.json
includes/api/i18n/qqq.json
includes/api/i18n/sr-ec.json
includes/api/i18n/sv.json
includes/api/i18n/tl.json [new file with mode: 0644]
includes/api/i18n/vi.json
includes/api/i18n/zh-hans.json
includes/api/i18n/zh-hant.json
includes/changes/RecentChange.php
includes/db/Database.php
includes/db/DatabaseMssql.php
includes/db/DatabaseMysqlBase.php
includes/db/DatabasePostgres.php
includes/filebackend/FileBackend.php
includes/filebackend/FileBackendStore.php
includes/filerepo/FileRepo.php
includes/filerepo/FileRepoStatus.php
includes/htmlform/HTMLCheckMatrix.php
includes/installer/i18n/fi.json
includes/installer/i18n/hu.json
includes/installer/i18n/id.json
includes/installer/i18n/it.json
includes/installer/i18n/lb.json
includes/installer/i18n/nap.json
includes/installer/i18n/pt-br.json
includes/installer/i18n/ru.json
includes/installer/i18n/sr-ec.json
includes/installer/i18n/sv.json
includes/installer/i18n/vi.json
includes/installer/i18n/zh-hant.json
includes/jobqueue/JobQueueRedis.php
includes/jobqueue/JobRunner.php
includes/jobqueue/jobs/RecentChangesUpdateJob.php [new file with mode: 0644]
includes/libs/MessageSpecifier.php [new file with mode: 0644]
includes/libs/StatusValue.php [new file with mode: 0644]
includes/media/FormatMetadata.php
includes/media/ImageHandler.php
includes/media/MediaTransformInvalidParametersException.php [new file with mode: 0644]
includes/objectcache/APCBagOStuff.php
includes/objectcache/BagOStuff.php
includes/objectcache/EmptyBagOStuff.php
includes/objectcache/HashBagOStuff.php
includes/objectcache/MemcachedBagOStuff.php
includes/objectcache/MemcachedPeclBagOStuff.php
includes/objectcache/MultiWriteBagOStuff.php
includes/objectcache/ObjectCacheSessionHandler.php
includes/objectcache/RedisBagOStuff.php
includes/objectcache/SqlBagOStuff.php
includes/objectcache/WinCacheBagOStuff.php
includes/objectcache/XCacheBagOStuff.php
includes/page/WikiPage.php
includes/profiler/TransactionProfiler.php
includes/registration/ExtensionProcessor.php
includes/registration/ExtensionRegistry.php
includes/resourceloader/ResourceLoader.php
includes/resourceloader/ResourceLoaderImage.php
includes/revisiondelete/RevDelRevisionList.php
includes/skins/SkinApiTemplate.php
includes/specials/SpecialProtectedpages.php
includes/specials/SpecialProtectedtitles.php
includes/specials/SpecialRunJobs.php
includes/specials/SpecialTags.php
includes/specials/SpecialUserrights.php
includes/specials/SpecialWhatlinkshere.php
languages/Language.php
languages/i18n/ang.json
languages/i18n/as.json
languages/i18n/ast.json
languages/i18n/awa.json
languages/i18n/az.json
languages/i18n/azb.json
languages/i18n/be-tarask.json
languages/i18n/bg.json
languages/i18n/bgn.json
languages/i18n/bn.json
languages/i18n/bs.json
languages/i18n/ca.json
languages/i18n/ce.json
languages/i18n/cs.json
languages/i18n/de.json
languages/i18n/diq.json
languages/i18n/egl.json
languages/i18n/en.json
languages/i18n/eo.json
languages/i18n/es.json
languages/i18n/et.json
languages/i18n/eu.json
languages/i18n/fa.json
languages/i18n/fi.json
languages/i18n/frr.json
languages/i18n/gl.json
languages/i18n/he.json
languages/i18n/hif-latn.json
languages/i18n/hu.json
languages/i18n/hy.json
languages/i18n/ia.json
languages/i18n/id.json
languages/i18n/inh.json
languages/i18n/it.json
languages/i18n/ja.json
languages/i18n/ka.json
languages/i18n/kk-cyrl.json
languages/i18n/ko.json
languages/i18n/lb.json
languages/i18n/lzh.json
languages/i18n/mg.json
languages/i18n/mk.json
languages/i18n/ml.json
languages/i18n/nap.json
languages/i18n/nds-nl.json
languages/i18n/nds.json
languages/i18n/nl.json
languages/i18n/pl.json
languages/i18n/pms.json
languages/i18n/pt-br.json
languages/i18n/pt.json
languages/i18n/qqq.json
languages/i18n/rm.json
languages/i18n/ro.json
languages/i18n/ru.json
languages/i18n/scn.json
languages/i18n/sr-ec.json
languages/i18n/sr-el.json
languages/i18n/sv.json
languages/i18n/szl.json
languages/i18n/th.json
languages/i18n/tt-cyrl.json
languages/i18n/uz.json
languages/i18n/vi.json
languages/i18n/xal.json
languages/i18n/yi.json
languages/i18n/zh-hans.json
languages/i18n/zh-hant.json
maintenance/Maintenance.php
maintenance/convertExtensionToRegistration.php
maintenance/doMaintenance.php
maintenance/eval.php
maintenance/runJobs.php
maintenance/storage/compressOld.php
maintenance/storage/moveToExternal.php
maintenance/storage/resolveStubs.php
package.json
profileinfo.php
resources/Resources.php
resources/lib/jquery/jquery.qunit.css [deleted file]
resources/lib/jquery/jquery.qunit.js [deleted file]
resources/lib/oojs-ui/i18n/awa.json [new file with mode: 0644]
resources/lib/oojs-ui/i18n/ce.json
resources/lib/oojs-ui/i18n/ko.json
resources/lib/oojs-ui/oojs-ui-mediawiki.css
resources/lib/oojs-ui/oojs-ui-mediawiki.js
resources/lib/oojs-ui/oojs-ui-mediawiki.svg.css
resources/lib/oojs-ui/oojs-ui.js
resources/lib/qunitjs/qunit.css [new file with mode: 0644]
resources/lib/qunitjs/qunit.js [new file with mode: 0644]
resources/src/jquery/jquery.mwExtension.js
resources/src/jquery/jquery.placeholder.js
resources/src/jquery/jquery.textSelection.js
resources/src/mediawiki.action/mediawiki.action.edit.preview.js
resources/src/mediawiki.action/mediawiki.action.view.metadata.css
resources/src/mediawiki.action/mediawiki.action.view.postEdit.js
resources/src/mediawiki.api/mediawiki.api.login.js
resources/src/mediawiki.language/mediawiki.language.init.js
resources/src/mediawiki.legacy/shared.css
resources/src/mediawiki.page/mediawiki.page.gallery.js
resources/src/mediawiki.special/mediawiki.special.pageLanguage.js
resources/src/mediawiki/mediawiki.cookie.js
resources/src/mediawiki/mediawiki.js
resources/src/mediawiki/mediawiki.startUp.js [new file with mode: 0644]
resources/src/mediawiki/mediawiki.user.js
resources/src/mediawiki/mediawiki.util.js
tests/parser/parserTests.txt
tests/phpunit/MediaWikiTestCase.php
tests/phpunit/bootstrap.php
tests/phpunit/includes/GlobalFunctions/GlobalTest.php
tests/phpunit/includes/GlobalFunctions/wfThumbIsStandardTest.php [new file with mode: 0644]
tests/phpunit/includes/LinkerTest.php
tests/phpunit/includes/MovePageTest.php
tests/phpunit/includes/StatusTest.php
tests/phpunit/includes/api/ApiTestCaseUpload.php
tests/phpunit/includes/api/ApiUploadTest.php
tests/phpunit/includes/filebackend/FileBackendTest.php
tests/phpunit/includes/filerepo/StoreBatchTest.php
tests/phpunit/includes/parser/NewParserTest.php
tests/phpunit/includes/registration/ExtensionProcessorTest.php
tests/phpunit/includes/upload/UploadBaseTest.php
tests/qunit/suites/resources/jquery/jquery.accessKeyLabel.test.js
tests/qunit/suites/resources/jquery/jquery.placeholder.test.js
tests/qunit/suites/resources/mediawiki/mediawiki.jqueryMsg.test.js
tests/qunit/suites/resources/mediawiki/mediawiki.language.test.js
tests/qunit/suites/resources/mediawiki/mediawiki.util.test.js
thumb.php

diff --git a/.jscsrc b/.jscsrc
index 2ebd40e..34b2435 100644 (file)
--- a/.jscsrc
+++ b/.jscsrc
@@ -3,6 +3,10 @@
 
        "disallowKeywordsOnNewLine": null,
        "disallowQuotedKeysInObjects": null,
+       "disallowImplicitTypeConversion": null,
+       "requireLineBreakAfterVariableAssignment": null,
+       "requireSpaceAfterLineComment": null,
+       "requireSpacesInsideParentheses": null,
        "requireSpacesInsideArrayBrackets": null,
        "validateIndentation": null
 }
index 9cf89d0..4481e39 100644 (file)
@@ -8,7 +8,10 @@ module.exports = function ( grunt ) {
        grunt.loadNpmTasks( 'grunt-karma' );
 
        var wgServer = process.env.MW_SERVER,
-               wgScriptPath = process.env.MW_SCRIPT_PATH;
+               wgScriptPath = process.env.MW_SCRIPT_PATH,
+               karmaProxy = {};
+
+       karmaProxy[wgScriptPath] = wgServer + wgScriptPath;
 
        grunt.initConfig( {
                pkg: grunt.file.readJSON( 'package.json' ),
@@ -62,27 +65,7 @@ module.exports = function ( grunt ) {
                },
                karma: {
                        options: {
-                               proxies: ( function () {
-                                       var obj = {};
-                                       // Set up a proxy for requests to relative urls inside wgScriptPath. Uses a
-                                       // property accessor instead of plain obj[wgScriptPath] assignment as throw if
-                                       // unset. Running grunt normally (e.g. npm test), should not fail over this.
-                                       // This ensures 'npm test' works out of the box, statically, on a git clone
-                                       // without MediaWiki fully installed or some environment variables set.
-                                       Object.defineProperty( obj, wgScriptPath, {
-                                               enumerable: true,
-                                               get: function () {
-                                                       if ( !wgServer ) {
-                                                               grunt.fail.fatal( 'MW_SERVER is not set' );
-                                                       }
-                                                       if ( !wgScriptPath ) {
-                                                               grunt.fail.fatal( 'MW_SCRIPT_PATH is not set' );
-                                                       }
-                                                       return wgServer + wgScriptPath;
-                                               }
-                                       } );
-                                       return obj;
-                               }() ),
+                               proxies: karmaProxy,
                                files: [ {
                                        pattern: wgServer + wgScriptPath + '/index.php?title=Special:JavaScriptTest/qunit/export',
                                        watched: false,
index d2edcb3..3f24db0 100644 (file)
@@ -36,6 +36,15 @@ production.
 * ProfilerStandard and ProfilerSimpleTrace were removed. Make sure that any
   StartProfiler.php config is updated to reflect this. Xhprof is available
   for zend/hhvm. Also, for hhvm, one can consider using its xenon profiler.
+* Default value of $wgSVGConverters['rsvg'] now uses the 'rsvg-convert' binary
+  rather than 'rsvg'.
+* Default value of $wgSVGConverters['ImageMagick'] now uses transparent
+  background with white fallback color, rather than just white background.
+ * MediaWikiBagOStuff class removed, make sure any object cache config
+   uses SqlBagOStuff instead.
+* The 'daemonized' flag must be set to true in $wgJobTypeConf for any redis
+  job queues. This means that mediawiki/services/jobrunner service has to
+  be installed and running for any such queues to work.
 
 === New features in 1.25 ===
 * (T64861) Updated plural rules to CLDR 26. Includes incompatible changes
@@ -80,6 +89,14 @@ production.
   they will add the proper credits to the skins or extensions section.
 * Update QUnit from v1.14.0 to v1.16.0.
 * Update Moment.js from v2.8.3 to v2.8.4.
+* Special:Tags now allows for manipulating the list of user-modifiable change
+  tags. Actually modifying the tagging of a revision or log entry is not
+  implemented yet.
+* Added 'managetags' user right and 'ChangeTagCanCreate', 'ChangeTagCanDelete',
+  and 'ChangeTagCanCreate' hooks to allow for managing user-modifiable change
+  tags.
+* Added 'ChangeTagsListActive' hook, to separate the concepts of "defined" and
+  "active" formerly conflated by the 'ListDefinedTags' hook.
 
 ==== External libraries ====
 * MediaWiki now requires certain external libraries to be installed. In the past
@@ -186,6 +203,11 @@ production.
   interwiki redirects to the list of interwiki titles.
 * (T85417) When outputting the list of redirect titles, a 'tointerwiki'
   property (like the existing 'tofragment' property) will be set.
+* Added action=managetags to allow for managing the list of
+  user-modifiable change tags. Actually modifying the tagging of a revision or
+  log entry is not implemented yet.
+* list=tags has additional properties to indicate 'active' status and tag
+  sources.
 
 === Action API internal changes in 1.25 ===
 * ApiHelp has been rewritten to support i18n and paginated HTML output.
index 90cd074..d0c313a 100644 (file)
@@ -51,6 +51,7 @@ $wgAutoloadLocalClasses = array(
        'ApiLogin' => __DIR__ . '/includes/api/ApiLogin.php',
        'ApiLogout' => __DIR__ . '/includes/api/ApiLogout.php',
        'ApiMain' => __DIR__ . '/includes/api/ApiMain.php',
+       'ApiManageTags' => __DIR__ . '/includes/api/ApiManageTags.php',
        'ApiModuleManager' => __DIR__ . '/includes/api/ApiModuleManager.php',
        'ApiMove' => __DIR__ . '/includes/api/ApiMove.php',
        'ApiOpenSearch' => __DIR__ . '/includes/api/ApiOpenSearch.php',
@@ -534,6 +535,7 @@ $wgAutoloadLocalClasses = array(
        'ImageQueryPage' => __DIR__ . '/includes/specialpage/ImageQueryPage.php',
        'ImportReporter' => __DIR__ . '/includes/specials/SpecialImport.php',
        'ImportSiteScripts' => __DIR__ . '/maintenance/importSiteScripts.php',
+       'ImportSource' => __DIR__ . '/includes/Import.php',
        'ImportStreamSource' => __DIR__ . '/includes/Import.php',
        'ImportStringSource' => __DIR__ . '/includes/Import.php',
        'ImportTitleFactory' => __DIR__ . '/includes/title/ImportTitleFactory.php',
@@ -724,9 +726,9 @@ $wgAutoloadLocalClasses = array(
        'MediaHandler' => __DIR__ . '/includes/media/MediaHandler.php',
        'MediaStatisticsPage' => __DIR__ . '/includes/specials/SpecialMediaStatistics.php',
        'MediaTransformError' => __DIR__ . '/includes/media/MediaTransformOutput.php',
+       'MediaTransformInvalidParametersException' => __DIR__ . '/includes/media/MediaTransformInvalidParametersException.php',
        'MediaTransformOutput' => __DIR__ . '/includes/media/MediaTransformOutput.php',
        'MediaWiki' => __DIR__ . '/includes/MediaWiki.php',
-       'MediaWikiBagOStuff' => __DIR__ . '/includes/objectcache/SqlBagOStuff.php',
        'MediaWikiI18N' => __DIR__ . '/includes/skins/MediaWikiI18N.php',
        'MediaWikiPageLinkRenderer' => __DIR__ . '/includes/title/MediaWikiPageLinkRenderer.php',
        'MediaWikiSite' => __DIR__ . '/includes/site/MediaWikiSite.php',
@@ -745,6 +747,7 @@ $wgAutoloadLocalClasses = array(
        'MessageBlobStore' => __DIR__ . '/includes/MessageBlobStore.php',
        'MessageCache' => __DIR__ . '/includes/cache/MessageCache.php',
        'MessageContent' => __DIR__ . '/includes/content/MessageContent.php',
+       'MessageSpecifier' => __DIR__ . '/includes/libs/MessageSpecifier.php',
        'MigrateUserGroup' => __DIR__ . '/maintenance/migrateUserGroup.php',
        'MimeMagic' => __DIR__ . '/includes/MimeMagic.php',
        'MinifyScript' => __DIR__ . '/maintenance/minify.php',
@@ -939,6 +942,7 @@ $wgAutoloadLocalClasses = array(
        'RebuildSitesCache' => __DIR__ . '/maintenance/rebuildSitesCache.php',
        'RebuildTextIndex' => __DIR__ . '/maintenance/rebuildtextindex.php',
        'RecentChange' => __DIR__ . '/includes/changes/RecentChange.php',
+       'RecentChangesUpdateJob' => __DIR__ . '/includes/jobqueue/jobs/RecentChangesUpdateJob.php',
        'RecompressTracked' => __DIR__ . '/maintenance/storage/recompressTracked.php',
        'RedirectSpecialArticle' => __DIR__ . '/includes/specialpage/RedirectSpecialPage.php',
        'RedirectSpecialPage' => __DIR__ . '/includes/specialpage/RedirectSpecialPage.php',
@@ -1151,6 +1155,7 @@ $wgAutoloadLocalClasses = array(
        'StatCounter' => __DIR__ . '/includes/StatCounter.php',
        'StatsOutput' => __DIR__ . '/maintenance/language/StatOutputs.php',
        'Status' => __DIR__ . '/includes/Status.php',
+       'StatusValue' => __DIR__ . '/includes/libs/StatusValue.php',
        'StorageTypeStats' => __DIR__ . '/maintenance/storage/storageTypeStats.php',
        'StoreFileOp' => __DIR__ . '/includes/filebackend/FileOp.php',
        'StreamFile' => __DIR__ . '/includes/StreamFile.php',
index a54719c..ff92898 100644 (file)
@@ -18,7 +18,7 @@
        "require": {
                "cssjanus/cssjanus": "1.1.1",
                "leafo/lessphp": "0.5.0",
-               "oojs/oojs-ui": "0.6.4",
+               "oojs/oojs-ui": "0.7.0",
                "php": ">=5.3.3",
                "psr/log": "1.0.0",
                "wikimedia/cdb": "1.0.1",
@@ -27,7 +27,7 @@
        },
        "require-dev": {
                "justinrainbow/json-schema": "~1.3",
-               "phpunit/phpunit": "*"
+               "phpunit/phpunit": "~4.5"
        },
        "suggest": {
                "ext-fileinfo": "*",
index 4583559..33029bd 100644 (file)
                                "Unlicense"
                        ]
                },
+               "ResourceFileModulePaths": {
+                       "type": "object",
+                       "description": "Default paths to use for all ResourceLoader file modules",
+                       "additionalProperties": false,
+                       "properties": {
+                               "localBasePath": {
+                                       "type": "string",
+                                       "description": "Base path to prepend to all local paths, relative to current directory"
+                               },
+                               "remoteExtPath": {
+                                       "type": "string",
+                                       "description": "Base path to prepend to all remote paths, relative to $wgExtensionAssetsPath"
+                               },
+                               "remoteSkinPath": {
+                                       "type": "string",
+                                       "description": "Base path to prepend to all remote paths, relative to $wgStylePath"
+                               }
+                       }
+               },
                "ResourceLoaderModules": {
                        "type": "object",
                        "description": "ResourceLoader modules to register",
index 4717c38..f47890d 100644 (file)
@@ -903,6 +903,38 @@ $name: name of the special page, e.g. 'Watchlist'
 &$join_conds: join conditions for the tables
 $opts: FormOptions for this request
 
+'ChangeTagAfterDelete': Called after a change tag has been deleted (that is,
+removed from all revisions and log entries to which it was applied). This gives
+extensions a chance to take it off their books.
+$tag: name of the tag
+&$status: Status object. Add warnings to this as required. There is no point
+  setting errors, as the deletion has already been partly carried out by this
+  point.
+
+'ChangeTagCanCreate': Tell whether a change tag should be able to be created
+from the UI (Special:Tags) or via the API. You could use this hook if you want
+to reserve a specific "namespace" of tags, or something similar.
+$tag: name of the tag
+$user: user initiating the action
+&$status: Status object. Add your errors using `$status->fatal()` or warnings
+  using `$status->warning()`. Errors and warnings will be relayed to the user.
+  If you set an error, the user will be unable to create the tag.
+
+'ChangeTagCanDelete': Tell whether a change tag should be able to be
+deleted from the UI (Special:Tags) or via the API. The default is that tags
+defined using the ListDefinedTags hook are not allowed to be deleted unless
+specifically allowed. If you wish to allow deletion of the tag, set
+`$status = Status::newGood()` to allow deletion, and then `return false` from
+the hook function. Ensure you consume the 'ChangeTagAfterDelete' hook to carry
+out custom deletion actions.
+$tag: name of the tag
+$user: user initiating the action
+&$status: Status object. See above.
+
+'ChangeTagsListActive': Allows you to nominate which of the tags your extension
+uses are in active use.
+&$tags: list of all active tags. Append to this array.
+
 'LoginUserMigrated': Called during login to allow extensions the opportunity to
 inform a user that their username doesn't exist for a specific reason, instead
 of letting the login form give the generic error message that the account does
@@ -2245,6 +2277,10 @@ configuration variables to JavaScript. Things that depend on the current page
 or request state must be added through MakeGlobalVariablesScript instead.
 &$vars: array( variable name => value )
 
+'ResourceLoaderGetLessVars': Called in ResourceLoader::getLessVars after variables
+from $wgResourceLoaderLESSVars are added. Can be used to add context-based variables.
+&$lessVars: array of variables already added
+
 'ResourceLoaderRegisterModules': Right before modules information is required,
 such as when responding to a resource
 loader request or generating HTML output.
index 51470b6..f44cac0 100644 (file)
@@ -201,7 +201,12 @@ function wfForbidden( $msg1, $msg2 ) {
        header( 'Cache-Control: no-cache' );
        header( 'Content-Type: text/html; charset=utf-8' );
        echo <<<ENDS
+<!DOCTYPE html>
 <html>
+<head>
+<meta charset="UTF-8" />
+<title>$msgHdr</title>
+</head>
 <body>
 <h1>$msgHdr</h1>
 <p>$detailMsg</p>
index c898ec9..6b86853 100644 (file)
@@ -387,16 +387,13 @@ class CategoryViewer extends ContextSource {
 
                if ( $rescnt > 0 ) {
                        # Showing subcategories
-                       $r .= Html::openElement( 'div', array( 'id' => 'mw-subcategories' ) );
-                       $r .= "\n";
-                       $r .= Html::element( 'h2', array(), $this->msg( 'subcategories' )->text() );
-                       $r .= "\n";
+                       $r .= "<div id=\"mw-subcategories\">\n";
+                       $r .= '<h2>' . $this->msg( 'subcategories' )->parse() . "</h2>\n";
                        $r .= $countmsg;
                        $r .= $this->getSectionPagingLinks( 'subcat' );
                        $r .= $this->formatList( $this->children, $this->children_start_char );
                        $r .= $this->getSectionPagingLinks( 'subcat' );
-                       $r .= "\n";
-                       $r .= Html::closeElement( 'div' );
+                       $r .= "\n</div>";
                }
                return $r;
        }
@@ -419,16 +416,13 @@ class CategoryViewer extends ContextSource {
                $countmsg = $this->getCountMessage( $rescnt, $dbcnt, 'article' );
 
                if ( $rescnt > 0 ) {
-                       $r .= Html::openElement( 'div', array( 'id' => 'mw-pages' ) );
-                       $r .= "\n";
-                       $r .= Html::element( 'h2', array(), $this->msg( 'category_header', $ti )->text() );
-                       $r .= "\n";
+                       $r = "<div id=\"mw-pages\">\n";
+                       $r .= '<h2>' . $this->msg( 'category_header', $ti )->parse() . "</h2>\n";
                        $r .= $countmsg;
                        $r .= $this->getSectionPagingLinks( 'page' );
                        $r .= $this->formatList( $this->articles, $this->articles_start_char );
                        $r .= $this->getSectionPagingLinks( 'page' );
-                       $r .= "\n";
-                       $r .= Html::closeElement( 'div' );
+                       $r .= "\n</div>";
                }
                return $r;
        }
index 9ee2460..d597d6d 100644 (file)
  */
 
 class ChangeTags {
+       /**
+        * Can't delete tags with more than this many uses. Similar in intent to
+        * the bigdelete user right
+        * @todo Use the job queue for tag deletion to avoid this restriction
+        */
+       const MAX_DELETE_USES = 5000;
+
        /**
         * Creates HTML for the given tags
         *
@@ -185,6 +192,7 @@ class ChangeTags {
 
                $dbw->insert( 'change_tag', $tagsRows, __METHOD__, array( 'IGNORE' ) );
 
+               self::purgeTagUsageCache();
                return true;
        }
 
@@ -293,19 +301,479 @@ class ChangeTags {
                return $html;
        }
 
+       /**
+        * Defines a tag in the valid_tag table, without checking that the tag name
+        * is valid.
+        * Extensions should NOT use this function; they can use the ListDefinedTags
+        * hook instead.
+        *
+        * @param string $tag Tag to create
+        * @since 1.25
+        */
+       public static function defineTag( $tag ) {
+               $dbw = wfGetDB( DB_MASTER );
+               $dbw->replace( 'valid_tag',
+                       array( 'vt_tag' ),
+                       array( 'vt_tag' => $tag ),
+                       __METHOD__ );
+
+               // clear the memcache of defined tags
+               self::purgeTagCacheAll();
+       }
+
+       /**
+        * Removes a tag from the valid_tag table. The tag may remain in use by
+        * extensions, and may still show up as 'defined' if an extension is setting
+        * it from the ListDefinedTags hook.
+        *
+        * @param string $tag Tag to remove
+        * @since 1.25
+        */
+       public static function undefineTag( $tag ) {
+               $dbw = wfGetDB( DB_MASTER );
+               $dbw->delete( 'valid_tag', array( 'vt_tag' => $tag ), __METHOD__ );
+
+               // clear the memcache of defined tags
+               self::purgeTagCacheAll();
+       }
+
+       /**
+        * Writes a tag action into the tag management log.
+        *
+        * @param string $action
+        * @param string $tag
+        * @param string $reason
+        * @param User $user Who to attribute the action to
+        * @param int $tagCount For deletion only, how many usages the tag had before
+        * it was deleted.
+        * @since 1.25
+        */
+       protected static function logTagAction( $action, $tag, $reason, User $user,
+               $tagCount = null ) {
+
+               $dbw = wfGetDB( DB_MASTER );
+
+               $logEntry = new ManualLogEntry( 'managetags', $action );
+               $logEntry->setPerformer( $user );
+               // target page is not relevant, but it has to be set, so we just put in
+               // the title of Special:Tags
+               $logEntry->setTarget( Title::newFromText( 'Special:Tags' ) );
+               $logEntry->setComment( $reason );
+
+               $params = array( '4::tag' => $tag );
+               if ( !is_null( $tagCount ) ) {
+                       $params['5:number:count'] = $tagCount;
+               }
+               $logEntry->setParameters( $params );
+               $logEntry->setRelations( array( 'Tag' => $tag ) );
+
+               $logId = $logEntry->insert( $dbw );
+               $logEntry->publish( $logId );
+               return $logId;
+       }
+
+       /**
+        * Is it OK to allow the user to activate this tag?
+        *
+        * @param string $tag Tag that you are interested in activating
+        * @param User|null $user User whose permission you wish to check, or null if
+        * you don't care (e.g. maintenance scripts)
+        * @return Status
+        * @since 1.25
+        */
+       public static function canActivateTag( $tag, User $user = null ) {
+               if ( !is_null( $user ) && !$user->isAllowed( 'managechangetags' ) ) {
+                       return Status::newFatal( 'tags-manage-no-permission' );
+               }
+
+               // non-existing tags cannot be activated
+               $tagUsage = self::tagUsageStatistics();
+               if ( !isset( $tagUsage[$tag] ) ) {
+                       return Status::newFatal( 'tags-activate-not-found', $tag );
+               }
+
+               // defined tags cannot be activated (a defined tag is either extension-
+               // defined, in which case the extension chooses whether or not to active it;
+               // or user-defined, in which case it is considered active)
+               $definedTags = self::listDefinedTags();
+               if ( in_array( $tag, $definedTags ) ) {
+                       return Status::newFatal( 'tags-activate-not-allowed', $tag );
+               }
+
+               return Status::newGood();
+       }
+
+       /**
+        * Activates a tag, checking whether it is allowed first, and adding a log
+        * entry afterwards.
+        *
+        * Includes a call to ChangeTag::canActivateTag(), so your code doesn't need
+        * to do that.
+        *
+        * @param string $tag
+        * @param string $reason
+        * @param User $user Who to give credit for the action
+        * @param bool $ignoreWarnings Can be used for API interaction, default false
+        * @return Status If successful, the Status contains the ID of the added log
+        * entry as its value
+        * @since 1.25
+        */
+       public static function activateTagWithChecks( $tag, $reason, User $user,
+               $ignoreWarnings = false ) {
+
+               // are we allowed to do this?
+               $result = self::canActivateTag( $tag, $user );
+               if ( $ignoreWarnings ? !$result->isOK() : !$result->isGood() ) {
+                       $result->value = null;
+                       return $result;
+               }
+
+               // do it!
+               self::defineTag( $tag );
+
+               // log it
+               $logId = self::logTagAction( 'activate', $tag, $reason, $user );
+               return Status::newGood( $logId );
+       }
+
+       /**
+        * Is it OK to allow the user to deactivate this tag?
+        *
+        * @param string $tag Tag that you are interested in deactivating
+        * @param User|null $user User whose permission you wish to check, or null if
+        * you don't care (e.g. maintenance scripts)
+        * @return Status
+        * @since 1.25
+        */
+       public static function canDeactivateTag( $tag, User $user = null ) {
+               if ( !is_null( $user ) && !$user->isAllowed( 'managechangetags' ) ) {
+                       return Status::newFatal( 'tags-manage-no-permission' );
+               }
+
+               // only explicitly-defined tags can be deactivated
+               $explicitlyDefinedTags = self::listExplicitlyDefinedTags();
+               if ( !in_array( $tag, $explicitlyDefinedTags ) ) {
+                       return Status::newFatal( 'tags-deactivate-not-allowed', $tag );
+               }
+               return Status::newGood();
+       }
+
+       /**
+        * Deactivates a tag, checking whether it is allowed first, and adding a log
+        * entry afterwards.
+        *
+        * Includes a call to ChangeTag::canDeactivateTag(), so your code doesn't need
+        * to do that.
+        *
+        * @param string $tag
+        * @param string $reason
+        * @param User $user Who to give credit for the action
+        * @param bool $ignoreWarnings Can be used for API interaction, default false
+        * @return Status If successful, the Status contains the ID of the added log
+        * entry as its value
+        * @since 1.25
+        */
+       public static function deactivateTagWithChecks( $tag, $reason, User $user,
+               $ignoreWarnings = false ) {
+
+               // are we allowed to do this?
+               $result = self::canDeactivateTag( $tag, $user );
+               if ( $ignoreWarnings ? !$result->isOK() : !$result->isGood() ) {
+                       $result->value = null;
+                       return $result;
+               }
+
+               // do it!
+               self::undefineTag( $tag );
+
+               // log it
+               $logId = self::logTagAction( 'deactivate', $tag, $reason, $user );
+               return Status::newGood( $logId );
+       }
+
+       /**
+        * Is it OK to allow the user to create this tag?
+        *
+        * @param string $tag Tag that you are interested in creating
+        * @param User|null $user User whose permission you wish to check, or null if
+        * you don't care (e.g. maintenance scripts)
+        * @return Status
+        * @since 1.25
+        */
+       public static function canCreateTag( $tag, User $user = null ) {
+               if ( !is_null( $user ) && !$user->isAllowed( 'managechangetags' ) ) {
+                       return Status::newFatal( 'tags-manage-no-permission' );
+               }
+
+               // no empty tags
+               if ( $tag === '' ) {
+                       return Status::newFatal( 'tags-create-no-name' );
+               }
+
+               // tags cannot contain commas (used as a delimiter in tag_summary table) or
+               // slashes (would break tag description messages in MediaWiki namespace)
+               if ( strpos( $tag, ',' ) !== false || strpos( $tag, '/' ) !== false ) {
+                       return Status::newFatal( 'tags-create-invalid-chars' );
+               }
+
+               // could the MediaWiki namespace description messages be created?
+               $title = Title::makeTitleSafe( NS_MEDIAWIKI, "Tag-$tag-description" );
+               if ( is_null( $title ) ) {
+                       return Status::newFatal( 'tags-create-invalid-title-chars' );
+               }
+
+               // does the tag already exist?
+               $tagUsage = self::tagUsageStatistics();
+               if ( isset( $tagUsage[$tag] ) ) {
+                       return Status::newFatal( 'tags-create-already-exists', $tag );
+               }
+
+               // check with hooks
+               $canCreateResult = Status::newGood();
+               Hooks::run( 'ChangeTagCanCreate', array( $tag, $user, &$canCreateResult ) );
+               return $canCreateResult;
+       }
+
+       /**
+        * Creates a tag by adding a row to the `valid_tag` table.
+        *
+        * Includes a call to ChangeTag::canDeleteTag(), so your code doesn't need to
+        * do that.
+        *
+        * @param string $tag
+        * @param string $reason
+        * @param User $user Who to give credit for the action
+        * @param bool $ignoreWarnings Can be used for API interaction, default false
+        * @return Status If successful, the Status contains the ID of the added log
+        * entry as its value
+        * @since 1.25
+        */
+       public static function createTagWithChecks( $tag, $reason, User $user,
+               $ignoreWarnings = false ) {
+
+               // are we allowed to do this?
+               $result = self::canCreateTag( $tag, $user );
+               if ( $ignoreWarnings ? !$result->isOK() : !$result->isGood() ) {
+                       $result->value = null;
+                       return $result;
+               }
+
+               // do it!
+               self::defineTag( $tag );
+
+               // log it
+               $logId = self::logTagAction( 'create', $tag, $reason, $user );
+               return Status::newGood( $logId );
+       }
+
+       /**
+        * Permanently removes all traces of a tag from the DB. Good for removing
+        * misspelt or temporary tags.
+        *
+        * This function should be directly called by maintenance scripts only, never
+        * by user-facing code. See deleteTagWithChecks() for functionality that can
+        * safely be exposed to users.
+        *
+        * @param string $tag Tag to remove
+        * @return Status The returned status will be good unless a hook changed it
+        * @since 1.25
+        */
+       public static function deleteTagEverywhere( $tag ) {
+               $dbw = wfGetDB( DB_MASTER );
+               $dbw->begin( __METHOD__ );
+
+               // delete from valid_tag
+               self::undefineTag( $tag );
+
+               // find out which revisions use this tag, so we can delete from tag_summary
+               $result = $dbw->select( 'change_tag',
+                       array( 'ct_rc_id', 'ct_log_id', 'ct_rev_id', 'ct_tag' ),
+                       array( 'ct_tag' => $tag ),
+                       __METHOD__ );
+               foreach ( $result as $row ) {
+                       if ( $row->ct_rev_id ) {
+                               $field = 'ts_rev_id';
+                               $fieldValue = $row->ct_rev_id;
+                       } elseif ( $row->ct_log_id ) {
+                               $field = 'ts_log_id';
+                               $fieldValue = $row->ct_log_id;
+                       } elseif ( $row->ct_rc_id ) {
+                               $field = 'ts_rc_id';
+                               $fieldValue = $row->ct_rc_id;
+                       } else {
+                               // don't know what's up; just skip it
+                               continue;
+                       }
+
+                       // remove the tag from the relevant row of tag_summary
+                       $tsResult = $dbw->selectField( 'tag_summary',
+                               'ts_tags',
+                               array( $field => $fieldValue ),
+                               __METHOD__ );
+                       $tsValues = explode( ',', $tsResult );
+                       $tsValues = array_values( array_diff( $tsValues, array( $tag ) ) );
+                       if ( !$tsValues ) {
+                               // no tags left, so delete the row altogether
+                               $dbw->delete( 'tag_summary',
+                                       array( $field => $fieldValue ),
+                                       __METHOD__ );
+                       } else {
+                               $dbw->update( 'tag_summary',
+                                       array( 'ts_tags' => implode( ',', $tsValues ) ),
+                                       array( $field => $fieldValue ),
+                                       __METHOD__ );
+                       }
+               }
+
+               // delete from change_tag
+               $dbw->delete( 'change_tag', array( 'ct_tag' => $tag ), __METHOD__ );
+
+               $dbw->commit( __METHOD__ );
+
+               // give extensions a chance
+               $status = Status::newGood();
+               Hooks::run( 'ChangeTagAfterDelete', array( $tag, &$status ) );
+               // let's not allow error results, as the actual tag deletion succeeded
+               if ( !$status->isOK() ) {
+                       wfDebug( 'ChangeTagAfterDelete error condition downgraded to warning' );
+                       $status->ok = true;
+               }
+
+               // clear the memcache of defined tags
+               self::purgeTagCacheAll();
+
+               return $status;
+       }
+
+       /**
+        * Is it OK to allow the user to delete this tag?
+        *
+        * @param string $tag Tag that you are interested in deleting
+        * @param User|null $user User whose permission you wish to check, or null if
+        * you don't care (e.g. maintenance scripts)
+        * @return Status
+        * @since 1.25
+        */
+       public static function canDeleteTag( $tag, User $user = null ) {
+               $tagUsage = self::tagUsageStatistics();
+
+               if ( !is_null( $user ) && !$user->isAllowed( 'managechangetags' ) ) {
+                       return Status::newFatal( 'tags-manage-no-permission' );
+               }
+
+               if ( !isset( $tagUsage[$tag] ) ) {
+                       return Status::newFatal( 'tags-delete-not-found', $tag );
+               }
+
+               if ( $tagUsage[$tag] > self::MAX_DELETE_USES ) {
+                       return Status::newFatal( 'tags-delete-too-many-uses', $tag, self::MAX_DELETE_USES );
+               }
+
+               $extensionDefined = self::listExtensionDefinedTags();
+               if ( in_array( $tag, $extensionDefined ) ) {
+                       // extension-defined tags can't be deleted unless the extension
+                       // specifically allows it
+                       $status = Status::newFatal( 'tags-delete-not-allowed' );
+               } else {
+                       // user-defined tags are deletable unless otherwise specified
+                       $status = Status::newGood();
+               }
+
+               Hooks::run( 'ChangeTagCanDelete', array( $tag, $user, &$status ) );
+               return $status;
+       }
+
+       /**
+        * Deletes a tag, checking whether it is allowed first, and adding a log entry
+        * afterwards.
+        *
+        * Includes a call to ChangeTag::canDeleteTag(), so your code doesn't need to
+        * do that.
+        *
+        * @param string $tag
+        * @param string $reason
+        * @param User $user Who to give credit for the action
+        * @param bool $ignoreWarnings Can be used for API interaction, default false
+        * @return Status If successful, the Status contains the ID of the added log
+        * entry as its value
+        * @since 1.25
+        */
+       public static function deleteTagWithChecks( $tag, $reason, User $user,
+               $ignoreWarnings = false ) {
+
+               // are we allowed to do this?
+               $result = self::canDeleteTag( $tag, $user );
+               if ( $ignoreWarnings ? !$result->isOK() : !$result->isGood() ) {
+                       $result->value = null;
+                       return $result;
+               }
+
+               // store the tag usage statistics
+               $tagUsage = self::tagUsageStatistics();
+
+               // do it!
+               $deleteResult = self::deleteTagEverywhere( $tag );
+               if ( !$deleteResult->isOK() ) {
+                       return $deleteResult;
+               }
+
+               // log it
+               $logId = self::logTagAction( 'delete', $tag, $reason, $user, $tagUsage[$tag] );
+               $deleteResult->value = $logId;
+               return $deleteResult;
+       }
+
+       /**
+        * Lists those tags which extensions report as being "active".
+        *
+        * @return array
+        * @since 1.25
+        */
+       public static function listExtensionActivatedTags() {
+               // Caching...
+               global $wgMemc;
+               $key = wfMemcKey( 'active-tags' );
+               $tags = $wgMemc->get( $key );
+               if ( $tags ) {
+                       return $tags;
+               }
+
+               // ask extensions which tags they consider active
+               $extensionActive = array();
+               Hooks::run( 'ChangeTagsListActive', array( &$extensionActive ) );
+
+               // Short-term caching.
+               $wgMemc->set( $key, $extensionActive, 300 );
+               return $extensionActive;
+       }
+
        /**
         * Basically lists defined tags which count even if they aren't applied to anything.
-        * Tags on items in table 'change_tag' which are not (or no longer) in table 'valid_tag'
-        * are not included.
+        * It returns a union of the results of listExplicitlyDefinedTags() and
+        * listExtensionDefinedTags().
+        *
+        * @return string[] Array of strings: tags
+        */
+       public static function listDefinedTags() {
+               $tags1 = self::listExplicitlyDefinedTags();
+               $tags2 = self::listExtensionDefinedTags();
+               return array_values( array_unique( array_merge( $tags1, $tags2 ) ) );
+       }
+
+       /**
+        * Lists tags explicitly defined in the `valid_tag` table of the database.
+        * Tags in table 'change_tag' which are not in table 'valid_tag' are not
+        * included.
         *
         * Tries memcached first.
         *
         * @return string[] Array of strings: tags
+        * @since 1.25
         */
-       public static function listDefinedTags() {
+       public static function listExplicitlyDefinedTags() {
                // Caching...
                global $wgMemc;
-               $key = wfMemcKey( 'valid-tags' );
+               $key = wfMemcKey( 'valid-tags-db' );
                $tags = $wgMemc->get( $key );
                if ( $tags ) {
                        return $tags;
@@ -320,8 +788,33 @@ class ChangeTags {
                        $emptyTags[] = $row->vt_tag;
                }
 
-               Hooks::run( 'ListDefinedTags', array( &$emptyTags ) );
+               $emptyTags = array_filter( array_unique( $emptyTags ) );
 
+               // Short-term caching.
+               $wgMemc->set( $key, $emptyTags, 300 );
+               return $emptyTags;
+       }
+
+       /**
+        * Lists tags defined by extensions using the ListDefinedTags hook.
+        * Extensions need only define those tags they deem to be in active use.
+        *
+        * Tries memcached first.
+        *
+        * @return string[] Array of strings: tags
+        * @since 1.25
+        */
+       public static function listExtensionDefinedTags() {
+               // Caching...
+               global $wgMemc;
+               $key = wfMemcKey( 'valid-tags-hook' );
+               $tags = $wgMemc->get( $key );
+               if ( $tags ) {
+                       return $tags;
+               }
+
+               $emptyTags = array();
+               Hooks::run( 'ListDefinedTags', array( &$emptyTags ) );
                $emptyTags = array_filter( array_unique( $emptyTags ) );
 
                // Short-term caching.
@@ -329,13 +822,46 @@ class ChangeTags {
                return $emptyTags;
        }
 
+       /**
+        * Invalidates the short-term cache of defined tags used by the
+        * list*DefinedTags functions, as well as the tag statistics cache.
+        * @since 1.25
+        */
+       public static function purgeTagCacheAll() {
+               global $wgMemc;
+               $wgMemc->delete( wfMemcKey( 'active-tags' ) );
+               $wgMemc->delete( wfMemcKey( 'valid-tags-db' ) );
+               $wgMemc->delete( wfMemcKey( 'valid-tags-hook' ) );
+               self::purgeTagUsageCache();
+       }
+
+       /**
+        * Invalidates the tag statistics cache only.
+        * @since 1.25
+        */
+       public static function purgeTagUsageCache() {
+               global $wgMemc;
+               $wgMemc->delete( wfMemcKey( 'change-tag-statistics' ) );
+       }
+
        /**
         * Returns a map of any tags used on the wiki to number of edits
         * tagged with them, ordered descending by the hitcount.
         *
+        * Keeps a short-term cache in memory, so calling this multiple times in the
+        * same request should be fine.
+        *
         * @return array Array of string => int
         */
        public static function tagUsageStatistics() {
+               // Caching...
+               global $wgMemc;
+               $key = wfMemcKey( 'change-tag-statistics' );
+               $stats = $wgMemc->get( $key );
+               if ( $stats ) {
+                       return $stats;
+               }
+
                $out = array();
 
                $dbr = wfGetDB( DB_SLAVE );
@@ -356,6 +882,8 @@ class ChangeTags {
                        }
                }
 
+               // Cache for a very short time
+               $wgMemc->set( $key, $out, 300 );
                return $out;
        }
 }
index 7bd80c4..3f7604d 100644 (file)
@@ -951,12 +951,12 @@ $wgExiv2Command = '/usr/bin/exiv2';
  * are passed as parameters after $srcPath, $dstPath, $width, $height
  */
 $wgSVGConverters = array(
-       'ImageMagick' => '$path/convert -background white -thumbnail $widthx$height\! $input PNG:$output',
+       'ImageMagick' => '$path/convert -background "#ffffff00" -thumbnail $widthx$height\! $input PNG:$output',
        'sodipodi' => '$path/sodipodi -z -w $width -f $input -e $output',
        'inkscape' => '$path/inkscape -z -w $width -f $input -e $output',
        'batik' => 'java -Djava.awt.headless=true -jar $path/batik-rasterizer.jar -w $width -d '
                . '$output $input',
-       'rsvg' => '$path/rsvg -w $width -h $height $input $output',
+       'rsvg' => '$path/rsvg-convert -w $width -h $height -o $output $input',
        'imgserv' => '$path/imgserv-wrapper -i svg -o png -w$width $input $output',
        'ImagickExt' => array( 'SvgHandler::rasterizeImagickExt' ),
 );
@@ -1320,9 +1320,11 @@ $wgDirectoryMode = 0777;
  * Generate and use thumbnails suitable for screens with 1.5 and 2.0 pixel densities.
  *
  * This means a 320x240 use of an image on the wiki will also generate 480x360 and 640x480
- * thumbnails, output via data-src-1-5 and data-src-2-0. Runtime JavaScript switches the
- * images in after loading the original low-resolution versions depending on the reported
- * window.devicePixelRatio.
+ * thumbnails, output via the srcset attribute.
+ *
+ * On older browsers, a JavaScript polyfill switches the appropriate images in after loading
+ * the original low-resolution versions depending on the reported window.devicePixelRatio.
+ * The polyfill can be found in the jquery.hidpi module.
  */
 $wgResponsiveImages = true;
 
@@ -3541,6 +3543,9 @@ $wgResourceLoaderExperimentalAsyncLoading = false;
  *
  * Changes to LESS variables do not trigger cache invalidation.
  *
+ * If the LESS variables need to be dynamic, you can use the
+ * ResourceLoaderGetLessVars hook (since 1.25).
+ *
  * @par Example:
  * @code
  *   $wgResourceLoaderLESSVars = array(
@@ -4622,6 +4627,7 @@ $wgGroupPermissions['sysop']['suppressredirect'] = true;
 #$wgGroupPermissions['sysop']['pagelang'] = true;
 #$wgGroupPermissions['sysop']['upload_by_url'] = true;
 $wgGroupPermissions['sysop']['mergehistory'] = true;
+$wgGroupPermissions['sysop']['managechangetags'] = true;
 
 // Permission to change users' group assignments
 $wgGroupPermissions['bureaucrat']['userrights'] = true;
@@ -6416,6 +6422,7 @@ $wgJobClasses = array(
        'AssembleUploadChunks' => 'AssembleUploadChunksJob',
        'PublishStashedFile' => 'PublishStashedFileJob',
        'ThumbnailRender' => 'ThumbnailRenderJob',
+       'recentChangesUpdate' => 'RecentChangesUpdateJob',
        'null' => 'NullJob'
 );
 
@@ -6565,6 +6572,7 @@ $wgLogTypes = array(
        'patrol',
        'merge',
        'suppress',
+       'managetags',
 );
 
 /**
@@ -6693,6 +6701,10 @@ $wgLogActionsHandlers = array(
        'upload/overwrite' => 'LogFormatter',
        'upload/revert' => 'LogFormatter',
        'merge/merge' => 'MergeLogFormatter',
+       'managetags/create' => 'LogFormatter',
+       'managetags/delete' => 'LogFormatter',
+       'managetags/activate' => 'LogFormatter',
+       'managetags/deactivate' => 'LogFormatter',
 );
 
 /**
index 2fdfa42..9be3f57 100644 (file)
@@ -184,7 +184,8 @@ class FeedItem {
 }
 
 /**
- * @todo document (needs one-sentence top-level class description).
+ * Class to support the outputting of syndication feeds in Atom and RSS format.
+ *
  * @ingroup Feed
  */
 abstract class ChannelFeed extends FeedItem {
@@ -338,13 +339,14 @@ class RSSFeed extends ChannelFeed {
  */
 class AtomFeed extends ChannelFeed {
        /**
-        * @todo document
-        * @param string|int $ts
+        * Format a date given timestamp.
+        *
+        * @param string|int $timestamp
         * @return string
         */
-       function formatTime( $ts ) {
+       function formatTime( $timestamp ) {
                // need to use RFC 822 time format at least for rss2.0
-               return gmdate( 'Y-m-d\TH:i:s', wfTimestamp( TS_UNIX, $ts ) );
+               return gmdate( 'Y-m-d\TH:i:s', wfTimestamp( TS_UNIX, $timestamp ) );
        }
 
        /**
index 2025e17..5232413 100644 (file)
@@ -4198,3 +4198,91 @@ function wfIsConfiguredProxy( $ip ) {
        wfDeprecated( __METHOD__, '1.24' );
        return IP::isConfiguredProxy( $ip );
 }
+
+/**
+ * Returns true if these thumbnail parameters match one that MediaWiki
+ * requests from file description pages and/or parser output.
+ *
+ * $params is considered non-standard if they involve a non-standard
+ * width or any non-default parameters aside from width and page number.
+ * The number of possible files with standard parameters is far less than
+ * that of all combinations; rate-limiting for them can thus be more generious.
+ *
+ * @param File $file
+ * @param array $params
+ * @return bool
+ * @since 1.24 Moved from thumb.php to GlobalFunctions in 1.25
+ */
+function wfThumbIsStandard( File $file, array $params ) {
+       global $wgThumbLimits, $wgImageLimits, $wgResponsiveImages;
+
+       $multipliers = array( 1 );
+       if ( $wgResponsiveImages ) {
+               // These available sizes are hardcoded currently elsewhere in MediaWiki.
+               // @see Linker::processResponsiveImages
+               $multipliers[] = 1.5;
+               $multipliers[] = 2;
+       }
+
+       $handler = $file->getHandler();
+       if ( !$handler || !isset( $params['width'] ) ) {
+               return false;
+       }
+
+       $basicParams = array();
+       if ( isset( $params['page'] ) ) {
+               $basicParams['page'] = $params['page'];
+       }
+
+       $thumbLimits = array();
+       $imageLimits = array();
+       // Expand limits to account for multipliers
+       foreach ( $multipliers as $multiplier ) {
+               $thumbLimits = array_merge( $thumbLimits, array_map(
+                       function ( $width ) use ( $multiplier ) {
+                               return round( $width * $multiplier );
+                       }, $wgThumbLimits )
+               );
+               $imageLimits = array_merge( $imageLimits, array_map(
+                       function ( $pair ) use ( $multiplier ) {
+                               return array(
+                                       round( $pair[0] * $multiplier ),
+                                       round( $pair[1] * $multiplier ),
+                               );
+                       }, $wgImageLimits )
+               );
+       }
+
+       // Check if the width matches one of $wgThumbLimits
+       if ( in_array( $params['width'], $thumbLimits ) ) {
+               $normalParams = $basicParams + array( 'width' => $params['width'] );
+               // Append any default values to the map (e.g. "lossy", "lossless", ...)
+               $handler->normaliseParams( $file, $normalParams );
+       } else {
+               // If not, then check if the width matchs one of $wgImageLimits
+               $match = false;
+               foreach ( $imageLimits as $pair ) {
+                       $normalParams = $basicParams + array( 'width' => $pair[0], 'height' => $pair[1] );
+                       // Decide whether the thumbnail should be scaled on width or height.
+                       // Also append any default values to the map (e.g. "lossy", "lossless", ...)
+                       $handler->normaliseParams( $file, $normalParams );
+                       // Check if this standard thumbnail size maps to the given width
+                       if ( $normalParams['width'] == $params['width'] ) {
+                               $match = true;
+                               break;
+                       }
+               }
+               if ( !$match ) {
+                       return false; // not standard for description pages
+               }
+       }
+
+       // Check that the given values for non-page, non-width, params are just defaults
+       foreach ( $params as $key => $value ) {
+               if ( !isset( $normalParams[$key] ) || $normalParams[$key] != $value ) {
+                       return false;
+               }
+       }
+
+       return true;
+}
index 9d1bbc0..7eff5da 100644 (file)
@@ -45,10 +45,10 @@ class WikiImporter {
 
        /**
         * Creates an ImportXMLReader drawing from the source provided
-        * @param ImportStreamSource $source
+        * @param ImportSource $source
         * @param Config $config
         */
-       function __construct( ImportStreamSource $source, Config $config = null ) {
+       function __construct( ImportSource $source, Config $config = null ) {
                $this->reader = new XMLReader();
                if ( !$config ) {
                        wfDeprecated( __METHOD__ . ' without a Config instance', '1.25' );
@@ -497,36 +497,48 @@ class WikiImporter {
 
                $keepReading = $this->reader->read();
                $skip = false;
-               while ( $keepReading ) {
-                       $tag = $this->reader->name;
-                       $type = $this->reader->nodeType;
-
-                       if ( !Hooks::run( 'ImportHandleToplevelXMLTag', array( $this ) ) ) {
-                               // Do nothing
-                       } elseif ( $tag == 'mediawiki' && $type == XMLReader::END_ELEMENT ) {
-                               break;
-                       } elseif ( $tag == 'siteinfo' ) {
-                               $this->handleSiteInfo();
-                       } elseif ( $tag == 'page' ) {
-                               $this->handlePage();
-                       } elseif ( $tag == 'logitem' ) {
-                               $this->handleLogItem();
-                       } elseif ( $tag != '#text' ) {
-                               $this->warn( "Unhandled top-level XML tag $tag" );
-
-                               $skip = true;
-                       }
+               $rethrow = null;
+               try {
+                       while ( $keepReading ) {
+                               $tag = $this->reader->name;
+                               $type = $this->reader->nodeType;
+
+                               if ( !Hooks::run( 'ImportHandleToplevelXMLTag', array( $this ) ) ) {
+                                       // Do nothing
+                               } elseif ( $tag == 'mediawiki' && $type == XMLReader::END_ELEMENT ) {
+                                       break;
+                               } elseif ( $tag == 'siteinfo' ) {
+                                       $this->handleSiteInfo();
+                               } elseif ( $tag == 'page' ) {
+                                       $this->handlePage();
+                               } elseif ( $tag == 'logitem' ) {
+                                       $this->handleLogItem();
+                               } elseif ( $tag != '#text' ) {
+                                       $this->warn( "Unhandled top-level XML tag $tag" );
+
+                                       $skip = true;
+                               }
 
-                       if ( $skip ) {
-                               $keepReading = $this->reader->next();
-                               $skip = false;
-                               $this->debug( "Skip" );
-                       } else {
-                               $keepReading = $this->reader->read();
+                               if ( $skip ) {
+                                       $keepReading = $this->reader->next();
+                                       $skip = false;
+                                       $this->debug( "Skip" );
+                               } else {
+                                       $keepReading = $this->reader->read();
+                               }
                        }
+               } catch ( Exception $ex ) {
+                       $rethrow = $ex;
                }
 
+               // finally
                libxml_disable_entity_loader( $oldDisable );
+               $this->reader->close();
+
+               if ( $rethrow ) {
+                       throw $rethrow;
+               }
+
                return true;
        }
 
@@ -967,10 +979,10 @@ class UploadSourceAdapter {
        private $mPosition;
 
        /**
-        * @param ImportStreamSource $source
+        * @param ImportSource $source
         * @return string
         */
-       static function registerSource( ImportStreamSource $source ) {
+       static function registerSource( ImportSource $source ) {
                $id = wfRandomString();
 
                self::$sourceRegistrations[$id] = $source;
@@ -1708,6 +1720,30 @@ class WikiRevision {
 
 }
 
+/**
+ * Source interface for XML import.
+ */
+interface ImportSource {
+
+       /**
+        * Indicates whether the end of the input has been reached.
+        * Will return true after a finite number of calls to readChunk.
+        *
+        * @return bool true if there is no more input, false otherwise.
+        */
+       function atEnd();
+
+       /**
+        * Return a chunk of the input, as a (possibly empty) string.
+        * When the end of input is reached, readChunk() returns false.
+        * If atEnd() returns false, readChunk() will return a string.
+        * If atEnd() returns true, readChunk() will return false.
+        *
+        * @return bool|string
+        */
+       function readChunk();
+}
+
 /**
  * Used for importing XML dumps where the content of the dump is in a string.
  * This class is ineffecient, and should only be used for small dumps.
@@ -1715,7 +1751,7 @@ class WikiRevision {
  *
  * @ingroup SpecialPage
  */
-class ImportStringSource {
+class ImportStringSource implements ImportSource {
        function __construct( $string ) {
                $this->mString = $string;
                $this->mRead = false;
@@ -1744,7 +1780,7 @@ class ImportStringSource {
  * Imports a XML dump from a file (either from file upload, files on disk, or HTTP)
  * @ingroup SpecialPage
  */
-class ImportStreamSource {
+class ImportStreamSource implements ImportSource {
        function __construct( $handle ) {
                $this->mHandle = $handle;
        }
index 3a039f6..238bb53 100644 (file)
@@ -1464,9 +1464,9 @@ class Linker {
 
                                                if ( $wikiId !== null ) {
                                                        $thelink = Linker::makeExternalLink(
-                                                               WikiMap::getForeignURL( $wikiId, $target->getPrefixedURL() ),
+                                                               WikiMap::getForeignURL( $wikiId, $target->getFullText() ),
                                                                $linkText . $inside,
-                                                               true
+                                                               /* escape = */ false // Already escaped
                                                        ) . $trail;
                                                } else {
                                                        $thelink = Linker::link(
index d94443b..431397f 100644 (file)
@@ -608,9 +608,11 @@ class MediaWiki {
                        $n = intval( $jobRunRate );
                }
 
+               $runJobsLogger = MWLoggerFactory::getInstance( 'runJobs' );
+
                if ( !$this->config->get( 'RunJobsAsync' ) ) {
                        // Fall back to running the job here while the user waits
-                       $runner = new JobRunner();
+                       $runner = new JobRunner( $runJobsLogger );
                        $runner->run( array( 'maxJobs'  => $n ) );
                        return;
                }
@@ -643,9 +645,9 @@ class MediaWiki {
                );
                wfRestoreWarnings();
                if ( !$sock ) {
-                       wfDebugLog( 'runJobs', "Failed to start cron API (socket error $errno): $errstr\n" );
+                       $runJobsLogger->error( "Failed to start cron API (socket error $errno): $errstr" );
                        // Fall back to running the job here while the user waits
-                       $runner = new JobRunner();
+                       $runner = new JobRunner( $runJobsLogger );
                        $runner->run( array( 'maxJobs'  => $n ) );
                        return;
                }
@@ -653,19 +655,19 @@ class MediaWiki {
                $url = wfAppendQuery( wfScript( 'index' ), $query );
                $req = "POST $url HTTP/1.1\r\nHost: {$info['host']}\r\nConnection: Close\r\nContent-Length: 0\r\n\r\n";
 
-               wfDebugLog( 'runJobs', "Running $n job(s) via '$url'\n" );
+               $runJobsLogger->info( "Running $n job(s) via '$url'" );
                // Send a cron API request to be performed in the background.
                // Give up if this takes too long to send (which should be rare).
                stream_set_timeout( $sock, 1 );
                $bytes = fwrite( $sock, $req );
                if ( $bytes !== strlen( $req ) ) {
-                       wfDebugLog( 'runJobs', "Failed to start cron API (socket write error)\n" );
+                       $runJobsLogger->error( "Failed to start cron API (socket write error)" );
                } else {
                        // Do not wait for the response (the script should handle client aborts).
                        // Make sure that we don't close before that script reaches ignore_user_abort().
                        $status = fgets( $sock );
                        if ( !preg_match( '#^HTTP/\d\.\d 202 #', $status ) ) {
-                               wfDebugLog( 'runJobs', "Failed to start cron API: received '$status'\n" );
+                               $runJobsLogger->error( "Failed to start cron API: received '$status'" );
                        }
                }
                fclose( $sock );
index 93a37cb..49437f4 100644 (file)
  *
  * @since 1.17
  */
-class Message {
+class Message implements MessageSpecifier {
 
        /**
         * In which language to get this message. True, which is the default,
@@ -276,7 +276,7 @@ class Message {
         * Returns the message key.
         *
         * If a list of multiple possible keys was supplied to the constructor, this method may
-        * return any of these keys. After the message ahs been fetched, this method will return
+        * return any of these keys. After the message has been fetched, this method will return
         * the key that was actually used to fetch the message.
         *
         * @since 1.21
index 90cc35a..d535028 100644 (file)
@@ -121,7 +121,9 @@ class Revision implements IDBAccessObject {
                if ( $id ) {
                        // Use the specified ID
                        $conds['rev_id'] = $id;
-                       return self::newFromConds( $conds, (int)$flags );
+                       // This uses slave->master fallback with READ_NORMAL. Assuming revdelete,
+                       // moves, and merges are rare, callers can use this to reduce master queries.
+                       return self::newFromConds( $conds, $flags );
                } else {
                        // Use a join to get the latest revision
                        $conds[] = 'rev_id=page_latest';
@@ -148,11 +150,15 @@ class Revision implements IDBAccessObject {
                $conds = array( 'page_id' => $pageId );
                if ( $revId ) {
                        $conds['rev_id'] = $revId;
+                       // This uses slave->master fallback with READ_NORMAL. Assuming revdelete
+                       // and merges are rare, callers can use this to reduce master queries.
+                       return self::newFromConds( $conds, $flags );
                } else {
                        // Use a join to get the latest revision
                        $conds[] = 'rev_id = page_latest';
+                       $db = wfGetDB( ( $flags & self::READ_LATEST ) ? DB_MASTER : DB_SLAVE );
+                       return self::loadFromConds( $db, $conds, $flags );
                }
-               return self::newFromConds( $conds, (int)$flags );
        }
 
        /**
index f79e94d..a2de004 100644 (file)
@@ -39,6 +39,12 @@ class Sanitizer {
                 |&\#[xX]([0-9A-Fa-f]+);
                 |(&)/x';
 
+       /**
+        * Acceptable tag name charset from HTML5 parsing spec
+        * http://dev.w3.org/html5/spec-preview/tokenization.html#tag-open-state
+        */
+       const ELEMENT_BITS_REGEX = '!^(/?)([A-Za-z][^\t\n\v />\0]*+)([^>]*?)(/?>)([^<]*)$!';
+
        /**
         * Blacklist for evil uris like javascript:
         * WARNING: DO NOT use this in any place that actually requires blacklisting
@@ -444,7 +450,7 @@ class Sanitizer {
                                # $params: String between element name and >
                                # $brace: Ending '>' or '/>'
                                # $rest: Everything until the next element of $bits
-                               if ( preg_match( '!^(/?)([^\\s/>]+)([^>]*?)(/{0,1}>)([^<]*)$!', $x, $regs ) ) {
+                               if ( preg_match( self::ELEMENT_BITS_REGEX, $x, $regs ) ) {
                                        list( /* $qbar */, $slash, $t, $params, $brace, $rest ) = $regs;
                                } else {
                                        $slash = $t = $params = $brace = $rest = null;
@@ -567,11 +573,7 @@ class Sanitizer {
                } else {
                        # this might be possible using tidy itself
                        foreach ( $bits as $x ) {
-                               preg_match(
-                                       '/^(\\/?)(\\w+)([^>]*?)(\\/{0,1}>)([^<]*)$/',
-                                       $x,
-                                       $regs
-                               );
+                               preg_match( self::ELEMENT_BITS_REGEX, $x, $regs );
 
                                wfSuppressWarnings();
                                list( /* $qbar */, $slash, $t, $params, $brace, $rest ) = $regs;
index fb267bd..61a0047 100644 (file)
  * so that a lack of error-handling will be explicit.
  */
 class Status {
-       /** @var bool */
-       public $ok = true;
+       /** @var StatusValue */
+       protected $sv;
 
        /** @var mixed */
        public $value;
-
-       /** Counters for batch operations */
-       /** @var int */
+       /** @var array Map of (key => bool) to indicate success of each part of batch operations */
+       public $success = array();
+       /** @var int Counter for batch operations */
        public $successCount = 0;
-
-       /** @var int */
+       /** @var int Counter for batch operations */
        public $failCount = 0;
 
-       /** Array to indicate which items of the batch operations were successful */
-       /** @var array */
-       public $success = array();
-
-       /** @var array */
-       public $errors = array();
-
        /** @var callable */
        public $cleanCallback = false;
 
+       /**
+        * @param StatusValue $sv [optional]
+        */
+       public function __construct( StatusValue $sv = null ) {
+               $this->sv = ( $sv === null ) ? new StatusValue() : $sv;
+               // B/C field aliases
+               $this->value =& $this->sv->value;
+               $this->successCount =& $this->sv->successCount;
+               $this->failCount =& $this->sv->failCount;
+               $this->success =& $this->sv->success;
+       }
+
+       /**
+        * Succinct helper method to wrap a StatusValue
+        *
+        * This is is useful when formatting StatusValue objects:
+        * <code>
+        *     $this->getOutput()->addHtml( Status::wrap( $sv )->getHTML() );
+        * </code>
+        *
+        * @param StatusValue|Status $sv
+        * @return Status
+        */
+       public static function wrap( $sv ) {
+               return $sv instanceof Status ? $sv : new self( $sv );
+       }
+
        /**
         * Factory function for fatal errors
         *
         * @param string|Message $message Message name or object
         * @return Status
         */
-       static function newFatal( $message /*, parameters...*/ ) {
-               $params = func_get_args();
-               $result = new self;
-               call_user_func_array( array( &$result, 'error' ), $params );
-               $result->ok = false;
-               return $result;
+       public static function newFatal( $message /*, parameters...*/ ) {
+               return new self( call_user_func_array(
+                       array( 'StatusValue', 'newFatal' ), func_get_args()
+               ) );
        }
 
        /**
@@ -81,10 +98,11 @@ class Status {
         * @param mixed $value
         * @return Status
         */
-       static function newGood( $value = null ) {
-               $result = new self;
-               $result->value = $value;
-               return $result;
+       public static function newGood( $value = null ) {
+               $sv = new StatusValue();
+               $sv->value = $value;
+
+               return new self( $sv );
        }
 
        /**
@@ -94,8 +112,7 @@ class Status {
         * @param mixed $value
         */
        public function setResult( $ok, $value = null ) {
-               $this->ok = $ok;
-               $this->value = $value;
+               $this->sv->setResult( $ok, $value );
        }
 
        /**
@@ -105,7 +122,7 @@ class Status {
         * @return bool
         */
        public function isGood() {
-               return $this->ok && !$this->errors;
+               return $this->sv->isGood();
        }
 
        /**
@@ -114,7 +131,7 @@ class Status {
         * @return bool
         */
        public function isOK() {
-               return $this->ok;
+               return $this->sv->isOK();
        }
 
        /**
@@ -123,11 +140,7 @@ class Status {
         * @param string|Message $message Message name or object
         */
        public function warning( $message /*, parameters... */ ) {
-               $params = array_slice( func_get_args(), 1 );
-               $this->errors[] = array(
-                       'type' => 'warning',
-                       'message' => $message,
-                       'params' => $params );
+               call_user_func_array( array( $this->sv, 'warning' ), func_get_args() );
        }
 
        /**
@@ -137,11 +150,7 @@ class Status {
         * @param string|Message $message Message name or object
         */
        public function error( $message /*, parameters... */ ) {
-               $params = array_slice( func_get_args(), 1 );
-               $this->errors[] = array(
-                       'type' => 'error',
-                       'message' => $message,
-                       'params' => $params );
+               call_user_func_array( array( $this->sv, 'error' ), func_get_args() );
        }
 
        /**
@@ -151,35 +160,14 @@ class Status {
         * @param string|Message $message Message name or object
         */
        public function fatal( $message /*, parameters... */ ) {
-               $params = array_slice( func_get_args(), 1 );
-               $this->errors[] = array(
-                       'type' => 'error',
-                       'message' => $message,
-                       'params' => $params );
-               $this->ok = false;
-       }
-
-       /**
-        * Don't save the callback when serializing, because Closures can't be
-        * serialized and we're going to clear it in __wakeup anyway.
-        */
-       public function __sleep() {
-               $keys = array_keys( get_object_vars( $this ) );
-               return array_diff( $keys, array( 'cleanCallback' ) );
-       }
-
-       /**
-        * Sanitize the callback parameter on wakeup, to avoid arbitrary execution.
-        */
-       public function __wakeup() {
-               $this->cleanCallback = false;
+               call_user_func_array( array( $this->sv, 'fatal' ), func_get_args() );
        }
 
        /**
         * @param array $params
         * @return array
         */
-       protected function cleanParams( $params ) {
+       protected function cleanParams( array $params ) {
                if ( !$this->cleanCallback ) {
                        return $params;
                }
@@ -199,24 +187,26 @@ class Status {
         * @return string
         */
        public function getWikiText( $shortContext = false, $longContext = false ) {
-               if ( count( $this->errors ) == 0 ) {
-                       if ( $this->ok ) {
-                               $this->fatal( 'internalerror_info',
+               $rawErrors = $this->sv->getErrors();
+               if ( count( $rawErrors ) == 0 ) {
+                       if ( $this->sv->isOK() ) {
+                               $this->sv->fatal( 'internalerror_info',
                                        __METHOD__ . " called for a good result, this is incorrect\n" );
                        } else {
-                               $this->fatal( 'internalerror_info',
+                               $this->sv->fatal( 'internalerror_info',
                                        __METHOD__ . ": Invalid result object: no error text but not OK\n" );
                        }
+                       $rawErrors = $this->sv->getErrors(); // just added a fatal
                }
-               if ( count( $this->errors ) == 1 ) {
-                       $s = $this->getErrorMessage( $this->errors[0] )->plain();
+               if ( count( $rawErrors ) == 1 ) {
+                       $s = $this->getErrorMessage( $rawErrors[0] )->plain();
                        if ( $shortContext ) {
                                $s = wfMessage( $shortContext, $s )->plain();
                        } elseif ( $longContext ) {
                                $s = wfMessage( $longContext, "* $s\n" )->plain();
                        }
                } else {
-                       $errors = $this->getErrorMessageArray( $this->errors );
+                       $errors = $this->getErrorMessageArray( $rawErrors );
                        foreach ( $errors as &$error ) {
                                $error = $error->plain();
                        }
@@ -241,17 +231,19 @@ class Status {
         * @return Message
         */
        public function getMessage( $shortContext = false, $longContext = false ) {
-               if ( count( $this->errors ) == 0 ) {
-                       if ( $this->ok ) {
-                               $this->fatal( 'internalerror_info',
+               $rawErrors = $this->sv->getErrors();
+               if ( count( $rawErrors ) == 0 ) {
+                       if ( $this->sv->isOK() ) {
+                               $this->sv->fatal( 'internalerror_info',
                                        __METHOD__ . " called for a good result, this is incorrect\n" );
                        } else {
-                               $this->fatal( 'internalerror_info',
+                               $this->sv->fatal( 'internalerror_info',
                                        __METHOD__ . ": Invalid result object: no error text but not OK\n" );
                        }
+                       $rawErrors = $this->sv->getErrors(); // just added a fatal
                }
-               if ( count( $this->errors ) == 1 ) {
-                       $s = $this->getErrorMessage( $this->errors[0] );
+               if ( count( $rawErrors ) == 1 ) {
+                       $s = $this->getErrorMessage( $rawErrors[0] );
                        if ( $shortContext ) {
                                $s = wfMessage( $shortContext, $s );
                        } elseif ( $longContext ) {
@@ -260,7 +252,7 @@ class Status {
                                $s = wfMessage( $longContext, $wrapper );
                        }
                } else {
-                       $msgs = $this->getErrorMessageArray( $this->errors );
+                       $msgs = $this->getErrorMessageArray( $rawErrors );
                        $msgCount = count( $msgs );
 
                        if ( $shortContext ) {
@@ -339,13 +331,7 @@ class Status {
         * @param bool $overwriteValue Whether to override the "value" member
         */
        public function merge( $other, $overwriteValue = false ) {
-               $this->errors = array_merge( $this->errors, $other->errors );
-               $this->ok = $this->ok && $other->ok;
-               if ( $overwriteValue ) {
-                       $this->value = $other->value;
-               }
-               $this->successCount += $other->successCount;
-               $this->failCount += $other->failCount;
+               $this->sv->merge( $other->sv, $overwriteValue );
        }
 
        /**
@@ -353,9 +339,10 @@ class Status {
         *
         * @return array A list in which each entry is an array with a message key as its first element.
         *         The remaining array elements are the message parameters.
+        * @deprecated 1.25
         */
        public function getErrorsArray() {
-               return $this->getStatusArray( "error" );
+               return $this->getStatusArray( 'error' );
        }
 
        /**
@@ -363,21 +350,26 @@ class Status {
         *
         * @return array A list in which each entry is an array with a message key as its first element.
         *         The remaining array elements are the message parameters.
+        * @deprecated 1.25
         */
        public function getWarningsArray() {
-               return $this->getStatusArray( "warning" );
+               return $this->getStatusArray( 'warning' );
        }
 
        /**
         * Returns a list of status messages of the given type (or all if false)
+        *
+        * @note: this handles RawMessage poorly
+        *
         * @param string $type
         * @return array
         */
        protected function getStatusArray( $type = false ) {
                $result = array();
-               foreach ( $this->errors as $error ) {
+
+               foreach ( $this->sv->getErrors() as $error ) {
                        if ( $type === false || $error['type'] === $type ) {
-                               if ( $error['message'] instanceof Message ) {
+                               if ( $error['message'] instanceof MessageSpecifier ) {
                                        $result[] = array_merge(
                                                array( $error['message']->getKey() ),
                                                $error['message']->getParams()
@@ -402,13 +394,7 @@ class Status {
         * @return array
         */
        public function getErrorsByType( $type ) {
-               $result = array();
-               foreach ( $this->errors as $error ) {
-                       if ( $error['type'] === $type ) {
-                               $result[] = $error;
-                       }
-               }
-               return $result;
+               return $this->sv->getErrorsByType( $type );
        }
 
        /**
@@ -419,19 +405,7 @@ class Status {
         * @return bool
         */
        public function hasMessage( $message ) {
-               if ( $message instanceof Message ) {
-                       $message = $message->getKey();
-               }
-               foreach ( $this->errors as $error ) {
-                       if ( $error['message'] instanceof Message
-                               && $error['message']->getKey() === $message
-                       ) {
-                               return true;
-                       } elseif ( $error['message'] === $message ) {
-                               return true;
-                       }
-               }
-               return false;
+               return $this->sv->hasMessage( $message );
        }
 
        /**
@@ -446,61 +420,67 @@ class Status {
         * @return bool Return true if the replacement was done, false otherwise.
         */
        public function replaceMessage( $source, $dest ) {
-               $replaced = false;
-               foreach ( $this->errors as $index => $error ) {
-                       if ( $error['message'] === $source ) {
-                               $this->errors[$index]['message'] = $dest;
-                               $replaced = true;
-                       }
-               }
-               return $replaced;
+               return $this->sv->replaceMessage( $source, $dest );
        }
 
        /**
         * @return mixed
         */
        public function getValue() {
-               return $this->value;
+               return $this->sv->getValue();
        }
 
        /**
-        * @return string
+        * Backwards compatibility logic
+        *
+        * @param string $name
         */
-       public function __toString() {
-               $status = $this->isOK() ? "OK" : "Error";
-               if ( count( $this->errors ) ) {
-                       $errorcount = "collected " . ( count( $this->errors ) ) . " error(s) on the way";
-               } else {
-                       $errorcount = "no errors detected";
+       function __get( $name ) {
+               if ( $name === 'ok' ) {
+                       return $this->sv->getOK();
+               } elseif ( $name === 'errors' ) {
+                       return $this->sv->getErrors();
                }
-               if ( isset( $this->value ) ) {
-                       $valstr = gettype( $this->value ) . " value set";
-                       if ( is_object( $this->value ) ) {
-                               $valstr .= "\"" . get_class( $this->value ) . "\" instance";
-                       }
+               throw new Exception( "Cannot get '$name' property." );
+       }
+
+       /**
+        * Backwards compatibility logic
+        *
+        * @param string $name
+        * @param mixed $value
+        */
+       function __set( $name, $value ) {
+               if ( $name === 'ok' ) {
+                       $this->sv->setOK( $value );
+               } elseif ( !property_exists( $this, $name ) ) {
+                       // Caller is using undeclared ad-hoc properties
+                       $this->$name = $value;
                } else {
-                       $valstr = "no value set";
+                       throw new Exception( "Cannot set '$name' property." );
                }
-               $out = sprintf( "<%s, %s, %s>",
-                       $status,
-                       $errorcount,
-                       $valstr
-               );
-               if ( count( $this->errors ) > 0 ) {
-                       $hdr = sprintf( "+-%'-4s-+-%'-25s-+-%'-40s-+\n", "", "", "" );
-                       $i = 1;
-                       $out .= "\n";
-                       $out .= $hdr;
-                       foreach ( $this->getStatusArray() as $stat ) {
-                               $out .= sprintf( "| %4d | %-25.25s | %-40.40s |\n",
-                                       $i,
-                                       $stat[0],
-                                       implode( " ", array_slice( $stat, 1 ) )
-                               );
-                               $i += 1;
-                       }
-                       $out .= $hdr;
-               };
-               return $out;
+       }
+
+       /**
+        * @return string
+        */
+       public function __toString() {
+               return $this->sv->__toString();
+       }
+
+       /**
+        * Don't save the callback when serializing, because Closures can't be
+        * serialized and we're going to clear it in __wakeup anyway.
+        */
+       function __sleep() {
+               $keys = array_keys( get_object_vars( $this ) );
+               return array_diff( $keys, array( 'cleanCallback' ) );
+       }
+
+       /**
+        * Sanitize the callback parameter on wakeup, to avoid arbitrary execution.
+        */
+       function __wakeup() {
+               $this->cleanCallback = false;
        }
 }
index 463f75e..4a372fb 100644 (file)
@@ -2749,7 +2749,6 @@ class Title {
 
                $sources = $getPages ? array() : false;
                $now = wfTimestampNow();
-               $purgeExpired = false;
 
                foreach ( $res as $row ) {
                        $expiry = $wgContLang->formatExpiry( $row->pr_expiry, TS_MW );
@@ -2775,14 +2774,8 @@ class Title {
                                } else {
                                        $sources = true;
                                }
-                       } else {
-                               // Trigger lazy purge of expired restrictions from the db
-                               $purgeExpired = true;
                        }
                }
-               if ( $purgeExpired ) {
-                       Title::purgeExpiredRestrictions();
-               }
 
                if ( $getPages ) {
                        $this->mCascadeSources = $sources;
@@ -2933,7 +2926,6 @@ class Title {
                if ( count( $rows ) ) {
                        # Current system - load second to make them override.
                        $now = wfTimestampNow();
-                       $purgeExpired = false;
 
                        # Cycle through all the restrictions.
                        foreach ( $rows as $row ) {
@@ -2953,15 +2945,8 @@ class Title {
                                        $this->mRestrictions[$row->pr_type] = explode( ',', trim( $row->pr_level ) );
 
                                        $this->mCascadeRestriction |= $row->pr_cascade;
-                               } else {
-                                       // Trigger a lazy purge of expired restrictions
-                                       $purgeExpired = true;
                                }
                        }
-
-                       if ( $purgeExpired ) {
-                               Title::purgeExpiredRestrictions();
-                       }
                }
 
                $this->mRestrictionsLoaded = true;
@@ -2999,7 +2984,6 @@ class Title {
                                                $this->mRestrictionsExpiry['create'] = $expiry;
                                                $this->mRestrictions['create'] = explode( ',', trim( $title_protection['permission'] ) );
                                        } else { // Get rid of the old restrictions
-                                               Title::purgeExpiredRestrictions();
                                                $this->mTitleProtection = false;
                                        }
                                } else {
@@ -3607,7 +3591,7 @@ class Title {
         *
         * @deprecated since 1.25, use MovePage's methods instead
         * @param Title $nt The new title
-        * @param bool $auth Ignored
+        * @param bool $auth Whether to check user permissions (uses $wgUser)
         * @param string $reason Is the log summary of the move, used for spam checking
         * @return array|bool True on success, getUserPermissionsErrors()-like array on failure
         */
@@ -3621,10 +3605,13 @@ class Title {
                }
 
                $mp = new MovePage( $this, $nt );
-               $errors = wfMergeErrorArrays(
-                       $mp->isValidMove()->getErrorsArray(),
-                       $mp->checkPermissions( $wgUser, $reason )->getErrorsArray()
-               );
+               $errors = $mp->isValidMove()->getErrorsArray();
+               if ( $auth ) {
+                       $errors = wfMergeErrorArrays(
+                               $errors,
+                               $mp->checkPermissions( $wgUser, $reason )->getErrorsArray()
+                       );
+               }
 
                return $errors ? : true;
        }
index dd199ee..c2db67a 100644 (file)
@@ -134,6 +134,7 @@ class User implements IDBAccessObject {
                'import',
                'importupload',
                'ipblock-exempt',
+               'managechangetags',
                'markbotedits',
                'mergehistory',
                'minoredit',
index 53c69d8..3be5847 100644 (file)
@@ -211,6 +211,8 @@ class UserRightsProxy {
        /**
         * Replaces User::addUserGroup()
         * @param string $group
+        *
+        * @return bool
         */
        function addGroup( $group ) {
                $this->db->insert( 'user_groups',
@@ -220,11 +222,15 @@ class UserRightsProxy {
                        ),
                        __METHOD__,
                        array( 'IGNORE' ) );
+
+               return true;
        }
 
        /**
         * Replaces User::removeUserGroup()
         * @param string $group
+        *
+        * @return bool
         */
        function removeGroup( $group ) {
                $this->db->delete( 'user_groups',
@@ -233,6 +239,8 @@ class UserRightsProxy {
                                'ug_group' => $group,
                        ),
                        __METHOD__ );
+
+               return true;
        }
 
        /**
index 1e2f889..7189372 100644 (file)
@@ -67,8 +67,7 @@ class HistoryAction extends FormlessAction {
        }
 
        /**
-        * Get the Article object we are working on.
-        * @return Page
+        * @return WikiPage|Article|ImagePage|CategoryPage|Page The Article object we are working on.
         */
        public function getArticle() {
                return $this->page;
@@ -896,4 +895,5 @@ class HistoryPager extends ReverseChronologicalPager {
        function getPreventClickjacking() {
                return $this->preventClickjacking;
        }
+
 }
index 9a98054..f17b874 100644 (file)
@@ -87,6 +87,7 @@ class ApiMain extends ApiBase {
                'options' => 'ApiOptions',
                'imagerotate' => 'ApiImageRotate',
                'revisiondelete' => 'ApiRevisionDelete',
+               'managetags' => 'ApiManageTags',
        );
 
        /**
diff --git a/includes/api/ApiManageTags.php b/includes/api/ApiManageTags.php
new file mode 100644 (file)
index 0000000..b027f33
--- /dev/null
@@ -0,0 +1,107 @@
+<?php
+
+/**
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * @file
+ */
+
+/**
+ * @ingroup API
+ * @since 1.25
+ */
+class ApiManageTags extends ApiBase {
+
+       public function execute() {
+               $params = $this->extractRequestParams();
+
+               // make sure the user is allowed
+               if ( !$this->getUser()->isAllowed( 'managechangetags' ) ) {
+                       $this->dieUsage( "You don't have permission to manage change tags", 'permissiondenied' );
+               }
+
+               $result = $this->getResult();
+               $funcName = "{$params['operation']}TagWithChecks";
+               $status = ChangeTags::$funcName( $params['tag'], $params['reason'],
+                       $this->getUser(), $params['ignorewarnings'] );
+
+               if ( !$status->isOK() ) {
+                       $this->dieStatus( $status );
+               }
+
+               $ret = array(
+                       'operation' => $params['operation'],
+                       'tag' => $params['tag'],
+               );
+               if ( !$status->isGood() ) {
+                       $ret['warnings'] = $result->convertStatusToArray( $status, 'warning' );
+               }
+               if ( $status->value !== null ) {
+                       $ret['success'] = '';
+                       $ret['logid'] = $status->value;
+               }
+               $result->addValue( null, $this->getModuleName(), $ret );
+       }
+
+       public function mustBePosted() {
+               return true;
+       }
+
+       public function isWriteMode() {
+               return true;
+       }
+
+       public function getAllowedParams() {
+               return array(
+                       'operation' => array(
+                               ApiBase::PARAM_TYPE => array( 'create', 'delete', 'activate', 'deactivate' ),
+                               ApiBase::PARAM_REQUIRED => true,
+                       ),
+                       'tag' => array(
+                               ApiBase::PARAM_TYPE => 'string',
+                               ApiBase::PARAM_REQUIRED => true,
+                       ),
+                       'reason' => array(
+                               ApiBase::PARAM_TYPE => 'string',
+                       ),
+                       'ignorewarnings' => array(
+                               ApiBase::PARAM_TYPE => 'boolean',
+                               ApiBase::PARAM_DFLT => false,
+                       ),
+               );
+       }
+
+       public function needsToken() {
+               return 'csrf';
+       }
+
+       protected function getExamplesMessages() {
+               return array(
+                       'action=managetags&operation=create&tag=spam&reason=For+use+in+edit+patrolling&token=123ABC'
+                               => 'apihelp-managetags-example-create',
+                       'action=managetags&operation=delete&tag=vandlaism&reason=Misspelt&token=123ABC'
+                               => 'apihelp-managetags-example-delete',
+                       'action=managetags&operation=activate&tag=spam&reason=For+use+in+edit+patrolling&token=123ABC'
+                               => 'apihelp-managetags-example-activate',
+                       'action=managetags&operation=deactivate&tag=spam&reason=No+longer+required&token=123ABC'
+                               => 'apihelp-managetags-example-deactivate',
+               );
+       }
+
+       public function getHelpUrls() {
+               return 'https://www.mediawiki.org/wiki/API:Tag_management';
+       }
+}
index 16a491e..e489b2f 100644 (file)
@@ -174,7 +174,7 @@ class ApiQuerySearch extends ApiQueryGeneratorBase {
                                }
                                if ( !is_null( $result->getRedirectTitle() ) ) {
                                        if ( isset( $prop['redirecttitle'] ) ) {
-                                               $vals['redirecttitle'] = $result->getRedirectTitle();
+                                               $vals['redirecttitle'] = $result->getRedirectTitle()->getPrefixedText();
                                        }
                                        if ( isset( $prop['redirectsnippet'] ) ) {
                                                $vals['redirectsnippet'] = $result->getRedirectSnippet();
index f373021..4e5c42b 100644 (file)
@@ -429,10 +429,10 @@ class ApiQuerySiteinfo extends ApiQueryBase {
                        if ( substr( $row['iw_url'], 0, 2 ) == '//' ) {
                                $val['protorel'] = '';
                        }
-                       if ( isset( $row['iw_wikiid'] ) ) {
+                       if ( isset( $row['iw_wikiid'] ) && $row['iw_wikiid'] !== '' ) {
                                $val['wikiid'] = $row['iw_wikiid'];
                        }
-                       if ( isset( $row['iw_api'] ) ) {
+                       if ( isset( $row['iw_api'] ) && $row['iw_api'] !== '' ) {
                                $val['api'] = $row['iw_api'];
                        }
 
index 7f2dc85..0e3307b 100644 (file)
@@ -44,11 +44,17 @@ class ApiQueryTags extends ApiQueryBase {
                $fld_description = isset( $prop['description'] );
                $fld_hitcount = isset( $prop['hitcount'] );
                $fld_defined = isset( $prop['defined'] );
+               $fld_source = isset( $prop['source'] );
+               $fld_active = isset( $prop['active'] );
 
                $limit = $params['limit'];
                $result = $this->getResult();
 
-               $definedTags = array_fill_keys( ChangeTags::listDefinedTags(), 0 );
+               $extensionDefinedTags = array_fill_keys( ChangeTags::listExtensionDefinedTags(), 0 );
+               $explicitlyDefinedTags = array_fill_keys( ChangeTags::listExplicitlyDefinedTags(), 0 );
+               $extensionActivatedTags = array_fill_keys( ChangeTags::listExtensionActivatedTags(), 0 );
+
+               $definedTags = array_merge( $extensionDefinedTags, $explicitlyDefinedTags );
 
                # Fetch defined tags that aren't past the continuation
                if ( $params['continue'] !== null ) {
@@ -99,10 +105,29 @@ class ApiQueryTags extends ApiQueryBase {
                                $tag['hitcount'] = $hitcount;
                        }
 
-                       if ( $fld_defined && isset( $definedTags[$tagName] ) ) {
+                       $isExtension = isset( $extensionDefinedTags[$tagName] );
+                       $isExplicit = isset( $explicitlyDefinedTags[$tagName] );
+
+                       if ( $fld_defined && ( $isExtension || $isExplicit ) ) {
                                $tag['defined'] = '';
                        }
 
+                       if ( $fld_source ) {
+                               $tag['source'] = array();
+                               if ( $isExtension ) {
+                                       $tag['source'][] = 'extension';
+                               }
+                               if ( $isExplicit ) {
+                                       $tag['source'][] = 'manual';
+                               }
+                       }
+
+                       if ( $fld_active &&
+                               ( $isExplicit || isset( $extensionActivatedTags[$tagName] ) )
+                       ) {
+                               $tag['active'] = '';
+                       }
+
                        $fit = $result->addValue( array( 'query', $this->getModuleName() ), null, $tag );
                        if ( !$fit ) {
                                $this->setContinueEnumParameter( 'continue', $tagName );
@@ -137,6 +162,8 @@ class ApiQueryTags extends ApiQueryBase {
                                        'description',
                                        'hitcount',
                                        'defined',
+                                       'source',
+                                       'active',
                                ),
                                ApiBase::PARAM_ISMULTI => true
                        )
index aa38564..7fc0ba8 100644 (file)
@@ -181,7 +181,7 @@ class ApiQueryUserInfo extends ApiQueryBase {
                        if ( $count >= self::WL_UNREAD_LIMIT ) {
                                $vals['unreadcount'] = self::WL_UNREAD_LIMIT . '+';
                        } else {
-                               $vals['unreadcount'] = (int)$count;
+                               $vals['unreadcount'] = $count;
                        }
                }
 
diff --git a/includes/api/i18n/awa.json b/includes/api/i18n/awa.json
new file mode 100644 (file)
index 0000000..d094592
--- /dev/null
@@ -0,0 +1,11 @@
+{
+       "@metadata": {
+               "authors": [
+                       "1AnuraagPandey"
+               ]
+       },
+       "apihelp-block-description": "सदस्य कय अवरोधित करा जाय।",
+       "apihelp-block-param-reason": "ब्लाक करेकै कारण",
+       "apihelp-block-param-nocreate": "खाते बनावेकै रोका जाय",
+       "apihelp-edit-param-minor": "छोट संपादन"
+}
index a17b51d..a09cb5a 100644 (file)
        "apihelp-main-param-maxlag": "Максымальная затрымка можа ўжывацца, калі MediaWiki ўсталяваная ў клястэр з рэплікаванай базай зьвестак. Дзеля захаваньня дзеяньняў, якія выклікаюць затрымку рэплікацыі, гэты парамэтар можа прымусіць кліента чакаць, пакуль затрымка рэплікацыі меншая за яго значэньне. У выпадку доўгай затрымкі, вяртаецца код памылкі <samp>maxlag</samp> з паведамленьнем кшталту <samp>Чаканьне $host: $lag сэкундаў затрымкі</samp>.<br />Глядзіце [[mw:Manual:Maxlag_parameter|Інструкцыя:Парамэтар maxlag]] дзеля дадатковай інфармацыі.",
        "apihelp-main-param-smaxage": "Выстаўце загаловак <code>s-maxage</code> на зададзеную колькасьць сэкундаў. Памылкі ніколі не кэшуюцца.",
        "apihelp-main-param-maxage": "Выстаўляе загаловак <code>max-age</code> на зададзеную колькасьць сэкундаў. Памылкі ніколі не кэшуюцца.",
-       "apihelp-main-param-assert": "Упэўніцеся, што ўдзельнік увайшоў у сыстэму, калі зададзена «user», або мае правы робата, калі зададзена «bot».",
+       "apihelp-main-param-assert": "Упэўніцеся, што ўдзельнік увайшоў у сыстэму, калі зададзена <kbd>user</kbd>, або мае правы робата, калі зададзена <kbd>bot</kbd>.",
        "apihelp-main-param-requestid": "Любое значэньне, пададзенае тут, будзе ўключанае ў адказ. Можа быць выкарыстанае для адрозьненьня запытаў.",
        "apihelp-main-param-servedby": "Уключае ў вынік назву сэрвэра, які апрацаваў запыт.",
        "apihelp-main-param-curtimestamp": "Уключае ў вынік пазнаку актуальнага часу.",
-       "apihelp-main-param-origin": "Пры звароце да API з дапамогай міждамэннага AJAX-запыту (CORS), выстаўце парамэтру значэньне зыходнага дамэну. Ён мусіць быць уключаны ў кожны папярэдні запыт і такім чынам мусіць быць часткай URI-запыту (ня цела POST). Ён мусіць супадаць з адной з крыніц у загалоўку Origin, павінна быць зададзена нешта кшталту http://en.wikipedia.org або https://meta.wikimedia.org. Калі парамэтар не супадае з загалоўкам Origin, будзе вернуты адказ з кодам памылкі 403. Калі парамэтар супадае з загалоўкам Origin і крыніца знаходзіцца ў белым сьпісе, будзе выстаўлены загаловак Access-Control-Allow-Origin.",
-       "apihelp-main-param-uselang": "Мова для выкарыстаньня ў перакладах паведамленьняў. Сьпіс кодаў можа быць атрыманы з [[Special:ApiHelp/query+siteinfo|action=query&meta=siteinfo]] з siprop=languages, або трэба вызначыць «user», каб ужываць наладкі мовы цяперашняга карыстальніка, або вызначыць «content», каб ужываць мову зьместу гэтай вікі.",
+       "apihelp-main-param-origin": "Пры звароце да API з дапамогай міждамэннага AJAX-запыту (CORS), выстаўце парамэтру значэньне зыходнага дамэну. Ён мусіць быць уключаны ў кожны папярэдні запыт і такім чынам мусіць быць часткай URI-запыту (ня цела POST). Ён мусіць супадаць з адной з крыніц у загалоўку <code>Origin</code>, павінна быць зададзена нешта кшталту <kbd>https://en.wikipedia.org</kbd> або <kbd>https://meta.wikimedia.org</kbd>. Калі парамэтар не супадае з загалоўкам <code>Origin</code>, будзе вернуты адказ з кодам памылкі 403. Калі парамэтар супадае з загалоўкам <code>Origin</code> і крыніца знаходзіцца ў белым сьпісе, будзе выстаўлены загаловак <code>Access-Control-Allow-Origin</code>.",
+       "apihelp-main-param-uselang": "Мова для выкарыстаньня ў перакладах паведамленьняў. Сьпіс кодаў можа быць атрыманы з <kbd>[[Special:ApiHelp/query+siteinfo|action=query&meta=siteinfo]]</kbd> з <kbd>siprop=languages</kbd>, або трэба вызначыць <kbd>user</kbd>, каб ужываць наладкі мовы цяперашняга карыстальніка, або вызначыць <kbd>content</kbd>, каб ужываць мову зьместу гэтай вікі.",
        "apihelp-block-description": "Блякаваньне ўдзельніка.",
        "apihelp-block-param-user": "Імя ўдзельніка, IP-адрас або IP-дыяпазон, якія вы хочаце заблякаваць.",
-       "apihelp-block-param-expiry": "Час заканчэньня. Можа быць адносным (напрыклад, «5 months» або «2 weeks») ці аблсалютным (напрыклад, «2014-09-18T12:34:56Z»). Калі выстаўлены на «infinite», «indefinite» ці «never», блякаваньне будзе бестэрміновым.",
+       "apihelp-block-param-expiry": "Час заканчэньня. Можа быць адносным (напрыклад, <kbd>5 months</kbd> або <kbd>2 weeks</kbd>) ці абсалютным (напрыклад, <kbd>2014-09-18T12:34:56Z</kbd>). Калі выстаўлены на <kbd>infinite</kbd>, <kbd>indefinite</kbd> ці <kbd>never</kbd>, блякаваньне будзе бестэрміновым.",
        "apihelp-block-param-reason": "Прычына блякаваньня.",
        "apihelp-block-param-anononly": "Заблякаваць толькі ананімных удзельнікаў (напрыклад, забараніць ананімныя праўкі з гэтага IP-адрасу).",
        "apihelp-block-param-nocreate": "Забарона стварэньня рахункаў.",
        "apihelp-block-param-autoblock": "Аўтаматычна блякаваць апошні ўжыты IP-адрас, а таксама ўсе наступныя IP-адрасы, зь якіх будуць спробы ўваходу.",
-       "apihelp-block-param-noemail": "Забараняе ўдзельніку дасылаць лісты электроннай пошты празь вікі (трэба мець права «blockemail»).",
-       "apihelp-block-param-hidename": "Схаваць імя ўдзельніка з журналу блякаваньняў (патрабуе права «hideuser»).",
+       "apihelp-block-param-noemail": "Забараняе ўдзельніку дасылаць лісты электроннай пошты празь вікі (трэба мець права <code>blockemail</code>).",
+       "apihelp-block-param-hidename": "Схаваць імя ўдзельніка з журналу блякаваньняў (патрабуе права <code>hideuser</code>).",
        "apihelp-block-param-allowusertalk": "Дазволіць удзельніку рэдагаваць уласную старонку гутарак (залежыць ад <var>[[mw:Manual:$wgBlockAllowsUTEdit|$wgBlockAllowsUTEdit]]</var>).",
        "apihelp-block-param-reblock": "Калі ўдзельнік ужо заблякаваны, перапісаць дзейнае блякаваньне.",
        "apihelp-block-param-watchuser": "Назіраць за старонкай удзельніка або старонкай IP-адрасу, а таксама старонкай гутарак.",
-       "apihelp-block-example-ip-simple": "Заблякаваць IP-адрас 192.0.2.5 на тры дні з прычынай «First strike»",
-       "apihelp-block-example-user-complex": "Заблякаваць удзельніка Vandal назаўсёды з прычынай «Vandalism», а таксама забараніць стварэньне новых рахункаў і адсылку лістоў электроннай поштай",
+       "apihelp-block-example-ip-simple": "Заблякаваць IP-адрас <kbd>192.0.2.5</kbd> на тры дні з прычынай <kbd>First strike</kbd>.",
+       "apihelp-block-example-user-complex": "Заблякаваць удзельніка <kbd>Vandal</kbd> назаўсёды з прычынай <kbd>Vandalism</kbd>, а таксама забараніць стварэньне новых рахункаў і адсылку лістоў электроннай поштай.",
        "apihelp-clearhasmsg-description": "Ачышчае сьцяг <code>hasmsg</code> для актуальнага карыстальніка.",
        "apihelp-clearhasmsg-example-1": "Ачыстка сьцягу <code>hasmsg</code> для актуальнага карыстальніка",
        "apihelp-compare-description": "Атрымаць розьніцу паміж 2 старонкамі.\n\nВы мусіце перадаць нумар вэрсіі, назву або ID старонкі для абодвух «from» і «to».",
@@ -50,6 +50,6 @@
        "apihelp-createaccount-param-mailpassword": "Калі ўсталяванае любое значэньне, выпадковы пароль будзе дасланы карыстальніку на электронную пошту.",
        "apihelp-createaccount-param-reason": "Неабавязковая прычына стварэньня рахунку, якая будзе запісаная ў журнал.",
        "apihelp-createaccount-param-language": "Моўны код, які будзе выстаўлены ўдзельніку па змоўчаньні (неабавязкова, па змоўчаньні мова зьместу).",
-       "apihelp-createaccount-example-pass": "Стварэньне ўдзельніка «testuser» з паролем «test123»",
-       "apihelp-createaccount-example-mail": "Стварэньне ўдзельніка «testmailuser» і адпраўка выпадковага паролю электроннай поштай"
+       "apihelp-createaccount-example-pass": "Стварэньне ўдзельніка <kbd>testuser</kbd> з паролем <kbd>test123</kbd>.",
+       "apihelp-createaccount-example-mail": "Стварэньне ўдзельніка <kbd>testmailuser</kbd> і адпраўка выпадковага паролю электроннай поштай."
 }
diff --git a/includes/api/i18n/bn.json b/includes/api/i18n/bn.json
new file mode 100644 (file)
index 0000000..05407ff
--- /dev/null
@@ -0,0 +1,8 @@
+{
+       "@metadata": {
+               "authors": [
+                       "Aftabuzzaman"
+               ]
+       },
+       "apihelp-login-example-login": "প্রবেশ"
+}
index 1853866..b771587 100644 (file)
@@ -3,7 +3,8 @@
                "authors": [
                        "Mormegil",
                        "YjM",
-                       "Juandev"
+                       "Juandev",
+                       "Aktron"
                ]
        },
        "apihelp-main-description": "<div class=\"hlist plainlinks api-main-links\">\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/API:Main_page Dokumentace]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/API:FAQ FAQ]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-api E-mailová konference]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-api-announce Oznámení k API]\n* [https://phabricator.wikimedia.org/maniphest/query/GebfyV4uCaLd/#R Chyby a požadavky]\n</div>\n<strong>Stav:</strong> Všechny funkce uvedené na této stránce by měly fungovat, ale API se stále aktivně vyvíjí a může se kdykoli změnit. Upozornění na změny získáte přihlášením se k [https://lists.wikimedia.org/pipermail/mediawiki-api-announce/ e-mailové konferenci mediawiki-api-announce].\n\n<strong>Chybné požadavky:</strong> Pokud jsou do API zaslány chybné požadavky, bude vrácena HTTP hlavička s klíčem „MediaWiki-API-Error“ a hodnota této hlavičky a chybový kód budou nastaveny na stejnou hodnotu. Více informací najdete na stránce https://www.mediawiki.org/wiki/API:Errors_and_warnings.",
@@ -27,7 +28,7 @@
        "apihelp-block-param-hidename": "Skrýt uživatelské jméno v knize zablokování. (Vyžaduje oprávnění „hideuser“.)",
        "apihelp-block-param-allowusertalk": "Povolit uživateli editovat svou vlastní diskusní stránku (závisí na <var>[[mw:Manual:$wgBlockAllowsUTEdit|$wgBlockAllowsUTEdit]]</var>).",
        "apihelp-block-param-reblock": "Pokud již uživatel blokován je, přepsat současný blok.",
-       "apihelp-block-param-watchuser": "Sledovat uživatelskou a diskusní stranu tohoto uživatele nebo adresy IP.",
+       "apihelp-block-param-watchuser": "Sledovat stránku uživatele nebo IP adresy a jejich diskuzní stránky.",
        "apihelp-block-example-ip-simple": "Zablokovat IP 192.0.2.5 na tři dny s důvodem „First strike“",
        "apihelp-block-example-user-complex": "Trvale zablokovat uživatele Vandal s odůvodněním „Vandalism“ a bránit vytváření nových účtů a e-mailování",
        "apihelp-compare-description": "Vrátí rozdíl dvou stránek.\n\nVe „from“ a „to“ musíte zadat číslo revize, název stránky nebo ID stránky.",
        "apihelp-createaccount-param-email": "E-mailová adresa uživatele (nepovinné).",
        "apihelp-createaccount-param-realname": "Skutečné jméno uživatele (nepovinné).",
        "apihelp-createaccount-param-mailpassword": "Pokud je nastaveno na libovolnou hodnotu, zašle se náhodně vygenerované heslo na e-mail uživatele.",
+       "apihelp-createaccount-example-mail": "Vytvořit uživatele <kbd>testmailuser</kbd> a zaslat mu e-mail s náhodně vygenerovaným heslem.",
        "apihelp-delete-description": "Smazat stránku.",
+       "apihelp-disabled-description": "Tento modul byl deaktivován.",
+       "apihelp-edit-description": "Vytvářet a upravovat stránky.",
+       "apihelp-edit-param-sectiontitle": "Název nové sekce.",
+       "apihelp-edit-param-text": "Obsah stránky.",
        "apihelp-edit-param-minor": "Malá editace.",
        "apihelp-edit-param-notminor": "Nemalá editace.",
        "apihelp-edit-param-bot": "Označit tuto editaci jako editaci bota.",
        "apihelp-edit-param-createonly": "Needitovat stránku, pokud již existuje.",
        "apihelp-edit-param-watch": "Přidat stránku na váš seznam sledovaných stránek.",
        "apihelp-edit-param-unwatch": "Odstranit stránku z vašeho seznamu sledovaných stránek.",
+       "apihelp-edit-param-watchlist": "Bezpodmíněnečně přidat nebo odstranit stránku ze sledovaných stránek aktuálního uživatele, použít nastavení nebo neměnit sledování.",
+       "apihelp-edit-param-redirect": "Automaticky opravit přesměrování.",
+       "apihelp-edit-example-edit": "Upravit stránku.",
+       "apihelp-emailuser-description": "Poslat uživateli e-mail.",
+       "apihelp-emailuser-param-text": "Tělo zprávy.",
+       "apihelp-emailuser-param-ccme": "Odeslat mi kopii této zprávy.",
+       "apihelp-feedcontributions-param-year": "Od roku (a dříve).",
+       "apihelp-feedcontributions-param-month": "Od měsíce (a dříve)",
+       "apihelp-feedcontributions-param-deletedonly": "Zobrazit pouze smazané příspěvky.",
+       "apihelp-feedrecentchanges-param-hideminor": "Skrýt drobné změny.",
+       "apihelp-feedrecentchanges-param-hidebots": "Skrýt úpravy provedené roboty.",
+       "apihelp-feedrecentchanges-param-hideanons": "Skrýt změny provedené anonymními uživateli.",
+       "apihelp-feedrecentchanges-param-hideliu": "Skrýt změny provedené registrovanými uživateli.",
+       "apihelp-feedrecentchanges-param-hidepatrolled": "Skrýt prověřené změny.",
+       "apihelp-feedrecentchanges-param-hidemyself": "Skrýt změny aktuálního uživatele.",
+       "apihelp-feedrecentchanges-param-tagfilter": "Filtrovat podle značek.",
+       "apihelp-feedrecentchanges-param-target": "Zobrazit jen změny na stránkách odkazovaných z této stránky.",
+       "apihelp-feedrecentchanges-example-simple": "Zobrazit poslední změny.",
+       "apihelp-feedrecentchanges-example-30days": "Zobrazit poslední změny za 30 dní.",
+       "apihelp-filerevert-description": "Revertovat soubor na starší verzi.",
+       "apihelp-filerevert-param-filename": "Cílový název souboru, bez prefixu Soubor:",
+       "apihelp-filerevert-param-comment": "Vložit komentář.",
        "apihelp-help-description": "Zobrazuje nápovědu k uvedeným modulům.",
        "apihelp-help-param-modules": "Moduly, pro které se má zobrazit nápověda (hodnoty parametrů action= a format= nebo „main“). Submoduly lze zadávat pomocí „+“.",
        "apihelp-help-param-submodules": "Zahrnout nápovědu pro podmoduly uvedeného modulu.",
        "apihelp-help-example-recursive": "Veškerá nápověda na jedné stránce",
        "apihelp-help-example-help": "Nápověda k samotnému modulu nápovědy",
        "apihelp-help-example-query": "Nápověda pro dva podmoduly query",
+       "apihelp-imagerotate-description": "Otočit jeden nebo více obrázků.",
+       "apihelp-import-param-summary": "Import shrnutí.",
+       "apihelp-import-param-xml": "Nahraný XML soubor.",
+       "apihelp-import-param-rootpage": "Importovat jako podstránku k této stránce.",
+       "apihelp-login-param-name": "Uživatelské jméno.",
+       "apihelp-login-param-password": "Heslo.",
+       "apihelp-login-example-login": "Přihlášení",
+       "apihelp-logout-example-logout": "Odhlášení aktuálního uživatele.",
+       "apihelp-move-description": "Přesunout stránku.",
+       "apihelp-move-param-reason": "Důvod k přejmenování.",
+       "apihelp-move-param-movetalk": "Přejmenovat diskuzní stránku, pokud existuje.",
+       "apihelp-move-param-movesubpages": "Přejmenovat možné podstránky",
+       "apihelp-move-param-noredirect": "Nevytvářet přesměrování.",
+       "apihelp-move-param-watch": "Přidat stránku a přesměrování do sledovaných stránek aktuálního uživatele.",
+       "apihelp-move-param-unwatch": "Odstranit stránku a přesměrování ze sledovaných stránek současného uživatele.",
+       "apihelp-move-param-ignorewarnings": "Ignorovat všechna varování.",
+       "apihelp-opensearch-param-search": "Hledání řetězce.",
+       "apihelp-opensearch-param-limit": "Maximální počet vrácených výsledků",
+       "apihelp-opensearch-param-namespace": "Jmenné prostory pro vyhledávání.",
+       "apihelp-opensearch-param-format": "Formát výstupu.",
+       "apihelp-opensearch-example-te": "Najít stránky, začínající s <kbd>Te</kbd>.",
+       "apihelp-options-example-reset": "Vrátit všechna nastavení.",
+       "apihelp-parse-example-page": "Parsovat stránku.",
+       "apihelp-patrol-example-revid": "Prověřit revizi.",
+       "apihelp-protect-description": "Změnit úroveň zamčení stránky.",
+       "apihelp-protect-param-reason": "Důvod pro odemčení.",
+       "apihelp-protect-example-protect": "Zamknout stránku.",
+       "apihelp-query+alldeletedrevisions-example-user": "Seznam posledních 50 smazaných editací uživatele <kbd>Příklad<kbd>.",
+       "apihelp-query+alldeletedrevisions-example-ns-main": "Seznam prvních 50 smazaných revizí v hlavním jmenném prostoru.",
+       "apihelp-query+allfileusages-description": "Zobrazit seznam všech použití souboru, včetně neexistujících.",
+       "apihelp-query+alllinks-example-generator": "Získat stránky obsahující odkazy.",
+       "apihelp-query+allpages-param-filterredir": "Které stránky uvést na seznam.",
+       "apihelp-query+allpages-param-minsize": "Omezit na stránky s určitým počtem bajtů.",
+       "apihelp-query+allpages-param-prtype": "Omezit jen na zamčené stránky.",
+       "apihelp-query+allpages-example-B": "Zobrazit seznam stránek začínajících na písmeno <kbd>B</kbd>.",
+       "apihelp-query+allredirects-description": "Seznam všech přesměrování pro jmenný prostor.",
+       "apihelp-query+allredirects-example-unique": "Seznam unikátních cílových stránek.",
+       "apihelp-query+allredirects-example-generator": "Získat stránky obsahující přesměrování.",
+       "apihelp-query+alltransclusions-example-unique": "Seznam unikátně vložených titulů.",
+       "apihelp-query+backlinks-example-simple": "Zobrazit odkazy na <kbd>Hlavní stránka</kbd>",
+       "apihelp-query+categorymembers-description": "Seznam všech stránek v dané kategorii.",
+       "apihelp-query+deletedrevisions-param-limit": "Maximální počet revizí pro zobrazení v seznamu.",
+       "apihelp-query+embeddedin-example-simple": "Zobrazit stránky, které obahují <kbd>Template:Stub</kbd>.",
+       "apihelp-query+filearchive-example-simple": "Zobrazit seznam všech smazaných souborů.",
+       "apihelp-query+filerepoinfo-example-simple": "Získat informace o souborových repozitářích.",
+       "apihelp-query+linkshere-example-generator": "Získat informace o stránkách, které odkazují na [[Hlavní Stránka|Hlavní stránku]].",
+       "apihelp-query+recentchanges-example-simple": "Seznam posledních změn.",
+       "apihelp-query+tags-example-simple": "Získat seznam dostupných tagů.",
+       "apihelp-query+usercontribs-example-user": "Zobrazit příspěvky uživatele <kbd>Příklad</kbd>",
+       "apihelp-query+watchlistraw-description": "Získat všechny stránky, které jsou aktuálním uživatelem sledovány.",
+       "apihelp-query+watchlistraw-example-simple": "Seznam sledovaných stránek uživatele.",
+       "apihelp-unblock-param-user": "Uživatel, IP adresa nebo záběr IP adres k odblokování. Nelze použít dohromady s <var>$1id</var>.",
+       "apihelp-watch-example-watch": "Sledovat stránku <kbd>Hlavní stránka</kbd>.",
+       "apihelp-watch-example-generator": "Zobrazit prvních několik stránek z hlavního jmenného prostoru.",
        "apihelp-format-example-generic": "Výsledek dotazu vypsat ve formátu $1.",
        "apihelp-dbg-description": "Vypisuje data ve formátu funkce var_export() z PHP.",
        "apihelp-dbgfm-description": "Vypisuje data ve formátu funkce var_export() z PHP (v čitelné HTML podobě).",
index c19aeb2..0e766bf 100644 (file)
        "apihelp-logout-description": "Log out and clear session data.",
        "apihelp-logout-example-logout": "Log the current user out.",
 
+       "apihelp-managetags-description": "Perform management tasks relating to change tags.",
+       "apihelp-managetags-param-operation": "Which operation to perform:\n;create:Create a new change tag for manual use.\n;delete:Remove a change tag from the database, including removing the tag from all revisions, recent change entries and log entries on which it is used.\n;activate:Activate a change tag, allowing users to apply it manually.\n;deactivate:Deactivate a change tag, preventing users from applying it manually.",
+       "apihelp-managetags-param-tag": "Tag to create, delete, activate or deactivate. For tag creation, the tag must not exist. For tag deletion, the tag must exist. For tag activation, the tag must exist and not be in use by an extension. For tag deactivation, the tag must be currently active and manually defined.",
+       "apihelp-managetags-param-reason": "An optional reason for creating, deleting, activating or deactivating the tag.",
+       "apihelp-managetags-param-ignorewarnings": "Whether to ignore any warnings that are issued during the operation.",
+       "apihelp-managetags-example-create": "Create a tag named <kbd>spam</kbd> with the reason <kbd>For use in edit patrolling</kbd>",
+       "apihelp-managetags-example-delete": "Delete the <kbd>vandlaism</kbd> tag with the reason <kbd>Misspelt</kbd>",
+       "apihelp-managetags-example-activate": "Activate a tag named <kbd>spam</kbd> with the reason <kbd>For use in edit patrolling</kbd>",
+       "apihelp-managetags-example-deactivate": "Deactivate a tag named <kbd>spam</kbd> with the reason <kbd>No longer required</kbd>",
+
        "apihelp-move-description": "Move a page.",
        "apihelp-move-param-from": "Title of the page to rename. Cannot be used together with <var>$1fromid</var>.",
        "apihelp-move-param-fromid": "Page ID of the page to rename. Cannot be used together with <var>$1from</var>.",
 
        "apihelp-query+tags-description": "List change tags.",
        "apihelp-query+tags-param-limit": "The maximum number of tags to list.",
-       "apihelp-query+tags-param-prop": "Which properties to get:\n;name:Adds name of tag.\n;displayname:Adds system message for the tag.\n;description:Adds description of the tag.\n;hitcount:Adds the amount of revisions that have this tag.\n;defined:Indicate whether the tag is defined.",
+       "apihelp-query+tags-param-prop": "Which properties to get:\n;name:Adds name of tag.\n;displayname:Adds system message for the tag.\n;description:Adds description of the tag.\n;hitcount:Adds the number of revisions and log entries that have this tag.\n;defined:Indicate whether the tag is defined.\n;source:Gets the sources of the tag, which may include <samp>extension</samp> for extension-defined tags and <samp>manual</samp> for tags that may be applied manually by users.\n;active:Whether the tag is still being applied.",
        "apihelp-query+tags-example-simple": "List available tags.",
 
        "apihelp-query+templates-description": "Returns all pages transcluded on the given pages.",
index e116388..5c3cc6e 100644 (file)
@@ -4,7 +4,9 @@
                        "Macofe",
                        "Effy",
                        "Alan",
-                       "Fitoschido"
+                       "Fitoschido",
+                       "JasterTDC",
+                       "Edslov"
                ]
        },
        "apihelp-main-param-action": "Qué acción se realizará.",
        "apihelp-block-description": "Bloquear usuario",
        "apihelp-block-param-user": "El nombre de usuario, dirección IP o intervalo de IP que quieres bloquear.",
        "apihelp-block-param-reason": "Razón para el bloqueo.",
-       "apihelp-block-param-anononly": "Bloquear solo usuarios anónimos (es decir, desactivar ediciones anónimas de esta IP).",
+       "apihelp-block-param-anononly": "Bloquear solo usuarios anónimos (es decir, desactivar ediciones anónimas de esta dirección IP).",
        "apihelp-block-param-nocreate": "Prevenir la creación de cuentas.",
+       "apihelp-block-param-reblock": "Si la cuenta ya está bloqueada, sobrescribir el bloqueo existente.",
+       "apihelp-block-param-watchuser": "Vigilar las páginas de usuario y de discusión del usuario o de la dirección IP.",
        "apihelp-compare-param-fromtitle": "Primer título para comparar",
        "apihelp-createaccount-description": "Crear una nueva cuenta de usuario.",
        "apihelp-createaccount-param-name": "Nombre de usuario.",
        "apihelp-createaccount-param-email": "Dirección de correo electrónico del usuario (opcional).",
        "apihelp-createaccount-param-realname": "Nombre verdadero del usuario (opcional).",
-       "apihelp-createaccount-example-pass": "Crear cuenta de usuario «testuser» con la contraseña «test123»",
+       "apihelp-createaccount-example-pass": "Crear usuario <kbd>testuser</kbd> con la contraseña <kbd>test123</kbd>.",
        "apihelp-delete-description": "Borrar una página.",
-       "apihelp-delete-param-watch": "Añadir esta página a tu lista de seguimiento.",
-       "apihelp-delete-param-unwatch": "Borrar esta página de tu lista de seguimiento.",
-       "apihelp-delete-example-simple": "Borrar la Página Principal",
+       "apihelp-delete-param-watch": "Añadir esta página a la lista de seguimiento del usuario actual.",
+       "apihelp-delete-param-unwatch": "Quitar la página de la lista de seguimiento del usuario actual.",
+       "apihelp-delete-example-simple": "Borrar la <kbd>Página principal</kbd>",
        "apihelp-disabled-description": "Se desactivó este módulo.",
        "apihelp-edit-description": "Crear y editar páginas.",
        "apihelp-edit-param-sectiontitle": "El título de una sección nueva.",
        "apihelp-edit-param-bot": "Marcar esta edición como de bot.",
        "apihelp-edit-param-createonly": "No editar la página si ya existe.",
        "apihelp-edit-param-nocreate": "Producir un error si la página no existe.",
-       "apihelp-edit-param-watch": "Añadir la página a tu lista de seguimiento.",
-       "apihelp-edit-param-unwatch": "Quitar la página de tu lista de seguimiento.",
+       "apihelp-edit-param-watch": "Añadir la página a la lista de seguimiento del usuario actual.",
+       "apihelp-edit-param-unwatch": "Quitar la página de la lista de seguimiento del usuario actual.",
        "apihelp-edit-example-edit": "Editar una página",
-       "apihelp-edit-example-prepend": "Anteponer <kbd>_&#95;NOTOC_&#95;</kbd> a una página",
+       "apihelp-edit-example-prepend": "Anteponer <kbd>_&#95;NOTOC_&#95;</kbd> a una página.",
        "apihelp-edit-example-undo": "Deshacer intervalo de revisiones 13579-13585 con resumen automático",
        "apihelp-emailuser-description": "Enviar un mensaje de correo electrónico a un usuario.",
        "apihelp-emailuser-param-target": "Cuenta de usuario destinatario.",
@@ -58,7 +62,7 @@
        "apihelp-feedrecentchanges-param-hideanons": "Ocultar los cambios realizados por usuarios anónimos.",
        "apihelp-feedrecentchanges-param-hideliu": "Ocultar los cambios realizados por usuarios registrados.",
        "apihelp-feedrecentchanges-param-hidepatrolled": "Ocultar los cambios patrullados.",
-       "apihelp-feedrecentchanges-param-hidemyself": "Ocultar los cambios realizados por ti.",
+       "apihelp-feedrecentchanges-param-hidemyself": "Ocultar los cambios realizados por el usuario actual.",
        "apihelp-feedrecentchanges-param-tagfilter": "Filtrar por etiquetas.",
        "apihelp-feedrecentchanges-param-target": "Mostrar solo los cambios en las páginas enlazadas en esta.",
        "apihelp-feedrecentchanges-param-showlinkedto": "Mostrar los cambios en páginas enlazadas con la página seleccionada.",
@@ -66,6 +70,7 @@
        "apihelp-feedrecentchanges-example-30days": "Mostrar los cambios recientes limitados a 30 días",
        "apihelp-feedwatchlist-description": "Devuelve el canal de una lista de seguimiento.",
        "apihelp-feedwatchlist-param-feedformat": "El formato del canal.",
+       "apihelp-feedwatchlist-example-all6hrs": "Mostrar todos los cambios en páginas vigiladas en las últimas 6 horas.",
        "apihelp-filerevert-description": "Revertir el archivo a una versión anterior.",
        "apihelp-filerevert-param-filename": "Nombre de archivo final, sin el prefijo Archivo:",
        "apihelp-filerevert-param-comment": "Comentario de carga.",
        "apihelp-login-example-login": "Acceder",
        "apihelp-logout-description": "Salir y vaciar los datos de la sesión.",
        "apihelp-logout-example-logout": "Cerrar la sesión del usuario actual",
+       "apihelp-managetags-param-reason": "Un motivo opcional para crear, eliminar, activar o desactivar la etiqueta.",
        "apihelp-move-description": "Mover una página.",
-       "apihelp-move-param-reason": "Motivo del traslado.",
-       "apihelp-move-param-movetalk": "Trasladar la página de discusión si existe.",
-       "apihelp-move-param-movesubpages": "Trasladar las subpáginas si procede.",
+       "apihelp-move-param-reason": "Motivo del cambio de nombre.",
+       "apihelp-move-param-movetalk": "Renombrar la página de discusión si existe.",
+       "apihelp-move-param-movesubpages": "Renombrar las subpáginas si procede.",
        "apihelp-move-param-noredirect": "No crear una redirección.",
-       "apihelp-move-param-watch": "Añadir la página y su redirección a tu lista de seguimiento.",
-       "apihelp-move-param-unwatch": "Quitar la página y su redirección de tu lista de seguimiento.",
+       "apihelp-move-param-watch": "Añadir la página y su redirección a la lista de seguimiento del usuario actual.",
+       "apihelp-move-param-unwatch": "Eliminar la página y la redirección de la lista de seguimiento del usuario.",
        "apihelp-move-param-ignorewarnings": "Ignorar cualquier aviso.",
        "apihelp-opensearch-description": "Buscar en el wiki mediante el protocolo OpenSearch.",
        "apihelp-opensearch-param-search": "Buscar cadena.",
        "apihelp-options-example-reset": "Restablecer todas las preferencias",
+       "apihelp-paraminfo-description": "Obtener información acerca de los módulos de la API.",
+       "apihelp-paraminfo-param-helpformat": "Formato de las cadenas de ayuda.",
        "apihelp-patrol-example-rcid": "Patrullar un cambio reciente",
        "apihelp-patrol-example-revid": "Patrullar una revisión",
        "apihelp-protect-param-reason": "Motivo de la (des)protección.",
        "apihelp-protect-example-protect": "Proteger una página",
        "apihelp-query+allimages-param-sha1": "Suma SHA1 de la imagen. Invalida $1sha1base36.",
        "apihelp-query+allimages-param-sha1base36": "Suma SHA1 de la imagen en base 36 (usada en MediaWiki).",
+       "apihelp-query+alllinks-example-unique-generator": "Obtiene todos los títulos enlazados, marcando los que falten.",
+       "apihelp-query+allpages-example-B": "Mostrar una lista de páginas que empiecen con la letra <kbd>B</kbd>.",
        "apihelp-query+allusers-param-activeusers": "Solo listar usuarios activos en {{PLURAL:$1|el último día|los $1 últimos días}}.",
+       "apihelp-query+backlinks-param-pageid": "Identificador de página que buscar. No puede usarse junto con <var>$1title</var>",
+       "apihelp-query+backlinks-example-simple": "Mostrar enlaces a la <kbd>Portada<kbd>.",
+       "apihelp-query+blocks-example-simple": "Listar bloques.",
+       "apihelp-query+categoryinfo-example-simple": "Obtener información acerca de <kbd>Category:Foo</kbd> y <kbd>Category:Bar</kbd>",
+       "apihelp-query+deletedrevs-example-mode3-talk": "Listar las primeras 50 páginas en el espacio de nombres {{ns:talk}} (modo 3).",
+       "apihelp-query+duplicatefiles-example-simple": "Buscar duplicados de [[:File:Alber Einstein Head.jpg]].",
+       "apihelp-query+duplicatefiles-example-generated": "Buscar duplicados en todos los ficheros.",
+       "apihelp-query+exturlusage-example-simple": "Mostrar páginas que enlacen con <kbd>http://www.mediawiki.org</kbd>.",
+       "apihelp-query+filerepoinfo-example-simple": "Obtener información acerca de los repositorios de archivos.",
        "apihelp-query+images-description": "Devuelve todos los archivos contenidos en las páginas dadas.",
+       "apihelp-query+images-example-simple": "Obtener una lista de los archivos usados en la [[Main Page|Portada]].",
+       "apihelp-query+imageusage-example-simple": "Mostrar las páginas que usan [[:File:Albert Einstein Head.jpg]].",
+       "apihelp-query+info-example-protection": "Obtén información general y protección acerca de la página <kb>Página principal</kbd>.",
+       "apihelp-query+iwbacklinks-example-simple": "Obtener las páginas enlazadas a [[wikibooks:Test]]",
+       "apihelp-query+langbacklinks-example-simple": "Obtener las páginas enlazadas a [[:fr:Test]]",
+       "apihelp-query+linkshere-example-generator": "Obtener información acerca de las páginas enlazadas a la [[Main Page|Portada]].",
+       "apihelp-query+protectedtitles-example-generator": "Encuentra enlaces a títulos protegidos en el espacio de nombres principal.",
+       "apihelp-query+recentchanges-example-simple": "Lista de cambios recientes.",
+       "apihelp-query+redirects-example-simple": "Mostrar una lista de las redirecciones a la [[Main Page|Portada]]",
+       "apihelp-query+revisions-example-last5": "Mostrar las últimas 5 revisiones de la <kbd>Portada</kbd>.",
        "apihelp-query+search-param-info": "Qué metadatos devolver.",
+       "apihelp-query+search-example-text": "Buscar <kbd>meaning</kbd> en los textos.",
+       "apihelp-query+siteinfo-example-simple": "Obtener información del sitio.",
+       "apihelp-query+usercontribs-example-user": "Mostrar contribuciones del usuario <kbd>Ejemplo</kbd>.",
        "apihelp-query+userinfo-description": "Obtener información sobre el usuario actual.",
        "apihelp-query+watchlist-param-excludeuser": "No listar cambios de este usuario.",
        "apihelp-query+watchlistraw-param-show": "Sólo listar los elementos que cumplen estos criterios.",
+       "apihelp-unblock-example-user": "Desbloquear al usuario <kbd>Bob</kbd> con el motivo <kbd>Lo siento, Bob</kbd>",
+       "apihelp-upload-example-url": "Subir desde una URL.",
+       "apihelp-watch-example-unwatch": "Dejar de vigilar la <kbd>Portada</kbd>.",
        "api-help-parameters": "{{PLURAL:$1|Parámetro|Parámetros}}:",
        "api-help-examples": "{{PLURAL:$1|Ejemplo|Ejemplos}}:"
 }
index c0fd34a..d6d6306 100644 (file)
@@ -4,7 +4,8 @@
                        "Gomoko",
                        "Windes",
                        "Orlodrim",
-                       "McDutchie"
+                       "McDutchie",
+                       "Element303"
                ]
        },
        "apihelp-main-description": "<div class=\"hlist plainlinks api-main-links\">\n* [https://www.mediawiki.org/wiki/API:Main_page Documentation]\n* [https://www.mediawiki.org/wiki/API:FAQ FAQ]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-api Liste de diffusion]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-api-announce Annonces de l’API]\n* [https://phabricator.wikimedia.org/maniphest/query/GebfyV4uCaLd/#R Bogues et demandes]\n</div>\n<strong>État :</strong> Toutes les fonctionnalités affichées sur cette page devraient fonctionner, mais l’API est encore en cours de développement et peut changer à tout moment. Inscrivez-vous à [https://lists.wikimedia.org/pipermail/mediawiki-api-announce/ la liste de diffusion mediawiki-api-announce] pour être informé des mises à jour.\n\n<strong>Requêtes erronées :</strong> Si des requêtes erronées sont envoyées à l’API, un en-tête HTTP sera renvoyé avec la clé « MediaWiki-API-Error ». La valeur de cet en-tête et le code d’erreur renvoyé prendront la même valeur. Pour plus d’information, voyez https://www.mediawiki.org/wiki/API:Errors_and_warnings.",
        "apihelp-query+deletedrevs-example-mode1": "Lister les dernières révisions supprimées de Main Page et Talk:Main Page, avec le contenu (mode 1)",
        "apihelp-query+deletedrevs-example-mode2": "Lister les 50 dernières contributions de Bob supprimées (mode 2)",
        "apihelp-query+deletedrevs-example-mode3-main": "Lister les 50 premières révisions supprimées dans l’espace de noms principal (mode 3)",
-       "apihelp-query+deletedrevs-example-mode3-talk": "Lister les 50 premières pages supprimées dans l’espace de noms Talk (mode 3) :",
+       "apihelp-query+deletedrevs-example-mode3-talk": "Lister les 50 premières pages supprimées dans l’espace de noms {{ns:talk}} (mode 3).",
        "apihelp-query+disabled-description": "Ce module de requête a été désactivé.",
        "apihelp-query+duplicatefiles-description": "Lister tous les fichiers qui sont des doublons des fichiers donnés d’après leurs valeurs de hachage.",
        "apihelp-query+duplicatefiles-param-limit": "Combien de fichiers dupliqués à renvoyer.",
        "apihelp-watch-param-title": "La page à (ne plus) suivre. Utiliser plutôt $1titles.",
        "apihelp-watch-param-unwatch": "Si défini, la page ne sera plus suivie plutôt que suivie.",
        "apihelp-watch-example-watch": "Suivre la page « Page principale »",
-       "apihelp-watch-example-unwatch": "Ne plus suivre la page « Page principale »",
+       "apihelp-watch-example-unwatch": "Ne plus suivre la page <kbd>Page principale</kbd>.",
        "apihelp-watch-example-generator": "Suivre les quelques premières pages de l’espace de nom principal",
        "apihelp-format-example-generic": "Mettre en forme le résultat de la requête dans le format $1",
        "apihelp-dbg-description": "Extraire les données au format de var_export() de PHP.",
index a64730c..b338e70 100644 (file)
@@ -1,13 +1,20 @@
 {
        "@metadata": {
                "authors": [
-                       "Elisardojm"
+                       "Elisardojm",
+                       "Agremon",
+                       "Chairego apc",
+                       "VaiPolaSombra",
+                       "Banjo",
+                       "Fisterraeomar"
                ]
        },
        "apihelp-main-description": "<div class=\"hlist plainlinks api-main-links\">\n* [[mw:API:Main_page|Documentación]]\n* [[mw:API:FAQ|FAQ]]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-api Lista de discusión]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-api-announce Anuncios da API]\n* [https://phabricator.wikimedia.org/maniphest/query/GebfyV4uCaLd/#R Erros e solicitudes]\n</div>\n<strong>Estado:</strong> Tódalas funcionalidades mostradas nesta páxina deberían estar funcionanado, pero a API aínda está desenrolo, e pode ser modificada en calquera momento. Apúntese na [https://lists.wikimedia.org/pipermail/mediawiki-api-announce/ lista de discusión mediawiki-api-announce] para estar informado acerca das actualizacións.\n\n<strong>Solicitudes incorrectas:</strong> Cando se envían solicitudes incorrectas á API, envíase unha cabeceira HTTP coa chave \"MediaWiki-API-Error\" e, a seguir, tanto o valor da cabeceira como o código de erro retornado serán definidos co mesmo valor. Para máis información, consulte [[mw:API:Errors_and_warnings|API: Erros e avisos]].",
        "apihelp-main-param-action": "Que acción se realizará.",
        "apihelp-main-param-format": "O formato de saída.",
+       "apihelp-main-param-maxlag": "O retardo máximo pode usarse cando MediaWiki está instalada nun cluster de base de datos replicadas. Para gardar accións que causen calquera retardo máis de replicación do sitio, este parámetro pode facer que o cliente espere ata que o retardo de replicación sexa menor que o valor especificado. No caso de retardo excesivo, é devolto o código de erro <samp>maxlag</samp> cunha mensaxe como <samp>esperando por $host: $lag segundos de retardo</samp>.<br />Para máis información, ver [[mw:Manual:Maxlag_parameter|Manual: Maxlag parameter]].",
        "apihelp-main-param-requestid": "Calquera valor dado aquí será incluído na resposta. Pode usarse para distingir peticións.",
+       "apihelp-main-param-servedby": "Inclúa o nome do servidor que servía a solicitude nos resultados.",
        "apihelp-main-param-curtimestamp": "Incluir a marca de tempo actual no resultado.",
        "apihelp-block-description": "Bloquear un usuario.",
        "apihelp-block-param-user": "Nome de usuario, dirección ou rango de IPs que quere bloquear.",
        "apihelp-block-param-anononly": "Bloquear só usuarios anónimos (é dicir, desactivar edicións anónimas desta dirección IP).",
        "apihelp-block-param-nocreate": "Previr a creación de contas.",
        "apihelp-block-param-autoblock": "Bloquear automaticamente o último enderezo IP utilizado, e calquera outro enderezo desde o que intente conectarse.",
+       "apihelp-block-param-allowusertalk": "Permitir que o usuario edite a súa propia páxina de conversa (depende de <var>[[mw:Manual:$wgBlockAllowsUTEdit|$wgBlockAllowsUTEdit]]</var>).",
        "apihelp-block-param-reblock": "Se o usuario xa está bloqueado, sobreescribir o bloqueo existente.",
        "apihelp-block-param-watchuser": "Vixiar a páxina de usuario ou direccións IP e a de conversa deste usuario",
+       "apihelp-clearhasmsg-description": "Limpar a bandeira <code>hasmsg</code> para o usuario actual",
+       "apihelp-clearhasmsg-example-1": "Limpar a bandeira <code>hasmsg</code> para o usuario actual",
        "apihelp-compare-param-fromtitle": "Primeiro título para comparar.",
        "apihelp-compare-param-fromid": "Identificador da primeira páxina a comparar.",
        "apihelp-compare-param-fromrev": "Primeira revisión a comparar.",
@@ -30,6 +40,7 @@
        "apihelp-createaccount-param-domain": "Dominio para autenticación externa (opcional)",
        "apihelp-createaccount-param-email": "Enderezo de correo eletrónico do usuario (opcional).",
        "apihelp-createaccount-param-realname": "Nome real do usuario (opcional).",
+       "apihelp-createaccount-param-mailpassword": "Se se establece calquera valor, enviarase un contrasinal aleatorio ao usuario.",
        "apihelp-createaccount-example-pass": "Crear usuario <kbd>testuser</kbd> con contrasinal <kbd>test123</kbd>.",
        "apihelp-createaccount-example-mail": "Crear usuario <kbd>testmailuser</kbd>\"testmailuser\" e enviar por correo electrónico un contrasinal xenerado de forma aleatoria.",
        "apihelp-delete-description": "Borrar a páxina.",
        "apihelp-edit-param-notminor": "Edición non pequena.",
        "apihelp-edit-param-bot": "Marcar esta edición como de bot.",
        "apihelp-edit-param-createonly": "Non editar a páxina se xa existe.",
+       "apihelp-edit-param-nocreate": "Amosar un mensaxe de erro se a páxina non existe",
        "apihelp-edit-param-watch": "Engadir esta páxina á lista de vixilancia do usuario actual.",
        "apihelp-edit-param-unwatch": "Eliminar esta páxina da lista de vixilancia do usuario actual.",
+       "apihelp-edit-param-prependtext": "Engadir este texto ao comezo da páxina. Sobreescribirase $1text.",
+       "apihelp-edit-param-redirect": "Resolver redireccións automáticamente",
        "apihelp-edit-example-edit": "Editar a páxina",
        "apihelp-emailuser-description": "Enviar un correo electrónico a un usuario.",
        "apihelp-emailuser-param-target": "Usuario ó que lle mandar correo electrónico.",
        "apihelp-feedcontributions-description": "Devolve a lista de contribucións dun usuario.",
        "apihelp-feedcontributions-param-year": "Desde o ano (e anteriores).",
        "apihelp-feedcontributions-param-month": "Desde o mes de (e anteriores).",
+       "apihelp-feedcontributions-param-tagfilter": "Filtrar as contribucións que teñan estas etiquetas.",
        "apihelp-feedcontributions-param-deletedonly": "Mostrar só as contribuciones eliminadas.",
        "apihelp-feedcontributions-param-toponly": "Mostrar só as edicións que que son as ultimas revisións.",
        "apihelp-feedcontributions-param-newonly": "Mostrar só as edicións que crearon páxinas.",
        "apihelp-feedcontributions-param-showsizediff": "Mostrar diferenza de tamaño entre edicións.",
+       "apihelp-feedcontributions-example-simple": "Mostrar as contribucións do usuario <kbd>Example</kbd>.",
+       "apihelp-feedrecentchanges-param-invert": "Tódolos nomes de espazos agás o seleccionado",
+       "apihelp-feedrecentchanges-param-days": "Días a limitar os resultados",
        "apihelp-feedrecentchanges-param-limit": "Número máximo de resultados a visualizar.",
        "apihelp-feedrecentchanges-param-from": "Mostrar modificacións desde entón.",
        "apihelp-feedrecentchanges-param-hideminor": "Ocultar cambios menores.",
        "apihelp-feedrecentchanges-param-showlinkedto": "Mostrar os cambios nas páxinas ligadas coa páxina seleccionada.",
        "apihelp-feedrecentchanges-example-simple": "Mostrar os cambios recentes",
        "apihelp-feedrecentchanges-example-30days": "Mostrar os cambios recentes limitados a 30 días",
+       "apihelp-feedwatchlist-example-all6hrs": "Amosar tódolos cambios feitos ás páxinas vixiadas nas últimas 6 horas.",
        "apihelp-filerevert-description": "Revertir o ficheiro a unha versión anterior.",
        "apihelp-filerevert-param-filename": "Nome de ficheiro final, sen o prefixo Ficheiro:",
        "apihelp-filerevert-param-comment": "Comentario de carga.",
        "apihelp-help-param-submodules": "Incluír axuda para os submódulos do módulo nomeado.",
        "apihelp-help-param-recursivesubmodules": "Incluír axuda para os submódulos de forma recursiva.",
        "apihelp-help-param-helpformat": "Formato de saída da axuda.",
+       "apihelp-help-param-toc": "Incluír unha táboa de contidos na saída por HTML",
        "apihelp-help-example-main": "Axuda para o módulo principal",
        "apihelp-help-example-recursive": "Toda a axuda nunha páxina",
-       "apihelp-help-example-help": "Ayuda do módulo de axuda en si",
+       "apihelp-help-example-help": "Axuda do módulo de axuda en si",
        "apihelp-imagerotate-description": "Xirar unha ou máis imaxes.",
        "apihelp-imagerotate-param-rotation": "Graos a rotar a imaxe no sentido do reloxio.",
        "apihelp-imagerotate-example-simple": "Rotar <kbd>File:Example.png</kbd> <kbd>90</kbd> graos.",
        "apihelp-login-param-domain": "Dominio (opcional).",
        "apihelp-login-example-login": "Identificarse",
        "apihelp-logout-description": "Terminar e limpar datos de sesión.",
+       "apihelp-managetags-description": "Realizar tarefas de xestión relacionadas coa modificación de etiquetas.",
        "apihelp-move-description": "Mover unha páxina.",
        "apihelp-move-param-from": "Título da páxina que quere renomear. Non pode usarse xunto con <var>$1fromid</var>.",
        "apihelp-move-param-fromid": "Identificador da páxina que quere renomear. Non pode usarse xunto con <var>$1from</var>.",
        "apihelp-protect-param-title": "Título da páxina que quere (des)protexer. Non pode usarse xunto con $1pageid.",
        "apihelp-protect-param-pageid": "Identificador da páxina que quere (des)protexer. Non pode usarse xunto con $1title.",
        "apihelp-protect-param-reason": "Razón para (des)protexer.",
+       "apihelp-protect-param-watch": "Se se define este parámetro, engadir a páxina que se (des)protexe á lista de vixilancia do usuario actual.",
        "apihelp-protect-example-protect": "Protexer unha páxina",
        "apihelp-purge-param-forcelinkupdate": "Actualizar as táboas de ligazóns.",
        "apihelp-purge-example-simple": "Purgar a <kbd>Páxina Principal</kbd> e páxina da <kbd>API</kbd>.",
+       "apihelp-purge-example-generator": "Purgar as primeiras 10 páxinas no espazo de nomes principal.",
+       "apihelp-query+allcategories-description": "Numerar tódalas categorías",
+       "apihelp-query+alldeletedrevisions-paraminfo-nonuseronly": "Non pode usarse con <var>$3user</var>.",
        "apihelp-query+alldeletedrevisions-param-start": "Selo de tempo para comezar a enumeración.",
        "apihelp-query+alldeletedrevisions-param-end": "Selo de tempo para rematar a enumeración.",
        "apihelp-query+alldeletedrevisions-param-from": "Comezar listado neste título.",
        "apihelp-query+allfileusages-param-prefix": "Buscar tódolos títulos de ficheiro que comezan con este valor.",
        "apihelp-query+allfileusages-param-limit": "Número total de obxectos a devolver.",
        "apihelp-query+allfileusages-param-dir": "Dirección na cal listar.",
+       "apihelp-query+allfileusages-example-unique": "Listar títulos únicos de ficheiros.",
        "apihelp-query+allimages-description": "Enumerar tódalas imaxes secuencialmente.",
        "apihelp-query+allimages-param-sort": "Propiedade pol que ordenar.",
        "apihelp-query+allimages-param-dir": "Dirección na cal listar.",
        "apihelp-query+allimages-param-filterbots": "Como filtrar ficheiros subidos por bots. Só pode usarse con $1sort=timestamp. Non pode usarse xunto con $1user.",
        "apihelp-query+allimages-param-mime": "Que tipos MIME  buscar, por exemplo <kbd>imaxe/jpeg</kbd>.",
        "apihelp-query+allimages-param-limit": "Cantas imaxes mostar en total.",
+       "apihelp-query+alllinks-description": "Numerar tódalas ligazóns que apuntan a un nome de espazos determinado.",
        "apihelp-query+alllinks-param-from": "Título da ligazón na que comezar a enumerar.",
        "apihelp-query+alllinks-param-to": "Título da ligazón na que rematar de enumerar.",
+       "apihelp-query+alllinks-param-prefix": "Buscar tódolos títulos ligados que comezan con este valor.",
        "apihelp-query+alllinks-param-namespace": "Espazo de nomes a enumerar.",
        "apihelp-query+alllinks-param-limit": "Número total de obxectos a devolver.",
        "apihelp-query+alllinks-param-dir": "Dirección na cal listar.",
+       "apihelp-query+alllinks-example-unique": "Listar títulos ligados únicos",
        "apihelp-query+allmessages-param-prop": "Que propiedades obter.",
        "apihelp-query+allmessages-param-args": "Argumentos a substituír na mensaxe.",
+       "apihelp-query+allmessages-param-filter": "Retornar só mensaxes con nomes que conteñan esta cadea.",
+       "apihelp-query+allmessages-param-lang": "Retornar mensaxes nesta lingua.",
+       "apihelp-query+allmessages-param-from": "Retornar mensaxes que comezan nesta mensaxe.",
+       "apihelp-query+allmessages-param-to": "Retornar mensaxes que rematan nesta mensaxe.",
        "apihelp-query+allmessages-example-ipb": "Mostar mensaxes que comecen por <kbd>ipb-</kbd>.",
+       "apihelp-query+allpages-description": "Numerar tódalas páxinas secuencialmente nun espazo de nomes determinado.",
        "apihelp-query+allpages-param-from": "Título da páxina na que comezar a enumerar.",
        "apihelp-query+allpages-param-to": "Título da páxina na que rematar de enumerar.",
        "apihelp-query+allpages-param-prefix": "Buscar tódolos títulos de páxinas que comezan con este valor.",
        "apihelp-query+allpages-param-namespace": "Espazo de nomes a enumerar.",
        "apihelp-query+allpages-param-filterredir": "Que páxinas listar.",
+       "apihelp-query+allpages-param-prtype": "Limitar a só protección de páxinas.",
+       "apihelp-query+allpages-param-prlevel": "Filtrar proteccións baseándose no nivel de protección (debe empregarse có parámetro $1prtype= ).",
        "apihelp-query+allpages-param-limit": "Número total de páxinas a devolver.",
        "apihelp-query+allpages-param-dir": "Dirección na cal listar.",
        "apihelp-query+allpages-example-B": "Mostrar unha lista de páxinas que comezan pola letra <kbd>B</kbd>.",
        "apihelp-query+allredirects-param-dir": "Dirección na cal listar.",
        "apihelp-query+alltransclusions-param-from": "Título da transclusión na que comezar a enumerar.",
        "apihelp-query+alltransclusions-param-to": "Título da transclusión na que rematar de enumerar.",
+       "apihelp-query+alltransclusions-param-namespace": "Nome de espazos a numerar.",
+       "apihelp-query+allusers-description": "Enumerar tódolos usuarios rexistrados.",
+       "apihelp-query+allusers-param-excludegroup": "Excluír usuarios nos grupos dados.",
+       "apihelp-query+allusers-param-witheditsonly": "Só listar usuarios que teñan feito edicións.",
+       "apihelp-query+categories-param-show": "Tipo de categorías a amosar.",
+       "apihelp-query+categorymembers-description": "Listar tódalas páxinas nunha categoría determinada.",
+       "apihelp-query+categorymembers-param-limit": "Máximo número de páxinas a retornar.",
+       "apihelp-query+contributors-param-excludegroup": "Excluír usuarios nos grupos dados. Non se inclúen grupos implícitos nin autopromocionados como *, usuario ou autoconfirmado.",
+       "apihelp-query+deletedrevisions-param-user": "Só listar revisións deste usuario.",
+       "apihelp-query+deletedrevisions-param-excludeuser": "Non listar revisións deste usuario.",
        "apihelp-query+deletedrevs-param-prefix": "Buscar tódolos títulos de páxina que comezan con este valor.",
        "apihelp-query+deletedrevs-param-unique": "Só listar unha revisión por cada páxina.",
        "apihelp-query+deletedrevs-param-tag": "Só listar revisións marcadas con esta etiqueta.",
        "apihelp-query+imageinfo-description": "Devolve información de ficheiros e historial de subidas.",
        "apihelp-query+imageinfo-paramvalue-prop-user": "Engade o usuario que subeu cada versión de ficheiro.",
        "apihelp-query+imageinfo-paramvalue-prop-comment": "Comentario da versión.",
+       "apihelp-query+imageinfo-param-localonly": "Só buscar ficheiros no repositorio local.",
+       "apihelp-query+images-example-simple": "Obter unha lista de arquivos empregados na [[Main Page]].",
+       "apihelp-query+imageusage-param-namespace": "Nome de espazos a numerar.",
+       "apihelp-query+pagepropnames-param-limit": "Máximo número de nomes a retornar.",
        "apihelp-query+prefixsearch-param-search": "Buscar texto.",
        "apihelp-query+prefixsearch-param-namespace": "Espazo de nomes no que buscar.",
        "apihelp-query+prefixsearch-param-limit": "Número máximo de resultados a visualizar.",
        "apihelp-upload-param-text": "Texto da páxina inicial para novos ficheiros.",
        "apihelp-upload-param-watch": "Vixiar a páxina.",
        "apihelp-upload-param-ignorewarnings": "Ignorar as advertencias.",
+       "apihelp-upload-param-file": "Contido do ficheiro.",
        "apihelp-upload-param-filesize": "Tamaño de ficheiro completo da carga.",
        "apihelp-upload-example-url": "Carga dunha URL",
        "apihelp-upload-example-filekey": "Completar carga que fallou debido a avisos",
index 884eb21..218d24c 100644 (file)
@@ -1,9 +1,12 @@
 {
        "@metadata": {
                "authors": [
-                       "Beta16"
+                       "Beta16",
+                       "Nivit"
                ]
        },
+       "apihelp-query+recentchanges-example-simple": "Elenco modifiche recenti.",
+       "apihelp-upload-example-url": "Carica da un URL.",
        "api-help-parameters": "{{PLURAL:$1|Parametro|Parametri}}:",
        "api-help-param-deprecated": "Deprecato.",
        "api-help-param-required": "Questo parametro è obbligatorio.",
index 2fa5e64..f61a8b8 100644 (file)
@@ -11,7 +11,7 @@
        "apihelp-main-param-format": "出力する形式です。",
        "apihelp-main-param-smaxage": "<code>s-maxage</code> ヘッダーにこの秒数を設定します。エラーがキャッシュされることはありません。",
        "apihelp-main-param-maxage": "<code>max-age</code> ヘッダーにこの秒数を設定します。エラーがキャッシュされることはありません。",
-       "apihelp-main-param-assert": "\"user\" を設定した場合は利用者がログイン済みかどうかを、\"bot\" を指定した場合はボット権限があるかどうかを、それぞれ検証します。",
+       "apihelp-main-param-assert": "<kbd>user</kbd> を設定した場合は利用者がログイン済みかどうかを、<kbd>bot</kbd> を指定した場合はボット権限があるかどうかを、それぞれ検証します。",
        "apihelp-main-param-requestid": "任意の値を指定でき、その値が結果に含められます。リクエストを識別するために使用できます。",
        "apihelp-main-param-servedby": "リクエストを処理したホスト名を結果に含めます。",
        "apihelp-main-param-curtimestamp": "現在のタイムスタンプを結果に含めます。",
        "apihelp-block-description": "利用者をブロックします。",
        "apihelp-block-param-user": "ブロックする利用者名、IPアドレスまたはIPレンジ。",
        "apihelp-block-param-reason": "ブロックの理由。",
-       "apihelp-block-param-anononly": "匿名利用者のみブロックします(つまり、このIPからの匿名での編集を不可能にします)。",
+       "apihelp-block-param-anononly": "å\8c¿å\90\8då\88©ç\94¨è\80\85ã\81®ã\81¿ã\83\96ã\83­ã\83\83ã\82¯ã\81\97ã\81¾ã\81\99ï¼\88ã\81¤ã\81¾ã\82\8aã\80\81ã\81\93ã\81®IPã\82¢ã\83\89ã\83¬ã\82¹ã\81\8bã\82\89ã\81®å\8c¿å\90\8dã\81§ã\81®ç·¨é\9b\86ã\82\92ä¸\8då\8f¯è\83½ã\81«ã\81\97ã\81¾ã\81\99ï¼\89ã\80\82",
        "apihelp-block-param-nocreate": "アカウントの作成を禁止します。",
        "apihelp-block-param-autoblock": "その利用者が最後に使用したIPアドレスと、ブロック後に編集を試みた際のIPアドレスを自動的にブロックします。",
-       "apihelp-block-param-noemail": "Wikiを通して電子メールを送信することを禁止します。(\"blockemail\" 権限が必要です)",
-       "apihelp-block-param-hidename": "ブロック記録から利用者名を秘匿します。(\"hideuser\" 権限が必要です)",
+       "apihelp-block-param-noemail": "Wikiを通して電子メールを送信することを禁止します。(<code>blockemail</code> 権限が必要です)",
+       "apihelp-block-param-hidename": "ブロック記録から利用者名を秘匿します。(<code>hideuser</code> 権限が必要です)",
        "apihelp-block-param-reblock": "その利用者がすでにブロックされている場合、ブロックを上書きします。",
-       "apihelp-block-param-watchuser": "その利用者またはIPの利用者ページとトークページをウォッチします。",
-       "apihelp-block-example-ip-simple": "IP 192.0.2.5 を \"First strike\" という理由で3日ブロックする",
-       "apihelp-block-example-user-complex": "利用者 \"Vandal\" を \"Vandalism\" という理由で無期限ブロックし、新たなアカウント作成とメールの送信を禁止する。",
+       "apihelp-block-param-watchuser": "ã\81\9dã\81®å\88©ç\94¨è\80\85ã\81¾ã\81\9fã\81¯IPã\82¢ã\83\89ã\83¬ã\82¹ã\81®å\88©ç\94¨è\80\85ã\83\9aã\83¼ã\82¸ã\81¨ã\83\88ã\83¼ã\82¯ã\83\9aã\83¼ã\82¸ã\82\92ã\82¦ã\82©ã\83\83ã\83\81ã\81\97ã\81¾ã\81\99ã\80\82",
+       "apihelp-block-example-ip-simple": "IPアドレス <kbd>192.0.2.5</kbd> を <kbd>First strike<kbd> という理由で3日ブロックする",
+       "apihelp-block-example-user-complex": "利用者 <kbd>Vandal</kbd> を <kbd>Vandalism</kbd> という理由で無期限ブロックし、新たなアカウント作成とメールの送信を禁止する。",
        "apihelp-createaccount-description": "新しい利用者アカウントを作成します。",
        "apihelp-createaccount-param-name": "利用者名。",
        "apihelp-createaccount-param-password": "パスワード (<var>$1mailpassword</var> が設定されると無視されます)。",
        "apihelp-createaccount-param-token": "最初のリクエストで得られたアカウント作成用トークンです。",
        "apihelp-createaccount-param-email": "利用者の電子メールアドレス (任意)。",
        "apihelp-createaccount-param-mailpassword": "設定されると (その値を問わず)、ランダムなパスワードがその利用者に電子メールで送られます。",
-       "apihelp-createaccount-example-mail": "利用者「testuser」を作成し、ランダムに生成されたパスワードをメールで送る",
+       "apihelp-createaccount-example-mail": "利用者 <kbd>testuser</kbd>を作成し、ランダムに生成されたパスワードをメールで送る",
        "apihelp-delete-description": "ページを削除します。",
-       "apihelp-delete-param-title": "削除するページ名です。 $1pageid とは同時に使用できません。",
-       "apihelp-delete-param-pageid": "削除するページIDです。 $1title とは同時に使用できません。",
+       "apihelp-delete-param-title": "削除するページ名です。<var>$1pageid</var> とは同時に使用できません。",
+       "apihelp-delete-param-pageid": "削除するページIDです。<var>$1title</var> とは同時に使用できません。",
        "apihelp-delete-param-reason": "削除の理由です。入力しない場合、自動的に生成された理由が使用されます。",
        "apihelp-delete-param-watch": "そのページをウォッチリストに追加します。",
        "apihelp-delete-param-unwatch": "そのページをウォッチリストから除去します。",
-       "apihelp-delete-example-simple": "「Main Page」を削除する",
-       "apihelp-delete-example-reason": "\"Preparing for move\" という理由で Main Page を削除する",
+       "apihelp-delete-example-simple": "<kbd>Main Page</kbd> を削除する",
+       "apihelp-delete-example-reason": "<kbd>Preparing for move</kbd> という理由で <kbd>Main Page</kbd> を削除する",
        "apihelp-disabled-description": "このモジュールは無効化されています。",
        "apihelp-edit-description": "ページを作成、編集します。",
-       "apihelp-edit-param-title": "編集するページ名です。$1pageid とは同時に使用できません。",
-       "apihelp-edit-param-pageid": "編集するページIDです。$1title とは同時に使用できません。",
+       "apihelp-edit-param-title": "編集するページ名です。<var>$1pageid</var> とは同時に使用できません。",
+       "apihelp-edit-param-pageid": "編集するページIDです。<var>$1title</var> とは同時に使用できません。",
        "apihelp-edit-param-text": "ページの本文。",
        "apihelp-edit-param-minor": "細部の編集",
        "apihelp-edit-param-createonly": "すでにそのページが存在する場合は編集を行いません。",
        "apihelp-emailuser-param-target": "送信先の利用者名。",
        "apihelp-emailuser-param-text": "電子メールの本文。",
        "apihelp-emailuser-param-ccme": "電子メールの複製を自分にも送信します。",
+       "apihelp-feedcontributions-example-simple": "利用者 <kbd>Example</kbd> の投稿記録を取得する。",
        "apihelp-filerevert-example-revert": "<kbd>Wiki.png</kbd> を <kbd>2011-03-05T15:27:40Z</kbd> の版に差し戻す。",
        "apihelp-help-description": "指定したモジュールのヘルプを表示します。",
-       "apihelp-help-param-modules": "ヘルプを表示するモジュールです (action= パラメーターおよび format= パラメーターの値、または \"main\")。\"+\" を使用して下位モジュールを指定できます。",
+       "apihelp-help-param-modules": "ヘルプを表示するモジュールです (<var>action</var> パラメーターおよび <var>format</var> パラメーターの値、または <kbd>main</kbd>)。<kbd>+</kbd> を使用して下位モジュールを指定できます。",
        "apihelp-help-param-submodules": "指定したモジュールの下位モジュールのヘルプを含めます。",
        "apihelp-help-param-recursivesubmodules": "下位モジュールのヘルプを再帰的に含めます。",
        "apihelp-help-param-helpformat": "ヘルプの出力形式です。",
        "apihelp-help-example-recursive": "すべてのヘルプを1つのページに",
        "apihelp-help-example-help": "ヘルプ モジュール自身のヘルプ",
        "apihelp-help-example-query": "2つの下位モジュールのヘルプ",
+       "apihelp-import-param-xml": "XMLファイルをアップロード",
        "apihelp-login-param-name": "利用者名。",
        "apihelp-login-param-password": "パスワード。",
        "apihelp-login-example-login": "ログイン",
        "apihelp-move-description": "ページを移動します。",
-       "apihelp-move-param-from": "移動するページのページ名です。 $1fromid とは同時に使用できません。",
-       "apihelp-move-param-fromid": "移動するページのページIDです。 $1from とは同時に使用できません。",
+       "apihelp-move-param-from": "移動するページのページ名です。<var>$1fromid</var> とは同時に使用できません。",
+       "apihelp-move-param-fromid": "移動するページのページIDです。<var>$1from</var> とは同時に使用できません。",
        "apihelp-move-param-to": "移動後のページ名。",
        "apihelp-move-param-reason": "移動の理由。",
        "apihelp-move-param-movetalk": "存在する場合、トークページも移動します。",
        "apihelp-move-param-noredirect": "転送ページを作成しません。",
        "apihelp-move-param-watch": "そのページと転送ページをウォッチリストに追加します。",
        "apihelp-move-param-unwatch": "そのページと転送ページをウォッチリストから除去します。",
-       "apihelp-move-example-move": "「Badtitle」を「Goodtitle」に転送ページを残さず移動",
+       "apihelp-move-param-ignorewarnings": "あらゆる警告を無視",
+       "apihelp-move-example-move": "<kbd>Badtitle</kbd> を <kbd>Goodtitle</kbd> に転送ページを残さず移動",
+       "apihelp-patrol-example-rcid": "最近の更新を巡回",
        "apihelp-format-example-generic": "クエリの結果を $1 形式に整形します",
-       "apihelp-dbg-description": "データを PHP の var_export() 形式で出力します。",
-       "apihelp-dbgfm-description": "データを PHP の var_export() 形式 (HTML に埋め込んだ形式) で出力します。",
-       "apihelp-dump-description": "データを PHP の var_dump() 形式で出力します。",
-       "apihelp-dumpfm-description": "データを PHP の var_dump() 形式 (HTML に埋め込んだ形式) で出力します。",
+       "apihelp-dbg-description": "データを PHP の <code>var_export()</code> 形式で出力します。",
+       "apihelp-dbgfm-description": "データを PHP の <code>var_export()</code> 形式 (HTML に埋め込んだ形式) で出力します。",
+       "apihelp-dump-description": "データを PHP の <code>var_dump()</code> 形式で出力します。",
+       "apihelp-dumpfm-description": "データを PHP の <code>var_dump()</code> 形式 (HTML に埋め込んだ形式) で出力します。",
        "apihelp-json-description": "データを JSON 形式で出力します。",
        "apihelp-json-param-callback": "指定すると、指定した関数呼び出しで出力をラップします。安全のため、利用者固有のデータはすべて制限されます。",
        "apihelp-json-param-utf8": "指定すると、大部分の非 ASCII 文字 (すべてではありません) を、16 進のエスケープ シーケンスに置換する代わりに UTF-8 として符号化します。",
        "apihelp-php-description": "データを PHP のシリアル化した形式で出力します。",
        "apihelp-phpfm-description": "データを PHP のシリアル化した形式 (HTML に埋め込んだ形式) で出力します。",
        "apihelp-rawfm-description": "データをデバッグ要素付きで JSON 形式 (HTML に埋め込んだ形式) で出力します。",
-       "apihelp-txt-description": "データを PHP の print_r() 形式で出力します。",
-       "apihelp-txtfm-description": "データを PHP の print_r() 形式 (HTML に埋め込んだ形式) で出力します。",
+       "apihelp-txt-description": "データを PHP の <code>print_r()</code> 形式で出力します。",
+       "apihelp-txtfm-description": "データを PHP の <code>print_r()</code> 形式 (HTML に埋め込んだ形式) で出力します。",
        "apihelp-wddx-description": "データを WDDX 形式で出力します。",
        "apihelp-wddxfm-description": "データを WDDX 形式 (HTML に埋め込んだ形式) で出力します。",
        "apihelp-xml-description": "データを XML 形式で出力します。",
        "apihelp-yaml-description": "データを YAML 形式で出力します。",
        "apihelp-yamlfm-description": "データを YAML 形式 (HTML に埋め込んだ形式) で出力します。",
        "api-format-title": "MediaWiki API の結果",
-       "api-format-prettyprint-header": "このページは $1 形式を HTML で表現したものです。HTML はデバッグに役立ちますが、アプリケーションでの使用には適していません。\n\nformat パラメーターを指定すると出力形式を変更できます 。$1 形式の非 HTML 版を閲覧するには、format=$2 を設定してください。\n\n詳細情報については [https://www.mediawiki.org/wiki/API 完全な説明文書]または [[Special:ApiHelp/main|API のヘルプ]]を参照してください。",
+       "api-format-prettyprint-header": "このページは $1 形式を HTML で表現したものです。HTML はデバッグに役立ちますが、アプリケーションでの使用には適していません。\n\n<var>format</var> パラメーターを指定すると出力形式を変更できます 。$1 形式の非 HTML 版を閲覧するには、format=$2 を設定してください。\n\n詳細情報については [[mw:API|完全な説明文書]]または [[Special:ApiHelp/main|API のヘルプ]]を参照してください。",
        "api-help-title": "MediaWiki API ヘルプ",
        "api-help-lead": "このページは自動生成された MediaWiki API の説明文書ページです。\n\n説明文書と例: https://www.mediawiki.org/wiki/API",
        "api-help-main-header": "メイン モジュール",
        "api-help-parameters": "{{PLURAL:$1|パラメーター}}:",
        "api-help-param-deprecated": "廃止予定です。",
        "api-help-param-required": "このパラメーターは必須です。",
-       "api-help-param-list": "{{PLURAL:$1|1=値 (いずれか1つ)|2=値 (「{{!}}」で区切る)}}: $2",
+       "api-help-param-list": "{{PLURAL:$1|1=値 (いずれか1つ)|2=値 (<kbd>{{!}}</kbd>で区切る)}}: $2",
        "api-help-param-list-can-be-empty": "{{PLURAL:$1|0=空欄にしてください|空欄にするか、または $2}}",
        "api-help-param-integer-min": "{{PLURAL:$1|値}}は $2 以上にしてください。",
        "api-help-param-integer-max": "{{PLURAL:$1|値}}は $3 以下にしてください。",
        "api-help-param-integer-minmax": "{{PLURAL:$1|値}}は $2 以上 $3 以下にしてください。",
        "api-help-param-upload": "multipart/form-data 形式でファイルをアップロードしてください。",
-       "api-help-param-multi-separate": "複数の値は「|」で区切ってください。",
+       "api-help-param-multi-separate": "複数の値は <kbd>|</kbd> で区切ってください。",
        "api-help-param-multi-max": "値の最大値は {{PLURAL:$1|$1}} (ボットの場合は {{PLURAL:$2|$2}}) です。",
        "api-help-param-default": "既定値: $1",
        "api-help-param-default-empty": "既定値: <span class=\"apihelp-empty\">(空)</span>",
index b20de56..5e18dc1 100644 (file)
@@ -1,10 +1,11 @@
 {
        "@metadata": {
                "authors": [
-                       "Kwj2772"
+                       "Kwj2772",
+                       "Twotwo2019"
                ]
        },
-       "apihelp-main-description": "<div class=\"hlist plainlinks api-main-links\"> * [https://www.mediawiki.org/wiki/API:Main_page 설명문서] * [https://www.mediawiki.org/wiki/API:FAQ FAQ] * [https://lists.wikimedia.org/mailman/listinfo/mediawiki-api 메일링 리스트] * [https://lists.wikimedia.org/mailman/listinfo/mediawiki-api-announce API 공지 사항] * [https://phabricator.wikimedia.org/maniphest/query/GebfyV4uCaLd/#R 버그 및 요청] </div>\n<strong>상태:</strong> 이 페이지에 표시된 모든 기능은 정상 작동할 것이지만, API는 여전히 활발하게 개발되고 있으며, 언제든지 바뀔 수 있습니다. 업데이트 정보를 받아보려면 [https://lists.wikimedia.org/pipermail/mediawiki-api-announce/ the mediawiki-api-announce 메일링 리스트]를 구독하십시오.\n\n<strong>잘못된 요청:</strong> API에 잘못된 요청이 전송되면 HTTP 헤더에서 \"MediaWiki-API-Error\" 키를 보내고, 헤더 값과 오류 코드가 같게 설정됩니다. 자세한 정보에 대해서는 https://www.mediawiki.org/wiki/API:Errors_and_warnings 를 참고하십시오.",
+       "apihelp-main-description": "<div class=\"hlist plainlinks api-main-links\">\n* [https://www.mediawiki.org/wiki/API:Main_page 설명문서]\n* [https://www.mediawiki.org/wiki/API:FAQ FAQ]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-api 메일링 리스트]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-api-announce API 공지 사항] * [https://phabricator.wikimedia.org/maniphest/query/GebfyV4uCaLd/#R 버그 및 요청] </div>\n<strong>상태:</strong> 이 페이지에 표시된 모든 기능은 정상 작동할 것이지만, API는 여전히 활발하게 개발되고 있으며, 언제든지 바뀔 수 있습니다. 업데이트 정보를 받아보려면 [https://lists.wikimedia.org/pipermail/mediawiki-api-announce/ the mediawiki-api-announce 메일링 리스트]를 구독하십시오.\n\n<strong>잘못된 요청:</strong> API에 잘못된 요청이 전송되면 HTTP 헤더에서 \"MediaWiki-API-Error\" 키를 보내고, 헤더 값과 오류 코드가 같게 설정됩니다. 자세한 정보에 대해서는 https://www.mediawiki.org/wiki/API:Errors_and_warnings 를 참고하십시오.",
        "apihelp-main-param-action": "수행할 동작",
        "apihelp-main-param-format": "출력값의 형식.",
        "apihelp-block-description": "사용자를 차단합니다.",
        "apihelp-block-param-anononly": "익명 사용자만 차단합니다. (즉, 이 IP의 익명 편집을 막음)",
        "apihelp-block-param-nocreate": "계정 생성을 막습니다.",
        "apihelp-block-param-autoblock": "최근 사용한 IP 주소나 로그인을 시도한 이후에 사용한 모든 IP 주소를 자동으로 차단합니다.",
-       "apihelp-block-param-noemail": "위키를 통해 이메일을 보내지 못하도록 막습니다. (\"blockemail\" 권한 필요)",
-       "apihelp-block-param-hidename": "차단 기록에서 사용자 이름을 숨깁니다. (\"hideuser\" 권한 필요)",
+       "apihelp-block-param-noemail": "위키를 통해 이메일을 보내지 못하도록 막습니다. (<code>blockemail</code> 권한 필요)",
+       "apihelp-block-param-hidename": "차단 기록에서 사용자 이름을 숨깁니다. (<code>hideuser</code> 권한 필요)",
        "apihelp-block-param-allowusertalk": "자신의 토론 문서를 편집할 수 있도록 허용합니다. (<var>[[mw:Manual:$wgBlockAllowsUTEdit|$wgBlockAllowsUTEdit]]</var> 값에 따라 다름)",
        "apihelp-block-param-reblock": "사용자가 이미 차단된 경우, 기존 차단 설정을 바꿉니다.",
        "apihelp-block-param-watchuser": "해당 사용자 또는 IP 주소의 사용자 문서 및 토론 문서를 주시합니다.",
-       "apihelp-block-example-ip-simple": "IP 192.0.2.5에 대해 \"First strike\"라는 이유로 3일간 차단하기",
-       "apihelp-block-example-user-complex": "사용자 Vandal을 \"Vandalism\"이라는 이유로 무기한 차단하며 계정 생성 및 이메일 발송을 막기",
+       "apihelp-block-example-ip-simple": "IP <kbd>192.0.2.5</kbd>에 대해 <kbd>First strike</kbd>라는 이유로 3일간 차단하기",
+       "apihelp-block-example-user-complex": "사용자 <kbd>Vandal</kbd>을 <kbd>Vandalism</kbd>이라는 이유로 무기한 차단하며 계정 생성 및 이메일 발송을 막기",
        "api-help-param-list": "{{PLURAL:$1|1=하나의 값|2=값 (\"{{!}}\"로 구분)}}: $2",
        "api-help-param-default": "기본값: $1"
 }
index 5f4e0df..c54e089 100644 (file)
@@ -7,40 +7,44 @@
        "apihelp-block-description": "E Benotzer spären.",
        "apihelp-block-param-user": "Benotzernumm, IP-Adress oder IP-Beräich deen Dir späre wëllt.",
        "apihelp-block-param-reason": "Grond fir ze spären.",
-       "apihelp-block-param-anononly": "Nëmmen anonym Benotzer spären (z. Bsp. anonym Ännerunge vun dëser IP ausschalten)",
+       "apihelp-block-param-anononly": "Nëmmen anonym Benotzer spären (z. Bsp. anonym Ännerunge vun dëser IP-Adress ausschalten)",
        "apihelp-block-param-nocreate": "Opmaache vun engem Benotzerkont verhënneren.",
        "apihelp-block-param-reblock": "Wann de Benotzer scho gespaart ass, déi aktuell Spär iwwerschreiwen.",
-       "apihelp-block-param-watchuser": "Dem Benotzer oder der IP hier Benotzer- an Diskussiouns-Säiten iwwerwaachen.",
+       "apihelp-block-param-watchuser": "Dem Benotzer oder der IP-Adress hier Benotzer- an Diskussiouns-Säiten iwwerwaachen.",
        "apihelp-createaccount-description": "En neie Benotzerkont uleeën.",
        "apihelp-createaccount-param-name": "Benotzernumm.",
        "apihelp-createaccount-param-email": "E-Mail-Adress vum Benotzer (fakultativ).",
        "apihelp-createaccount-param-realname": "Richtegen Numm vum Benotzer (fakultativ).",
        "apihelp-delete-description": "Eng Säit läschen.",
-       "apihelp-delete-param-watch": "D'Säit op Är Iwwerwaachungslëscht derbäisetzen.",
-       "apihelp-delete-example-simple": "D'Haaptsäit läschen",
+       "apihelp-delete-param-watch": "D'Säit op dem aktuelle Benotzer seng Iwwerwaachungslëscht dobäisetzen.",
+       "apihelp-delete-example-simple": "D'<kbd>Haaptsäit</kbd> läschen.",
        "apihelp-disabled-description": "Dëse Modul gouf ausgeschalt.",
        "apihelp-edit-param-sectiontitle": "Den Titel fir en neien Abschnitt.",
        "apihelp-edit-param-minor": "Kleng Ännerung.",
        "apihelp-edit-param-bot": "Dës Ännerung als Bot-Ännerung markéieren.",
-       "apihelp-edit-param-watch": "D'Säit op Är Iwwerwaachungslëscht derbäisetzen.",
+       "apihelp-edit-param-watch": "D'Säit op dem aktuelle Benotzer seng Iwwerwaachungslëscht dobäisetzen.",
        "apihelp-edit-example-edit": "Eng Säit änneren",
        "apihelp-expandtemplates-param-title": "Titel vun der Säit.",
        "apihelp-feedrecentchanges-param-hideminor": "Kleng Ännerunge verstoppen.",
        "apihelp-feedrecentchanges-param-hideanons": "Ännerunge vun anonyme Benotzer verstoppen.",
        "apihelp-feedrecentchanges-param-hideliu": "Ännerunge vu registréierte Benotzer verstoppen.",
        "apihelp-feedrecentchanges-example-simple": "Rezent Ännerunge weisen",
+       "apihelp-help-example-main": "Hëllef fir den Haaptmodul.",
        "apihelp-help-example-recursive": "All Hëllef op enger Säit",
        "apihelp-imagerotate-description": "Eent oder méi Biller dréinen.",
-       "apihelp-imagerotate-example-generator": "All Biller an der [[:Category:Flip]] ëm 180 Grad dréinen",
+       "apihelp-imagerotate-example-generator": "All Biller an der <kbd>Category:Flip]]<kbd> ëm <kbd>180<kbd> Grad dréinen.",
        "apihelp-import-param-summary": "Resumé importéieren.",
        "apihelp-login-param-name": "Benotzernumm.",
        "apihelp-login-param-password": "Passwuert.",
+       "apihelp-login-example-login": "Aloggen.",
        "apihelp-move-description": "Eng Säit réckelen.",
        "apihelp-move-param-ignorewarnings": "All Warnungen ignoréieren.",
        "apihelp-options-example-reset": "All Astellungen zrécksetzen",
+       "apihelp-patrol-example-rcid": "Eng rezent Ännerung nokucken.",
+       "apihelp-patrol-example-revid": "Eng Versioun nokucken.",
        "apihelp-protect-example-protect": "Eng Säit spären",
        "apihelp-query+allcategories-description": "All Kategorien opzielen.",
-       "apihelp-query+alldeletedrevisions-paraminfo-useronly": "Kann nëmme mam $3user benotzt ginn.",
+       "apihelp-query+alldeletedrevisions-paraminfo-useronly": "Kann nëmme mam <var>$3user</var> benotzt ginn.",
        "apihelp-query+alldeletedrevisions-param-user": "Nëmme Versioune vun dësem Benotzer opzielen.",
        "apihelp-query+alldeletedrevisions-param-excludeuser": "Versioune vun dësem Benotzer net opzielen.",
        "apihelp-query+allusers-description": "All registréiert Benotzer opzielen.",
@@ -49,7 +53,7 @@
        "apihelp-query+blocks-example-simple": "Lëscht vun de Spären",
        "apihelp-query+categories-description": "All Kategorien opzielen zu deenen dës Säit gehéiert.",
        "apihelp-query+categorymembers-description": "All Säiten aus enger bestëmmter Kategorie opzielen.",
-       "apihelp-query+categorymembers-example-simple": "Déi éischt 10 Säiten aus der [[:Category:Physics]] kréien",
+       "apihelp-query+categorymembers-example-simple": "Déi éischt 10 Säiten aus der <kbd>Category:Physics</kbd> kréien.",
        "apihelp-query+deletedrevisions-param-excludeuser": "Versioune vun dësem Benotzer net opzielen.",
        "apihelp-query+deletedrevs-param-unique": "Nëmmen eng Versioun fir all Säit weisen.",
        "apihelp-query+filearchive-example-simple": "Eng Lëscht vun alle geläschte Fichiere weisen",
@@ -64,7 +68,7 @@
        "apihelp-query+protectedtitles-param-namespace": "Nëmmen Titelen aus dësen Nummraim opzielen.",
        "apihelp-query+recentchanges-param-user": "Nëmmen Ännerunge vun dësem Benotzer opzielen.",
        "apihelp-query+recentchanges-example-simple": "Rezent Ännerunge weisen",
-       "apihelp-query+revisions-example-last5": "Déi lescht 5 Versioune vun der \"Haaptsäit\" kréien",
+       "apihelp-query+revisions-example-last5": "Déi lescht 5 Versioune vun der <kbd>Haaptsäit</kbd> kréien.",
        "apihelp-query+usercontribs-description": "All Ännerunge vun engem Benotzer kréien.",
        "apihelp-query+watchlist-param-user": "Nëmmen Ännerunge vun dësem Benotzer opzielen.",
        "apihelp-query+watchlist-param-excludeuser": "Ännerunge vun dësem Benotzer net opzielen.",
        "apihelp-unblock-description": "D'Spär vun engem Benotzer ophiewen.",
        "apihelp-unblock-param-reason": "Grond fir d'Spär opzehiewen",
        "apihelp-undelete-param-reason": "Grond fir ze restauréieren.",
-       "apihelp-undelete-example-page": "[[Main Page]] restauréieren",
+       "apihelp-undelete-example-page": "<kbd>Main Page</kbd> restauréieren.",
        "apihelp-upload-param-watch": "D'Säit iwwerwaachen.",
+       "apihelp-upload-example-url": "Vun enger URL eroplueden.",
        "apihelp-userrights-param-user": "Benotzernumm.",
        "apihelp-userrights-param-userid": "Benotzer Id.",
        "apihelp-userrights-param-reason": "Grond fir d'Ännerung.",
-       "apihelp-watch-example-watch": "D'Säit \"Haaptsäit\" iwwerwaachen",
+       "apihelp-watch-example-watch": "D'Säit <kbd>Haaptsäit</kbd> iwwerwaachen.",
        "api-help-param-deprecated": "Vereelst.",
        "api-help-param-required": "Dëse Parameter ass obligatoresch.",
        "api-help-examples": "{{PLURAL:$1|Beispill|Beispiler}}:"
diff --git a/includes/api/i18n/nap.json b/includes/api/i18n/nap.json
new file mode 100644 (file)
index 0000000..a285b04
--- /dev/null
@@ -0,0 +1,10 @@
+{
+       "@metadata": {
+               "authors": [
+                       "Chelin"
+               ]
+       },
+       "apihelp-block-description": "Blocca n'utente.",
+       "apihelp-createaccount-param-name": "Nomme utente.",
+       "apihelp-delete-description": "Scancella 'na paggena."
+}
diff --git a/includes/api/i18n/nds.json b/includes/api/i18n/nds.json
new file mode 100644 (file)
index 0000000..3f7cb12
--- /dev/null
@@ -0,0 +1,8 @@
+{
+       "@metadata": {
+               "authors": [
+                       "Servien"
+               ]
+       },
+       "apihelp-login-param-password": "Passwoort."
+}
diff --git a/includes/api/i18n/pam.json b/includes/api/i18n/pam.json
new file mode 100644 (file)
index 0000000..d23472f
--- /dev/null
@@ -0,0 +1,25 @@
+{
+       "@metadata": {
+               "authors": [
+                       "Leeheonjin"
+               ]
+       },
+       "apihelp-help-example-main": "Saup para king pun modyul.",
+       "apihelp-patrol-example-rcid": "Magbante king bayung mengayalili.",
+       "apihelp-query+alldeletedrevisions-paraminfo-nonuseronly": "E malyaring gamitan a yating <var>$3user</var>.",
+       "apihelp-query+allpages-example-B": "Ipakit ing talaan da reng bulung a mangumpisa king titik <kbd>B</kbd>.",
+       "apihelp-query+categoryinfo-example-simple": "Kumuwa ning impormasyun tungkul king <kbd>Kategorya:Foo</kbd> at <kbd>Kategorya:Bar</kbd>.",
+       "apihelp-query+deletedrevs-example-mode2": "Ilista la reng 50 binurang kontribusyun nang <kbd>Bob</kbd> (mode 2).",
+       "apihelp-query+deletedrevs-example-mode3-talk": "Ilista mu la reng minunang 50 meburang bulung king {{ns:talk}} lagyu-espasyu (mode 3)",
+       "apihelp-query+duplicatefiles-example-generated": "Mayintun para kareng duplika da reng egana-ganang simpan (file).",
+       "apihelp-query+extlinks-example-simple": "Kumuwa ning lista da reng suglung paluwal king <kbd>Pun Bulung</kbd>.",
+       "apihelp-query+exturlusage-example-simple": "Pakit la reng bulung a makasuglung king <kbd>http://www.mediawiki.org</kbd>.",
+       "apihelp-query+imageusage-example-simple": "Ipakit la reng bulung a gagamit ning [[:Simpan:Albert Einstein Head.jpg]].",
+       "apihelp-query+langbacklinks-example-simple": "Kunan deng bulung a maka-suglung king [[:fr:Test]].",
+       "apihelp-query+protectedtitles-example-generator": "Pantunan deng suglung king maka-protektang titulu king pun lagyu-espasyu.",
+       "apihelp-query+recentchanges-example-simple": "Talaan da reng bayung mengayalili.",
+       "apihelp-query+search-example-text": "Pantunan mo la reng tekstu para king <kbd>kabaldugan</kbd>",
+       "apihelp-query+siteinfo-example-simple": "Kung ing impormasyun ning sityu.",
+       "apihelp-upload-example-url": "Maglulan (upload) ibat king URL.",
+       "apihelp-watch-example-unwatch": "E banten ing bulung <kbd>Pun Bulung</kbd>"
+}
index 4578a06..478ee89 100644 (file)
@@ -39,6 +39,7 @@
        "apihelp-login-param-name": "Nazwa użytkownika.",
        "apihelp-login-param-password": "Hasło.",
        "apihelp-login-example-login": "Zaloguj się",
+       "apihelp-managetags-param-ignorewarnings": "Czy zignorować ostrzeżenia, które pojawiają się w trakcie operacji.",
        "apihelp-move-description": "Przenieś stronę.",
        "apihelp-move-param-ignorewarnings": "Ignoruj wszystkie ostrzeżenia.",
        "apihelp-protect-example-protect": "Zabezpiecz stronę",
        "apihelp-upload-param-filename": "Nazwa pliku docelowego.",
        "apihelp-userrights-param-user": "Nazwa użytkownika.",
        "apihelp-userrights-param-reason": "Powód zmiany.",
-       "apihelp-dbg-description": "Dane wyjściowe w formacie var_export() (funkcji PHP).",
-       "apihelp-dbgfm-description": "Dane wyjściowe w formacie var_export() (funkcji PHP) (prawidłowo wyświetlane w HTML).",
-       "apihelp-dump-description": "Dane wyjściowe w formacie var_dump() (funkcji PHP).",
-       "apihelp-dumpfm-description": "Dane wyjściowe w formacie var_dump() (funkcji PHP) (prawidłowo wyświetlane w HTML).",
+       "apihelp-dbg-description": "Dane wyjściowe w formacie <code>var_export()</code> (funkcji PHP).",
+       "apihelp-dbgfm-description": "Dane wyjściowe w formacie <code>var_export()</code> (funkcji PHP) (prawidłowo wyświetlane w HTML).",
+       "apihelp-dump-description": "Dane wyjściowe w formacie <code>var_dump()</code> (funkcji PHP).",
+       "apihelp-dumpfm-description": "Dane wyjściowe w formacie <code>var_dump()</code> (funkcji PHP) (prawidłowo wyświetlane w HTML).",
        "apihelp-json-description": "Dane wyjściowe w formacie JSON.",
        "apihelp-jsonfm-description": "Dane wyjściowe w formacie JSON (prawidłowo wyświetlane w HTML).",
        "apihelp-php-description": "Dane wyjściowe w serializowany formacie PHP.",
        "apihelp-phpfm-description": "Dane wyjściowe w serializowanym formacie PHP (prawidłowo wyświetlane w HTML).",
-       "apihelp-txt-description": "Dane wyjściowe w formacie print_r() (funkcji PHP).",
-       "apihelp-txtfm-description": "Dane wyjściowe w formacie print_r() (funkcji PHP) (prawidłowo wyświetlane w HTML).",
+       "apihelp-txt-description": "Dane wyjściowe w formacie <code>print_r()</code> (funkcji PHP).",
+       "apihelp-txtfm-description": "Dane wyjściowe w formacie <code>print_r()</code> (funkcji PHP) (prawidłowo wyświetlane w HTML).",
        "apihelp-wddx-description": "Dane wyjściowe w formacie WDDX.",
        "apihelp-wddxfm-description": "Dane wyjściowe w formacie WDDX (prawidłowo wyświetlane w HTML).",
        "apihelp-xml-description": "Dane wyjściowe w formacie XML.",
        "api-help-parameters": "{{PLURAL:$1|Parametr|Parametry}}:",
        "api-help-param-deprecated": "Przestarzałe.",
        "api-help-param-required": "Ten parametr jest wymagany.",
-       "api-help-param-list": "{{PLURAL:$1|1=Jedna wartość|2=Wartości (oddziel z \"{{!}}\")}}: $2",
+       "api-help-param-list": "{{PLURAL:$1|1=Jedna wartość|2=Wartości (oddziel za pomocą <kbd>{{!}}</kbd>)}}: $2",
        "api-help-param-limit": "Nie więcej niż $1 dozwolone.",
        "api-help-param-limit2": "Nie więcej niż $1 ($2 dla botów) dozwolone.",
        "api-help-param-integer-min": "{{PLURAL:$1|1=Wartość|2=Wartości}} musza być mniejsze niż $2.",
        "api-help-param-integer-max": "{{PLURAL:$1|1=Wartość musi|2=Wartości muszą}} być nie większa niż $3.",
        "api-help-param-integer-minmax": "{{PLURAL:$1|1=Wartość musi|2=Wartości muszą}} być pomiędzy $2 a $3.",
-       "api-help-param-multi-separate": "Oddziel wartości z \"|\".",
+       "api-help-param-multi-separate": "Oddziel wartości za pomocą <kbd>|</kbd>.",
        "api-help-param-multi-max": "Maksymalna ilość wartości to {{PLURAL:$1|$1}} ({{PLURAL:$2|$2}} dla botów).",
        "api-help-param-default": "Domyślnie: $1",
        "api-help-param-default-empty": "Domyślnie: <span class=\"apihelp-empty\">(puste)</span>",
diff --git a/includes/api/i18n/pt-br.json b/includes/api/i18n/pt-br.json
new file mode 100644 (file)
index 0000000..5af806d
--- /dev/null
@@ -0,0 +1,14 @@
+{
+       "@metadata": {
+               "authors": [
+                       "Fasouzafreitas"
+               ]
+       },
+       "apihelp-main-param-requestid": "Qualquer valor dado aqui será incluído na resposta. Pode ser usado para distinguir requisições.",
+       "apihelp-block-description": "Bloquear um usuário",
+       "apihelp-block-param-user": "Nome de usuário, endereço IP ou faixa de IP para bloquear.",
+       "apihelp-feedrecentchanges-param-hidemyself": "Ocultar alterações feitas pelo usuário atual.",
+       "apihelp-feedrecentchanges-example-30days": "Mostrar as alterações recentes por 30 dias.",
+       "apihelp-move-param-movetalk": "Renomear a página de discussão, se existir.",
+       "apihelp-options-example-reset": "Resetar todas as preferências"
+}
index ad6abc5..57059e4 100644 (file)
@@ -50,6 +50,8 @@
        "apihelp-login-param-domain": "Domínio (opcional).",
        "apihelp-login-example-login": "Entrar",
        "apihelp-logout-description": "Terminar e limpar dados de sessão.",
+       "apihelp-managetags-description": "Executar tarefas de gestão relacionadas com alteração de etiquetas.",
+       "apihelp-managetags-param-reason": "Um motivo, opcional, para a criação, eliminação, ativação ou desativação da etiqueta.",
        "apihelp-move-description": "Mover uma página.",
        "apihelp-move-param-noredirect": "Não criar um redirecionamento.",
        "apihelp-move-param-ignorewarnings": "Ignorar quaisquer avisos.",
index 0791acd..f539ac6 100644 (file)
        "apihelp-login-example-login": "{{doc-apihelp-example|login}}",
        "apihelp-logout-description": "{{doc-apihelp-description|logout}}",
        "apihelp-logout-example-logout": "{{doc-apihelp-example|logout}}",
+       "apihelp-managetags-description": "{{doc-apihelp-description|managetags}}",
+       "apihelp-managetags-param-operation": "{{doc-apihelp-param|managetags|operation}}",
+       "apihelp-managetags-param-tag": "{{doc-apihelp-param|managetags|tag}}",
+       "apihelp-managetags-param-reason": "{{doc-apihelp-param|managetags|reason}}",
+       "apihelp-managetags-param-ignorewarnings": "{{doc-apihelp-param|managetags|ignorewarnings}}",
+       "apihelp-managetags-example-create": "{{doc-apihelp-example|managetags}}",
+       "apihelp-managetags-example-delete": "{{doc-apihelp-example|managetags}}",
+       "apihelp-managetags-example-activate": "{{doc-apihelp-example|managetags}}",
+       "apihelp-managetags-example-deactivate": "{{doc-apihelp-example|managetags}}",
        "apihelp-move-description": "{{doc-apihelp-description|move}}",
        "apihelp-move-param-from": "{{doc-apihelp-param|move|from}}",
        "apihelp-move-param-fromid": "{{doc-apihelp-param|move|fromid}}",
index cf3a4de..db801b8 100644 (file)
@@ -1,11 +1,24 @@
 {
        "@metadata": {
                "authors": [
-                       "Milicevic01"
+                       "Milicevic01",
+                       "Aktron"
                ]
        },
        "apihelp-block-description": "Блокирај корисника.",
        "apihelp-block-param-reason": "Разлог за блокирање.",
+       "apihelp-createaccount-param-name": "Корисничко име.",
        "apihelp-delete-description": "Обриши страницу.",
-       "apihelp-edit-param-minor": "Мања измена."
+       "apihelp-edit-param-text": "Страница са садржајем.",
+       "apihelp-edit-param-minor": "Мања измена.",
+       "apihelp-edit-example-edit": "Уређивање странице.",
+       "apihelp-emailuser-description": "Слање е-поруке кориснику",
+       "apihelp-emailuser-param-target": "Корисник је послао е-поруку.",
+       "apihelp-feedcontributions-param-year": "Од године (и раније).",
+       "apihelp-filerevert-description": "Вратити датотеку у ранију верзију.",
+       "apihelp-help-example-recursive": "Сва помоћ у једној страници.",
+       "apihelp-login-param-name": "Корисничко име.",
+       "apihelp-login-param-password": "Лозинка.",
+       "apihelp-login-example-login": "Пријавa.",
+       "apihelp-move-description": "Премештање странице."
 }
index 638b161..3a5baa2 100644 (file)
                        "Boom"
                ]
        },
-       "apihelp-main-description": "<div class=\"hlist plainlinks api-main-links\">\n* [https://www.mediawiki.org/wiki/API:Main_page Dokumentation]\n* [https://www.mediawiki.org/wiki/API:FAQ FAQ]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-api E-postlist]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-api-announce API-aviseringar]\n* [https://phabricator.wikimedia.org/maniphest/query/GebfyV4uCaLd/#R Buggar & förslag]\n</div>\n<strong>Status:</strong> Alla funktioner som visas på denna sida borde fungera. API:et är dock fortfarande under aktiv utveckling och kan ändras när som helst. Prenumerera på [https://lists.wikimedia.org/pipermail/mediawiki-api-announce/ mediawiki-api-announce e-postlistan] för att få aviseringar om uppdateringar.\n\n<strong>Felaktiga förfrågningar:</strong> När felaktiga förfrågningar skickas till API:et skickas en HTTP-header med nyckeln \"MediaWiki-API-Error\" och sedan sätts både värdet på headern och den felkoden som returneras till samma värde. För mer information läs https://www.mediawiki.org/wiki/API:Errors_and_warnings.",
+       "apihelp-main-description": "<div class=\"hlist plainlinks api-main-links\">\n* [[mw:API:Main_page|Dokumentation]]\n* [[mw:API:FAQ|FAQ]]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-api E-postlista]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-api-announce API-aviseringar]\n* [https://phabricator.wikimedia.org/maniphest/query/GebfyV4uCaLd/#R|Buggar & förslag]\n</div>\n<strong>Status:</strong> Alla funktioner som visas på denna sida borde fungera. API:et är dock fortfarande under aktiv utveckling och kan ändras när som helst. Prenumerera på [https://lists.wikimedia.org/pipermail/mediawiki-api-announce/mediawiki-api-announce e-postlistan] för att få aviseringar om uppdateringar.\n\n<strong>Felaktiga förfrågningar:</strong> När felaktiga förfrågningar skickas till API:et skickas en HTTP-header med nyckeln \"MediaWiki-API-Error\" och sedan sätts både värdet på headern och den felkoden som returneras till samma värde. För mer information läs [[mw:API:Errors_and_warnings|API: Fel och varningar]].",
        "apihelp-main-param-action": "Vilken åtgärd som ska utföras.",
        "apihelp-main-param-format": "Formatet för utdata.",
-       "apihelp-main-param-assert": "Bekräftar att användaren är inloggad om satt till \"user\", eller har bot-användarrättigheter om satt till \"bot\".",
+       "apihelp-main-param-assert": "Bekräftar att användaren är inloggad om satt till <kbd>user</kbd>, eller har bot-användarrättigheter om satt till <kbd>bot</kbd>.",
        "apihelp-main-param-requestid": "Alla värde som anges här kommer att inkluderas i svaret. Kan användas för att särskilja förfrågningar.",
        "apihelp-main-param-servedby": "Inkludera det värdnamn som besvarade förfrågan i resultatet.",
        "apihelp-main-param-curtimestamp": "Inkludera den aktuella tidsstämpeln i resultatet.",
-       "apihelp-main-param-origin": "När API:et används genom en cross-domain AJAX-begäran (CORS), ange detta till den ursprungliga domänen. Detta måste inkluderas i alla pre-flight-begäran, och mpste därför vara en del av den begärda URI:n (inte i POST-datat). Detta måste överensstämma med en av källorna i Origin:-headern exakt, så den måste sättas till något i stil med http://en.wikipedia.org eller https://meta.wikimedia.org. Om denna parameter inte överensstämmer med Origin:-headern, returneras ett 403-svar. Om denna parameter överensstämmer med Origin:-headern och källan är vitlistad, sätts en Access-Control-Allow-Origin-header.",
-       "apihelp-main-param-uselang": "Språk som ska användas för meddelandeöversättningar. En lista med koder kan hämtas från [[Special:ApiHelp/query+siteinfo|action=query&meta=siteinfo]] med siprop=languages, eller ange \"user\" för att använda den aktuella användarens språkpreferenser, eller ange \"content\" för att använda innehållsspråket.",
+       "apihelp-main-param-origin": "När API:et används genom en cross-domain AJAX-begäran (CORS), ange detta till den ursprungliga domänen. Detta måste inkluderas i alla pre-flight-begäran, och mpste därför vara en del av den begärda URI:n (inte i POST-datat). Detta måste överensstämma med en av källorna i headern <code>Origin</code> exakt, så den måste sättas till något i stil med <kbd>http://en.wikipedia.org</kbd> eller <kbd>https://meta.wikimedia.org</kbd>. Om denna parameter inte överensstämmer med headern <code>Origin</code>, returneras ett 403-svar. Om denna parameter överensstämmer med headern <code>Origin</code> och källan är vitlistad, sätts en <code>Access-Control-Allow-Origin</code>-header.",
+       "apihelp-main-param-uselang": "Språk som ska användas för meddelandeöversättningar. En lista med koder kan hämtas från <kbd>[[Special:ApiHelp/query+siteinfo|action=query&meta=siteinfo]]</kbd> med <kbd>siprop=languages</kbd>, eller ange <kbd>user</kbd> för att använda den aktuella användarens språkpreferenser, eller ange <kbd>content</kbd> för att använda innehållsspråket.",
        "apihelp-block-description": "Blockera en användare.",
        "apihelp-block-param-user": "Användare, IP-adress eller IP-intervall du vill blockera.",
-       "apihelp-block-param-expiry": "Förfallotid. Kan vara Kan vara relativt (t.ex. \"5 months\" eller \"2 weeks\") eller absolut (t.ex. 2014-09-18T12:34:56Z\"). Om satt till \"infinite\", \"indefinite\" eller \"never\", kommer blockeringen aldrig att löpa ut.",
+       "apihelp-block-param-expiry": "Förfallotid. Kan vara Kan vara relativt (t.ex. <kbd>5 months</kbd> eller <kbd>2 weeks</kbd>) eller absolut (t.ex. <kbd>2014-09-18T12:34:56Z</kbd>). Om satt till <kbd>infinite</kbd>, <kbd>indefinite</kbd> eller <kbd>never</kbd>, kommer blockeringen aldrig att löpa ut.",
        "apihelp-block-param-reason": "Orsak till blockering.",
        "apihelp-block-param-anononly": "Blockera endast anonyma användare (t.ex. inaktivera anonyma redigeringar för denna IP-adress).",
        "apihelp-block-param-nocreate": "Förhindra registrering av användarkonton.",
        "apihelp-block-param-autoblock": "Blockera automatiskt den senast använda IP-adressen, och alla efterföljande IP-adresser de försöker logga in från.",
-       "apihelp-block-param-noemail": "Hindra användaren från att skicka e-post via wikin. (Kräver \"blockemail\"-rättigheten).",
-       "apihelp-block-param-hidename": "Döljer användarnamnet från blockeringsloggen. (Kräver rättigheten \"hideuser\").",
+       "apihelp-block-param-noemail": "Hindra användaren från att skicka e-post via wikin. (Kräver rättigheten <code>blockemail</code>).",
+       "apihelp-block-param-hidename": "Döljer användarnamnet från blockeringsloggen. (Kräver rättigheten <code>hideuser</code>).",
        "apihelp-block-param-allowusertalk": "Låt användaren redigera sin egen diskussionssida (beror på <var>[[mw:Manual:$wgBlockAllowsUTEdit|$wgBlockAllowsUTEdit]]</var>).",
        "apihelp-block-param-reblock": "Skriv över befintlig blockering om användaren redan är blockerad.",
        "apihelp-block-param-watchuser": "Bevaka användarens eller IP-adressens användarsida och diskussionssida",
-       "apihelp-block-example-ip-simple": "Blockera IP-adressen 192.0.2.5 i tre dagar med motivationen \"First strike\"",
-       "apihelp-block-example-user-complex": "Blockera användare Vandal på obegränsad tid med motivationen \"Vandalism\", och förhindra kontoskapande och e-post.",
+       "apihelp-block-example-ip-simple": "Blockera IP-adressen <kbd>192.0.2.5</kbd> i tre dagar med motivationen <kbd>First strike</kbd>",
+       "apihelp-block-example-user-complex": "Blockera användare <kbd>Vandal</kbd> på obegränsad tid med motivationen <kbd>Vandalism</kbd>, och förhindra kontoskapande och e-post.",
        "apihelp-clearhasmsg-description": "Rensa <code>hasmsg</code>-flaggan för den aktuella användaren.",
        "apihelp-clearhasmsg-example-1": "Rensa <code>hasmsg</code>-flaggan för den aktuella användaren",
-       "apihelp-compare-description": "Hämta skillnaden mellan två sidor.\n\nDu behöver skicka ett versionsnummer, en sidtitel, eller ett sid-Id för både \"from\" och \"to\".",
+       "apihelp-compare-description": "Hämta skillnaden mellan två sidor.\n\nEtt versionsnummer, en sidtitel, eller ett sid-Id för både \"from\" och \"to\" måste skickas.",
        "apihelp-compare-param-fromtitle": "Första titeln att jämföra.",
        "apihelp-compare-param-fromid": "Första sid-ID att jämföra.",
        "apihelp-compare-param-fromrev": "Första version att jämföra.",
        "apihelp-createaccount-param-mailpassword": "Om satt till ett värde, skickas ett slumpmässigt lösenord till användaren via e-post.",
        "apihelp-createaccount-param-reason": "Valfri anledning för att skapa kontot för att läggas till i loggarna.",
        "apihelp-createaccount-param-language": "Språkkod att använda som standard för användaren (valfri, standardvärdet är innehållsspråket).",
-       "apihelp-createaccount-example-pass": "Skapa användaren \"testuser\" med lösenordet \"test123\"",
-       "apihelp-createaccount-example-mail": "Skapa användaren \"testmailuser\" och skicka ett slumpgenererat lösenord via e-post",
+       "apihelp-createaccount-example-pass": "Skapa användaren <kbd>testuser</kbd> med lösenordet <kbd>test123</kbd>",
+       "apihelp-createaccount-example-mail": "Skapa användaren <kbd>testmailuser</kbd> och skicka ett slumpgenererat lösenord via e-post",
        "apihelp-delete-description": "Radera en sida.",
-       "apihelp-delete-param-title": "Titel på sidan du vill radera. Kan inte användas tillsammans med $1pageid.",
-       "apihelp-delete-param-pageid": "Sid-ID för sidan du vill radera. Kan inte användas tillsammans med $1titel.",
+       "apihelp-delete-param-title": "Titel på sidan du vill radera. Kan inte användas tillsammans med <var>$1pageid</var>.",
+       "apihelp-delete-param-pageid": "Sid-ID för sidan att radera. Kan inte användas tillsammans med <var>$1titel</var>.",
        "apihelp-delete-param-reason": "Orsak till radering. Om orsak inte ges kommer en orsak att automatiskt genereras och användas.",
-       "apihelp-delete-param-watch": "Lägg till sidan i din bevakningslista.",
-       "apihelp-delete-param-unwatch": "Ta bort sidan från din bevakningslista.",
-       "apihelp-delete-example-simple": "Radera huvudsidan",
-       "apihelp-delete-example-reason": "Raderar huvudsidan med orsaken \"Förbereder flyttning\"",
+       "apihelp-delete-param-watch": "Lägg till sidan i aktuell användares bevakningslista.",
+       "apihelp-delete-param-unwatch": "Ta bort sidan från aktuell användares bevakningslista.",
+       "apihelp-delete-param-oldimage": "Namnet på den gamla bilden att radera som tillhandahålls av [[Special:ApiHelp/query+imageinfo|action=query&prop=imageinfo&iiprop=archivename]].",
+       "apihelp-delete-example-simple": "Radera <kbd>huvudsidan</kbd>.",
+       "apihelp-delete-example-reason": "Raderar <kbd>huvudsidan</kbd> med orsaken <kbd>Förbereder flyttning</kbd>.",
        "apihelp-disabled-description": "Denna modul har inaktiverats.",
        "apihelp-edit-description": "Skapa och redigera sidor.",
-       "apihelp-edit-param-title": "Titel på sidan du vill redigera. Kan inte användas tillsammans med $1pageid.",
-       "apihelp-edit-param-pageid": "Sid-ID för sidan du vill redigera. Kan inte användas tillsammans med $1titel.",
-       "apihelp-edit-param-section": "Avsnittsnummer. 0 för det översta avsnittet, \"new\" för ett nytt avsnitt.",
+       "apihelp-edit-param-title": "Titel på sidan du vill redigera. Kan inte användas tillsammans med <var>$1pageid</var>.",
+       "apihelp-edit-param-pageid": "Sid-ID för sidan du vill redigera. Kan inte användas tillsammans med <var>$1titel</var>.",
+       "apihelp-edit-param-section": "Avsnittsnummer. <kbd>0</kbd> för det översta avsnittet, <kbd>new</kbd> för ett nytt avsnitt.",
        "apihelp-edit-param-sectiontitle": "Rubriken för ett nytt avsnitt.",
        "apihelp-edit-param-text": "Sidans innehåll.",
        "apihelp-edit-param-summary": "Redigeringssammanfattning. Även avsnittets rubrik när $1section=new och $1sectiontitle inte anges.",
        "apihelp-edit-param-notminor": "Icke-mindre redigering.",
        "apihelp-edit-param-bot": "Markera denna redigering som robotredigering.",
        "apihelp-edit-param-basetimestamp": "Tidsstämpel för grundversionen, används för att upptäcka redigeringskonflikter. Kan erhållas genom [[Special:ApiHelp/query+revisions|action=query&prop=revisions&rvprop=timestamp]].",
-       "apihelp-edit-param-starttimestamp": "Tidsstämpel för när du började redigeringsprocessen, används för att upptäcka redigeringskonflikter. Ett lämpligt värde kan erhållas via  [[Special:ApiHelp/main|curtimestamp]] när redigeringsprocessen startas (t.ex. när sidans innehåll laddas för redigering).",
+       "apihelp-edit-param-starttimestamp": "Tidsstämpel för när redigeringsprocessen började, används för att upptäcka redigeringskonflikter. Ett lämpligt värde kan erhållas via  <var>[[Special:ApiHelp/main|curtimestamp]]</var> när redigeringsprocessen startas (t.ex. när sidans innehåll laddas för redigering).",
        "apihelp-edit-param-createonly": "Redigera inte sidan om den redan finns.",
        "apihelp-edit-param-nocreate": "Kasta ett fel om sidan inte finns.",
-       "apihelp-edit-param-watch": "Lägg till sidan i din bevakningslista.",
-       "apihelp-edit-param-unwatch": "Ta bort sidan från din bevakningslista.",
+       "apihelp-edit-param-watch": "Lägg till sidan i den aktuella användarens bevakningslista.",
+       "apihelp-edit-param-unwatch": "Ta bort sidan från aktuell användares bevakningslista.",
        "apihelp-edit-param-md5": "MD5-hash för $1text-parametern, eller $1prependtext- och $1appendtext-parametrarna sammanfogade.",
        "apihelp-edit-param-prependtext": "Lägg till denna text i början på sidan. Ersätter $1text.",
        "apihelp-edit-param-appendtext": "Lägg till denna text i slutet på sidan. Ersätter $1text.\n\nAnvänd $1section=new för att lägga till en ny sektion, hellre än denna parameter.",
        "apihelp-emailuser-param-subject": "Ämnesrubrik.",
        "apihelp-emailuser-param-text": "E-postmeddelandets innehåll.",
        "apihelp-emailuser-param-ccme": "Skicka en kopia av detta e-postmeddelande till mig.",
-       "apihelp-emailuser-example-email": "Skicka ett e-postmeddelande till användaren \"WikiSysop\" med texten \"Content\"",
+       "apihelp-emailuser-example-email": "Skicka ett e-postmeddelande till användaren <kbd>WikiSysop</kbd> med texten <kbd>Content</kbd>.",
        "apihelp-expandtemplates-description": "Expanderar alla mallar i wikitext.",
        "apihelp-expandtemplates-param-title": "Sidans rubrik.",
        "apihelp-expandtemplates-param-text": "Wikitext att konvertera.",
        "apihelp-expandtemplates-param-revid": "Revision ID, för <nowiki>{{REVISIONID}}</nowiki> och liknande variabler.",
-       "apihelp-expandtemplates-example-simple": "Expandera wikitexten \"<nowiki>{{Projekt:Sandbox}}</nowiki>\"",
+       "apihelp-expandtemplates-param-includecomments": "Om HTML-kommentarer skall inkluderas i utdata.",
+       "apihelp-expandtemplates-example-simple": "Expandera wikitexten <kbd><nowiki>{{Projekt:Sandbox}}</nowiki></kbd>.",
+       "apihelp-feedcontributions-param-namespace": "Vilken namnrymd att filtrera bidrag med.",
        "apihelp-feedcontributions-param-year": "Från år (och tidigare).",
        "apihelp-feedcontributions-param-month": "Från månad (och tidigare).",
        "apihelp-feedcontributions-param-tagfilter": "Filtrera bidrag som har dessa taggar.",
        "apihelp-feedcontributions-param-newonly": "Visa endast redigeringar där sidor skapas.",
        "apihelp-feedcontributions-param-showsizediff": "Visa skillnaden i storlek mellan revisioner.",
        "apihelp-feedcontributions-example-simple": "Returnera bidrag för [[User:Example]]",
+       "apihelp-feedrecentchanges-param-namespace": "Namnrymder att begränsa resultaten till.",
+       "apihelp-feedrecentchanges-param-invert": "Alla namnrymder utom den valda.",
        "apihelp-feedrecentchanges-param-days": "Dagar att begränsa resultaten till.",
        "apihelp-feedrecentchanges-param-limit": "Maximalt antal resultat att returnera.",
        "apihelp-feedrecentchanges-param-from": "Visa förändringar sedan dess.",
        "apihelp-feedrecentchanges-param-hideanons": "Dölj ändringar av oinloggade användare.",
        "apihelp-feedrecentchanges-param-hideliu": "Dölj ändringar av inloggade användare.",
        "apihelp-feedrecentchanges-param-hidepatrolled": "Dölj patrullerade ändringar.",
-       "apihelp-feedrecentchanges-param-hidemyself": "Dölj mina ändringar.",
+       "apihelp-feedrecentchanges-param-hidemyself": "Dölj ändringar av aktuell användare.",
        "apihelp-feedrecentchanges-param-tagfilter": "Filtrera efter tagg.",
        "apihelp-feedrecentchanges-param-target": "Visa endast ändringarna av sidor som den här sidan länkar till.",
        "apihelp-feedrecentchanges-param-showlinkedto": "Visa ändringarna på sidor som är länkade till den valda sidan i stället.",
        "apihelp-feedwatchlist-param-linktosections": "Länka direkt till ändrade avsnitt om möjligt.",
        "apihelp-filerevert-description": "Återställ en fil till en äldre version.",
        "apihelp-filerevert-param-comment": "Ladda upp kommentar.",
+       "apihelp-filerevert-param-archivename": "Arkiv-namn för revisionen att gå tillbaka till.",
        "apihelp-filerevert-example-revert": "Återställ <kbd>Wiki.png</kbd> till versionen från <kbd>2011-03-05T15:27:40Z</kbd>",
+       "apihelp-help-description": "Visa hjälp för de angivna modulerna.",
+       "apihelp-help-param-submodules": "Inkludera hjälp för undermoduler av den namngivna modulen.",
+       "apihelp-help-param-recursivesubmodules": "Inkludera hjälp för undermoduler rekursivt.",
+       "apihelp-help-param-helpformat": "Formatet för hjälp-utdata.",
+       "apihelp-help-param-toc": "Inkludera en innehållsförteckning i HTML-utdata.",
        "apihelp-help-example-main": "Hjälp för huvudmodul",
        "apihelp-help-example-recursive": "All hjälp på en sida",
        "apihelp-help-example-help": "Hjälp för själva hjälpmodulen",
        "apihelp-imagerotate-description": "Rotera en eller flera bilder.",
        "apihelp-imagerotate-param-rotation": "Grader att rotera bild medurs.",
-       "apihelp-imagerotate-example-simple": "Rotera [[:File:Example.png]] med 90 grader",
-       "apihelp-imagerotate-example-generator": "Rotera alla bilder i [[:Category:Flip]] med 180 grader",
+       "apihelp-imagerotate-example-simple": "Rotera <kbd>File:Example.png</kbd> med <kbd>90</kbd> grader",
+       "apihelp-imagerotate-example-generator": "Rotera alla bilder i <kbd>Category:Flip</kbd> med <kbd>180</kbd> grader.",
+       "apihelp-import-description": "Importera en sida från en annan wiki, eller en XML fil. \n\nNotera att HTTP POST måste bli gjord som en fil uppladdning (d.v.s med multipart/form-data) när man skickar en fil för  <var>xml</var> parametern.",
        "apihelp-import-param-summary": "Importera sammanfattning.",
        "apihelp-import-param-xml": "Uppladdad XML-fil.",
        "apihelp-import-param-interwikisource": "För interwiki-importer: wiki som du vill importera från.",
        "apihelp-login-example-login": "Logga in",
        "apihelp-logout-description": "Logga ut och rensa sessionsdata.",
        "apihelp-logout-example-logout": "Logga ut den aktuella användaren",
+       "apihelp-managetags-param-tag": "Tagg att skapa, radera, aktivera eller inaktivera. För skapande av tagg, får taggen inte existera. För raderande av tagg, så måste taggen existera. För aktiverande av tagg, taggen måste existera och inte användas i en förlängning. För tagg inaktivering, taggen måste användas just nu och vara manuellt definierat.",
+       "apihelp-managetags-param-reason": "En icke-obligatorisk orsak för att skapa, radera, aktivera, eller inaktivera taggen.",
+       "apihelp-managetags-param-ignorewarnings": "Om du vill ignorera varningar som utfärdas under operationen.",
        "apihelp-move-description": "Flytta en sida.",
-       "apihelp-move-param-from": "Titeln på sidan du vill flytta. Kan inte användas tillsammans med $1fromid.",
-       "apihelp-move-param-reason": "Orsak till flyttningen.",
-       "apihelp-move-param-movetalk": "Flytta diskussionssidan om den finns.",
+       "apihelp-move-param-from": "Titeln på sidan du vill flytta. Kan inte användas tillsammans med <var>$1fromid</var>.",
+       "apihelp-move-param-to": "Titel att byta namn på sidan till.",
+       "apihelp-move-param-reason": "Orsak till namnbytet.",
+       "apihelp-move-param-movetalk": "Byt namn på diskussionssidan, om den finns.",
+       "apihelp-move-param-movesubpages": "Byt namn på undersidor, om tillämpligt.",
        "apihelp-move-param-noredirect": "Skapa inte en omdirigering.",
-       "apihelp-move-param-watch": "Lägg till sidan och omdirigeringen till din bevakningslista.",
-       "apihelp-move-param-unwatch": "Ta bort sidan och omdirigeringen från din bevakningslista.",
+       "apihelp-move-param-watch": "Lägg till sidan och omdirigeringen till den aktuella användarens bevakningslista.",
+       "apihelp-move-param-unwatch": "Ta bort sidan och omdirigeringen från den aktuella användarens bevakningslista.",
        "apihelp-move-param-ignorewarnings": "Ignorera alla varningar.",
+       "apihelp-opensearch-description": "Sök wikin med protokollet OpenSearch.",
        "apihelp-opensearch-param-search": "Söksträng.",
        "apihelp-opensearch-param-limit": "Maximalt antal resultat att returnera.",
        "apihelp-opensearch-param-namespace": "Namnrymder att genomsöka.",
-       "apihelp-opensearch-param-suggest": "Gör ingenting om [https://www.mediawiki.org/wiki/Manual:$wgEnableOpenSearchSuggest $wgEnableOpenSearchSuggest] är falskt.",
+       "apihelp-opensearch-param-suggest": "Gör ingenting om <var>[[mw:Manual:$wgEnableOpenSearchSuggest|$wgEnableOpenSearchSuggest]]</var> är falskt.",
        "apihelp-opensearch-param-format": "Formatet för utdata.",
-       "apihelp-opensearch-example-te": "Hitta sidor som börjar med \"Te\"",
+       "apihelp-opensearch-example-te": "Hitta sidor som börjar med <kbd>Te</kbd>.",
+       "apihelp-options-param-reset": "Återställer inställningarna till sidans standardvärden.",
        "apihelp-options-example-reset": "Återställ alla inställningar",
-       "apihelp-options-example-complex": "Återställ alla inställningar, ställ sedan in \"skin\" och \"nickname\"",
+       "apihelp-options-example-complex": "Återställ alla inställningar, ställ sedan in <kbd>skin</kbd> och <kbd>nickname</kbd>.",
        "apihelp-paraminfo-description": "Få information om API moduler.",
        "apihelp-paraminfo-param-helpformat": "Format för hjälpsträngar.",
+       "apihelp-patrol-example-rcid": "Patrullera en nykommen ändring.",
        "apihelp-patrol-example-revid": "Patrullera en sidversion",
        "apihelp-protect-description": "Ändra skyddsnivån för en sida.",
        "apihelp-protect-example-protect": "Skydda en sida",
        "apihelp-query-param-list": "Vilka listor att hämta.",
        "apihelp-query-param-meta": "Vilka metadata att hämta.",
-       "apihelp-query+alldeletedrevisions-paraminfo-useronly": "Kan endast användas med $3user.",
-       "apihelp-query+alldeletedrevisions-paraminfo-nonuseronly": "Kan inte användas med $3user.",
+       "apihelp-query+allcategories-param-dir": "Riktning att sortera mot.",
+       "apihelp-query+allcategories-param-min": "Returnera endast kategorier med minst så här många medlemmar.",
+       "apihelp-query+allcategories-param-max": "Returnera endast kategorier med som mest så här många medlemmar.",
+       "apihelp-query+allcategories-param-limit": "Hur många kategorier att returnera.",
+       "apihelp-query+alldeletedrevisions-description": "Lista alla raderade revisioner av en användare or inom en namnrymd.",
+       "apihelp-query+alldeletedrevisions-paraminfo-useronly": "Kan endast användas med <var>$3user</var>.",
+       "apihelp-query+alldeletedrevisions-paraminfo-nonuseronly": "Kan inte användas med <var>$3user</var>.",
+       "apihelp-query+alldeletedrevisions-param-from": "Börja lista vid denna titel.",
+       "apihelp-query+alldeletedrevisions-param-to": "Sluta lista vid denna titel.",
+       "apihelp-query+alldeletedrevisions-param-prefix": "Sök alla sid-titlar som börjar med detta värde.",
+       "apihelp-query+alldeletedrevisions-param-tag": "Lista bara revideringar taggade med denna tagg.",
+       "apihelp-query+alldeletedrevisions-param-user": "Lista bara revideringar av denna användaren.",
+       "apihelp-query+alldeletedrevisions-param-excludeuser": "Lista inte revideringar av denna användaren.",
+       "apihelp-query+alldeletedrevisions-param-namespace": "Lista bara sidor i denna namnrymd.",
+       "apihelp-query+alldeletedrevisions-example-ns-main": "Lista dem första 50 revideringarna i huvud-namnrymden",
+       "apihelp-query+allfileusages-description": "Lista all fil användningsområden, inklusive icke-existerande.",
+       "apihelp-query+allfileusages-param-prefix": "Sök för all fil-titlar som börjar med detta värde.",
+       "apihelp-query+allfileusages-param-limit": "Hur många saker att returnera totalt.",
+       "apihelp-query+allfileusages-param-dir": "Riktningen att lista mot.",
        "apihelp-query+allfileusages-example-unique": "Lista unika filtitlar",
+       "apihelp-query+allfileusages-example-unique-generator": "Hämtar alla fil titlar, markerar dem saknade.",
+       "apihelp-query+allfileusages-example-generator": "Hämtar sidor som innehåller filerna.",
        "apihelp-query+allimages-param-sort": "Egenskap att sortera efter.",
+       "apihelp-query+allimages-param-dir": "Riktningen att lista mot.",
+       "apihelp-query+allimages-param-prefix": "Sök för alla bild titlar som börjar med detta värde. Kan endast användas med $1sort=name.",
+       "apihelp-query+allimages-param-minsize": "Begränsning på bilder med åtminstone så här många bytes.",
+       "apihelp-query+allimages-param-maxsize": "Begränsning på bilder med som mest så här många bytes.",
+       "apihelp-query+allimages-param-sha1base36": "SHA1 hash av bild i bas 36 (används i MediaWiki).",
+       "apihelp-query+allimages-param-user": "Returnera enbart filer uppladdade av denna användare. Kan enbart användas med $1sort=timestamp. Kan inte användas tillsammans med $1filterbots.",
+       "apihelp-query+allimages-param-filterbots": "Hur man filtrerar filer uppladdade av bots. Kan enbart användas med $1sort=timestamp. Kan inte användas tillsammans med $1user.",
+       "apihelp-query+allimages-param-limit": "Hur många bilder att returnera totalt.",
+       "apihelp-query+allimages-example-B": "Visa en lista över filer som börjar på bokstaven <kbd>B</kbd>.",
+       "apihelp-query+allimages-example-generator": "Visa infom om 4 filer som börjar med bokstaven <kbd>T</kbd>.",
+       "apihelp-query+alllinks-param-prefix": "Sök alla länkade titlar som börjar med detta värde.",
+       "apihelp-query+alllinks-param-limit": "Hur många saker att returnera totalt.",
+       "apihelp-query+alllinks-param-dir": "Riktningen att lista mot.",
+       "apihelp-query+allmessages-description": "Returnera meddelande från denna sida.",
+       "apihelp-query+allmessages-param-prop": "Vilka egenskaper att hämta.",
        "apihelp-query+allmessages-param-lang": "Returnera meddelanden på detta språk.",
        "apihelp-query+allmessages-example-ipb": "Visa meddelanden som börjar med \"ipb-\"",
        "apihelp-query+allmessages-example-de": "Visa meddelandena \"august\" och \"mainpage\" på tyska",
        "apihelp-query+allpages-param-filterredir": "Vilka sidor att lista.",
+       "apihelp-query+allpages-param-dir": "Riktningen att lista mot.",
+       "apihelp-query+allredirects-param-dir": "Riktningen att lista mot.",
+       "apihelp-query+alltransclusions-param-dir": "Riktningen att lista mot.",
+       "apihelp-query+allusers-param-prefix": "Sök för alla användare som börjar med detta värde.",
        "apihelp-query+allusers-param-dir": "Riktning att sortera i.",
-       "apihelp-query+allusers-example-Y": "Lista användare som börjar på Y",
+       "apihelp-query+allusers-param-group": "Inkludera bara användare i de givna grupperna.",
+       "apihelp-query+allusers-param-excludegroup": "Exkludera användare i de givna grupperna.",
+       "apihelp-query+allusers-param-rights": "Inkludera bara användare med de givna rättigheterna. Inkluderar inte rättigheter givna med implicita eller automatiskt promotade grupper som *, användare, eller auto-konfirmerad.",
+       "apihelp-query+allusers-param-limit": "Hur många användarnamn att returnera totalt.",
+       "apihelp-query+allusers-param-witheditsonly": "Lista bara användare som har gjort redigeringar.",
+       "apihelp-query+allusers-param-activeusers": "Lista bara användare aktiva i dem sista $1{{PLURAL:$1|dagen|dagarna}}.",
+       "apihelp-query+allusers-example-Y": "Lista användare som börjar på <kbd>Y</kbd>.",
+       "apihelp-query+backlinks-description": "Hitta alla sidor som länkar till den givna sidan.",
+       "apihelp-query+backlinks-param-dir": "Riktningen att lista mot.",
+       "apihelp-query+categories-param-dir": "Riktningen att lista mot.",
+       "apihelp-query+duplicatefiles-param-dir": "Riktningen att lista mot.",
+       "apihelp-query+embeddedin-param-dir": "Riktningen att lista mot.",
+       "apihelp-query+filearchive-param-dir": "Riktningen att lista mot.",
+       "apihelp-query+images-param-dir": "Riktningen att lista mot.",
+       "apihelp-query+imageusage-param-dir": "Riktningen att lista mot.",
+       "apihelp-query+iwbacklinks-param-dir": "Riktningen att lista mot.",
+       "apihelp-query+iwlinks-param-dir": "Riktningen att lista mot.",
+       "apihelp-query+langbacklinks-param-dir": "Riktningen att lista mot.",
+       "apihelp-query+langlinks-param-dir": "Riktningen att lista mot.",
+       "apihelp-query+links-param-dir": "Riktningen att lista mot.",
        "apihelp-query+revisions-example-first5-not-localhost": "Hämta första 5 revideringarna av \"huvudsidan\" och som inte gjorts av anonym användare \"127.0.0.1\"",
        "apihelp-query+stashimageinfo-description": "Returnerar filinformation för temporära filer.",
        "apihelp-query+stashimageinfo-param-filekey": "Nyckel som identifierar en tidigare uppladdning som lagrats temporärt.",
diff --git a/includes/api/i18n/tl.json b/includes/api/i18n/tl.json
new file mode 100644 (file)
index 0000000..d35ce3e
--- /dev/null
@@ -0,0 +1,21 @@
+{
+       "@metadata": {
+               "authors": [
+                       "Leeheonjin"
+               ]
+       },
+       "apihelp-help-example-main": "Tulong para sa pangunahing modulo.",
+       "apihelp-move-example-move": "I-urong ang <kbd>Badtitle</kbd> sa <kbd>Goodtitle</kbd> nang hindi nag-iiwan ng redirekta.",
+       "apihelp-patrol-example-rcid": "Bantayan ang kasalukuyang pagbabago.",
+       "apihelp-query+allpages-example-B": "Ipakita ang talaan ng mga pahinang nagsisimula sa titik <kbd>B</kbd>.",
+       "apihelp-query+alltransclusions-example-generator": "Kinukuha ang mga pahinang naglalaman ng mga transklusyon.",
+       "apihelp-query+categoryinfo-example-simple": "Kumuha ng impormasyon tungkol sa <kbd>Kategorya:Foo</kbd> at <kbd>Kategorya:Bar</kbd>.",
+       "apihelp-query+images-example-simple": "Kumuha ng talaan ng mga talakasang ginagamit sa [[Unang Pahina]].",
+       "apihelp-query+imageusage-example-simple": "Ipakita ang mga pahina gamit ang [[:File:Albert Einstein Head.jpg]].",
+       "apihelp-query+iwbacklinks-example-simple": "Kumuha ng mga pahinang nakarugtong sa [[wikibooks:Test]].",
+       "apihelp-query+recentchanges-example-simple": "Talaan ng mga kamakailang pagbabago.",
+       "apihelp-query+search-example-text": "Hanapin ang mga teksto para sa <kbd>kahulugan</kbd>.",
+       "apihelp-query+watchlist-example-simple": "Itala ang mga punong pagbabago ng mga kasalukuyang binagong pahina sa kasalukuyang listahan ng binabantayan ng tagagamit.",
+       "apihelp-revisiondelete-example-revision": "Itago ang nilalaman para sa pagbabago ng <kbd>12345</kbd> sa pahinang <kbd>Unang Pahina</kbd>.",
+       "apihelp-upload-example-url": "Mag-karga mula sa URL."
+}
index f948fac..ff00e7c 100644 (file)
        "apihelp-block-param-nocreate": "Cấm tạo tài khoản.",
        "apihelp-clearhasmsg-description": "Xóa cờ <code>hasmsg</code> cho người dùng hiện tại.",
        "apihelp-clearhasmsg-example-1": "Xóa cờ <code>hasmsg</code> cho người dùng hiện tại",
+       "apihelp-compare-param-fromtitle": "So sánh tiêu đề đầu tiên.",
+       "apihelp-compare-param-fromid": "So sánh ID trang đầu tiên.",
+       "apihelp-compare-param-fromrev": "So sánh sửa đổi đầu tiên.",
+       "apihelp-compare-param-totitle": "So sánh tiêu đề thứ hai.",
+       "apihelp-compare-param-toid": "So sánh ID tran thứ hai.",
+       "apihelp-compare-param-torev": "So sánh sửa đổi thứ hai.",
+       "apihelp-compare-example-1": "Tạo một so sánh giữa phiên bản 1 và 2.",
        "apihelp-createaccount-description": "Mở tài khoản mới.",
        "apihelp-createaccount-param-name": "Tên người dùng.",
        "apihelp-createaccount-param-password": "Mật khẩu (được bỏ qua nếu <var>$1mailpassword</var> được đặt).",
        "apihelp-createaccount-param-token": "Dấu hiệu mở tài khoản được lấy trong yêu cầu đầu tiên.",
        "apihelp-createaccount-param-email": "Địa chỉ thư điện tử của thành viên (tùy chọn).",
        "apihelp-createaccount-param-realname": "Tên thật của thành viên (tùy chọn).",
+       "apihelp-createaccount-param-mailpassword": "Nếu đặt bất kỳ giá trị nào, một mật khẩu ngẫu nhiên sẽ được email lại cho người dùng.",
+       "apihelp-createaccount-param-reason": "Lý do tùy chọn cho việc tạo tài khoản để đăng nhập.",
+       "apihelp-createaccount-param-language": "Mã ngôn ngữ để thiết lập mặc định cho người dùng (tùy chọn, mặc định là ngôn ngữ nội dung).",
+       "apihelp-createaccount-example-pass": "Tạo người dùng <kbd>người kiểm tra</kbd> với mật khẩu <kbd>test123</kbd>.",
+       "apihelp-createaccount-example-mail": "Tạo người dùng <kbd>người dùng kiểm tra email> và email một mật khẩu được tạo ra ngẫu nhiên.",
        "apihelp-delete-description": "Xóa trang.",
+       "apihelp-delete-param-title": "Xóa tiêu đề của trang. Không thể sử dụng cùng với <var>$1pageid</var>.",
+       "apihelp-delete-param-pageid": "Xóa ID của trang. Không thể sử dụng cùng với <var>$1title</var>.",
        "apihelp-delete-param-watch": "Thêm trang vào danh sách theo dõi của bạn.",
        "apihelp-delete-param-unwatch": "Bỏ trang này khỏi danh sách theo dõi của bạn.",
        "apihelp-delete-example-simple": "Xóa Trang Chính",
index db7c1df..af857b9 100644 (file)
                        "JuneAugsut"
                ]
        },
-       "apihelp-main-description": "<div class=\"hlist plainlinks api-main-links\">\n* [https://www.mediawiki.org/wiki/API:Main_page/zh 文档]\n* [https://www.mediawiki.org/wiki/API:FAQ/zh 常见问题]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-api 邮件列表]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-api-announce API公告]\n* [https://phabricator.wikimedia.org/maniphest/query/GebfyV4uCaLd/#R 程序错误与功能请求]\n</div>\n<strong>状态信息:</strong> 本页所展示的所有特性都应正常工作,但是API仍在开发当中,将会随时变化。请订阅[https://lists.wikimedia.org/pipermail/mediawiki-api-announce/ mediawiki-api-announce 邮件列表]以便获得更新通知。\n\n<strong>错误请求:</strong> 当API收到错误请求时,HTTP header将会返回一个包含\"MediaWiki-API-Error\"的值,随后header的值与error code将会送回并设置为相同的值。详细信息请参阅 https://www.mediawiki.org/wiki/API:Errors_and_warnings 。",
+       "apihelp-main-description": "<div class=\"hlist plainlinks api-main-links\">\n* [[mw:API:Main_page|文档]]\n* [[mw:API:FAQ|常见问题]]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-api 邮件列表]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-api-announce API公告]\n* [https://phabricator.wikimedia.org/maniphest/query/GebfyV4uCaLd/#R 程序错误与功能请求]\n</div>\n<strong>状态信息:</strong>本页所展示的所有特性都应正常工作,但是API仍在开发当中,将会随时变化。请订阅[https://lists.wikimedia.org/pipermail/mediawiki-api-announce/ mediawiki-api-announce 邮件列表]以便获得更新通知。\n\n<strong>错误请求:</strong>当API收到错误请求时,HTTP header将会返回一个包含\"MediaWiki-API-Error\"的值,随后header的值与error code将会送回并设置为相同的值。详细信息请参阅[[mw:API:Errors_and_warnings|API: 错误与警告]]。",
        "apihelp-main-param-action": "要执行的操作。",
        "apihelp-main-param-format": "输出的格式。",
        "apihelp-main-param-maxlag": "最大延迟可被用于MediaWiki安装于数据库复制集中。要保存导致更多网站复制延迟的操作,此参数可使客户端等待直到复制延迟少于指定值时。万一发生过多延迟,错误代码“maxlag”会返回消息,例如“等待$host中:延迟$lag秒”。<br />参见https://www.mediawiki.org/wiki/Manual:Maxlag_parameter以获取更多信息。",
        "apihelp-main-param-smaxage": "设置<code>s-maxage</code>页顶至这些秒。错误不会缓存。",
        "apihelp-main-param-maxage": "设置<code>max-age</code>页顶至这些秒。错误不会缓存。",
-       "apihelp-main-param-assert": "如果设置为“user”就验证用户是否登录,或如果设置为“bot”就验证是否有机器人用户权限。",
+       "apihelp-main-param-assert": "如果设置为<kbd>user</kbd>就验证用户是否登录,或如果设置为<kbd>bot</kbd>就验证是否有机器人用户权限。",
        "apihelp-main-param-requestid": "任何在此提供的值将包含在响应中。可能可以用以区别请求。",
        "apihelp-main-param-servedby": "包含保存结果请求的主机名。",
        "apihelp-main-param-curtimestamp": "在结果中包括当前时间戳。",
-       "apihelp-main-param-origin": "当通过跨域名AJAX请求(CORS)访问API时,设置此作为起始域名。这必须包括在任何pre-flight请求中,并因此必须是请求的URI的一部分(而不是POST正文)。这必须匹配Origin中的一个起点:从头到底,因此它已经设置为像http://zh.wikipedia.org或https://meta.wikimedia.org的东西。如果此参数不匹配Origin: header,就返回403错误响应。如果此参数匹配Origin: header并且起点被白名单,将设置一个Access-Control-Allow-Origin开头。",
+       "apihelp-main-param-origin": "当通过跨域名AJAX请求(CORS)访问API时,设置此作为起始域名。这必须包括在任何pre-flight请求中,并因此必须是请求的URI的一部分(而不是POST正文)。这必须匹配<code>Origin</code>中的一个起点:从头到底,因此它已经设置为像<kbd>https://zh.wikipedia.org</kbd>或<kbd>https://meta.wikimedia.org</kbd>的东西。如果此参数不匹配<code>Origin</code>页顶,就返回403错误响应。如果此参数匹配<code>Origin</code>页顶并且起点被白名单,将设置一个<code>Access-Control-Allow-Origin</code>开头。",
        "apihelp-main-param-uselang": "用于消息翻译的语言。代码列表可从[[Special:ApiHelp/query+siteinfo|action=query&meta=siteinfo]]通过siprop=languages获取,或指定“user”以使用当前用户的语言设置,或指定“content”以使用此wiki的内容语言。",
        "apihelp-block-description": "封禁一位用户。",
        "apihelp-block-param-user": "您要封禁的用户、IP地址或IP地址段。",
-       "apihelp-block-param-expiry": "到期时间。可以是相对时间(例如“5个月”或“2周”)或绝对时间(例如“2014-09-18T12:34:56Z”)。如果设置为“infinite”、“indefinite”或“never”,封禁将无限期。",
+       "apihelp-block-param-expiry": "到期时间。可以是相对时间(例如<kbd>5 months</kbd>或<kbd>2 weeks</kbd>)或绝对时间(例如<kbd>2014-09-18T12:34:56Z</kbd>)。如果设置为<kbd>infinite</kbd>、<kbd>indefinite</kbd>或<kbd>never</kbd>,封禁将无限期。",
        "apihelp-block-param-reason": "封禁的原因",
-       "apihelp-block-param-anononly": "只封禁匿名用户(也就是说禁止此IP的匿名编辑)。",
+       "apihelp-block-param-anononly": "只封禁匿名用户(也就是说禁止此 IP 地址的匿名编辑)。",
        "apihelp-block-param-nocreate": "防止创建帐户。",
        "apihelp-block-param-autoblock": "自动封禁最近使用的IP地址,以及以后他们尝试登陆使用的IP地址。",
-       "apihelp-block-param-noemail": "阻止用户通过 wiki发送电子邮件。(要求\"blockemail\"权限)。",
-       "apihelp-block-param-hidename": "从封禁日志中隐藏用户名。(需要“隐藏用户”权限)。",
+       "apihelp-block-param-noemail": "阻止用户通过wiki发送电子邮件。(需要<code>blockemail</code>权限)。",
+       "apihelp-block-param-hidename": "从封禁日志中隐藏用户名。(需要<code>hideuser</code>权限)。",
        "apihelp-block-param-allowusertalk": "允许用户编辑自己的讨论页 (取决于 <var>[[mw:Manual:$wgBlockAllowsUTEdit|$wgBlockAllowsUTEdit]]</var>)。",
        "apihelp-block-param-reblock": "如果该用户已被封禁,则覆盖已有的封禁。",
-       "apihelp-block-param-watchuser": "监视用户或该 IP 的用户页和讨论页。",
-       "apihelp-block-example-ip-simple": "封禁IP地址192.0.2.5三天,原因“首次处理”",
-       "apihelp-block-example-user-complex": "æ\97 é\99\90æ\9c\9få°\81ç¦\81ç ´å\9d\8fç\94¨æ\88·ï¼\8cå\8e\9få\9b â\80\9c纯破å\9d\8fç\94¨æ\88·â\80\9dï¼\8c并é\98»æ­¢æ\96°è´¦æ\88·å\88\9b建å\92\8cç\94µå­\90é\82®ä»¶",
-       "apihelp-clearhasmsg-description": "清除当前用户的 <code>hasmsg</code> 标志。",
+       "apihelp-block-param-watchuser": "监视用户或该 IP 的用户页和讨论页。",
+       "apihelp-block-example-ip-simple": "封禁IP地址<kbd>192.0.2.5</kbd>三天,原因<kbd>First strike</kbd>。",
+       "apihelp-block-example-user-complex": "æ\97 é\99\90æ\9c\9få°\81ç¦\81ç\94¨æ\88·<kbd>Vandal</kbd>ï¼\8cå\8e\9få\9b <kbd>Vandalism</kbd>ï¼\8c并é\98»æ­¢æ\96°è´¦æ\88·å\88\9b建å\92\8cç\94µå­\90é\82®ä»¶å\8f\91é\80\81ã\80\82",
+       "apihelp-clearhasmsg-description": "清除当前用户的<code>hasmsg</code>标记。",
        "apihelp-clearhasmsg-example-1": "清除当前用户的 <code>hasmsg</code> 标志",
-       "apihelp-compare-description": "获取2个页面之间的差别。\n\n您必须为\"from\"和\"to\"传递特定的修订版本号、 页面标题或页面ID。",
+       "apihelp-compare-description": "获取2个页面之间的差别。\n\n用于“from”和“to”的修订版本号、页面标题或页面 ID 必须获得通过。",
        "apihelp-compare-param-fromtitle": "要比较的第一个标题。",
        "apihelp-compare-param-fromid": "要比较的第一个页面 ID。",
        "apihelp-compare-param-fromrev": "要比较的第一个修订版本。",
        "apihelp-createaccount-param-mailpassword": "如果设置为任何值,将向用户发送一个随机密码。",
        "apihelp-createaccount-param-reason": "将要放在日志中的,关于创建帐户的可选原因。",
        "apihelp-createaccount-param-language": "要为用户设置为默认值的语言代码(可选,默认为内容语言)。",
-       "apihelp-createaccount-example-pass": "创建用户“testuser”和密码“test123”",
-       "apihelp-createaccount-example-mail": "创建用户“testmailuser”并电邮发送一个随机生成的密码",
+       "apihelp-createaccount-example-pass": "创建用户<kbd>testuser</kbd>和密码<kbd>test123</kbd>。",
+       "apihelp-createaccount-example-mail": "创建用户<kbd>testmailuser</kbd>并电邮发送一个随机生成的密码。",
        "apihelp-delete-description": "删除一个页面。",
-       "apihelp-delete-param-title": "你所希望删除的页面的标题。不能与$1pageid一起使用。",
-       "apihelp-delete-param-pageid": "你所希望删除的页面的页面ID。不能与$1title一起使用。",
+       "apihelp-delete-param-title": "你所希望删除的页面的标题。不能与<var>$1pageid</var>一起使用。",
+       "apihelp-delete-param-pageid": "要删除的页面的页面 ID。不能与<var>$1title</var>一起使用。",
        "apihelp-delete-param-reason": "删除原因。如果未设置,将使用一个自动生成的原因。",
-       "apihelp-delete-param-watch": "将该页面加入的监视列表。",
+       "apihelp-delete-param-watch": "将该页面加入当前用户的监视列表。",
        "apihelp-delete-param-watchlist": "无条件地将页面加入至您的监视列表或将其移除,使用设置或不更改监视。",
-       "apihelp-delete-param-unwatch": "将该页面从的监视列表删除。",
+       "apihelp-delete-param-unwatch": "将该页面从当前用户的监视列表删除。",
        "apihelp-delete-param-oldimage": "由[[Special:ApiHelp/query+imageinfo|action=query&prop=imageinfo&iiprop=archivename]]提供的要删除的旧图片名称。",
-       "apihelp-delete-example-simple": "删除首页",
-       "apihelp-delete-example-reason": "删除首页,原因“准备移动”",
+       "apihelp-delete-example-simple": "删除<kbd>Main Page</kbd>。",
+       "apihelp-delete-example-reason": "删除<kbd>Main Page</kbd>,原因<kbd>Preparing for move</kbd>。",
        "apihelp-disabled-description": "此模块已禁用。",
        "apihelp-edit-description": "创建和编辑页面。",
-       "apihelp-edit-param-title": "您希望编辑的页面标题。不能与$1pageid一起使用。",
-       "apihelp-edit-param-pageid": "您希望编辑的页面ID。不能与$1title一起使用。",
-       "apihelp-edit-param-section": "段落数。0用于首段,“new”用于新的段落。",
+       "apihelp-edit-param-title": "您希望编辑的页面标题。不能与<var>$1pageid</var>一起使用。",
+       "apihelp-edit-param-pageid": "要编辑的页面的页面 ID。不能与<var>$1title</var>一起使用。",
+       "apihelp-edit-param-section": "段落数。<kbd>0</kbd>用于首段,<kbd>new</kbd>用于新的段落。",
        "apihelp-edit-param-sectiontitle": "新小节的标题。",
        "apihelp-edit-param-text": "页面内容。",
        "apihelp-edit-param-summary": "编辑摘要。当$1section=new且未设置$1sectiontitle时,还包括小节标题。",
@@ -85,8 +85,8 @@
        "apihelp-edit-param-recreate": "覆盖有关该页面在此期间已被删除的任何错误。",
        "apihelp-edit-param-createonly": "不要编辑页面,如果已经存在。",
        "apihelp-edit-param-nocreate": "如果该页面不存在,则抛出一个错误。",
-       "apihelp-edit-param-watch": "将页面加入的监视列表。",
-       "apihelp-edit-param-unwatch": "将页面从您的监视列表移除。",
+       "apihelp-edit-param-watch": "将页面加入当前用户的监视列表。",
+       "apihelp-edit-param-unwatch": "将页面从当前用户的监视列表中移除。",
        "apihelp-edit-param-watchlist": "无条件地将页面加入至您的监视列表或将其移除,使用设置或不更改监视。",
        "apihelp-edit-param-md5": "$1text参数或$1prependtext和$1appendtext级联参数的MD5哈希值。如果设置,除非哈希值正确否则编辑无法完成。",
        "apihelp-edit-param-prependtext": "将该文本添加到该页面的开始。覆盖$1text。",
        "apihelp-emailuser-param-subject": "主题页眉。",
        "apihelp-emailuser-param-text": "邮件正文。",
        "apihelp-emailuser-param-ccme": "给我发送一份该邮件的副本。",
-       "apihelp-emailuser-example-email": "向用户“WikiSysop”发送邮件,带文字“Content”",
+       "apihelp-emailuser-example-email": "向用户<kbd>WikiSysop</kbd>发送邮件,带文字<kbd>Content</kbd>。",
        "apihelp-expandtemplates-description": "展开维基文本中的所有模板。",
        "apihelp-expandtemplates-param-title": "页面标题。",
        "apihelp-expandtemplates-param-text": "要转换的wiki文本。",
        "apihelp-expandtemplates-param-prop": "要获取的那条信息:\n;wikitext:展开的wiki文本。\n;categories:任何在不代表wiki文本输出的输入框出现的分类。\n;properties:由wiki文本中扩充的魔术字定义的页面属性。\n;volatile:输出是否不稳定,并且不应在任何页面中再度使用。\n;ttl:结果的哪个缓存后等待最长时间应无效化。\n;parsetree:输入的XML解析树。\n注意如果没有选定值,结果将包含wiki文本,但将以弃用的格式显示。",
        "apihelp-expandtemplates-param-includecomments": "输出时是否包含HTML摘要。",
        "apihelp-expandtemplates-param-generatexml": "生成XML解析树(取代自$1prop=parsetree)。",
-       "apihelp-expandtemplates-example-simple": "展开wiki文本“<nowiki>{{Project:Sandbox}}</nowiki>”",
+       "apihelp-expandtemplates-example-simple": "展开wiki文本<kbd><nowiki>{{Project:Sandbox}}</nowiki></kbd>。",
        "apihelp-feedcontributions-description": "返回用户贡献纲要。",
        "apihelp-feedcontributions-param-feedformat": "纲要的格式。",
        "apihelp-feedcontributions-param-user": "获取哪些用户的贡献。",
        "apihelp-feedcontributions-param-toponly": "仅仅显示那些作为最新修订的编辑。",
        "apihelp-feedcontributions-param-newonly": "仅仅显示那些作为页面创建的编辑。",
        "apihelp-feedcontributions-param-showsizediff": "显示修订版本之间的大小差别。",
-       "apihelp-feedcontributions-example-simple": "返回[[User:Example]]的贡献",
+       "apihelp-feedcontributions-example-simple": "返回用户<kbd>Example</kbd>的贡献。",
        "apihelp-feedrecentchanges-description": "返回最新变更纲要。",
        "apihelp-feedrecentchanges-param-feedformat": "纲要的格式。",
        "apihelp-feedrecentchanges-param-namespace": "用于限制结果的命名空间。",
        "apihelp-feedrecentchanges-param-hideanons": "隐藏匿名用户做出的更改。",
        "apihelp-feedrecentchanges-param-hideliu": "隐藏注册用户做出的更改。",
        "apihelp-feedrecentchanges-param-hidepatrolled": "隐藏已巡查更改。",
-       "apihelp-feedrecentchanges-param-hidemyself": "隐藏做出的更改。",
+       "apihelp-feedrecentchanges-param-hidemyself": "隐藏当前用户做出的更改。",
        "apihelp-feedrecentchanges-param-tagfilter": "按标签过滤。",
        "apihelp-feedrecentchanges-param-target": "仅仅显示从该页面链出的那些页面的变更。",
        "apihelp-feedrecentchanges-param-showlinkedto": "仅仅显示链入到该页面的那些页面的变更。",
        "apihelp-filerevert-param-filename": "目标文件名,不包含前缀“File:”。",
        "apihelp-filerevert-param-comment": "上传评论。",
        "apihelp-filerevert-param-archivename": "恢复到修订版存档名称。",
-       "apihelp-filerevert-example-revert": "回退<kbd>Wiki.png</kbd>至<kbd>2011-03-05T15:27:40Z</kbd>的版本",
+       "apihelp-filerevert-example-revert": "回退<kbd>Wiki.png</kbd>至<kbd>2011-03-05T15:27:40Z</kbd>的版本",
        "apihelp-help-description": "显示指定模块的帮助。",
        "apihelp-help-param-submodules": "包括给定名称模块的子模块的帮助。",
        "apihelp-help-param-recursivesubmodules": "包括递归子模块的帮助。",
        "apihelp-help-example-query": "两个查询子模块的帮助",
        "apihelp-imagerotate-description": "旋转一幅或多幅图像。",
        "apihelp-imagerotate-param-rotation": "顺时针旋转图像的度数。",
-       "apihelp-imagerotate-example-simple": "90度旋转[[:File:Example.png]]",
-       "apihelp-imagerotate-example-generator": "将[[:Category:Flip]]之中的所有图像旋转180度",
+       "apihelp-imagerotate-example-simple": "<kbd>90</kbd>度旋转<kbd>File:Example.png</kbd>。",
+       "apihelp-imagerotate-example-generator": "将<kbd>Category:Flip</kbd>之中的所有图像旋转<kbd>180</kbd>度。",
        "apihelp-import-param-summary": "导入摘要。",
        "apihelp-import-param-xml": "上传的XML文件。",
        "apihelp-import-param-interwikisource": "用于跨wiki导入:导入的来源wiki。",
        "apihelp-login-example-login": "登录",
        "apihelp-logout-description": "退出并清除会话数据。",
        "apihelp-logout-example-logout": "退出当前用户",
+       "apihelp-managetags-description": "执行有关更改标签的管理任务。",
+       "apihelp-managetags-param-operation": "要执行哪个操作:\n;create:创建一个新的更改标签供手动使用。\n;delete:从数据库中移除一个更改标签,包括移除已使用在所有修订版本、最近更改记录和日志记录上的该标签。\n;activate:激活一个更改标签,允许用户手动应用它。\n;deactivate:停用一个更改标签,阻止用户手动应用它。",
+       "apihelp-managetags-param-reason": "一个创建、删除、激活或停用标签时的原因,可选。",
+       "apihelp-managetags-param-ignorewarnings": "是否忽略操作期间发生的任何警告。",
+       "apihelp-managetags-example-create": "创建一个名为<kbd>spam</kbd>的标签,原因<kbd>For use in edit patrolling</kbd>",
+       "apihelp-managetags-example-delete": "删除<kbd>vandlaism</kbd>标签,原因<kbd>Misspelt</kbd>",
+       "apihelp-managetags-example-activate": "激活一个名为<kbd>spam</kbd>的标签,原因<kbd>For use in edit patrolling</kbd>",
+       "apihelp-managetags-example-deactivate": "停用一个名为<kbd>spam</kbd>的标签,原因<kbd>No longer required</kbd>",
        "apihelp-move-description": "移动一个页面。",
-       "apihelp-move-param-from": "您希望移动的页面标题。不能与$1fromid一起使用。",
+       "apihelp-move-param-from": "要重命名的页面标题。不能与<var>$1fromid</var>一起使用。",
        "apihelp-move-param-fromid": "您希望移动的页面ID。不能与$1from一起使用。",
-       "apihelp-move-param-to": "您重命名操作的目标页面标题。",
-       "apihelp-move-param-reason": "移动原因。",
-       "apihelp-move-param-movetalk": "移动讨论页,如果存在。",
-       "apihelp-move-param-movesubpages": "移动子页面,如果可以。",
+       "apihelp-move-param-to": "页面重命名的目标标题。",
+       "apihelp-move-param-reason": "重命名的原因。",
+       "apihelp-move-param-movetalk": "重命名讨论页,如果存在。",
+       "apihelp-move-param-movesubpages": "重命名子页面,如果可以。",
        "apihelp-move-param-noredirect": "不要创建重定向。",
        "apihelp-move-param-watch": "将页面和重定向加入至您的监视列表中。",
-       "apihelp-move-param-unwatch": "从的监视列表中移除页面及重定向。",
+       "apihelp-move-param-unwatch": "从当前用户的监视列表中移除页面及重定向。",
        "apihelp-move-param-watchlist": "无条件地将页面加入至您的监视列表或将其移除,使用设置或不更改监视。",
        "apihelp-move-param-ignorewarnings": "忽略任何警告。",
-       "apihelp-move-example-move": "移动“坏标题”到“好标题”并且不留下重定向",
+       "apihelp-move-example-move": "移动<kbd>坏标题</kbd>到<kbd>好标题</kbd>并且不留下重定向。",
        "apihelp-opensearch-description": "使用OpenSearch协议搜索本wiki。",
        "apihelp-opensearch-param-search": "搜索字符串。",
        "apihelp-opensearch-param-limit": "要返回的结果最大数。",
        "apihelp-opensearch-param-namespace": "搜索的名字空间。",
-       "apihelp-opensearch-param-suggest": "如果[https://www.mediawiki.org/wiki/Manual:$wgEnableOpenSearchSuggest $wgEnableOpenSearchSuggest]设置为false则不做任何事情。",
+       "apihelp-opensearch-param-suggest": "如果<var>[[mw:Manual:$wgEnableOpenSearchSuggest|$wgEnableOpenSearchSuggest]]</var>设置为false则不做任何事情。",
        "apihelp-opensearch-param-redirects": "如何处理重定向:\n;return:返回重定向本身。\n;resolve:返回目标页面。可能返回少于$1limit个结果。\n由于历史原因,$1format=json默认为\"return\",其他格式默认为\"resolve\"",
        "apihelp-opensearch-param-format": "输出格式。",
-       "apihelp-opensearch-example-te": "查找以“Te”开头的页面",
+       "apihelp-opensearch-example-te": "查找以<kbd>Te</kbd>开头的页面。",
        "apihelp-options-description": "更改当前用户的偏好设置。\n\n只有注册在核心或者已安装扩展中的选项,或者具有\"userjs-\"键值前缀(旨在被用户脚本使用)的选项可被设置。",
        "apihelp-options-param-reset": "重置偏好设置到网站默认设置。",
        "apihelp-options-example-reset": "重置所有用户设置",
-       "apihelp-options-example-change": "更改“皮肤”和“hideminot”设置",
-       "apihelp-options-example-complex": "重置所有设置,之后设置“皮肤”和“昵称”",
+       "apihelp-options-example-change": "更改<kbd>skin</kbd>和<kbd>hideminor</kbd>设置。",
+       "apihelp-options-example-complex": "重置所有设置,然后设置<kbd>皮肤</kbd>和<kbd>昵称</kbd>。",
        "apihelp-paraminfo-description": "获取关于 API 模块的信息。",
-       "apihelp-paraminfo-param-modules": "模块名称列表(action=和format=参数值,或“主”)。可通过“+”指定子模块。",
+       "apihelp-paraminfo-param-modules": "模块名称(<var>action</var>和<var>format</var>参数值,或<kbd>main</kbd>)的列表。可通过<kbd>+</kbd>指定子模块。",
        "apihelp-paraminfo-param-helpformat": "帮助字符串的格式。",
-       "apihelp-paraminfo-example-1": "显示[[Special:ApiHelp/parse|action=parse]]、[[Special:ApiHelp/jsonfm|format=jsonfm]]、[[Special:ApiHelp/query+allpages|action=query&list=allpages]]和[[Special:ApiHelp/query+siteinfo|action=query&meta=siteinfo]]的信息",
+       "apihelp-paraminfo-param-querymodules": "查询模块名称(<var>prop</var>、<var>meta</var>或<var>list</var>参数值)的列表。使用<kbd>$1modules=query+foo</kbd>而不是<kbd>$1querymodules=foo</kbd>。",
+       "apihelp-paraminfo-param-mainmodule": "获得有关主要(最高级)模块的信息。也可使用<kbd>$1modules=main</kbd>。",
+       "apihelp-paraminfo-param-pagesetmodule": "获得有关页面设置模块(提供titles=和朋友)的信息。",
+       "apihelp-paraminfo-param-formatmodules": "格式模块名称(<var>format</var>参数的值)的列表。也可使用<var>$1modules</kbd>。",
+       "apihelp-paraminfo-example-1": "显示<kbd>[[Special:ApiHelp/parse|action=parse]]</kbd>、<kbd>[[Special:ApiHelp/jsonfm|format=jsonfm]]</kbd>、<kbd>[[Special:ApiHelp/query+allpages|action=query&list=allpages]]</kbd>和<kbd>[[Special:ApiHelp/query+siteinfo|action=query&meta=siteinfo]]</kbd>的信息。",
+       "apihelp-parse-description": "解析内容并返回解析器输出。\n\n参见<kbd>[[Special:ApiHelp/query|action=query]]</kbd>的各种prop-module以从页面的当前版本获得信息。\n\n这里有几种方法可以指定解析的文本:\n# 指定一个页面或修订,使用<var>$1page</var>、<var>$1pageid</var>或<var>$1oldid</var>。\n# 明确指定内容,使用<var>$1text</var>、<var>$1title</var>和<var>$1contentmodel</var>。\n# 只指定一段摘要解析。<var>$1prop</var>应提供一个空值。",
        "apihelp-parse-param-summary": "所要解析的摘要。",
-       "apihelp-parse-param-page": "解析此页的内容。不能与$1text和$1title一起使用。",
-       "apihelp-parse-param-pageid": "解析此页的内容。覆盖 $1 页。",
+       "apihelp-parse-param-page": "解析此页的内容。不能与<var>$1text</var>和<var>$1title</var>一起使用。",
+       "apihelp-parse-param-pageid": "解析此页的内容。覆盖<var>$1page</var>。",
        "apihelp-parse-param-redirects": "如果 $1page 或 $1 pageid 参数被设置为一个重定向,则解析它。",
        "apihelp-parse-param-oldid": "解析该修订版本的内容。覆盖 $1page 和 $1 pageid。",
-       "apihelp-parse-param-generatexml": "生成XML解析树(需要内容模型\"$1\")。",
+       "apihelp-parse-param-disablepp": "从解析器输出中禁用PP报告。",
+       "apihelp-parse-param-disableeditsection": "从解析器输出中禁用编辑段落链接。",
+       "apihelp-parse-param-generatexml": "生成XML解析树(需要内容模型<code>$1</code>)。",
        "apihelp-parse-param-preview": "在预览模式下解析。",
        "apihelp-parse-param-sectionpreview": "在小节预览模式下解析 (同时要启用预览模式)。",
        "apihelp-parse-param-disabletoc": "在输出中禁用目录。",
        "apihelp-protect-description": "更改页面的保护等级。",
        "apihelp-protect-param-title": "要(解除)保护的页面标题。不能与$1pageid一起使用。",
        "apihelp-protect-param-pageid": "要(解除)保护的页面ID。不能与$1title一起使用。",
-       "apihelp-protect-param-protections": "保护等级列表,格式:action=level(例如edit=sysop)。\n\n'''注意:'''未列出的操作将移除限制。",
+       "apihelp-protect-param-protections": "保护等级列表,格式:<kbd>action=level</kbd>(例如<kbd>edit=sysop</kbd>)。\n\n<strong>注意:</strong>未列出的操作将移除限制。",
+       "apihelp-protect-param-expiry": "到期时间戳。如果只有一个时间戳被设置,它将被用于所有保护。使用<kbd>infinite</kbd>、<kbd>indefinite</kbd>、<kbd>infinity</kbd>或<kbd>never</kbd>用于永不过期的保护。",
        "apihelp-protect-param-reason": "(解除)保护的原因。",
        "apihelp-protect-example-protect": "保护一个页面",
        "apihelp-protect-example-unprotect": "通过设置限制为“all”解除保护一个页面",
        "apihelp-protect-example-unprotect2": "通过设置没有限制解除保护一个页面",
        "apihelp-purge-param-forcelinkupdate": "更新链接表。",
        "apihelp-purge-param-forcerecursivelinkupdate": "更新链接表中,并更新任何使用此页作为模板的页面的链接表。",
-       "apihelp-purge-example-simple": "刷新“首页”和“API”页面",
+       "apihelp-purge-example-simple": "刷新<kbd>Main Page</kbd>和<kbd>API</kbd>页面。",
        "apihelp-purge-example-generator": "刷新主名字空间的前10个页面",
        "apihelp-query-description": "获取来自和有关MediaWiki的数据。\n\n所有数据修改将首先要使用查询以获得令牌以阻止来自恶意网站的滥用破坏。",
        "apihelp-query-param-list": "要获取的列表。",
        "apihelp-query-param-meta": "要获取的元数据。",
-       "apihelp-query-example-revisions": "获取首页的[[Special:ApiHelp/query+siteinfo|站点信息]]和[[Special:ApiHelp/query+revisions|修订版本]]",
-       "apihelp-query-example-allpages": "获取以“API/”开头的页面的修订版本",
+       "apihelp-query-example-revisions": "获取<kbd>Main Page</kbd>的[[Special:ApiHelp/query+siteinfo|网站信息]]和[[Special:ApiHelp/query+revisions|修订版本]]。",
+       "apihelp-query-example-allpages": "获取以<kbd>API/</kbd>开头的页面的修订版本",
        "apihelp-query+allcategories-description": "枚举所有类别。",
        "apihelp-query+allcategories-param-from": "要作为枚举起始点的类别。",
        "apihelp-query+allcategories-param-to": "要作为枚举终止点的类别。",
+       "apihelp-query+allcategories-param-prefix": "搜索此值开头的所有分类标题。",
        "apihelp-query+allcategories-param-dir": "排序方向。",
        "apihelp-query+allcategories-param-limit": "要返回多少个类别。",
-       "apihelp-query+alldeletedrevisions-paraminfo-useronly": "只可以与$3user一起使用。",
-       "apihelp-query+alldeletedrevisions-paraminfo-nonuseronly": "不能与$3user一起使用。",
+       "apihelp-query+allcategories-example-size": "列出分类及其含有多少页面的信息。",
+       "apihelp-query+alldeletedrevisions-paraminfo-useronly": "只可以与<var>$3user</var>一起使用。",
+       "apihelp-query+alldeletedrevisions-paraminfo-nonuseronly": "不能与<var>$3user</var>一起使用。",
        "apihelp-query+alldeletedrevisions-param-from": "从此标题开始列出。",
        "apihelp-query+alldeletedrevisions-param-to": "列出至此标题为止。",
        "apihelp-query+alldeletedrevisions-param-user": "只列出此用户做出的修订。",
        "apihelp-query+alldeletedrevisions-param-excludeuser": "不要列出此用户做出的修订。",
        "apihelp-query+alldeletedrevisions-param-namespace": "只列出此名字空间的页面。",
-       "apihelp-query+alldeletedrevisions-param-miser-user-namespace": "'''注意:'''由于[https://www.mediawiki.org/wiki/Manual:$wgMiserMode miser模式],同时使用$1user和$1namespace将导致继续前返回少于“$1limit”个结果,在极端条件下可能不返回任何结果。",
-       "apihelp-query+alldeletedrevisions-example-user": "列出由User:Example作出的最近50次已删除贡献",
-       "apihelp-query+alldeletedrevisions-example-ns-main": "列出最近50次已删除的主名字空间修订",
+       "apihelp-query+alldeletedrevisions-param-miser-user-namespace": "<strong>注意:</strong>由于[[mw:Manual:$wgMiserMode|miser模式]],同时使用<var>$1user</var>和<var>$1namespace</var>将导致继续前返回少于<var>$1limit</var>个结果,在极端条件下可能不返回任何结果。",
+       "apihelp-query+alldeletedrevisions-example-user": "列出由<kbd>Example<kbd>作出的最近50次已删除贡献。",
+       "apihelp-query+alldeletedrevisions-example-ns-main": "列出前50次已删除的主名字空间修订。",
+       "apihelp-query+allfileusages-description": "列出所有文件用途,包括不存在的。",
        "apihelp-query+allfileusages-param-prefix": "搜索此值开头的所有文件标题。",
        "apihelp-query+allfileusages-param-limit": "要返回的总计项目。",
        "apihelp-query+allfileusages-param-dir": "罗列所采用的方向。",
        "apihelp-query+allimages-param-sha1": "图像的 SHA1 哈希。覆盖$1sha1base36。",
        "apihelp-query+allimages-param-mime": "要搜索的MIME类型,例如<kbd>image/jpeg</kbd>。",
        "apihelp-query+allimages-param-limit": "共计要返回多少图像。",
-       "apihelp-query+allimages-example-B": "显示以字母“B”开始的文件列表",
+       "apihelp-query+allimages-example-B": "显示以字母<kbd>B</kbd>开始的文件列表。",
+       "apihelp-query+allimages-example-recent": "显示一个最近上传文件的列表,类似[[Special:NewFiles]]。",
        "apihelp-query+allimages-example-mimetypes": "显示带MIME类型<kbd>image/png</kbd>或<kbd>image/gif</kbd>的文件列表",
-       "apihelp-query+allimages-example-generator": "显示有关4个以“T”开头的文件的信息",
+       "apihelp-query+allimages-example-generator": "显示有关4个以<kbd>T</kbd>开头的文件的信息。",
        "apihelp-query+alllinks-param-namespace": "要列举的名字空间。",
        "apihelp-query+alllinks-param-limit": "总共要返回多少个项目。",
        "apihelp-query+alllinks-param-dir": "列出方向。",
        "apihelp-query+alllinks-example-unique": "列出唯一的链接标题",
+       "apihelp-query+alllinks-example-unique-generator": "获得所有已链接的标题,标记缺少的。",
        "apihelp-query+alllinks-example-generator": "获取包含这些链接的页面",
        "apihelp-query+allmessages-description": "返回来自该站点的消息。",
        "apihelp-query+allmessages-param-messages": "要输出的哪些消息。\"*\" (默认值) 表示所有消息。",
        "apihelp-query+allmessages-param-prop": "要获取的属性。",
        "apihelp-query+allmessages-param-lang": "返回这种语言的信息。",
        "apihelp-query+allmessages-param-prefix": "返回带有该前缀的消息。",
-       "apihelp-query+allmessages-example-ipb": "显示以“ipb-”开始的消息",
-       "apihelp-query+allmessages-example-de": "显示德语版的“八月”和“首页”消息",
+       "apihelp-query+allmessages-example-ipb": "显示以<kbd>ipb-</kbd>开始的消息。",
+       "apihelp-query+allmessages-example-de": "显示德语版的<kbd>august</kbd>和<kbd>mainpage</kbd>消息。",
        "apihelp-query+allpages-param-namespace": "要列举的名字空间。",
        "apihelp-query+allpages-param-filterredir": "要列出哪些页面。",
        "apihelp-query+allpages-param-minsize": "限于至少这么多字节的页面。",
        "apihelp-query+allpages-param-maxsize": "限于至多这么多字节的页面。",
        "apihelp-query+allpages-param-prtype": "仅限于受保护页面。",
        "apihelp-query+allpages-param-limit": "返回的总计页面数。",
+       "apihelp-query+allpages-example-B": "显示以字母<kbd>B</kbd>开头的页面的列表。",
        "apihelp-query+allredirects-description": "列出至一个名字空间的重定向。",
        "apihelp-query+allredirects-param-namespace": "要列举的名字空间。",
        "apihelp-query+allredirects-param-limit": "返回的总计项目数。",
        "apihelp-query+alltransclusions-param-namespace": "要列举的名字空间。",
        "apihelp-query+alltransclusions-param-dir": "罗列所采用的方向。",
        "apihelp-query+alltransclusions-example-unique": "列出孤立嵌入标题",
+       "apihelp-query+allusers-description": "列举所有注册用户。",
        "apihelp-query+allusers-param-dir": "排序方向。",
        "apihelp-query+allusers-param-group": "只包含指定组中的用户。",
        "apihelp-query+allusers-param-excludegroup": "排除指定组中的用户。",
        "apihelp-query+allusers-param-witheditsonly": "只列出有编辑的用户。",
        "apihelp-query+allusers-param-activeusers": "只列出最近$1天内活跃的用户。",
-       "apihelp-query+allusers-example-Y": "列出以Y开头的用户",
-       "apihelp-query+backlinks-param-title": "要搜索的标题。不能与$1pageid一起使用。",
-       "apihelp-query+backlinks-param-pageid": "要搜索的页面ID。不能与$1title一起使用。",
+       "apihelp-query+allusers-example-Y": "列出以<kbd>Y</kbd>开头的用户。",
+       "apihelp-query+backlinks-param-title": "要搜索的标题。不能与<var>$1pageid</var>一起使用。",
+       "apihelp-query+backlinks-param-pageid": "要搜索的页面ID。不能与<var>$1title</var>一起使用。",
        "apihelp-query+backlinks-param-namespace": "要列举的名字空间。",
        "apihelp-query+backlinks-param-dir": "罗列所采用的方向。",
-       "apihelp-query+backlinks-example-simple": "显示至[[首页]]的链接",
-       "apihelp-query+backlinks-example-generator": "获取关于链接至[[首页]]的页面的信息",
+       "apihelp-query+backlinks-param-limit": "返回总计页面数。如果<var>$1redirect</var>被启用,则限定分别适用于每一等级(这意味着将返回多达2 * <var>$1limit</var>个结果)。",
+       "apihelp-query+backlinks-example-simple": "显示至<kbd>Main page<kbd>的链接。",
+       "apihelp-query+backlinks-example-generator": "获得关于链接至<kbd>Main page<kbd>的页面的信息。",
        "apihelp-query+blocks-description": "列出所有被封禁的用户和IP地址。",
        "apihelp-query+blocks-param-ids": "要列出的封禁ID列表(可选)。",
        "apihelp-query+blocks-param-users": "要搜索的用户列表(可选)。",
        "apihelp-query+blocks-example-simple": "封禁列表",
-       "apihelp-query+blocks-example-users": "列出用户Alice和Bob的封禁",
+       "apihelp-query+blocks-example-users": "列出用户<kbd>Alice</kbd>和<kbd>Bob</kbd>的封禁。",
        "apihelp-query+categories-param-show": "显示何种分类。",
        "apihelp-query+categories-param-limit": "返回多少分类。",
        "apihelp-query+categories-param-dir": "罗列所采用的方向。",
-       "apihelp-query+categories-example-simple": "获取属于[[阿尔伯特·爱因斯坦]]的分类列表",
-       "apihelp-query+categories-example-generator": "è\8e·å\8f\96æ\9c\89å\85³ç\94¨äº\8e[[é\98¿å°\94伯ç\89¹Â·ç\88±å\9b æ\96¯å\9d¦]]ç\9a\84å\88\86ç±»ç\9a\84ä¿¡æ\81¯",
-       "apihelp-query+categoryinfo-example-simple": "获取有关[[:Category:Foo]]和[[:Category:Bar]]的信息",
+       "apihelp-query+categories-example-simple": "获取属于<kbd>Albert Einstein</kbd>的分类列表。",
+       "apihelp-query+categories-example-generator": "è\8e·å¾\97æ\9c\89å\85³ç\94¨äº\8e<kbd>Albert Einstein</kbd>ç\9a\84å\88\86ç±»ç\9a\84ä¿¡æ\81¯ã\80\82",
+       "apihelp-query+categoryinfo-example-simple": "获取有关<kbd>Category:Foo</kbd>和<kbd>Category:Bar</kbd>的信息。",
        "apihelp-query+categorymembers-description": "在指定的分类中列出所有页面。",
+       "apihelp-query+categorymembers-param-namespace": "仅包含这些名字空间的页面。注意<kbd>$1type=subcat</kbd>或<kbd>$1type=file</kbd>可能被使用,而不是<kbd>$1namespace=14</kbd>或<kbd>6</kbd>。",
+       "apihelp-query+categorymembers-param-type": "包含的分类成员类型。当<kbd>$1sort=timestamp</kbd>被设置时会忽略。",
        "apihelp-query+categorymembers-param-sort": "要作为排序方式的属性。",
        "apihelp-query+categorymembers-param-dir": "排序的方向。",
-       "apihelp-query+categorymembers-param-start": "开始列举的时间戳。不能与$1sort=timestamp一起使用。",
-       "apihelp-query+categorymembers-param-end": "列举的结尾时间戳。不能与$1sort=timestamp一起使用。",
+       "apihelp-query+categorymembers-param-start": "开始列举的时间戳。只能与<kbd>$1sort=timestamp</kbd>一起使用。",
+       "apihelp-query+categorymembers-param-end": "列举的结尾时间戳。只能与<kbd>$1sort=timestamp</kbd>一起使用。",
        "apihelp-query+categorymembers-param-startsortkey": "请改用$1starthexsortkey。",
        "apihelp-query+categorymembers-param-endsortkey": "请改用$1endhexsortkey。",
-       "apihelp-query+categorymembers-example-simple": "è\8e·å\8f\96[[:Category:Physics]]中的前10个页面。",
-       "apihelp-query+categorymembers-example-generator": "è\8e·å\8f\96å\85³äº\8e[[:Category:Physics]]中的前10个页面的页面信息。",
+       "apihelp-query+categorymembers-example-simple": "è\8e·å¾\97<kbd>Category:Physics</kbd>中的前10个页面。",
+       "apihelp-query+categorymembers-example-generator": "è\8e·å¾\97æ\9c\89å\85³<kbd>Category:Physics</kbd>中的前10个页面的页面信息。",
        "apihelp-query+contributors-description": "获取对一个页面的登录贡献者列表和匿名贡献数。",
        "apihelp-query+contributors-param-limit": "返回的贡献数。",
-       "apihelp-query+contributors-example-simple": "显示[[首页]]的贡献",
+       "apihelp-query+contributors-example-simple": "显示<kbd>Main Page</kbd>的贡献。",
+       "apihelp-query+deletedrevisions-description": "获得删除修订版本信息。\n\n可在很多途径中使用:\n# 获得一组页面的已删除修订,通过设置标题或页面ID。以标题和时间戳排序。\n# 通过设置它们的ID与修订ID获得关于一组已删除修订。以修订ID排序。",
+       "apihelp-query+deletedrevisions-param-tag": "只列出被此标签标记的修订。",
+       "apihelp-query+deletedrevisions-param-user": "只列出此用户做出的修订。",
+       "apihelp-query+deletedrevisions-param-excludeuser": "不要列出此用户做出的修订。",
        "apihelp-query+deletedrevisions-example-titles": "列出[[首页]]和[[Talk:首页]]的已删除修订,包含内容",
-       "apihelp-query+deletedrevisions-example-revids": "列出已删除修订123456的信息",
+       "apihelp-query+deletedrevisions-example-revids": "列出已删除修订<kbd>123456</kbd>的信息。",
        "apihelp-query+deletedrevs-paraminfo-modes": "{{PLURAL:$1|模式}}:$2",
        "apihelp-query+deletedrevs-param-from": "从此标题开始列出。",
        "apihelp-query+deletedrevs-param-to": "列出至此标题为止。",
        "apihelp-query+deletedrevs-param-excludeuser": "不要列出此用户做出的修订。",
        "apihelp-query+deletedrevs-param-namespace": "只列出此名字空间的页面。",
        "apihelp-query+deletedrevs-example-mode1": "列出最近已删除的对首页和Talk:首页的贡献,带内容(模式1)",
-       "apihelp-query+deletedrevs-example-mode2": "列出由Bob作出的最近50次已删除贡献(模式2)",
+       "apihelp-query+deletedrevs-example-mode2": "列出由<kbd>Bob</kbd>作出的最近50次已删除贡献(模式2)。",
        "apihelp-query+deletedrevs-example-mode3-main": "列出前50次主名字空间已删除贡献(模式3)",
        "apihelp-query+deletedrevs-example-mode3-talk": "列出前50次{{ns:talk}}名字空间已删除页面(模式3):",
        "apihelp-query+disabled-description": "此查询模块已被禁用。",
        "apihelp-query+embeddedin-param-dir": "罗列所采用的方向。",
        "apihelp-query+embeddedin-param-filterredir": "如何过滤重定向。",
        "apihelp-query+embeddedin-param-limit": "返回的总计页面数。",
-       "apihelp-query+embeddedin-example-simple": "显示嵌入[[Template:Stub]]的页面",
-       "apihelp-query+embeddedin-example-generator": "è\8e·å\8f\96æ\9c\89å\85³æ\98¾ç¤ºåµ\8cå\85¥[[Template:Stub]]ç\9a\84页é\9d¢ç\9a\84ä¿¡æ\81¯",
+       "apihelp-query+embeddedin-example-simple": "显示嵌入<kbd>Template:Stub</kbd>的页面。",
+       "apihelp-query+embeddedin-example-generator": "è\8e·å¾\97æ\9c\89å\85³æ\98¾ç¤ºåµ\8cå\85¥<kbd>Template:Stub</kbd>ç\9a\84页é\9d¢ç\9a\84ä¿¡æ\81¯ã\80\82",
        "apihelp-query+extlinks-param-limit": "返回多少链接。",
-       "apihelp-query+extlinks-example-simple": "获取[[首页]]的外部链接列表",
+       "apihelp-query+extlinks-example-simple": "获取<kbd>首页</kbd>的外部链接列表。",
        "apihelp-query+exturlusage-param-limit": "返回多少页面。",
-       "apihelp-query+exturlusage-example-simple": "显示链接至http://www.mediawiki.org的页面",
+       "apihelp-query+exturlusage-example-simple": "显示链接至<kbd>http://www.mediawiki.org</kbd>的页面。",
        "apihelp-query+filearchive-param-dir": "罗列所采用的方向。",
        "apihelp-query+filearchive-param-sha1": "图片的SHA1哈希值。覆盖$1sha1base36。",
        "apihelp-query+filearchive-param-sha1base36": "基于base 36的图片的SHA1哈希值(用于MediaWiki)。",
        "apihelp-query+info-param-prop": "要获取的额外属性:",
        "apihelp-query+info-paramvalue-prop-watchers": "监视人员数,如果允许。",
        "apihelp-query+info-param-token": "请改用[[Special:ApiHelp/query+tokens|action=query&meta=tokens]]。",
-       "apihelp-query+info-example-simple": "è\8e·å\8f\96æ\9c\89å\85³[[é¦\96页]]ç\9a\84ä¿¡æ\81¯",
-       "apihelp-query+info-example-protection": "获取[[首页]]的一般和保护信息",
+       "apihelp-query+info-example-simple": "è\8e·å¾\97æ\9c\89å\85³é¡µé\9d¢<kbd>Main Page</kbd>ç\9a\84ä¿¡æ\81¯ã\80\82",
+       "apihelp-query+info-example-protection": "获取<kbd>首页</kbd>相关的常规和保护信息。",
        "apihelp-query+iwbacklinks-param-prefix": "跨维基前缀。",
+       "apihelp-query+iwbacklinks-param-title": "要搜索的跨wiki链接。必须与<var>$1blprefix</var>一起使用。",
        "apihelp-query+iwbacklinks-param-limit": "返回的总计页面数。",
        "apihelp-query+iwbacklinks-param-prop": "要获取的属性:\n;iwprefix:加入跨wiki前缀。\n;iwtitle:加入跨wiki标题。",
        "apihelp-query+iwbacklinks-param-dir": "罗列所采用的方向。",
-       "apihelp-query+iwbacklinks-example-simple": "获取链接至[[wikibooks:Test]]的页面",
-       "apihelp-query+iwbacklinks-example-generator": "获取有关链接至[[wikibooks:Test]]的页面的信息",
+       "apihelp-query+iwbacklinks-example-simple": "获得链接至[[wikibooks:Test]]的页面。",
+       "apihelp-query+iwbacklinks-example-generator": "获得有关链接至[[wikibooks:Test]]的页面的信息。",
+       "apihelp-query+iwlinks-description": "从指定页面返回所有跨wiki链接。",
        "apihelp-query+iwlinks-param-url": "是否获取完整URL(不能与$1prop一起使用)。",
        "apihelp-query+iwlinks-param-limit": "返回多少跨wiki链接。",
        "apihelp-query+iwlinks-param-prefix": "只返回此前缀的跨wiki链接。",
-       "apihelp-query+iwlinks-param-title": "用于搜索的跨wiki链接。必须与$1prefix一起使用。",
+       "apihelp-query+iwlinks-param-title": "用于搜索的跨wiki链接。必须与<var>$1prefix</var>一起使用。",
        "apihelp-query+iwlinks-param-dir": "罗列所采用的方向。",
-       "apihelp-query+iwlinks-example-simple": "从[[首页]]获取跨wiki链接",
+       "apihelp-query+iwlinks-example-simple": "从页面<kbd>Main Page</kbd>获得跨wiki链接。",
        "apihelp-query+langbacklinks-param-lang": "用于语言链接的语言。",
        "apihelp-query+langbacklinks-param-title": "要搜索的语言链接。必须与$1lang一起使用。",
+       "apihelp-query+langbacklinks-param-limit": "返回的总计页面数。",
+       "apihelp-query+langbacklinks-param-prop": "要获得的属性:\n;lllang:添加语言链接的语言代码。\n;lltitle:添加语言链接的标题。",
        "apihelp-query+langbacklinks-param-dir": "罗列所采用的方向。",
        "apihelp-query+langbacklinks-example-simple": "获取链接至[[:fr:Test]]的页面",
        "apihelp-query+langbacklinks-example-generator": "获取链接至[[:fr:Test]]的页面的信息",
+       "apihelp-query+langlinks-description": "从指定页面返回所有跨语言链接。",
        "apihelp-query+langlinks-param-limit": "返回多少语言链接。",
-       "apihelp-query+langlinks-param-url": "是否获取完整URL(不能与$1prop一起使用)。",
-       "apihelp-query+langlinks-param-title": "要搜索的链接。必须与$1lang一起使用。",
+       "apihelp-query+langlinks-param-url": "是否获取完整URL(不能与<var>$1prop</var>一起使用)。",
+       "apihelp-query+langlinks-param-lang": "只返回带此语言代码的语言链接。",
+       "apihelp-query+langlinks-param-title": "要搜索的链接。必须与<var>$1lang</var>一起使用。",
        "apihelp-query+langlinks-param-dir": "罗列所采用的方向。",
        "apihelp-query+langlinks-param-inlanguagecode": "本地化语言名称的语言代码。",
-       "apihelp-query+langlinks-example-simple": "从[[首页]]获取跨语言链接",
+       "apihelp-query+langlinks-example-simple": "从页面<kbd>Main Page</kbd>获得跨语言链接。",
+       "apihelp-query+links-description": "从指定页面返回所有链接。",
+       "apihelp-query+links-param-namespace": "只显示这些名字空间的链接。",
        "apihelp-query+links-param-limit": "返回多少链接。",
        "apihelp-query+links-param-dir": "罗列所采用的方向。",
-       "apihelp-query+links-example-simple": "从[[首页]]获取链接",
-       "apihelp-query+links-example-generator": "è\8e·å\8f\96æ\9c\89å\85³[[é¦\96页]]é\93¾æ\8e¥é¡µé\9d¢ç\9a\84ä¿¡æ\81¯",
-       "apihelp-query+links-example-namespaces": "è\8e·å\8f\96ç\94¨æ\88·å\92\8c模æ\9d¿å\90\8då­\97空é\97´ä¸­æ\9d¥è\87ª[[é¦\96页]]ç\9a\84é\93¾æ\8e¥",
+       "apihelp-query+links-example-simple": "从页面<kbd>Main Page</kbd>获得链接",
+       "apihelp-query+links-example-generator": "è\8e·å¾\97æ\9c\89å\85³å\9c¨é¡µé\9d¢<kbd>Main Page</kbd>中è¿\9eæ\8e¥ç\9a\84页é\9d¢ç\9a\84ä¿¡æ\81¯ã\80\82",
+       "apihelp-query+links-example-namespaces": "è\8e·å¾\97å\9c¨{{ns:user}}å\92\8c{{ns:template}}å\90\8då­\97空é\97´ä¸­æ\9d¥è\87ªé¡µé\9d¢<kbd>Main Page</kbd>ç\9a\84é\93¾æ\8e¥ã\80\82",
        "apihelp-query+linkshere-param-namespace": "只包括这些名字空间的页面。",
        "apihelp-query+linkshere-param-limit": "返回多少。",
        "apihelp-query+linkshere-param-show": "只显示符合以下标准的项:\n;redirect:只显示重定向。\n;!redirect:只显示非重定向。",
        "apihelp-query+logevents-description": "从日志获取事件。",
        "apihelp-query+logevents-example-simple": "列出最近日志活动",
        "apihelp-query+pagepropnames-description": "列出wiki中所有使用中的页面属性名称。",
-       "apihelp-query+pagepropnames-example-simple": "获取前10个常用名称",
-       "apihelp-query+pageprops-example-simple": "获取用于[[:Category:Foo]]的属性",
+       "apihelp-query+pagepropnames-example-simple": "获取前10个属性名称。",
+       "apihelp-query+pageprops-example-simple": "获得用于<kbd>Category:Foo</kbd>的属性。",
+       "apihelp-query+pageswithprop-description": "列出所有使用指定页面属性的页面。",
        "apihelp-query+pageswithprop-param-dir": "排序的方向。",
-       "apihelp-query+pageswithprop-example-simple": "列出前10个使用&#123;&#123;DISPLAYTITLE:&#125;&#125;的页面",
+       "apihelp-query+pageswithprop-example-simple": "列出前10个使用<code>&#123;&#123;DISPLAYTITLE:&#125;&#125;</code>的页面。",
        "apihelp-query+pageswithprop-example-generator": "获取有关前10个使用<code>_&#95;NOTOC_&#95;</code>的页面的信息。",
        "apihelp-query+prefixsearch-param-search": "搜索字符串。",
        "apihelp-query+prefixsearch-param-namespace": "搜索的名字空间。",
        "apihelp-query+prefixsearch-param-offset": "跳过的结果数。",
+       "apihelp-query+prefixsearch-example-simple": "搜索以<kbd>meaning</kbd>开头的页面标题。",
        "apihelp-query+protectedtitles-param-namespace": "只列出这些名字空间的标题。",
        "apihelp-query+protectedtitles-param-limit": "返回的总计页面数。",
        "apihelp-query+protectedtitles-example-simple": "受保护标题列表",
+       "apihelp-query+protectedtitles-example-generator": "找到主命名空间中已保护的标题的链接。",
        "apihelp-query+querypage-param-limit": "返回的结果数。",
        "apihelp-query+querypage-example-ancientpages": "返回[[Special:Ancientpages]]的结果。",
        "apihelp-query+random-param-namespace": "只返回这些名字空间的页面。",
+       "apihelp-query+random-param-limit": "限制返回多少随机页面。",
+       "apihelp-query+random-param-redirect": "加载一个随机重定向而不是一个随机页面。",
+       "apihelp-query+random-example-simple": "从主名字空间返回两个随机页面。",
        "apihelp-query+recentchanges-description": "枚举最近更改。",
        "apihelp-query+recentchanges-param-user": "只列出此用户的更改。",
        "apihelp-query+recentchanges-param-excludeuser": "不要列出此用户的更改。",
        "apihelp-query+recentchanges-param-tag": "只列出带此标签的更改。",
-       "apihelp-query+recentchanges-param-token": "请改用[[Special:ApiHelp/query+tokens|action=query&meta=tokens]]。",
+       "apihelp-query+recentchanges-param-token": "请改用<kbd>[[Special:ApiHelp/query+tokens|action=query&meta=tokens]]</kbd>。",
        "apihelp-query+recentchanges-param-limit": "返回的总计更新数。",
        "apihelp-query+recentchanges-param-type": "显示的更改类型。",
        "apihelp-query+recentchanges-example-simple": "最近更改列表",
        "apihelp-query+redirects-param-limit": "返回多少重定向。",
        "apihelp-query+redirects-example-simple": "获取至[[Project:首页]]的重定向列表",
        "apihelp-query+redirects-example-generator": "获取所有重定向至[[首页]]的信息",
-       "apihelp-query+revisions-example-last5": "获取“首页”的最近5次修订",
-       "apihelp-query+revisions-example-first5": "获取“首页”的前5次修订版本",
-       "apihelp-query+revisions-example-first5-after": "获取“首页”于2006年05月01日之后做出的前5次修订版本",
+       "apihelp-query+revisions-example-content": "获得带内容的数据,用于标题<kbd>API</kbd>和<kbd>Main Page</kbd>的最近修订。",
+       "apihelp-query+revisions-example-last5": "获取<kbd>Main Page</kbd>的最近5次修订。",
+       "apihelp-query+revisions-example-first5": "获取<kbd>Main Page</kbd>的前5次修订。",
+       "apihelp-query+revisions-example-first5-after": "获得<kbd>Main Page</kbd>于2006年05月01日之后做出的前5次修订版本。",
+       "apihelp-query+revisions-example-first5-not-localhost": "获取<kbd>Main Page</kbd>的前5次不是由匿名用户<kbd>127.0.0.1</kbd>做出的修订。",
+       "apihelp-query+revisions-example-first5-user": "获取<kbd>Main Page</kbd>的前5次由用户<kbd>MediaWiki default</kbd>做出的修订。",
+       "apihelp-query+revisions+base-param-limit": "限制返回多少修订。",
        "apihelp-query+search-param-search": "搜索所有拥有此值的页面标题(或内容)。",
        "apihelp-query+search-param-namespace": "只在这些名字空间搜索。",
        "apihelp-query+search-param-info": "要返回的元数据。",
        "apihelp-query+search-param-limit": "返回的总计页面数。",
        "apihelp-query+search-param-interwiki": "搜索结果中包含跨wiki结果,如果可用。",
-       "apihelp-query+search-example-simple": "搜索“意义”",
+       "apihelp-query+search-example-simple": "搜索<kbd>meaning</kbd>。",
        "apihelp-query+search-example-text": "搜索文本<kbd>meaning</kbd>。",
+       "apihelp-query+search-example-generator": "获得有关搜索<kbd>meaning</kbd>返回页面的页面信息。",
        "apihelp-query+siteinfo-param-numberingroup": "列出用户组中的用户数。",
        "apihelp-query+siteinfo-example-simple": "获取网站信息",
        "apihelp-query+siteinfo-example-interwiki": "获取本地跨wiki前缀列表",
        "apihelp-query+siteinfo-example-replag": "检查当前的响应延迟。",
        "apihelp-query+tags-description": "列出更改标签。",
+       "apihelp-query+tags-param-prop": "要获取哪个属性:\n;name:添加标签名称。\n;displayname:为标签添加系统消息。\n;description:为标签添加描述。\n;hitcount:已添加此标签的修订版本与日志数量。\n;defined:标识标签是否已定义。\n;source:获得标签来源,它可能包括用于扩展定义的标签的<samp>extension</samp>,以及用于可被用户手动应用的标签的<samp>manual</samp>。\n;active:标签是否仍可被应用。",
        "apihelp-query+tags-example-simple": "可用标签列表",
        "apihelp-query+templates-param-namespace": "只显示此名字空间的模板。",
        "apihelp-query+templates-param-limit": "返回多少模板。",
        "apihelp-query+templates-param-templates": "只列出这些模板。对于检查某一页面使用某一模板很有用。",
        "apihelp-query+templates-param-dir": "罗列所采用的方向。",
-       "apihelp-query+templates-example-simple": "从[[首页]]获取模板",
-       "apihelp-query+templates-example-generator": "è\8e·å\8f\96æ\9c\89å\85³[[é¦\96页]]中ç\9a\84模æ\9d¿é¡µé\9d¢ç\9a\84ä¿¡æ\81¯",
-       "apihelp-query+templates-example-namespaces": "从[[首页]]获取用户和模板名字空间中的模板",
+       "apihelp-query+templates-example-simple": "获得在页面<kbd>Main Page</kbd>使用的模板。",
+       "apihelp-query+templates-example-generator": "è\8e·å¾\97æ\9c\89å\85³<kbd>Main Page</kbd>中使ç\94¨ç\9a\84模æ\9d¿é¡µé\9d¢ç\9a\84ä¿¡æ\81¯ã\80\82",
+       "apihelp-query+templates-example-namespaces": "获得在{{ns:user}}和{{ns:template}}名字空间中,嵌入在<kbd>Main Page</kbd>页面的页面。",
        "apihelp-query+tokens-param-type": "要请求的令牌类型。",
        "apihelp-query+transcludedin-param-namespace": "至包含这些名字空间的页面。",
        "apihelp-query+transcludedin-param-limit": "返回多少。",
-       "apihelp-query+transcludedin-example-simple": "è\8e·å\8f\96åµ\8cå\85¥[[é¦\96页]]ç\9a\84页é\9d¢å\88\97表",
-       "apihelp-query+transcludedin-example-generator": "è\8e·å\8f\96æ\9c\89å\85³åµ\8cå\85¥[[é¦\96页]]ç\9a\84页é\9d¢ç\9a\84ä¿¡æ\81¯",
+       "apihelp-query+transcludedin-example-simple": "è\8e·å¾\97åµ\8cå\85¥<kbd>Main Page</kbd>ç\9a\84页é\9d¢å\88\97表ã\80\82",
+       "apihelp-query+transcludedin-example-generator": "è\8e·å¾\97æ\9c\89å\85³åµ\8cå\85¥<kbd>Main Page</kbd>ç\9a\84页é\9d¢ç\9a\84ä¿¡æ\81¯ã\80\82",
        "apihelp-query+usercontribs-description": "获取一位用户的所有编辑。",
        "apihelp-query+usercontribs-param-namespace": "只列出这些名字空间的贡献。",
-       "apihelp-query+usercontribs-example-user": "显示[[User:Example]]的贡献",
-       "apihelp-query+usercontribs-example-ipprefix": "显示来自“192.0.2.”前缀所有IP地址的贡献",
+       "apihelp-query+usercontribs-example-user": "显示用户<kbd>Example</kbd>的贡献。",
+       "apihelp-query+usercontribs-example-ipprefix": "显示来自<kbd>192.0.2.</kbd>前缀所有 IP 地址的贡献。",
        "apihelp-query+userinfo-description": "获取有关当前用户的信息。",
        "apihelp-query+userinfo-example-simple": "获取有关当前用户的信息",
        "apihelp-query+userinfo-example-data": "获取有关当前用户的额外信息",
        "apihelp-query+users-description": "获取有关列出用户的信息。",
-       "apihelp-query+users-param-token": "请改用[[Special:ApiHelp/query+tokens|action=query&meta=tokens]]。",
-       "apihelp-query+users-example-simple": "返回[[User:Example]]的信息",
+       "apihelp-query+users-param-token": "请改用<kbd>[[Special:ApiHelp/query+tokens|action=query&meta=tokens]]</kbd>。",
+       "apihelp-query+users-example-simple": "返回用户<kbd>Example</kbd>的信息。",
        "apihelp-query+watchlist-param-user": "只列出此用户的更改。",
        "apihelp-query+watchlist-param-excludeuser": "不要列出此用户的更改。",
        "apihelp-query+watchlist-param-token": "允许访问其他用户监视列表的安全密钥(可通过用户的[[Special:Preferences#mw-prefsection-watchlist|参数设置]]找到)。",
-       "apihelp-query+watchlistraw-description": "获取登录用户的监视列表的所有页面。",
+       "apihelp-query+watchlist-example-generator": "在当前用户的监视列表中检索用于最近更改页面的页面信息。",
+       "apihelp-query+watchlistraw-description": "获得当前用户的监视列表上的所有页面。",
        "apihelp-query+watchlistraw-param-namespace": "只列出指定名字空间的页面。",
        "apihelp-query+watchlistraw-param-token": "允许访问其他用户监视列表的安全密钥(可通过用户的[[Special:Preferences#mw-prefsection-watchlist|参数设置]]找到)。",
        "apihelp-query+watchlistraw-example-simple": "列出当前用户的监视列表中的页面。",
        "apihelp-revisiondelete-param-hide": "每次修订要隐藏的东西。",
        "apihelp-revisiondelete-param-show": "每次修订要恢复显示的东西。",
        "apihelp-revisiondelete-param-reason": "删除或恢复的原因。",
-       "apihelp-rollback-example-simple": "回退由用户Example对[[首页]]做出的最近编辑",
+       "apihelp-revisiondelete-example-revision": "隐藏<kbd>首页</kbd>的修订版本<kbd>12345</kbd>的内容。",
+       "apihelp-rollback-param-title": "要回退的页面标题。不能与<var>$1pageid</var>一起使用。",
+       "apihelp-rollback-example-simple": "回退由用户<kbd>Example</kbd>对<kbd>Main Page</kbd>做出的最近编辑。",
        "apihelp-rollback-example-summary": "回退由IP用户192.0.2.5对[[首页]]做出的最近编辑,带编辑摘要“回退破坏”,并将这些编辑和回退标记为“机器人”",
        "apihelp-rsd-description": "导出一个RSD(Really Simple Discovery)架构",
        "apihelp-rsd-example-simple": "导出RSD架构",
        "apihelp-unblock-param-id": "解封时需要的封禁ID(通过list=blocks获得)。不能与$1user一起使用。",
        "apihelp-unblock-param-user": "要解封的用户名、IP地址或IP段。不能与$1id一起使用。",
        "apihelp-unblock-param-reason": "解封的原因。",
-       "apihelp-unblock-example-id": "解封封禁ID#105",
-       "apihelp-unblock-example-user": "解封用户Bob,原因“抱歉Bob”",
+       "apihelp-unblock-example-id": "解封封禁ID #<kbd>105</kbd>。",
+       "apihelp-unblock-example-user": "解封用户<kbd>Bob</kbd>,原因<kbd>Sorry Bob</kbd>。",
        "apihelp-undelete-param-title": "要恢复的页面标题。",
        "apihelp-undelete-param-reason": "恢复的原因。",
-       "apihelp-undelete-example-page": "恢复[[首页]]",
+       "apihelp-undelete-example-page": "恢复页面<kbd>Main Page</kbd>。",
        "apihelp-undelete-example-revisions": "恢复<kbd>首页</kbd>的两个修订。",
        "apihelp-upload-param-filename": "目标文件名。",
        "apihelp-upload-param-watch": "监视页面。",
        "apihelp-upload-param-stash": "如果设置,服务器将临时藏匿文件而不是加入存储库。",
        "apihelp-upload-param-chunk": "大块内容。",
        "apihelp-upload-example-url": "从URL上传",
+       "apihelp-upload-example-filekey": "完成一次由于警告而失败的上传。",
        "apihelp-userrights-description": "更改一位用户的组成员。",
        "apihelp-userrights-param-user": "用户名。",
        "apihelp-userrights-param-userid": "用户ID。",
        "apihelp-userrights-param-add": "将用户加入至这些组中。",
        "apihelp-userrights-param-remove": "将用户从这些组中移除。",
        "apihelp-userrights-param-reason": "更改原因。",
-       "apihelp-userrights-example-user": "将用户FooBot添加至“机器人”用户组,并从“管理员”和“行政员”组移除",
-       "apihelp-userrights-example-userid": "将ID为123的用户加入至“机器人”组,并将其从“管理员”和“行政员”组移除",
-       "apihelp-watch-param-title": "要(取消)监视的页面。也可使用$1titles。",
-       "apihelp-watch-example-watch": "监视页面“首页”",
+       "apihelp-userrights-example-user": "将用户<kbd>FooBot</kbd>添加至<kbd>bot</kbd>用户组,并从<kbd>sysop</kbd>和<kbd>bureaucrat</kbd>组移除。",
+       "apihelp-userrights-example-userid": "将ID为<kbd>123</kbd>的用户加入至<kbd>机器人</kbd>组,并将其从<kbd>管理员</kbd>和<kbd>行政员</kbd>组移除。",
+       "apihelp-watch-param-title": "要(取消)监视的页面。也可使用<var>$1titles</var>。",
+       "apihelp-watch-example-watch": "监视页面<kbd>Main Page</kbd>。",
        "apihelp-watch-example-unwatch": "取消监视页面<kbd>首页</kbd>。",
-       "apihelp-dbg-description": "输出数据为PHP的var_export()格式。",
-       "apihelp-dbgfm-description": "输出数据为PHP的var_export()格式(HTML优质打印效果)。",
-       "apihelp-dump-description": "输出数据为PHP的var_dump()格式。",
+       "apihelp-format-example-generic": "格式化查询结果为$1格式。",
+       "apihelp-dbg-description": "输出数据为PHP的<code>var_export()</code>格式。",
+       "apihelp-dbgfm-description": "输出数据为PHP的<code>var_export()</code>格式(HTML优质打印效果)。",
+       "apihelp-dump-description": "输出数据为PHP的<code>var_dump()</code>格式。",
        "apihelp-dumpfm-description": "输出数据为PHP的var_dump()格式(HTML优质打印效果)。",
        "apihelp-json-description": "输出数据为JSON格式。",
        "apihelp-jsonfm-description": "输出数据为JSON格式(HTML优质打印效果)。",
        "apihelp-php-description": "输出数据为序列化PHP格式。",
        "apihelp-phpfm-description": "输出数据为序列化PHP格式(HTML优质打印效果)。",
        "apihelp-rawfm-description": "输出数据为JSON格式,带调试元素(HTML优质打印效果)。",
-       "apihelp-txt-description": "输出数据为PHP的print_r()格式。",
-       "apihelp-txtfm-description": "输出数据为PHP的print_r()格式(HTML优质打印效果)。",
+       "apihelp-txt-description": "输出数据为PHP的<code>print_r()</code>格式。",
+       "apihelp-txtfm-description": "输出数据为PHP的<code>print_r()</code>格式(HTML优质打印效果)。",
        "apihelp-wddx-description": "输出数据为WDDX格式。",
        "apihelp-wddxfm-description": "输出数据为WDDX格式(HTML优质打印效果)。",
        "apihelp-xml-description": "输出数据为XML格式。",
+       "apihelp-xml-param-xslt": "如果指定,加入已命名的页面作为一个XSL样式表。值必须是在{{ns:mediawiki}}名字空间以<code>.xsl</code>为结尾的标题。",
        "apihelp-xmlfm-description": "输出数据为XML格式(HTML优质打印效果)。",
        "apihelp-yaml-description": "输出数据为YAML格式。",
        "apihelp-yamlfm-description": "输出数据为YAML格式(HTML优质打印效果)。",
        "api-format-prettyprint-header": "您正在查看$1格式的HTML表示。HTML对调试很有用,但不适合应用程序使用。\n\n指定格式参数以更改输出格式。要查看$1格式的非HTML表示,设置format=$2。\n\n参见[https://www.mediawiki.org/wiki/Special:MyLanguage/API 完整文档],或[[Special:ApiHelp/main|API帮助]]以获取更多信息。",
        "api-orm-param-props": "要查询的字段。",
        "api-orm-param-limit": "返回的总行数。",
+       "api-pageset-param-redirects-nogenerator": "自动解决<var>$1titles</var>、<var>$1pageids</var>和<var>$1revids</var>中的重定向。",
        "api-help-title": "MediaWiki API 帮助",
        "api-help-lead": "这是自动生成的MediaWiki API文档页面。\n\n文档和例子:https://www.mediawiki.org/wiki/API:Main_page/zh",
        "api-help-main-header": "主模块",
        "api-help-param-integer-min": "{{PLURAL:$1|值}}必须不少于$2。",
        "api-help-param-integer-max": "{{PLURAL:$1|值}}必须不大于$2。",
        "api-help-param-integer-minmax": "{{PLURAL:$1|值}}必须介于$2和$3之间。",
-       "api-help-param-multi-separate": "通过“|”隔开各值。",
+       "api-help-param-multi-separate": "通过“<kbd>|</kbd>”隔开各值。",
        "api-help-param-multi-max": "值的最高数字是{{PLURAL:$1|$1}}(对于机器人则是{{PLURAL:$2|$2}})。",
        "api-help-param-default": "默认:$1",
        "api-help-param-default-empty": "默认:<span class=\"apihelp-empty\">(空)</span>",
        "api-help-param-token": "从[[Special:ApiHelp/query+tokens|action=query&meta=tokens]]取回的“$1”令牌",
-       "api-help-param-disabled-in-miser-mode": "由于[https://www.mediawiki.org/wiki/Manual:$wgMiserMode miser模式]而禁用。",
-       "api-help-param-limited-in-miser-mode": "'''注意:'''由于[https://www.mediawiki.org/wiki/Manual:$wgMiserMode miser模式],使用这个可能导致继续前返回少于“$1limit”个结果;极端情况下可能不会返回任何结果。",
+       "api-help-param-disabled-in-miser-mode": "由于[[mw:Manual:$wgMiserMode|miser模式]]而禁用。",
+       "api-help-param-limited-in-miser-mode": "<strong>注意:</strong>由于[[mw:Manual:$wgMiserMode|miser模式]],使用这个可能导致继续前返回少于<var>$1limit</var>个结果;极端情况下可能不会返回任何结果。",
        "api-help-param-direction": "列举的方向:\n;newer:最早的优先。注意:$1start应早于$1end。\n;older:最新的优先(默认)。注意:$1start应晚于$1end。",
        "api-help-param-continue": "当更多结果可用时,使用这个继续。",
        "api-help-param-no-description": "<span class=\"apihelp-empty\">(没有说明)</span>",
index 6c2febe..c6aa730 100644 (file)
@@ -6,6 +6,7 @@
                        "LNDDYL"
                ]
        },
+       "apihelp-main-description": "<div class=\"hlist plainlinks api-main-links\">\n* [[mw:API:Main_page|文件]]\n* [[mw:API:FAQ|FAQ]]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-api 郵件清單]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-api-announce API公告]\n* [https://phabricator.wikimedia.org/maniphest/query/GebfyV4uCaLd/#R Bug與請求]\n</div>\n<strong>狀態資訊:</strong>本頁所展示的所有功能都應正常工作,但是 API 仍在開發當中,將會隨時變化。請訂閱[https://lists.wikimedia.org/pipermail/mediawiki-api-announce/ mediawiki-api-announce 郵件清單]以便得到更新通知。\n\n<strong>錯誤請求:</strong>當 API 收到錯誤請求時, HTTP header 將會返回一個包含「MediaWiki-API-Error」的值,隨後 header 的值與錯誤碼將會送回並設定為相同的值。詳細資訊請參閱[[mw:API:Errors_and_warnings|API: 錯誤與警告]]。",
        "apihelp-main-param-action": "要執行的動作。",
        "apihelp-main-param-format": "輸出的格式。",
        "apihelp-block-description": "封鎖使用者。",
        "apihelp-expandtemplates-param-text": "要轉換的 Wikitext。",
        "apihelp-feedrecentchanges-example-simple": "顯示近期變動",
        "apihelp-feedrecentchanges-example-30days": "顯示近期30天內的變動",
+       "apihelp-feedwatchlist-description": "返回監視清單 feed。",
+       "apihelp-feedwatchlist-param-feedformat": "Feed 的格式。",
        "apihelp-filerevert-param-comment": "上載意見。",
        "apihelp-help-example-main": "主模組使用說明",
+       "apihelp-help-example-recursive": "一個頁面中的所有說明。",
+       "apihelp-help-example-help": "說明模組自身的說明。",
+       "apihelp-imagerotate-description": "旋轉一張或多張圖片。",
+       "apihelp-import-param-summary": "匯入摘要。",
        "apihelp-import-param-xml": "上載的 XML 檔。",
        "apihelp-import-param-interwikisource": "用於跨 wiki 匯入:匯入的來源 wiki。",
        "apihelp-import-param-interwikipage": "用於跨 wiki 匯入:匯入的頁面。",
        "apihelp-logout-description": "登出並清除 session 資料。",
        "apihelp-logout-example-logout": "登出當前使用者",
        "apihelp-move-description": "移動頁面。",
+       "apihelp-move-param-from": "重新命名本頁面的標題。不能與 <var>$1fromid</var> 一起出現。",
+       "apihelp-move-param-fromid": "重新命名本頁面的 ID 。不能與 <var>$1fromid</var> 一起出現。",
+       "apihelp-move-param-to": "將本頁面的標題重新命名為",
+       "apihelp-move-param-reason": "重新命名的原因。",
+       "apihelp-move-param-movesubpages": "如果適用,則重新命名子頁面。",
+       "apihelp-move-param-noredirect": "不要建立重新導向。",
+       "apihelp-opensearch-description": "使用 OpenSearch 協定搜尋本 wiki。",
        "apihelp-opensearch-param-search": "搜尋字串。",
+       "apihelp-opensearch-param-namespace": "搜尋的命名空間。",
        "apihelp-options-example-reset": "重設所有偏好設定",
        "apihelp-userrights-param-user": "使用者名稱。",
        "apihelp-userrights-param-userid": "使用者 ID。",
        "api-help-param-required": "此參數為必填。",
        "api-help-param-limit": "不允許超過 $1。",
        "api-help-param-limit2": "不允許超過 $1 (機器人為 $2)。",
-       "api-help-param-multi-separate": "使用 \"|\" 分隔數值。",
+       "api-help-param-multi-separate": "使用 <kbd>|</kbd> 分隔數值。",
        "api-help-param-default": "預設值:$1",
        "api-help-param-default-empty": "預設值:<span class=\"apihelp-empty\">(空)</span>",
        "api-help-param-no-description": "<span class=\"apihelp-empty\">(無描述)</span>",
index 86cd1d7..b430bab 100644 (file)
@@ -796,29 +796,6 @@ class RecentChange {
                return ChangesList::showCharacterDifference( $old, $new );
        }
 
-       /**
-        * Purge expired changes from the recentchanges table
-        * @since 1.22
-        */
-       public static function purgeExpiredChanges() {
-               if ( wfReadOnly() ) {
-                       return;
-               }
-
-               $method = __METHOD__;
-               $dbw = wfGetDB( DB_MASTER );
-               $dbw->onTransactionIdle( function () use ( $dbw, $method ) {
-                       global $wgRCMaxAge;
-
-                       $cutoff = $dbw->timestamp( time() - $wgRCMaxAge );
-                       $dbw->delete(
-                               'recentchanges',
-                               array( 'rc_timestamp < ' . $dbw->addQuotes( $cutoff ) ),
-                               $method
-                       );
-               } );
-       }
-
        private static function checkIPAddress( $ip ) {
                global $wgRequest;
                if ( $ip ) {
index 054f27a..9df96f1 100644 (file)
@@ -46,9 +46,6 @@ abstract class DatabaseBase implements IDatabase {
        /** Maximum time to wait before retry */
        const DEADLOCK_DELAY_MAX = 1500000;
 
-       /** How many row changes in a write query trigger a log entry */
-       const LOG_WRITE_THRESHOLD = 300;
-
        protected $mLastQuery = '';
        protected $mDoneWrites = false;
        protected $mPHPError = false;
@@ -1160,11 +1157,13 @@ abstract class DatabaseBase implements IDatabase {
 
                # Log the query time and feed it into the DB trx profiler
                if ( $queryProf != '' ) {
+                       $that = $this;
                        $queryStartTime = microtime( true );
                        $queryProfile = new ScopedCallback(
-                               function () use ( $queryStartTime, $queryProf, $isMaster ) {
-                                       $trxProfiler = Profiler::instance()->getTransactionProfiler();
-                                       $trxProfiler->recordQueryCompletion( $queryProf, $queryStartTime, $isMaster );
+                               function () use ( $that, $queryStartTime, $queryProf, $isMaster ) {
+                                       $n = $that->affectedRows();
+                                       $trxProf = Profiler::instance()->getTransactionProfiler();
+                                       $trxProf->recordQueryCompletion( $queryProf, $queryStartTime, $isMaster, $n );
                                }
                        );
                }
@@ -1206,13 +1205,6 @@ abstract class DatabaseBase implements IDatabase {
 
                if ( false === $ret ) {
                        $this->reportQueryError( $this->lastError(), $this->lastErrno(), $sql, $fname, $tempIgnore );
-               } else {
-                       $n = $this->affectedRows();
-                       if ( $isWriteQuery && $n > self::LOG_WRITE_THRESHOLD && PHP_SAPI !== 'cli' ) {
-                               wfDebugLog( 'DBPerformance',
-                                       "Query affected $n rows:\n" .
-                                       DatabaseBase::generalizeSQL( $sql ) . "\n" . wfBacktrace( true ) );
-                       }
                }
 
                $res = $this->resultObject( $ret );
@@ -1391,9 +1383,13 @@ abstract class DatabaseBase implements IDatabase {
         *
         * @return bool|mixed The value from the field, or false on failure.
         */
-       public function selectField( $table, $var, $cond = '', $fname = __METHOD__,
-               $options = array()
+       public function selectField(
+               $table, $var, $cond = '', $fname = __METHOD__, $options = array()
        ) {
+               if ( $var === '*' ) { // sanity
+                       throw new DBUnexpectedError( $this, "Cannot use a * field: got '$var'" );
+               }
+
                if ( !is_array( $options ) ) {
                        $options = array( $options );
                }
@@ -1401,7 +1397,6 @@ abstract class DatabaseBase implements IDatabase {
                $options['LIMIT'] = 1;
 
                $res = $this->select( $table, $var, $cond, $fname, $options );
-
                if ( $res === false || !$this->numRows( $res ) ) {
                        return false;
                }
@@ -1415,6 +1410,48 @@ abstract class DatabaseBase implements IDatabase {
                }
        }
 
+       /**
+        * A SELECT wrapper which returns a list of single field values from result rows.
+        *
+        * Usually throws a DBQueryError on failure. If errors are explicitly
+        * ignored, returns false on failure.
+        *
+        * If no result rows are returned from the query, false is returned.
+        *
+        * @param string|array $table Table name. See DatabaseBase::select() for details.
+        * @param string $var The field name to select. This must be a valid SQL
+        *   fragment: do not use unvalidated user input.
+        * @param string|array $cond The condition array. See DatabaseBase::select() for details.
+        * @param string $fname The function name of the caller.
+        * @param string|array $options The query options. See DatabaseBase::select() for details.
+        *
+        * @return bool|array The values from the field, or false on failure
+        * @since 1.25
+        */
+       public function selectFieldValues(
+               $table, $var, $cond = '', $fname = __METHOD__, $options = array()
+       ) {
+               if ( $var === '*' ) { // sanity
+                       throw new DBUnexpectedError( $this, "Cannot use a * field: got '$var'" );
+               }
+
+               if ( !is_array( $options ) ) {
+                       $options = array( $options );
+               }
+
+               $res = $this->select( $table, $var, $cond, $fname, $options );
+               if ( $res === false ) {
+                       return false;
+               }
+
+               $values = array();
+               foreach ( $res as $row ) {
+                       $values[] = $row->$var;
+               }
+
+               return $values;
+       }
+
        /**
         * Returns an optional USE INDEX clause to go after the table, and a
         * string to go at the end of the query.
@@ -1822,7 +1859,7 @@ abstract class DatabaseBase implements IDatabase {
 
                if ( $res ) {
                        $row = $this->fetchRow( $res );
-                       $rows = ( isset( $row['rowcount'] ) ) ? $row['rowcount'] : 0;
+                       $rows = ( isset( $row['rowcount'] ) ) ? (int)$row['rowcount'] : 0;
                }
 
                return $rows;
@@ -1852,7 +1889,7 @@ abstract class DatabaseBase implements IDatabase {
 
                if ( $res ) {
                        $row = $this->fetchRow( $res );
-                       $rows = ( isset( $row['rowcount'] ) ) ? $row['rowcount'] : 0;
+                       $rows = ( isset( $row['rowcount'] ) ) ? (int)$row['rowcount'] : 0;
                }
 
                return $rows;
index a7bc6dd..d62769c 100644 (file)
@@ -518,7 +518,7 @@ class DatabaseMssql extends DatabaseBase {
                        $row = $this->fetchRow( $res );
 
                        if ( isset( $row['EstimateRows'] ) ) {
-                               $rows = $row['EstimateRows'];
+                               $rows = (int)$row['EstimateRows'];
                        }
                }
 
index 7b903d6..458b286 100644 (file)
@@ -468,7 +468,7 @@ abstract class DatabaseMysqlBase extends DatabaseBase {
                        $rows *= $plan->rows > 0 ? $plan->rows : 1; // avoid resetting to zero
                }
 
-               return $rows;
+               return (int)$rows;
        }
 
        /**
index ce14d7a..abf26e0 100644 (file)
@@ -712,7 +712,7 @@ class DatabasePostgres extends DatabaseBase {
                        $row = $this->fetchRow( $res );
                        $count = array();
                        if ( preg_match( '/rows=(\d+)/', $row[0], $count ) ) {
-                               $rows = $count[1];
+                               $rows = (int)$count[1];
                        }
                }
 
index 9504112..b87e26d 100644 (file)
@@ -1204,7 +1204,9 @@ abstract class FileBackend {
 
        /**
         * Preload file stat information (concurrently if possible) into in-process cache.
+        *
         * This should be used when stat calls will be made on a known list of a many files.
+        * This does not make use of the persistent file stat cache.
         *
         * @see FileBackend::getFileStat()
         *
index a3b0009..de189ec 100644 (file)
@@ -627,7 +627,7 @@ abstract class FileBackendStore extends FileBackend {
                }
                $ps = Profiler::instance()->scopedProfileIn( __METHOD__ . "-{$this->name}" );
                $latest = !empty( $params['latest'] ); // use latest data?
-               if ( !$this->cheapCache->has( $path, 'stat', self::CACHE_TTL ) ) {
+               if ( !$latest && !$this->cheapCache->has( $path, 'stat', self::CACHE_TTL ) ) {
                        $this->primeFileCache( array( $path ) ); // check persistent cache
                }
                if ( $this->cheapCache->has( $path, 'stat', self::CACHE_TTL ) ) {
@@ -1745,17 +1745,18 @@ abstract class FileBackendStore extends FileBackend {
                // Get all cache entries for these container cache keys...
                $values = $this->memCache->getMulti( array_keys( $pathNames ) );
                foreach ( $values as $cacheKey => $val ) {
+                       $path = $pathNames[$cacheKey];
                        if ( is_array( $val ) ) {
-                               $path = $pathNames[$cacheKey];
+                               $val['latest'] = false; // never completely trust cache
                                $this->cheapCache->set( $path, 'stat', $val );
                                if ( isset( $val['sha1'] ) ) { // some backends store SHA-1 as metadata
                                        $this->cheapCache->set( $path, 'sha1',
-                                               array( 'hash' => $val['sha1'], 'latest' => $val['latest'] ) );
+                                               array( 'hash' => $val['sha1'], 'latest' => false ) );
                                }
                                if ( isset( $val['xattr'] ) ) { // some backends store headers/metadata
                                        $val['xattr'] = self::normalizeXAttributes( $val['xattr'] );
                                        $this->cheapCache->set( $path, 'xattr',
-                                               array( 'map' => $val['xattr'], 'latest' => $val['latest'] ) );
+                                               array( 'map' => $val['xattr'], 'latest' => false ) );
                                }
                        }
                }
index 58245a5..d1a16b5 100644 (file)
@@ -1681,23 +1681,26 @@ class FileRepo {
         * Create a new fatal error
         *
         * @param string $message
-        * @return FileRepoStatus
+        * @return Status
         */
        public function newFatal( $message /*, parameters...*/ ) {
-               $params = func_get_args();
-               array_unshift( $params, $this );
+               $status = call_user_func_array( array( 'Status', 'newFatal' ), func_get_args() );
+               $status->cleanCallback = $this->getErrorCleanupFunction();
 
-               return call_user_func_array( array( 'FileRepoStatus', 'newFatal' ), $params );
+               return $status;
        }
 
        /**
         * Create a new good result
         *
         * @param null|string $value
-        * @return FileRepoStatus
+        * @return Status
         */
        public function newGood( $value = null ) {
-               return FileRepoStatus::newGood( $this, $value );
+               $status = Status::newGood( $value );
+               $status->cleanCallback = $this->getErrorCleanupFunction();
+
+               return $status;
        }
 
        /**
index 56848df..daf26ba 100644 (file)
 /**
  * Generic operation result class for FileRepo-related operations
  * @ingroup FileRepo
+ * @deprecated 1.25
  */
-class FileRepoStatus extends Status {
-       /**
-        * Factory function for fatal errors
-        *
-        * @param FileRepo $repo
-        * @return FileRepoStatus
-        */
-       static function newFatal( $repo /*, parameters...*/ ) {
-               $params = array_slice( func_get_args(), 1 );
-               $result = new self( $repo );
-               call_user_func_array( array( &$result, 'error' ), $params );
-               $result->ok = false;
-
-               return $result;
-       }
-
-       /**
-        * @param FileRepo|bool $repo Default: false
-        * @param mixed $value
-        * @return FileRepoStatus
-        */
-       static function newGood( $repo = false, $value = null ) {
-               $result = new self( $repo );
-               $result->value = $value;
-
-               return $result;
-       }
-
-       /**
-        * @param bool|FileRepo $repo
-        */
-       function __construct( $repo = false ) {
-               if ( $repo ) {
-                       $this->cleanCallback = $repo->getErrorCleanupFunction();
-               }
-       }
-}
+class FileRepoStatus extends Status {}
index 6c538fd..83f1266 100644 (file)
@@ -178,6 +178,13 @@ class HTMLCheckMatrix extends HTMLFormField implements HTMLNestedFilterable {
                $helptext = $this->getHelpTextHtmlTable( $this->getHelpText() );
                $cellAttributes = array( 'colspan' => 2 );
 
+               $hideClass = '';
+               $hideAttributes = array();
+               if ( $this->mHideIf ) {
+                       $hideAttributes['data-hide-if'] = FormatJson::encode( $this->mHideIf );
+                       $hideClass = 'mw-htmlform-hide-if';
+               }
+
                $label = $this->getLabelHtml( $cellAttributes );
 
                $field = Html::rawElement(
@@ -186,9 +193,12 @@ class HTMLCheckMatrix extends HTMLFormField implements HTMLNestedFilterable {
                        $inputHtml . "\n$errors"
                );
 
-               $html = Html::rawElement( 'tr', array( 'class' => 'mw-htmlform-vertical-label' ), $label );
+               $html = Html::rawElement( 'tr',
+                       array( 'class' => "mw-htmlform-vertical-label $hideClass" ) + $hideAttributes,
+                       $label );
                $html .= Html::rawElement( 'tr',
-                       array( 'class' => "mw-htmlform-field-$fieldType {$this->mClass} $errorClass" ),
+                       array( 'class' => "mw-htmlform-field-$fieldType {$this->mClass} $errorClass $hideClass" ) +
+                               $hideAttributes,
                        $field );
 
                return $html . $helptext;
index 0a118f0..6b01b61 100644 (file)
@@ -15,7 +15,8 @@
                        "Syreeni",
                        "Stryn",
                        "SMAUG",
-                       "SuperPete"
+                       "SuperPete",
+                       "McSalama"
                ]
        },
        "config-desc": "MediaWiki-asennin",
        "config-pg-test-error": "Tietokantaan <strong>$1 ei voida muodostaa yhteyttä</strong>: $2",
        "config-sqlite-dir": "SQLiten datahakemisto:",
        "config-sqlite-dir-help": "SQLite tallentaa kaiken sisällön yhteen tiedostoon.\n\nPalvelimen pitää pystyä kirjoittamaan tietoa hakemistoon asennuksen aikana.\n\nHakemiston <strong>ei</strong> tulisi olla nähtävissä www-selaimella. Siksi hakemisto on eri kuin missä PHP-tiedostot sijaitsevat.\n\nAsennusohjelma luo <code>.htaccess</code>-tiedoston, mutta jos sen luomisessa ilmenee ongelmia joku voi päästä käsiksi tietokantaasi. \nTietokannassa on kaikki sähköpostiosoitteet, salasanat, poistetut versiot ja kaikki muu tieto, joka ei näy wikissä.\n\nSuosittelemme tallentamaan tietokannan eri hakemistoon, esimerkiksi <code>/var/lib/mediawiki/yourwiki</code>.",
+       "config-oracle-def-ts": "Oletus taulukkotila:",
+       "config-oracle-temp-ts": "Väliaikainen taulukkotila:",
        "config-type-mysql": "MySQL (tai yhteensopiva)",
        "config-type-postgres": "PostgreSQL",
        "config-type-sqlite": "SQLite",
        "config-type-oracle": "Oracle",
+       "config-type-mssql": "Microsoft SQL Server",
        "config-header-mysql": "MySQL-asetukset",
        "config-header-postgres": "PostgreSQL-asetukset",
        "config-header-sqlite": "SQLite-asetukset",
index a35ea31..2303658 100644 (file)
@@ -52,6 +52,7 @@
        "config-env-good": "A környezet ellenőrzése befejeződött.\nA MediaWiki telepíthető.",
        "config-env-bad": "A környezet ellenőrzése befejeződött.\nA MediaWiki nem telepíthető.",
        "config-env-php": "A PHP verziója: $1",
+       "config-env-hhvm": "HHVM verziója: $1",
        "config-unicode-using-utf8": "A rendszer Unicode normalizálására Brion Vibber utf8_normalize.so könyvtárát használja.",
        "config-unicode-using-intl": "A rendszer Unicode normalizálására az [http://pecl.php.net/intl intl PECL kiterjesztést] használja.",
        "config-unicode-pure-php-warning": "'''Figyelmeztetés''': Az Unicode normalizáláshoz szükséges [http://pecl.php.net/intl intl PECL kiterjesztés] nem érhető el, helyette a lassú, PHP alapú implementáció lesz használva.\nHa nagy látogatottságú oldalt üzemeltetsz, itt találhatsz további információkat [//www.mediawiki.org/wiki/Special:MyLanguage/Unicode_normalization_considerations a témáról].",
index c2411ef..47dea14 100644 (file)
@@ -8,7 +8,8 @@
                        "아라",
                        "C5st4wr6ch",
                        "Seb35",
-                       "Arifin.wijaya"
+                       "Arifin.wijaya",
+                       "Ilham151096"
                ]
        },
        "config-desc": "Penginstal untuk MediaWiki",
@@ -53,6 +54,7 @@
        "config-env-good": "Kondisi telah diperiksa.\nAnda dapat menginstal MediaWiki.",
        "config-env-bad": "Kondisi telah diperiksa.\nAnda tidak dapat menginstal MediaWiki.",
        "config-env-php": "PHP $1 diinstal.",
+       "config-env-hhvm": "HHVM $1 telah dipasang.",
        "config-unicode-using-utf8": "Menggunakan utf8_normalize.so Brion Vibber untuk normalisasi Unicode.",
        "config-unicode-using-intl": "Menggunakan [http://pecl.php.net/intl ekstensi PECL intl] untuk normalisasi Unicode.",
        "config-unicode-pure-php-warning": "'''Peringatan''': [http://pecl.php.net/intl Ekstensi intl PECL] untuk menangani normalisasi Unicode tidak tersedia, kembali menggunakan implementasi murni PHP yang lambat.\nJika Anda menjalankan situs berlalu lintas tinggi, Anda harus sedikit membaca [//www.mediawiki.org/wiki/Special:MyLanguage/Unicode_normalization_considerations normalisasi Unicode].",
index 8ef3188..b9aab3a 100644 (file)
@@ -61,7 +61,7 @@
        "config-unicode-using-intl": "Usa [http://pecl.php.net/intl l'estensione PECL intl] per la normalizzazione Unicode.",
        "config-unicode-pure-php-warning": "'''Attenzione:''' [http://pecl.php.net/intl l'estensione PECL intl] non è disponibile per gestire la normalizzazione Unicode, così si usa la lenta implementazione in puro PHP.\nSe esegui un sito ad alto traffico, dovresti leggere alcune considerazioni sulla [//www.mediawiki.org/wiki/Special:MyLanguage/Unicode_normalization_considerations normalizzazione Unicode].",
        "config-unicode-update-warning": "'''Attenzione:''' La versione installata del gestore per la normalizzazione Unicode usa una vecchia versione della libreria [http://site.icu-project.org/ del progetto ICU].\nDovresti [//www.mediawiki.org/wiki/Special:MyLanguage/Unicode_normalization_considerations aggiornare] se ti interessa usare l'Unicode.",
-       "config-no-db": "Impossibile trovare un driver adatto per il database! È necessario installare un driver per PHP.\nI seguenti formati di database sono supportati: $1.\n\nSe compili PHP autonomamente, riconfiguralo attivando un client database, per esempio utilizzando <code>./configure --with-mysqli</code>.\nQualora avessi installato PHP per mezzo di un pacchetto Debian o Ubuntu, allora devi installare anche il pacchetto <code>php5-mysql</code>.",
+       "config-no-db": "Impossibile trovare un driver adatto per il database! È necessario installare un driver per PHP.\n{{PLURAL:$2|Il seguente formato di database è supportato|I seguenti formati di database sono supportati}}: $1.\n\nSe compili PHP autonomamente, riconfiguralo attivando un client database, per esempio utilizzando <code>./configure --with-mysqli</code>.\nQualora avessi installato PHP per mezzo di un pacchetto Debian o Ubuntu, allora devi installare anche il pacchetto <code>php5-mysql</code>.",
        "config-outdated-sqlite": "'''Attenzione''': è presente SQLite $1 mentre è richiesta la versione $2, SQLite non sarà disponibile.",
        "config-no-fts3": "'''Attenzione''': SQLite è compilato senza il [//sqlite.org/fts3.html modulo FTS3], le funzionalità di ricerca non saranno disponibili su questo backend.",
        "config-register-globals-error": "<strong>Errore: l'opzione PHP <code>[http://php.net/register_globals register_globals]</code> è abilitata.\nDeve essere disabilitata per continuare con l'installazione.</strong>\nVedi [https://www.mediawiki.org/wiki/register_globals https://www.mediawiki.org/wiki/register_globals] per un aiuto su come farlo.",
index fe450f6..2dccc50 100644 (file)
        "config-email-settings": "E-Mail-Astellungen",
        "config-enable-email": "E-Mailen déi no bausse ginn aschalten",
        "config-email-user": "Benotzer-op-Benotzer E-Mail aschalten",
+       "config-email-user-help": "All Benotzer erlaben sech géigesäiteg E-Mailen ze schécken, wa si dat an hiren Astellungen aktivéiert hunn.",
        "config-email-usertalk": "Benoriichtege bei Ännerung vun der Benotzerdiskussiounssäit aschalten",
        "config-email-watchlist": "Benoriichtigung vun der Iwwerwaachungslëscht aschalten",
        "config-email-watchlist-help": "Erlaabt et de Benotzer fir Notifikatioune vun hiren iwwerwaachte Säiten ze kréie wa si dat an hiren Astellungen aktivéiert hunn.",
index b8a68a7..3a43d90 100644 (file)
@@ -1,7 +1,8 @@
 {
        "@metadata": {
                "authors": [
-                       "C.R."
+                       "C.R.",
+                       "Chelin"
                ]
        },
        "config-desc": "'O prugramma d'istallazione 'e MediaWiki",
        "config-charset-mysql5-binary": "MySQL 4.1/5.0 binario",
        "config-charset-mysql5": "MySQL 4.1/5.0 UTF-8",
        "config-charset-mysql4": "MySQL 4.0 cu compatibbelità UTF-8",
+       "config-charset-help": "<strong>Attenziò:</strong> Si state ausanno <strong>backwards-compatible UTF-8</strong> ncopp' 'o MySQL 4.1+, e po' se fà 'o backup d' 'o databas c' 'o codece <code>mysqldump</code>, putesse scassà tutt' 'e carattere nun-ASCII, sfunnanno irreversibbilmente sti backup!\n\nDint' 'a <strong>modalità binaria</strong>, MediaWiki astipa 'o testo UTF-8 dint' 'o database 'n campe binarie.\nChest'è assaje cchiù efficiente rispett' 'a modalità UTF-8 'e MySQL, e te premmettesse 'ausà 'a gamma cumpreta 'e carattere unicode.\nDint' 'o <strong>UTF-8 mode</strong>, MySQL canoscerrà dint'a qualu set 'e carattere stanno 'e date vuoste, putenn'accussì apprisentà e cagnà chiste int'a nu modo appropriato,\nchesto però nun te lassarrà astipà 'e carattere pe' copp' 'o [//en.wikipedia.org/wiki/Mapping_of_Unicode_character_planes Basic Multilingual Plane].",
        "config-mysql-old": "MySQL $1 o cchiù muderno è necessario. Vuje avite $2.",
        "config-db-port": "Porta d' 'o database:",
        "config-db-schema": "Schema pe' MediaWiki:",
        "config-db-schema-help": "Stu schema 'n genere sarrà buono.\nSi 'o vulite cagnà facite sulamente si ne tenite abbesuogno.",
        "config-pg-test-error": "Nun se può connettà a 'o database <strong>$1</strong>: $2",
        "config-sqlite-dir": "Cartella 'e data 'e SQLite:",
+       "config-sqlite-dir-help": "SQLite astipa tutte 'e date dint'a n'uneco file.\n\n'A cartella ca starraje a innecà adda essere scrivibbele d' 'o server webe pe' tramente ca sta l'istallazione.\n\nAvess'a essere <strong>nun trasibbele via web</strong>, è pecchesto ca nun se sta mettenno addò stanno 'e file PHP.\n\nL'installatore scriverrà nzieme a chesta nu file <code>.htaccess</code>, ma si 'o tentativo scassasse, coccheruno putesse tenè acciesso dint' 'o database ncruro.\nChesto pure cunzidera 'e date ncruro 'e ll'utente (indirizze, password cifrate) accussì comme 'e verziune luvate e ati dati d'accesso limmetato dint' 'o wiki.\n\nCunzidera ll'opportunità 'e sistimà ô tiempo 'o database 'a n'ata parte, p'esempio int'a <code>/var/lib/mediawiki/tuowiki</code>.",
        "config-oracle-def-ts": "Tablespace 'e default:",
        "config-oracle-temp-ts": "Tablespace temporaneo:",
        "config-type-mysql": "MySQL (o compatibbele)",
        "config-type-mssql": "Microsoft SQL Server",
        "config-support-info": "MediaWiki supporta 'e sisteme 'e database ccà abbascio:\n\n$1\n\nSi nfra chiste ccà nun vedite 'o sistema 'e database ca vulite ausà, allora avite liegge 'e instruziune ccà ncoppa pe' ne dà supporto.",
+       "config-dbsupport-mysql": "* [{{int:version-db-mysql-url}} MySQL] è 'a configurazione cchiù mmeglio p' 'o MediaWiki e è chilla meglio suppurtata. MediaWiki può faticà pure cu' [{{int:version-db-mariadb-url}} MariaDB] e [{{int:version-db-percona-url}} Percona Server], ca fossero MySQL cumpatibbele. ([http://www.php.net/manual/en/mysqli.installation.php Comme s'adda fà pe' cumpilà PHP cu suppuorto MySQL])",
+       "config-dbsupport-postgres": "* [{{int:version-db-postgres-url}} PostgreSQL] è nu sistema canusciuto 'e database open source ca fosse n'alternativa a MySQL. Putess'avé cocch'errore p'arricettà, e nun è cunzigliato 'e ll'ausà dint'a n'ambiente 'e produziona. ([http://www.php.net/manual/en/pgsql.installation.php Comme s'avess'a cumpilà PHP cu suppuorto PostgreSQL])",
        "config-header-mysql": "Mpustaziune MySQL",
        "config-header-postgres": "Mpustaziune PostgreSQL",
        "config-header-sqlite": "Mpustaziune SQLite",
        "config-missing-db-name": "Avita miette nu valore p' 'o \"{{int:config-db-name}}\"",
        "config-missing-db-host": "Avita miette nu valore p' 'o \"{{int:config-db-host}}\"",
        "config-missing-db-server-oracle": "Avita miette nu valore p' 'o \"{{int:config-db-host-oracle}}\"",
+       "config-invalid-db-server-oracle": "'O database 'e TNS \"$1\" nun è buono.\nAusate 'o \"TNS Name\" o na catena d' \"Easy Connect\"([http://docs.oracle.com/cd/E11882_01/network.112/e10836/naming.htm Metude 'e Nommena Oracle]).",
        "config-connection-error": "$1.\n\nCuntrullate 'o host, nomme utente e password e tentate n'ata vota.",
        "config-invalid-schema": "Schema MediaWiki \"$1\" nun è buono.\nAusate surtanto 'e lettere ASCII (a-z, A-Z), nummere (0-9) e carattere 'e sottolineatura (_).",
        "config-db-sys-create-oracle": "'O prugramma 'e installazione supporta surtanto l'uso 'e nu cunto SYSDBA pe' putè crià nu cunto nuovo.",
+       "config-postgres-old": "PostgreSQL $1 o cchiù muderno è necessario. Vuje tenite $2.",
+       "config-mssql-old": "Microsoft SQL Server $1 o cchiù muderno è necessario. Vuje tenite $2.",
+       "config-sqlite-name-help": "Sciglite nu nomme ca identificasse 'o wiki vuosto.\nNun ausà spazie o trattine.\nChesto serverrà pe' putè miettere 'o nomme ro file 'e date SQLite.",
+       "config-sqlite-parent-unwritable-group": "Nun se pò crià 'a cartella 'e date <code><nowiki>$1</nowiki></code>, pecché 'a cartella supiriore <code><nowiki>$2</nowiki></code> nun se pò scrivere 'a 'o webserver.\n\n'O prugramma d'installazione ha determinato l'utente c' 'o quale 'o server web se stà a esecutà.\nDàte 'a pussibbelità 'e scrivere dint' 'a cartella <code><nowiki>$3</nowiki></code> pe' cuntinuà\nNcopp'a nu sistema Unix/Linux:\n\n<pre>cd $2\nmkdir $3\nchgrp $4 $3\nchmod g+w $3</pre>",
+       "config-sqlite-connection-error": "$1.\n\nCuntrullate 'a cartella 'e date e 'o nomme d' 'o database ccà abbascio e pruvate n'ata vota.",
        "config-sqlite-readonly": "'O file <code>$1</code> nun è scrivibbele.",
        "config-sqlite-cant-create-db": "Nun se può crià 'o file database <code>$1</code>.",
        "config-sqlite-fts3-downgrade": "'O PHP è mancante d' 'o suppuorto FTS3, declassamento tabbelle 'n curzo",
+       "config-can-upgrade": "Nce stanno tabbelle 'e MediaWiki int'a stu database.\nPe ll'agghiurnà a MediaWiki $1, facite click ncopp' 'a '''continua'''.",
+       "config-upgrade-done": "Agghiurnamiento cumpreto.\n\nMo' putite [$1 accummincià 'ausà 'o wiki vuosto].\n\nSi vulite ringignà 'o file vuosto 'e <code>LocalSettings.php</code>, cliccate ncopp' 'o buttone ccà abbascio. St'operazione '''nun è cunzigliata''', si nun è pecché forse tenite cocche prubblema c' 'o wiki vuosto.",
+       "config-upgrade-done-no-regenerate": "Agghiurnamiento cumpreto.\n\nPutite [$1 accummincià 'ausà 'o wiki vuosto].",
        "config-regenerate": "Rigennera LocalSettings.php →",
        "config-show-table-status": "'A query <code>SHOW TABLE STATUS</code> è fallita!",
        "config-unknown-collation": "<strong>Attenziò:</strong> 'O database sta ausanno reule 'e cunfronto nun ricanusciute.",
        "config-site-name-blank": "Scrive 'o nomme d' 'o sito.",
        "config-project-namespace": "Namespace d' 'o pruggetto:",
        "config-ns-generic": "Pruggetto",
-       "config-install-updates": "Mpiccià ll'agghiurnamiente ca nun fossero necessarie"
+       "config-ns-site-name": "'O stesso ch' 'o nomme d' 'o wiki: $1",
+       "config-ns-other": "Ati (specificà)",
+       "config-ns-other-default": "MyWiki",
+       "config-ns-invalid": "'O namespace specificato \"<nowiki>$1</nowiki>\" nun è buono.\nSpecificate nu namespace 'e pruggetto differente.",
+       "config-ns-conflict": "'O namespace innecato \"<nowiki>$1</nowiki>\" tràse ncunflitto cu nu namespace predefinito 'e MediaWiki.\nSpecifiate n'atu nomme divierzo 'e namespace 'e pruggetto.",
+       "config-admin-box": "Cunto ammenistratore",
+       "config-admin-name": "'O nomme utente vuosto:",
+       "config-admin-password": "'A password vuosta:",
+       "config-admin-password-confirm": "Password n'ata vota:",
+       "config-admin-help": "Mettite 'o nomme utente ca vuje vulite ccà, p'esempio \"Gennaro Esposito\".\nChest'è 'o nomme ca vuje auserrate pe' trasì 'o wiki.",
+       "config-admin-name-blank": "Mettite nu nomme utente p' 'ammenistratore.",
+       "config-admin-name-invalid": "'O namespace specificato \"<nowiki>$1</nowiki>\" nun è buono.\nSpecificate nu namespace differente.",
+       "config-admin-password-blank": "Miette na password p' 'o cunto d'ammenistratore.",
+       "config-admin-email": "Indirizzo e-mail:",
+       "config-admin-error-bademail": "Avite miso n'indirizzo e-mail invalido.",
+       "config-optional-continue": "Spiate cchiù dimanne.",
+       "config-profile": "Profilo 'e deritte utente:",
+       "config-profile-wiki": "Wiki araputo",
+       "config-profile-no-anon": "Cunto utente obbligatorio",
+       "config-profile-fishbowl": "Surtanto ll'editure premmesse",
+       "config-profile-private": "Wiki privato",
+       "config-license-pd": "Pubbreco duminio",
+       "config-logo": "URL d\"o logo:",
+       "config-cc-again": "Selezziona 'e novo...",
+       "config-install-step-done": "fatto",
+       "config-install-updates": "Mpiccià ll'agghiurnamiente ca nun fossero necessarie",
+       "config-help": "ajùto"
 }
index a28f610..132644d 100644 (file)
@@ -13,7 +13,8 @@
                        "Fabsouza1",
                        "Rodrigo codignoli",
                        "Tuliouel",
-                       "Marcos dias de oliveira"
+                       "Marcos dias de oliveira",
+                       "Fasouzafreitas"
                ]
        },
        "config-desc": "O instalador do MediaWiki",
        "config-install-done": "<strong>Parabéns!</strong>\nVocê concluiu a instalação do MediaWiki.\n\nO instalador gerou um arquivo <code>LocalSettings.php</code>.\nEste arquivo contém todas as suas configurações.\n\nVocê precisa fazer o download desse arquivo e colocá-lo na raiz da sua instalação (o mesmo diretório onde está o arquivo <code>index.php</code>). Este download deve ter sido iniciado automaticamente.\n\nSe o download não foi iniciado, ou se ele foi cancelado, pode recomeçá-lo clicando no link abaixo:\n\n$3\n\n<strong>Nota</strong>: Se não fizer isto agora, o arquivo que foi gerado não estará disponível depois que você sair do processo de instalação sem baixá-lo.\n\nQuando isso tiver sido feito, pode <strong>[$2 entrar na sua wiki]</strong>.",
        "config-download-localsettings": "Baixar <code>LocalSettings.php</code>",
        "config-help": "ajuda",
+       "config-help-tooltip": "clique para expandir",
        "config-nofile": "O arquivo \"$1\" não foi encontrado. Ele foi apagado?",
        "config-extension-link": "Você sabia que sua wiki suporta [//www.mediawiki.org/wiki/Special:MyLanguage/Manual:Extensions extensões]?\n\nVocê pode explorar as  [//www.mediawiki.org/wiki/Special:MyLanguage/Category:Extensions_by_category extensões por categoria] ou visitar a [//www.mediawiki.org/wiki/Extension_Matrix Matriz de Extensões] para ver a lista completa.",
        "mainpagetext": "<strong>O MediaWiki foi instalado com sucesso.</strong>",
index 40dca4d..386215a 100644 (file)
@@ -68,7 +68,7 @@
        "config-unicode-using-intl": "Будет использовано [http://pecl.php.net/intl расширение «intl» для PECL] для нормализации Юникода.",
        "config-unicode-pure-php-warning": "'''Внимание!''': [http://pecl.php.net/intl расширение intl из PECL] недоступно для нормализации Юникода, будет использоваться медленная реализация на чистом PHP.\nЕсли ваш сайт работает под высокой нагрузкой, вам следует больше узнать о [//www.mediawiki.org/wiki/Special:MyLanguage/Unicode_normalization_considerations нормализации Юникода].",
        "config-unicode-update-warning": "'''Предупреждение''': установленная версия обёртки нормализации Юникода использует старую версию библиотеки [http://site.icu-project.org/ проекта ICU].\nВы должны [//www.mediawiki.org/wiki/Special:MyLanguage/Unicode_normalization_considerations обновить версию], если хотите полноценно использовать Юникод.",
-       "config-no-db": "Не удалось найти подходящие драйвера баз данных! Вам необходимо установить драйвера базы данных для PHP.\nПоддерживаются следующие типы баз данных: $1.\nЕсли вы скомпилировали PHP сами, перенастройте его с включением клиента баз данных, например, с помощью <code>./configure --with-mysqli</code>.\nЕсли вы скомпилировали PHP сами, сконфигурируйте его снова с включенным клиентом базы данных, например, с помощью <code>./configure --with-mysql</code>.\nЕсли вы установили PHP из пакетов Debian или Ubuntu, то вам также необходимо установить, например, пакет <code>php5-mysql</code>.",
+       "config-no-db": "Не удалось найти подходящие драйвера баз данных! Вам необходимо установить драйвера базы данных для PHP.\n{{PLURAL:$2|Поддерживается следующий тип|Поддерживаются следующие типы}} баз данных: $1.\n\nЕсли вы скомпилировали PHP сами, перенастройте его с включением клиента баз данных, например, с помощью <code>./configure --with-mysqli</code>.\nЕсли вы установили PHP из пакетов Debian или Ubuntu, то вам также необходимо установить, например, пакет <code>php5-mysql</code>.",
        "config-outdated-sqlite": "'''Предупреждение''': у Вас установлен SQLite  $1, версия которого ниже требуемой $2 . SQLite будет недоступен.",
        "config-no-fts3": "'''Внимание''': SQLite собран без модуля [//sqlite.org/fts3.html FTS3] — поиск не будет работать для этой базы данных.",
        "config-register-globals-error": "<strong>Ошибка: Параметр PHP <code>[http://php.net/register_globals register_globals]</code> включен.\nОн должен быть отключен для того, чтобы можно было продолжить установку.</strong>\nПолучить справку о том, как это сделать, можно по адресу [https://www.mediawiki.org/wiki/register_globals https://www.mediawiki.org/wiki/register_globals].",
index 950ee44..964b3cc 100644 (file)
@@ -3,7 +3,8 @@
                "authors": [
                        "Rancher",
                        "Михајло Анђелковић",
-                       "Milicevic01"
+                       "Milicevic01",
+                       "Aktron"
                ]
        },
        "config-desc": "Инсталација за Медијавики",
@@ -42,6 +43,8 @@
        "config-db-type": "Тип базе података:",
        "config-db-host": "Хост базе података",
        "config-db-name": "Назив базе података:",
+       "config-db-password": "Лозинка за базу података:",
+       "config-db-password-empty": "Унесите лозинку за новог корисника базе података: ($1).\n\nМада је могуће отворити налоге без лозинки, то се не препоручује.",
        "config-type-mysql": "MySQL (или компактибилан)",
        "config-type-postgres": "PostgreSQL",
        "config-type-sqlite": "SQLite",
@@ -49,6 +52,7 @@
        "config-type-mssql": "Microsoft SQL Server",
        "config-header-mysql": "MySQL подешавања",
        "config-header-mssql": "Поставке Microsoft SQL Server-а",
+       "config-invalid-db-type": "Неважећи тип базе података.",
        "config-mssql-old": "Потребан је Microsoft SQL Server $1 или новији. Ви имате $2.",
        "config-mysql-innodb": "InnoDB",
        "config-mysql-myisam": "MyISAM",
        "config-admin-name": "Корисничко име:",
        "config-admin-password": "Лозинка:",
        "config-admin-email": "Адреса е-поште:",
+       "config-optional-skip": "Досадно ми је, хајде да инсталирамо вики.",
+       "config-profile-no-anon": "Неопходно је отворити налог",
+       "config-profile-fishbowl": "Само овлашћени корисници",
+       "config-profile-private": "Приватна вики",
        "config-license": "Ауторска права и лиценца:",
        "config-license-none": "Без заглавља са лиценцом",
        "config-license-cc-by-sa": "Creative Commons Ауторство-Делити под истим условима (CC BY-SA)",
        "config-license-cc-0": "Creative Commons Zero (јавно власништво)",
        "config-license-gfdl": "ГНУ-ова лиценца за слободну документацију верзија 1.3 или новија верзија",
        "config-license-pd": "Јавно власништво",
+       "config-email-settings": "Подешавања е-поште",
+       "config-cc-not-chosen": "Одаберите која Кријејтив комонс лиценца вам одговара и потврдите.",
+       "config-install-step-done": "готово",
+       "config-install-step-failed": "није успело",
+       "config-help": "помоћ",
+       "config-help-tooltip": "кликните да проширите",
        "mainpagetext": "'''Медијавики је успешно инсталиран.'''",
        "mainpagedocfooter": "Погледајте [//meta.wikimedia.org/wiki/Help:Contents кориснички водич] за коришћење програма.\n\n== Увод ==\n* [//www.mediawiki.org/wiki/Special:MyLanguage/Manual:Configuration_settings Помоћ у вези са подешавањима]\n* [//www.mediawiki.org/wiki/Special:MyLanguage/Manual:FAQ Често постављена питања]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-announce Дописна листа о издањима Медијавикија]"
 }
index 60d072a..87ac7a5 100644 (file)
@@ -7,7 +7,8 @@
                        "Josve05a",
                        "Lokal Profil",
                        "Tobulos1",
-                       "Rotsee"
+                       "Rotsee",
+                       "Boom"
                ]
        },
        "config-desc": "Installationsprogrammet för MediaWiki",
@@ -57,7 +58,7 @@
        "config-unicode-using-intl": "Använder [http://pecl.php.net/intl intl PECL-tillägget] för Unicode-normalisering.",
        "config-unicode-pure-php-warning": "'''Varning:''' [http://pecl.php.net/intl intl PECL-tillägget] är inte tillgängligt för att hantera Unicode-normalisering, faller tillbaka till en långsamt implementering i ren PHP.\nOm du driver en högtrafikerad webbplats bör du läsa lite om [//www.mediawiki.org/wiki/Special:MyLanguage/Unicode_normalization_considerations Unicode-normalisering].",
        "config-unicode-update-warning": "'''Varning:''' Den installerade versionen av Unicode-normaliserings \"wrappern\" använder en äldre version av [http://site.icu-project.org/ ICU projektets] bibliotek.\nDu bör [//www.mediawiki.org/wiki/Special:MyLanguage/Unicode_normalization_considerations uppgradera] om är intresserad av att använda Unicode.",
-       "config-no-db": "Kunde inte hitta en lämplig databasdrivrutin! Du måste installera en databasdrivrutin för PHP.\nFöljande databastyper stöds: $1.\n\nI du själv kompilerat din PHP, konfigurera den med en databasklient aktiverad genom att t.ex. använda <code>./configure --with-mysqli</code>.\nOm du installerade PHP från ett Debian- eller Ubuntupaket måste du även installera, t.ex. <code>php5-mysql</code>-paketet.",
+       "config-no-db": "Kunde inte hitta en lämplig databasdrivrutin! Du måste installera en databasdrivrutin för PHP.\nFöljande databas{{PLURAL:$2|typ |typer}} stöds: $1.\n\nI du själv kompilerat din PHP, konfigurera den med en databasklient aktiverad genom att t.ex. använda <code>./configure --with-mysqli</code>.\nOm du installerade PHP från ett Debian- eller Ubuntupaket måste du även installera, t.ex. <code>php5-mysql</code>-paketet.",
        "config-outdated-sqlite": "'''Varning:''' du har SQLite $1, vilket är lägre än minimikravet version $2. SQLite kommer inte att vara tillgänglig.",
        "config-no-fts3": "'''Varning:''' SQLite kompileras utan [//sqlite.org/fts3.html FTS3-modulen], sökfunktioner kommer att vara otillgängliga på denna backend.",
        "config-register-globals-error": "<strong>Fel: PHP-alternativet <code>[http://php.net/register_globals register_globals]</code> är aktiverad.\nDen måste vara inaktiverad för att fortsätta med installationen.</strong>\nSe [https://www.mediawiki.org/wiki/register_globals https://www.mediawiki.org/wiki/register_globals] för hjälp om hur man gör så.",
index 4b12c75..13309b5 100644 (file)
        "config-email-watchlist": "Gửi thư thông báo về bài theo dõi",
        "config-email-watchlist-help": "Cho phép người dùng nhận được thông báo về các trang theo dõi của họ nếu họ đã kích hoạt nó trong ưu tiên của họ.",
        "config-email-auth": "Xác minh qua thư điện tử",
+       "config-email-auth-help": "Nếu tùy chọn này được kích hoạt, người dùng phải xác nhận địa chỉ email của họ bằng cách sử dụng một liên kết được gửi tới cho họ bất cứ khi nào họ thiết lập hoặc thay đổi nó.\nChỉ có địa chỉ email được xác thực mới có thể nhận email từ những người dùng khác hoặc các email thông báo thay đổi.\nThiết lập tùy chọn này <strong>khuyến cáo sử dụng</strong> cho các wiki công cộng do khả năng các tính năng email dễ bị lạm dụng để gây hại.",
        "config-email-sender": "Địa chỉ thư điện tử trả lại:",
+       "config-email-sender-help": "Nhập địa chỉ email để làm địa chỉ trở về trong mail gửi đi.\nĐây là nơi mà thư từ chối sẽ được gửi đi.\nNhiều máy chủ mail yêu cầu phải có ít nhất là phần tên miền để đảm bảo tính hợp lệ.",
        "config-upload-settings": "Hình ảnh và tập tin tải lên",
        "config-upload-enable": "Cho phép tải lên tập tin",
+       "config-upload-help": "Tập tin tải lên có khả năng làm lộ các nguy cơ bảo mật của máy chủ của bạn.\nĐể biết thêm thông tin, xin đọc [//www.mediawiki.org/wiki/Special:MyLanguage/Manual:Security phần bảo mật] trong tài liệu hướng dẫn.\n\nĐể kích hoạt tính năng tải tập tin lên, thay đổi chế độ trên thư mục con <code>hình ảnh</code> trong thư mục gốc (root) của MediaWiki để máy chủ web có thể lưu dữ liệu vào đó.\nSau đó kích hoạt tùy chọn này.",
        "config-upload-deleted": "Thư mục chứa các tập tin đã xóa:",
        "config-upload-deleted-help": "Chọn một thư mục trong đó lưu trữ các tập tin đã bị xóa.\nLý tưởng nhất, thư mục này không nên được truy cập từ trang web.",
        "config-logo": "URL biểu trưng:",
        "config-logo-help": "Giao diện mặc định của MediaWiki bao gồm không gian cho một logo 135x160 điểm ảnh trên menu sidebar (thanh bên).\nTải lên một hình ảnh kích thước thích hợp, và nhập URL hình ảnh đó vào đây.\n\nBạn có thể sử dụng <code>$wgStylePath</code> hoặc <code>$wgScriptPath</code> nếu logo của bạn liên quan đường những đường dẫn ở đây.\n\nNếu bạn không muốn có một logo, hãy bỏ trống ô này.",
        "config-instantcommons": "Kích hoạt Instant Commons",
+       "config-instantcommons-help": "[//www.mediawiki.org/wiki/InstantCommons Instant Commons] là một tính năng cho phép wiki sử dụng hình ảnh, âm thanh và tập tin đa phương tiện khác được tìm thấy trong trang web [//commons.wikimedia.org/ Wikimedia Commons].\nĐể làm được điều này, MediaWiki yêu cầu phải truy cập vào Internet.\n\nĐể biết thêm thông tin về tính năng này, trong đó có hướng dẫn về cách thiết lập cho các wiki khác với Wikimedia Commons, tham khảo thêm tại [//www.mediawiki.org/wiki/Special:MyLanguage/Manual:$wgForeignFileRepos tài liệu hướng dẫn].",
        "config-cc-error": "Người chọn giấy phép Creative Commons đã không đưa ra kết quả nào.\nNhập tên giấy phép bằng tay.",
        "config-cc-again": "Chọn một lần nữa…",
        "config-cc-not-chosen": "Chọn một giấy phép Creative Commons và bấm “Tiếp tục”.",
        "config-advanced-settings": "Thiết lập nâng cao",
        "config-cache-options": "Thiết lập bộ nhớ đệm đối tượng:",
+       "config-cache-help": "Lưu vào bộ nhớ đệm đối tượng được sử dụng để cải thiện tốc độ của MediaWiki bằng cách lưu vào bộ nhớ đệm những dữ liệu thường xuyên sử dụng.\nCác trang web từ trung bình cho đến các trang web lớn rất được khuyến khích kích hoạt tính năng này, và các trang web nhỏ cũng sẽ nhìn thấy lợi ích tương tự.",
+       "config-cache-none": "Không lưu vào bộ nhớ đệm (không có chức năng nhiệm vụ sẽ được loại bỏ, nhưng tốc độ có thể bị ảnh hưởng trên các trang web wiki lớn hơn)",
        "config-cache-accel": "Bộ nhớ đệm đối tượng PHP (APC, XCache, hoặc WinCache)",
        "config-cache-memcached": "Sử dụng Memcached (cần thiết lập và cấu hình thêm)",
        "config-memcached-servers": "Máy chủ Memcached:",
        "config-extensions": "Phần mở rộng",
        "config-extensions-help": "Mở rộng được liệt kê ở trên đã được phát hiện trong thư mục <code>./extensions</code> của bạn.\n\nChúng có thể yêu cầu thêm cấu hình, nhưng bạn có thể kích hoạt chúng ngay bây giờ.",
        "config-skins": "Giao diện",
+       "config-skins-help": "Các giao diện được liệt kê ở trên đã được phát hiện trong thư mục <code>./skins</code> của bạn. Bạn phải kích hoạt ít nhất một giao diện, và chọn nó làm mặc định.",
        "config-skins-use-as-default": "Dùng giao diện này làm mặc định",
+       "config-skins-missing": "Không giao diện nào được tìm thấy; MediaWiki sẽ sử dụng một giao diện dự phòng cho đến khi bạn cài đặt giao diện thích hợp.",
        "config-skins-must-enable-some": "Phải chọn ít nhất một giao diện để kích hoạt.",
        "config-skins-must-enable-default": "Giao diện được chọn làm mặc định phải được kích hoạt.",
+       "config-install-alreadydone": "<strong>Cảnh báo:</strong> Bạn dường như đã cài đặt MediaWiki và đang cố gắng để cài đặt nó lại một lần nữa.\nXin hãy chuyển sang trang tiếp theo.",
+       "config-install-begin": "Bằng cách nhấn \"{{int:config-continue}}\", bạn sẽ bắt đầu cài đặt MediaWiki của mình.\nNếu bạn vẫn muốn thay đổi, nhấn \"{{int:config-back}}\".",
        "config-install-step-done": "hoàn tất",
        "config-install-step-failed": "thất bại",
        "config-install-extensions": "Đang bao gồm phần mở rộng",
        "config-install-interwiki-exists": "'''Cảnh báo:''' Hình như đã có mục trong bảng liên wiki.\nĐã bỏ qua danh sách mặc định.",
        "config-install-stats": "Đang khởi tạo các thống kê",
        "config-install-keys": "Tạo ra các chìa khóa bí mật",
+       "config-insecure-keys": "<strong>Cảnh báo:</strong>{{PLURAL:$2|Một khóa an toàn|Khóa an toàn}} ($1) được tạo ra trong quá trình cài đặt {{PLURAL:$2|là}} không hoàn toàn an toàn. Hãy cân nhắc việc thay đổi {{PLURAL: $2|nó|chúng}} bằng tay.",
        "config-install-updates": "Tránh các cập nhật không cần thiết",
        "config-install-updates-failed": "<strong>Lỗi:</strong> Chèn phím cập nhật vào các bảng không thành công với các lỗi sau:1$",
        "config-install-sysop": "Đang mở tài khoản người dùng bảo quản viên",
        "config-help": "Trợ giúp",
        "config-help-tooltip": "nhấn chuột để mở rộng",
        "config-nofile": "Không tìm thấy tập tin “$1”. Nó có phải bị xóa không?",
+       "config-extension-link": "Bạn có biết rằng wiki của bạn có hỗ trợ [//www.mediawiki.org/wiki/Special:MyLanguage/Manual:Extensions mở rộng]?\n\nBạn có thể truy cập [//www.mediawiki.org/wiki/Special:MyLanguage/Category:Extensions_by_category phần mở rộng theo thể loại] hoặc [//www.mediawiki.org/wiki/Extension_Matrix Ma trận Mở rộng] để xem danh sách đầy đủ các phần mở rộng.",
        "mainpagetext": "'''MediaWiki đã được cài đặt thành công.'''",
        "mainpagedocfooter": "Xin đọc [//meta.wikimedia.org/wiki/Help:Contents Hướng dẫn sử dụng] để biết thêm thông tin về cách sử dụng phần mềm wiki.\n\n== Để bắt đầu ==\n\n* [//www.mediawiki.org/wiki/Special:MyLanguage/Manual:Configuration_settings Danh sách các thiết lập cấu hình]\n* [//www.mediawiki.org/wiki/Special:MyLanguage/Manual:FAQ Các câu hỏi thường gặp MediaWiki]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-announce Danh sách gửi thư về việc phát hành MediaWiki]"
 }
index 0e03296..934b4b4 100644 (file)
@@ -63,7 +63,7 @@
        "config-unicode-using-intl": "使用 [http://pecl.php.net/intl intl PECL 擴充套件] 做 Unicode 正規化。",
        "config-unicode-pure-php-warning": "<strong>警告:</strong> 無法使用 [http://pecl.php.net/intl intl PECL 擴充套件] 處理 Unicode 正規化,故回退使用純 PHP 實作的正規化程式,此方式處理速度較緩慢。\n\n如果您的網站瀏覽人次很高,您應先閱讀 [//www.mediawiki.org/wiki/Special:MyLanguage/Unicode_normalization_considerations/zh Unicode 正規化]。",
        "config-unicode-update-warning": "<strong>警告</strong>:目前安裝的 Unicode 正規化包裝程式使用了舊版 [http://site.icu-project.org/ ICU 計劃] 的程式庫。\n若您需要使用 Unicode,您應先進行 [//www.mediawiki.org/wiki/Special:MyLanguage/Unicode_normalization_considerations 升級]。",
-       "config-no-db": "找不到合適的資料庫驅動程式!您需要安裝 PHP 資料庫驅動程式。\n目前支援以下類型的資料庫: $1 。\n\n如果您是自行編譯 PHP,您必須重新設定並開啟資料庫客戶端,例:使用 <code>./configure --with-mysqli</code> 指令參數。\n如果您是使用 Debian 或 Ubuntu 的套件安裝,您則需要額外安裝,例:<code>php5-mysql</code> 套件。",
+       "config-no-db": "找不到合適的資料庫驅動程式!您需要安裝 PHP 資料庫驅動程式。\n目前支援以下{{PLURAL:$2|type is|類型}}的資料庫: $1 。\n\n如果您是自行編譯 PHP,您必須重新設定並開啟資料庫用戶端,例:使用 <code>./configure --with-mysqli</code> 指令參數。\n如果您是使用 Debian 或 Ubuntu 的套件安裝 PHP ,您則需要額外安裝,例:<code>php5-mysql</code> 套件。",
        "config-outdated-sqlite": "<strong>警告:</strong>您已安裝 SQLite $1,但是它的版本低於最低需求版本 $2。 因此您無法使用 SQLite。",
        "config-no-fts3": "<strong>警告:</strong> SQLite 編譯時未包含 [//sqlite.org/fts3.html FTS3 模組],後台搜尋功能將無法使用。",
        "config-register-globals-error": "<strong>錯誤:PHP 的 <code>[http://php.net/register_globals register_globals]</code> 選項已開啟。\n要繼續安裝程序必須關閉該選項。</strong>\n請參考 [https://www.mediawiki.org/wiki/register_globals https://www.mediawiki.org/wiki/register_globals] 以取得操作說明。",
index abfdc8c..243fec9 100644 (file)
@@ -24,7 +24,7 @@
 /**
  * Class to handle job queues stored in Redis
  *
- * This is faster, less resource intensive, queue that JobQueueDB.
+ * This is a faster and less resource-intensive job queue than JobQueueDB.
  * All data for a queue using this class is placed into one redis server.
  *
  * There are eight main redis keys used to track jobs:
@@ -49,7 +49,7 @@
  *
  * This class requires Redis 2.6 as it makes use Lua scripts for fast atomic operations.
  * Additionally, it should be noted that redis has different persistence modes, such
- * as rdb snapshots, journaling, and no persistent. Appropriate configuration should be
+ * as rdb snapshots, journaling, and no persistence. Appropriate configuration should be
  * made on the servers based on what queues are using it and what tolerance they have.
  *
  * @ingroup JobQueue
@@ -64,8 +64,6 @@ class JobQueueRedis extends JobQueue {
        protected $server;
        /** @var string Compression method to use */
        protected $compression;
-       /** @var bool */
-       protected $daemonized;
 
        const MAX_AGE_PRUNE = 604800; // integer; seconds a job can live once claimed (7 days)
 
@@ -90,7 +88,11 @@ class JobQueueRedis extends JobQueue {
                $this->server = $params['redisServer'];
                $this->compression = isset( $params['compression'] ) ? $params['compression'] : 'none';
                $this->redisPool = RedisConnectionPool::singleton( $params['redisConfig'] );
-               $this->daemonized = !empty( $params['daemonized'] );
+               if ( empty( $params['daemonized'] ) ) {
+                       throw new Exception(
+                               "Non-daemonized mode is no longer supported. Please install the " .
+                               "mediawiki/services/jobrunner service and update \$wgJobTypeConf as needed." );
+               }
                $this->checkDelay = true; // always enabled
        }
 
@@ -291,19 +293,9 @@ LUA;
        protected function doPop() {
                $job = false;
 
-               // 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->daemonized && mt_rand( 0, 9 ) == 0 ) {
-                       $this->recyclePruneAndUndelayJobs();
-               }
-
                $conn = $this->getConnection();
                try {
                        do {
-                               // Keep the claimed job list down for high-traffic queues
-                               if ( !$this->daemonized && mt_rand( 0, 99 ) == 0 ) {
-                                       $this->recyclePruneAndUndelayJobs();
-                               }
                                $blob = $this->popAndAcquireBlob( $conn );
                                if ( !is_string( $blob ) ) {
                                        break; // no jobs; nothing to do
@@ -316,7 +308,7 @@ LUA;
                                        continue;
                                }
 
-                               // If $item is invalid, recyclePruneAndUndelayJobs() will cleanup as needed
+                               // If $item is invalid, the runner loop recyling will cleanup as needed
                                $job = $this->getJobFromFields( $item ); // may be false
                        } while ( !$job ); // job may be false if invalid
                } catch ( RedisException $e ) {
@@ -583,112 +575,11 @@ LUA;
                }
        }
 
-       /**
-        * 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/undelayed
-        * @throws MWException|JobQueueError
-        */
-       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.
-               // For those that cannot, they are marked as dead and kept around for
-               // investigation and manual job restoration but are eventually deleted.
-               $conn = $this->getConnection();
-               try {
-                       $now = time();
-                       static $script =
-<<<LUA
-                       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])
-                       for k,id in ipairs(staleClaims) do
-                               local timestamp = redis.call('zScore',kClaimed,id)
-                               local attempts = redis.call('hGet',kAttempts,id)
-                               if attempts < ARGV[3] then
-                                       -- Claim expired and retries left: re-enqueue the job
-                                       redis.call('lPush',kUnclaimed,id)
-                                       released = released + 1
-                               else
-                                       -- Claim expired and no retries left: mark the job as dead
-                                       redis.call('zAdd',kAbandoned,timestamp,id)
-                                       abandoned = abandoned + 1
-                               end
-                               redis.call('zRem',kClaimed,id)
-                       end
-                       -- Get all of the dead jobs that have been marked as dead for too long.
-                       -- The score for each item is the last claim timestamp (UNIX).
-                       local deadClaims = redis.call('zRangeByScore',kAbandoned,0,ARGV[2])
-                       for k,id in ipairs(deadClaims) do
-                               -- Stale and out of retries: remove any traces of the job
-                               redis.call('zRem',kAbandoned,id)
-                               redis.call('hDel',kAttempts,id)
-                               redis.call('hDel',kData,id)
-                               pruned = pruned + 1
-                       end
-                       -- 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(
-                                       $this->getQueueKey( 'z-claimed' ), # KEYS[1]
-                                       $this->getQueueKey( 'h-attempts' ), # KEYS[2]
-                                       $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]
-                                       $now # ARGV[4]
-                               ),
-                               6 # number of first argument(s) that are keys
-                       );
-                       if ( $res ) {
-                               list( $released, $abandoned, $pruned, $undelayed ) = $res;
-                               $count += $released + $pruned + $undelayed;
-                               JobQueue::incrStats( 'job-recycle', $this->type, $released, $this->wiki );
-                               JobQueue::incrStats( 'job-abandon', $this->type, $abandoned, $this->wiki );
-                               JobQueue::incrStats( 'job-undelay', $this->type, $undelayed, $this->wiki );
-                       }
-               } catch ( RedisException $e ) {
-                       $this->throwRedisException( $conn, $e );
-               }
-
-               return $count;
-       }
-
        /**
         * @return array
         */
        protected function doGetPeriodicTasks() {
-               if ( $this->daemonized ) {
-                       return array(); // managed in the runner loop
-               }
-               $periods = array( 300 ); // 5 min; delayed/stale jobs
-               if ( $this->claimTTL > 0 ) {
-                       $periods[] = ceil( $this->claimTTL / 2 ); // halved to avoid bad timing
-               }
-               $period = min( $periods );
-               $period = max( $period, 30 ); // sanity
-
-               return array(
-                       'recyclePruneAndUndelayJobs' => array(
-                               'callback' => array( $this, 'recyclePruneAndUndelayJobs' ),
-                               'period'   => $period,
-                       )
-               );
+               return array(); // managed in the runner loop
        }
 
        /**
index ef0f087..091e648 100644 (file)
  * @ingroup JobQueue
  */
 
+use Psr\Log\LoggerAwareInterface;
+use Psr\Log\LoggerInterface;
+
 /**
  * Job queue runner utility methods
  *
  * @ingroup JobQueue
  * @since 1.24
  */
-class JobRunner {
+class JobRunner implements LoggerAwareInterface {
        /** @var callable|null Debug output handler */
        protected $debug;
 
@@ -38,6 +41,28 @@ class JobRunner {
                $this->debug = $debug;
        }
 
+       /**
+        * @var LoggerInterface $logger
+        */
+       protected $logger;
+
+       /**
+        * @param LoggerInterface $logger
+        */
+       public function setLogger( LoggerInterface $logger ) {
+               $this->logger = $logger;
+       }
+
+       /**
+        * @param LoggerInterface $logger
+        */
+       public function __construct( LoggerInterface $logger = null ) {
+               if ( $logger === null ) {
+                       $logger = MWLoggerFactory::getInstance( 'runJobs' );
+               }
+               $this->setLogger( $logger );
+       }
+
        /**
         * Run jobs of the specified number/type for the specified time
         *
@@ -73,7 +98,9 @@ class JobRunner {
                // Handle any required periodic queue maintenance
                $count = $group->executeReadyPeriodicTasks();
                if ( $count > 0 ) {
-                       $this->runJobsLog( "Executed $count periodic queue task(s)." );
+                       $msg = "Executed $count periodic queue task(s).";
+                       $this->logger->debug( $msg );
+                       $this->debugCallback( $msg );
                }
 
                // Bail out if in read-only mode
@@ -132,7 +159,9 @@ class JobRunner {
                                        $backoffs = $this->syncBackoffDeltas( $backoffs, $backoffDeltas, $wait );
                                }
 
-                               $this->runJobsLog( $job->toString() . " STARTING" );
+                               $msg = $job->toString() . " STARTING";
+                               $this->logger->info( $msg );
+                               $this->debugCallback( $msg );
 
                                // Run the job...
                                $jobStartTime = microtime( true );
@@ -164,9 +193,13 @@ class JobRunner {
                                }
 
                                if ( $status === false ) {
-                                       $this->runJobsLog( $job->toString() . " t=$timeMs error={$error}" );
+                                       $msg = $job->toString() . " t=$timeMs error={$error}";
+                                       $this->logger->error( $msg );
+                                       $this->debugCallback( $msg );
                                } else {
-                                       $this->runJobsLog( $job->toString() . " t=$timeMs good" );
+                                       $msg = $job->toString() . " t=$timeMs good";
+                                       $this->logger->info( $msg );
+                                       $this->debugCallback( $msg );
                                }
 
                                $response['jobs'][] = array(
@@ -357,10 +390,9 @@ class JobRunner {
         * Log the job message
         * @param string $msg The message to log
         */
-       private function runJobsLog( $msg ) {
+       private function debugCallback( $msg ) {
                if ( $this->debug ) {
                        call_user_func_array( $this->debug, array( wfTimestamp( TS_DB ) . " $msg\n" ) );
                }
-               wfDebugLog( 'runJobs', $msg );
        }
 }
diff --git a/includes/jobqueue/jobs/RecentChangesUpdateJob.php b/includes/jobqueue/jobs/RecentChangesUpdateJob.php
new file mode 100644 (file)
index 0000000..236b4d4
--- /dev/null
@@ -0,0 +1,83 @@
+<?php
+/**
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * @file
+ * @author Aaron Schulz
+ */
+
+/**
+ * Job for pruning recent changes
+ *
+ * @ingroup JobQueue
+ * @since 1.25
+ */
+class RecentChangesUpdateJob extends Job {
+       function __construct( $title, $params ) {
+               parent::__construct( 'recentChangesUpdate', $title, $params );
+
+               if ( !isset( $params['type'] ) ) {
+                       throw new Exception( "Missing 'type' parameter." );
+               }
+
+               $this->removeDuplicates = true;
+       }
+
+       /**
+        * @return RecentChangesUpdateJob
+        */
+       final public static function newPurgeJob() {
+               return new self(
+                       SpecialPage::getTitleFor( 'Recentchanges' ), array( 'type' => 'purge' )
+               );
+       }
+
+       public function run() {
+               if ( $this->params['type'] === 'purge' ) {
+                       $this->purgeExpiredRows();
+               } else {
+                       throw new Exception( "Invalid 'type' parameter '{$this->params['type']}'." );
+               }
+
+               return true;
+       }
+
+       protected function purgeExpiredRows() {
+               global $wgRCMaxAge;
+
+               $lockKey = wfWikiID() . ':recentchanges-prune';
+
+               $dbw = wfGetDB( DB_MASTER );
+               if ( !$dbw->lock( $lockKey, __METHOD__, 1 ) ) {
+                       return; // already in progress
+               }
+
+               $cutoff = $dbw->timestamp( time() - $wgRCMaxAge );
+               do {
+                       $rcIds = $dbw->selectFieldValues( 'recentchanges',
+                               'rc_id',
+                               array( 'rc_timestamp < ' . $dbw->addQuotes( $cutoff ) ),
+                               __METHOD__,
+                               array( 'LIMIT' => 100 ) // avoid slave lag
+                       );
+                       if ( $rcIds ) {
+                               $dbw->delete( 'recentchanges', array( 'rc_id' => $rcIds ), __METHOD__ );
+                       }
+               } while ( $rcIds );
+
+               $dbw->unlock( $lockKey, __METHOD__ );
+       }
+}
diff --git a/includes/libs/MessageSpecifier.php b/includes/libs/MessageSpecifier.php
new file mode 100644 (file)
index 0000000..b417f29
--- /dev/null
@@ -0,0 +1,39 @@
+<?php
+/**
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * @file
+ */
+
+interface MessageSpecifier {
+       /**
+        * Returns the message key
+        *
+        * If a list of multiple possible keys was supplied to the constructor, this method may
+        * return any of these keys. After the message has been fetched, this method will return
+        * the key that was actually used to fetch the message.
+        *
+        * @return string
+        */
+       public function getKey();
+
+       /**
+        * Returns the message parameters
+        *
+        * @return array
+        */
+       public function getParams();
+}
diff --git a/includes/libs/StatusValue.php b/includes/libs/StatusValue.php
new file mode 100644 (file)
index 0000000..3c2dd40
--- /dev/null
@@ -0,0 +1,316 @@
+<?php
+/**
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * @file
+ */
+
+/**
+ * Generic operation result class
+ * Has warning/error list, boolean status and arbitrary value
+ *
+ * "Good" means the operation was completed with no warnings or errors.
+ *
+ * "OK" means the operation was partially or wholly completed.
+ *
+ * An operation which is not OK should have errors so that the user can be
+ * informed as to what went wrong. Calling the fatal() function sets an error
+ * message and simultaneously switches off the OK flag.
+ *
+ * The recommended pattern for Status objects is to return a StatusValue
+ * unconditionally, i.e. both on success and on failure -- so that the
+ * developer of the calling code is reminded that the function can fail, and
+ * so that a lack of error-handling will be explicit.
+ *
+ * The use of Message objects should be avoided when serializability is needed.
+ *
+ * @since 1.25
+ */
+class StatusValue {
+       /** @var bool */
+       protected $ok = true;
+       /** @var array */
+       protected $errors = array();
+
+       /** @var mixed */
+       public $value;
+       /** @var array Map of (key => bool) to indicate success of each part of batch operations */
+       public $success = array();
+       /** @var int Counter for batch operations */
+       public $successCount = 0;
+       /** @var int Counter for batch operations */
+       public $failCount = 0;
+
+       /**
+        * Factory function for fatal errors
+        *
+        * @param string|MessageSpecifier $message Message key or object
+        * @return Status
+        */
+       public static function newFatal( $message /*, parameters...*/ ) {
+               $params = func_get_args();
+               $result = new static();
+               call_user_func_array( array( &$result, 'fatal' ), $params );
+               return $result;
+       }
+
+       /**
+        * Factory function for good results
+        *
+        * @param mixed $value
+        * @return Status
+        */
+       public static function newGood( $value = null ) {
+               $result = new static();
+               $result->value = $value;
+               return $result;
+       }
+
+       /**
+        * Returns whether the operation completed and didn't have any error or
+        * warnings
+        *
+        * @return bool
+        */
+       public function isGood() {
+               return $this->ok && !$this->errors;
+       }
+
+       /**
+        * Returns whether the operation completed
+        *
+        * @return bool
+        */
+       public function isOK() {
+               return $this->ok;
+       }
+
+       /**
+        * @return mixed
+        */
+       public function getValue() {
+               return $this->value;
+       }
+
+       /**
+        * Get the list of errors
+        *
+        * Each error is a (message:string or MessageSpecifier,params:array) map
+        *
+        * @return array
+        */
+       public function getErrors() {
+               return $this->errors;
+       }
+
+       /**
+        * Change operation status
+        *
+        * @param bool $ok
+        */
+       public function setOK( $ok ) {
+               $this->ok = $ok;
+       }
+
+       /**
+        * Change operation resuklt
+        *
+        * @param bool $ok Whether the operation completed
+        * @param mixed $value
+        */
+       public function setResult( $ok, $value = null ) {
+               $this->ok = $ok;
+               $this->value = $value;
+       }
+
+       /**
+        * Add a new warning
+        *
+        * @param string|MessageSpecifier $message Message key or object
+        */
+       public function warning( $message /*, parameters... */ ) {
+               $this->errors[] = array(
+                       'type' => 'warning',
+                       'message' => $message,
+                       'params' => array_slice( func_get_args(), 1 )
+               );
+       }
+
+       /**
+        * Add an error, do not set fatal flag
+        * This can be used for non-fatal errors
+        *
+        * @param string|MessageSpecifier $message Message key or object
+        */
+       public function error( $message /*, parameters... */ ) {
+               $this->errors[] = array(
+                       'type' => 'error',
+                       'message' => $message,
+                       'params' => array_slice( func_get_args(), 1 )
+               );
+       }
+
+       /**
+        * Add an error and set OK to false, indicating that the operation
+        * as a whole was fatal
+        *
+        * @param string|MessageSpecifier $message Message key or object
+        */
+       public function fatal( $message /*, parameters... */ ) {
+               $this->errors[] = array(
+                       'type' => 'error',
+                       'message' => $message,
+                       'params' => array_slice( func_get_args(), 1 )
+               );
+               $this->ok = false;
+       }
+
+       /**
+        * Merge another status object into this one
+        *
+        * @param Status $other Other Status object
+        * @param bool $overwriteValue Whether to override the "value" member
+        */
+       public function merge( $other, $overwriteValue = false ) {
+               $this->errors = array_merge( $this->errors, $other->errors );
+               $this->ok = $this->ok && $other->ok;
+               if ( $overwriteValue ) {
+                       $this->value = $other->value;
+               }
+               $this->successCount += $other->successCount;
+               $this->failCount += $other->failCount;
+       }
+
+       /**
+        * Returns a list of status messages of the given type
+        *
+        * Each entry is a map of (message:string or MessageSpecifier,params:array))
+        *
+        * @param string $type
+        * @return array
+        */
+       public function getErrorsByType( $type ) {
+               $result = array();
+               foreach ( $this->errors as $error ) {
+                       if ( $error['type'] === $type ) {
+                               $result[] = $error;
+                       }
+               }
+
+               return $result;
+       }
+
+       /**
+        * Returns true if the specified message is present as a warning or error
+        *
+        * @param string|MessageSpecifier $message Message key or object to search for
+        *
+        * @return bool
+        */
+       public function hasMessage( $message ) {
+               if ( $message instanceof MessageSpecifier ) {
+                       $message = $message->getKey();
+               }
+               foreach ( $this->errors as $error ) {
+                       if ( $error['message'] instanceof MessageSpecifier
+                               && $error['message']->getKey() === $message
+                       ) {
+                               return true;
+                       } elseif ( $error['message'] === $message ) {
+                               return true;
+                       }
+               }
+
+               return false;
+       }
+
+       /**
+        * If the specified source message exists, replace it with the specified
+        * destination message, but keep the same parameters as in the original error.
+        *
+        * Note, due to the lack of tools for comparing IStatusMessage objects, this
+        * function will not work when using such an object as the search parameter.
+        *
+        * @param IStatusMessage|string $source Message key or object to search for
+        * @param IStatusMessage|string $dest Replacement message key or object
+        * @return bool Return true if the replacement was done, false otherwise.
+        */
+       public function replaceMessage( $source, $dest ) {
+               $replaced = false;
+
+               foreach ( $this->errors as $index => $error ) {
+                       if ( $error['message'] === $source ) {
+                               $this->errors[$index]['message'] = $dest;
+                               $replaced = true;
+                       }
+               }
+
+               return $replaced;
+       }
+
+       /**
+        * @return string
+        */
+       public function __toString() {
+               $status = $this->isOK() ? "OK" : "Error";
+               if ( count( $this->errors ) ) {
+                       $errorcount = "collected " . ( count( $this->errors ) ) . " error(s) on the way";
+               } else {
+                       $errorcount = "no errors detected";
+               }
+               if ( isset( $this->value ) ) {
+                       $valstr = gettype( $this->value ) . " value set";
+                       if ( is_object( $this->value ) ) {
+                               $valstr .= "\"" . get_class( $this->value ) . "\" instance";
+                       }
+               } else {
+                       $valstr = "no value set";
+               }
+               $out = sprintf( "<%s, %s, %s>",
+                       $status,
+                       $errorcount,
+                       $valstr
+               );
+               if ( count( $this->errors ) > 0 ) {
+                       $hdr = sprintf( "+-%'-4s-+-%'-25s-+-%'-40s-+\n", "", "", "" );
+                       $i = 1;
+                       $out .= "\n";
+                       $out .= $hdr;
+                       foreach ( $this->errors as $error ) {
+                               if ( $error['message'] instanceof MessageSpecifier ) {
+                                       $key = $error['message']->getKey();
+                                       $params = $error['message']->getParams();
+                               } elseif ( $error['params'] ) {
+                                       $key = $error['message'];
+                                       $params = $error['params'];
+                               } else {
+                                       $key = $error['message'];
+                                       $params = array();
+                               }
+
+                               $out .= sprintf( "| %4d | %-25.25s | %-40.40s |\n",
+                                       $i,
+                                       $key,
+                                       implode( " ", $params )
+                               );
+                               $i += 1;
+                       }
+                       $out .= $hdr;
+               }
+
+               return $out;
+       }
+}
index e8e73af..7246072 100644 (file)
@@ -1679,17 +1679,6 @@ class FormatMetadata extends ContextSource {
                        );
                }
 
-               $common = $file->getCommonMetaArray();
-
-               if ( $common !== false ) {
-                       foreach ( $common as $key => $value ) {
-                               $fileMetadata[$key] = array(
-                                       'value' => $value,
-                                       'source' => 'file-metadata',
-                               );
-                       }
-               }
-
                return $fileMetadata;
        }
 
index 6dd0453..787f21e 100644 (file)
@@ -57,7 +57,7 @@ abstract class ImageHandler extends MediaHandler {
                } elseif ( isset( $params['width'] ) ) {
                        $width = $params['width'];
                } else {
-                       throw new MWException( 'No width specified to ' . __METHOD__ );
+                       throw new MediaTransformInvalidParametersException( 'No width specified to ' . __METHOD__ );
                }
 
                # Removed for ProofreadPage
diff --git a/includes/media/MediaTransformInvalidParametersException.php b/includes/media/MediaTransformInvalidParametersException.php
new file mode 100644 (file)
index 0000000..15a2ca5
--- /dev/null
@@ -0,0 +1,26 @@
+<?php
+/**
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * @file
+ */
+
+/**
+ * MediaWiki exception thrown by some methods when the transform parameter array is invalid
+ *
+ * @ingroup Exception
+ */
+class MediaTransformInvalidParametersException extends MWException {}
index d879ca8..afc0f0a 100644 (file)
@@ -72,17 +72,16 @@ class APCBagOStuff extends BagOStuff {
         * @return bool
         * @throws MWException
         */
-       public function cas( $casToken, $key, $value, $exptime = 0 ) {
+       protected function cas( $casToken, $key, $value, $exptime = 0 ) {
                // APC's CAS functions only work on integers
                throw new MWException( "CAS is not implemented in " . __CLASS__ );
        }
 
        /**
         * @param string $key
-        * @param int $time
         * @return bool
         */
-       public function delete( $key, $time = 0 ) {
+       public function delete( $key ) {
                apc_delete( $key );
 
                return true;
@@ -90,12 +89,12 @@ class APCBagOStuff extends BagOStuff {
 
        /**
         * @param string $key
-        * @param Closure $callback Callback method to be executed
+        * @param callable $callback Callback method to be executed
         * @param int $exptime Either an interval in seconds or a unix timestamp for expiry
         * @param int $attempts The amount of times to attempt a merge in case of failure
         * @return bool Success
         */
-       public function merge( $key, Closure $callback, $exptime = 0, $attempts = 10 ) {
+       public function merge( $key, $callback, $exptime = 0, $attempts = 10 ) {
                return $this->mergeViaLock( $key, $callback, $exptime, $attempts );
        }
 
index 81c5625..2c10742 100644 (file)
@@ -83,9 +83,6 @@ abstract class BagOStuff implements LoggerAwareInterface {
                $this->debugMode = $bool;
        }
 
-       /* *** THE GUTS OF THE OPERATION *** */
-       /* Override these with functional things in subclasses */
-
        /**
         * Get an item with the given key. Returns false if it does not exist.
         * @param string $key
@@ -103,23 +100,12 @@ abstract class BagOStuff implements LoggerAwareInterface {
         */
        abstract public function set( $key, $value, $exptime = 0 );
 
-       /**
-        * Check and set an item.
-        * @param mixed $casToken
-        * @param string $key
-        * @param mixed $value
-        * @param int $exptime Either an interval in seconds or a unix timestamp for expiry
-        * @return bool Success
-        */
-       abstract public function cas( $casToken, $key, $value, $exptime = 0 );
-
        /**
         * Delete an item.
         * @param string $key
-        * @param int $time Amount of time to delay the operation (mostly memcached-specific)
         * @return bool True if the item was deleted or not found, false on failure
         */
-       abstract public function delete( $key, $time = 0 );
+       abstract public function delete( $key );
 
        /**
         * Merge changes into the existing cache value (possibly creating a new one).
@@ -127,12 +113,16 @@ abstract class BagOStuff implements LoggerAwareInterface {
         * and takes the arguments: (this BagOStuff object, cache key, current value).
         *
         * @param string $key
-        * @param Closure $callback Callback method to be executed
+        * @param callable $callback Callback method to be executed
         * @param int $exptime Either an interval in seconds or a unix timestamp for expiry
         * @param int $attempts The amount of times to attempt a merge in case of failure
         * @return bool Success
         */
-       public function merge( $key, Closure $callback, $exptime = 0, $attempts = 10 ) {
+       public function merge( $key, $callback, $exptime = 0, $attempts = 10 ) {
+               if ( !is_callable( $callback ) ) {
+                       throw new Exception( "Got invalid callback." );
+               }
+
                return $this->mergeViaCas( $key, $callback, $exptime, $attempts );
        }
 
@@ -140,16 +130,17 @@ abstract class BagOStuff implements LoggerAwareInterface {
         * @see BagOStuff::merge()
         *
         * @param string $key
-        * @param Closure $callback Callback method to be executed
+        * @param callable $callback Callback method to be executed
         * @param int $exptime Either an interval in seconds or a unix timestamp for expiry
         * @param int $attempts The amount of times to attempt a merge in case of failure
         * @return bool Success
         */
-       protected function mergeViaCas( $key, Closure $callback, $exptime = 0, $attempts = 10 ) {
+       protected function mergeViaCas( $key, $callback, $exptime = 0, $attempts = 10 ) {
                do {
                        $casToken = null; // passed by reference
-                       $currentValue = $this->get( $key, $casToken ); // get the old value
-                       $value = $callback( $this, $key, $currentValue ); // derive the new value
+                       $currentValue = $this->get( $key, $casToken );
+                       // Derive the new value from the old value
+                       $value = call_user_func( $callback, $this, $key, $currentValue );
 
                        if ( $value === false ) {
                                $success = true; // do nothing
@@ -165,22 +156,33 @@ abstract class BagOStuff implements LoggerAwareInterface {
                return $success;
        }
 
+       /**
+        * Check and set an item.
+        * @param mixed $casToken
+        * @param string $key
+        * @param mixed $value
+        * @param int $exptime Either an interval in seconds or a unix timestamp for expiry
+        * @return bool Success
+        */
+       abstract protected function cas( $casToken, $key, $value, $exptime = 0 );
+
        /**
         * @see BagOStuff::merge()
         *
         * @param string $key
-        * @param Closure $callback Callback method to be executed
+        * @param callable $callback Callback method to be executed
         * @param int $exptime Either an interval in seconds or a unix timestamp for expiry
         * @param int $attempts The amount of times to attempt a merge in case of failure
         * @return bool Success
         */
-       protected function mergeViaLock( $key, Closure $callback, $exptime = 0, $attempts = 10 ) {
+       protected function mergeViaLock( $key, $callback, $exptime = 0, $attempts = 10 ) {
                if ( !$this->lock( $key, 6 ) ) {
                        return false;
                }
 
-               $currentValue = $this->get( $key ); // get the old value
-               $value = $callback( $this, $key, $currentValue ); // derive the new value
+               $currentValue = $this->get( $key );
+               // Derive the new value from the old value
+               $value = call_user_func( $callback, $this, $key, $currentValue );
 
                if ( $value === false ) {
                        $success = true; // do nothing
index 9595b83..0fc65d9 100644 (file)
@@ -33,7 +33,7 @@ class EmptyBagOStuff extends BagOStuff {
         * @param mixed $casToken [optional]
         * @return bool
         */
-       function get( $key, &$casToken = null ) {
+       public function get( $key, &$casToken = null ) {
                return false;
        }
 
@@ -43,7 +43,7 @@ class EmptyBagOStuff extends BagOStuff {
         * @param int $exp
         * @return bool
         */
-       function set( $key, $value, $exp = 0 ) {
+       public function set( $key, $value, $exp = 0 ) {
                return true;
        }
 
@@ -54,27 +54,26 @@ class EmptyBagOStuff extends BagOStuff {
         * @param int $exp
         * @return bool
         */
-       function cas( $casToken, $key, $value, $exp = 0 ) {
+       protected function cas( $casToken, $key, $value, $exp = 0 ) {
                return true;
        }
 
        /**
         * @param string $key
-        * @param int $time
         * @return bool
         */
-       function delete( $key, $time = 0 ) {
+       public function delete( $key ) {
                return true;
        }
 
        /**
         * @param string $key
-        * @param Closure $callback Callback method to be executed
+        * @param callable $callback Callback method to be executed
         * @param int $exptime Either an interval in seconds or a unix timestamp for expiry
         * @param int $attempts The amount of times to attempt a merge in case of failure
         * @return bool Success
         */
-       public function merge( $key, Closure $callback, $exptime = 0, $attempts = 10 ) {
+       public function merge( $key, $callback, $exptime = 0, $attempts = 10 ) {
                return true;
        }
 }
index 6da1882..278a74e 100644 (file)
@@ -57,7 +57,7 @@ class HashBagOStuff extends BagOStuff {
         * @param mixed $casToken [optional]
         * @return bool|mixed
         */
-       function get( $key, &$casToken = null ) {
+       public function get( $key, &$casToken = null ) {
                if ( !isset( $this->bag[$key] ) ) {
                        return false;
                }
@@ -77,7 +77,7 @@ class HashBagOStuff extends BagOStuff {
         * @param int $exptime
         * @return bool
         */
-       function set( $key, $value, $exptime = 0 ) {
+       public function set( $key, $value, $exptime = 0 ) {
                $this->bag[$key] = array( $value, $this->convertExpiry( $exptime ) );
                return true;
        }
@@ -89,7 +89,7 @@ class HashBagOStuff extends BagOStuff {
         * @param int $exptime
         * @return bool
         */
-       function cas( $casToken, $key, $value, $exptime = 0 ) {
+       protected function cas( $casToken, $key, $value, $exptime = 0 ) {
                if ( $this->get( $key ) === $casToken ) {
                        return $this->set( $key, $value, $exptime );
                }
@@ -99,10 +99,9 @@ class HashBagOStuff extends BagOStuff {
 
        /**
         * @param string $key
-        * @param int $time
         * @return bool
         */
-       function delete( $key, $time = 0 ) {
+       function delete( $key ) {
                if ( !isset( $this->bag[$key] ) ) {
                        return false;
                }
index 6a98a8a..ac34570 100644 (file)
@@ -84,18 +84,17 @@ class MemcachedBagOStuff extends BagOStuff {
         * @param int $exptime
         * @return bool
         */
-       public function cas( $casToken, $key, $value, $exptime = 0 ) {
+       protected function cas( $casToken, $key, $value, $exptime = 0 ) {
                return $this->client->cas( $casToken, $this->encodeKey( $key ),
                        $value, $this->fixExpiry( $exptime ) );
        }
 
        /**
         * @param string $key
-        * @param int $time
         * @return bool
         */
-       public function delete( $key, $time = 0 ) {
-               return $this->client->delete( $this->encodeKey( $key ), $time );
+       public function delete( $key ) {
+               return $this->client->delete( $this->encodeKey( $key ) );
        }
 
        /**
index 4ead417..f2c4928 100644 (file)
@@ -145,19 +145,18 @@ class MemcachedPeclBagOStuff extends MemcachedBagOStuff {
         * @param int $exptime
         * @return bool
         */
-       public function cas( $casToken, $key, $value, $exptime = 0 ) {
+       protected function cas( $casToken, $key, $value, $exptime = 0 ) {
                $this->debugLog( "cas($key)" );
                return $this->checkResult( $key, parent::cas( $casToken, $key, $value, $exptime ) );
        }
 
        /**
         * @param string $key
-        * @param int $time
         * @return bool
         */
-       public function delete( $key, $time = 0 ) {
+       public function delete( $key ) {
                $this->debugLog( "delete($key)" );
-               $result = parent::delete( $key, $time );
+               $result = parent::delete( $key );
                if ( $result === false && $this->client->getResultCode() === Memcached::RES_NOTFOUND ) {
                        // "Not found" is counted as success in our interface
                        return true;
index dbaccd6..f9a8cfe 100644 (file)
@@ -84,7 +84,7 @@ class MultiWriteBagOStuff extends BagOStuff {
         * @return bool
         * @throws MWException
         */
-       public function cas( $casToken, $key, $value, $exptime = 0 ) {
+       protected function cas( $casToken, $key, $value, $exptime = 0 ) {
                throw new MWException( "CAS is not implemented in " . __CLASS__ );
        }
 
@@ -100,11 +100,10 @@ class MultiWriteBagOStuff extends BagOStuff {
 
        /**
         * @param string $key
-        * @param int $time
         * @return bool
         */
-       public function delete( $key, $time = 0 ) {
-               return $this->doWrite( 'delete', $key, $time );
+       public function delete( $key ) {
+               return $this->doWrite( 'delete', $key );
        }
 
        /**
@@ -164,12 +163,12 @@ class MultiWriteBagOStuff extends BagOStuff {
 
        /**
         * @param string $key
-        * @param Closure $callback Callback method to be executed
+        * @param callable $callback Callback method to be executed
         * @param int $exptime Either an interval in seconds or a unix timestamp for expiry
         * @param int $attempts The amount of times to attempt a merge in case of failure
         * @return bool Success
         */
-       public function merge( $key, Closure $callback, $exptime = 0, $attempts = 10 ) {
+       public function merge( $key, $callback, $exptime = 0, $attempts = 10 ) {
                return $this->doWrite( 'merge', $key, $callback, $exptime );
        }
 
index 40b40d1..24d2a22 100644 (file)
@@ -28,6 +28,9 @@
  * @ingroup Cache
  */
 class ObjectCacheSessionHandler {
+       /** @var array Map of (session ID => SHA-1 of the data) */
+       protected static $hashCache = array();
+
        /**
         * Install a session handler for the current web request
         */
@@ -51,8 +54,9 @@ class ObjectCacheSessionHandler {
         * Get the cache storage object to use for session storage
         * @return BagOStuff
         */
-       static function getCache() {
+       protected static function getCache() {
                global $wgSessionCacheType;
+
                return ObjectCache::getInstance( $wgSessionCacheType );
        }
 
@@ -62,10 +66,18 @@ class ObjectCacheSessionHandler {
         * @param string $id Session id
         * @return string Cache key
         */
-       static function getKey( $id ) {
+       protected static function getKey( $id ) {
                return wfMemcKey( 'session', $id );
        }
 
+       /**
+        * @param mixed $data
+        * @return string
+        */
+       protected static function getHash( $data ) {
+               return sha1( serialize( $data ) );
+       }
+
        /**
         * Callback when opening a session.
         *
@@ -95,10 +107,10 @@ class ObjectCacheSessionHandler {
         */
        static function read( $id ) {
                $data = self::getCache()->get( self::getKey( $id ) );
-               if ( $data === false ) {
-                       return '';
-               }
-               return $data;
+
+               self::$hashCache = array( $id => self::getHash( $data ) );
+
+               return ( $data === false ) ? '' : $data;
        }
 
        /**
@@ -110,7 +122,14 @@ class ObjectCacheSessionHandler {
         */
        static function write( $id, $data ) {
                global $wgObjectCacheSessionExpiry;
-               self::getCache()->set( self::getKey( $id ), $data, $wgObjectCacheSessionExpiry );
+
+               // Only issue a write if anything changed (PHP 5.6 already does this)
+               if ( !isset( self::$hashCache[$id] )
+                       || self::getHash( $data ) !== self::$hashCache[$id]
+               ) {
+                       self::getCache()->set( self::getKey( $id ), $data, $wgObjectCacheSessionExpiry );
+               }
+
                return true;
        }
 
@@ -122,6 +141,7 @@ class ObjectCacheSessionHandler {
         */
        static function destroy( $id ) {
                self::getCache()->delete( self::getKey( $id ) );
+
                return true;
        }
 
index fef7155..b1be9d8 100644 (file)
@@ -115,7 +115,7 @@ class RedisBagOStuff extends BagOStuff {
                return $result;
        }
 
-       public function cas( $casToken, $key, $value, $expiry = 0 ) {
+       protected function cas( $casToken, $key, $value, $expiry = 0 ) {
 
                list( $server, $conn ) = $this->getConnection( $key );
                if ( !$conn ) {
@@ -148,7 +148,7 @@ class RedisBagOStuff extends BagOStuff {
                return $result;
        }
 
-       public function delete( $key, $time = 0 ) {
+       public function delete( $key ) {
 
                list( $server, $conn ) = $this->getConnection( $key );
                if ( !$conn ) {
index 2a92bee..b9a9985 100644 (file)
@@ -405,7 +405,7 @@ class SqlBagOStuff extends BagOStuff {
         * @param int $exptime
         * @return bool
         */
-       public function cas( $casToken, $key, $value, $exptime = 0 ) {
+       protected function cas( $casToken, $key, $value, $exptime = 0 ) {
                list( $serverIndex, $tableName ) = $this->getTableByKey( $key );
                try {
                        $db = $this->getDB( $serverIndex );
@@ -447,10 +447,9 @@ class SqlBagOStuff extends BagOStuff {
 
        /**
         * @param string $key
-        * @param int $time
         * @return bool
         */
-       public function delete( $key, $time = 0 ) {
+       public function delete( $key ) {
                list( $serverIndex, $tableName ) = $this->getTableByKey( $key );
                try {
                        $db = $this->getDB( $serverIndex );
@@ -781,9 +780,3 @@ class SqlBagOStuff extends BagOStuff {
                }
        }
 }
-
-/**
- * Backwards compatibility alias
- */
-class MediaWikiBagOStuff extends SqlBagOStuff {
-}
index 78a512c..f59ed4e 100644 (file)
@@ -73,7 +73,7 @@ class WinCacheBagOStuff extends BagOStuff {
         * @param int $exptime Expiration time
         * @return bool
         */
-       public function cas( $casToken, $key, $value, $exptime = 0 ) {
+       protected function cas( $casToken, $key, $value, $exptime = 0 ) {
                return wincache_ucache_cas( $key, $casToken, serialize( $value ) );
        }
 
@@ -81,10 +81,9 @@ class WinCacheBagOStuff extends BagOStuff {
         * Remove a value from the WinCache object cache
         *
         * @param string $key Cache key
-        * @param int $time Not used in this implementation
         * @return bool
         */
-       public function delete( $key, $time = 0 ) {
+       public function delete( $key ) {
                wincache_ucache_delete( $key );
 
                return true;
index d7603b1..9be6624 100644 (file)
@@ -76,7 +76,7 @@ class XCacheBagOStuff extends BagOStuff {
         * @return bool
         * @throws MWException
         */
-       public function cas( $casToken, $key, $value, $exptime = 0 ) {
+       protected function cas( $casToken, $key, $value, $exptime = 0 ) {
                // Can't find any documentation on xcache cas
                throw new MWException( "CAS is not implemented in " . __CLASS__ );
        }
@@ -85,10 +85,9 @@ class XCacheBagOStuff extends BagOStuff {
         * Remove a value from the XCache object cache
         *
         * @param string $key Cache key
-        * @param int $time Not used in this implementation
         * @return bool
         */
-       public function delete( $key, $time = 0 ) {
+       public function delete( $key ) {
                xcache_unset( $key );
                return true;
        }
@@ -99,12 +98,12 @@ class XCacheBagOStuff extends BagOStuff {
         * provide a way to perform CAS-like functionality.
         *
         * @param string $key
-        * @param Closure $callback Callback method to be executed
+        * @param callable $callback Callback method to be executed
         * @param int $exptime Either an interval in seconds or a unix timestamp for expiry
         * @param int $attempts The amount of times to attempt a merge in case of failure
         * @return bool Success
         */
-       public function merge( $key, Closure $callback, $exptime = 0, $attempts = 10 ) {
+       public function merge( $key, $callback, $exptime = 0, $attempts = 10 ) {
                return $this->mergeViaLock( $key, $callback, $exptime, $attempts );
        }
 
index a0a3c69..2f900f9 100644 (file)
@@ -2200,11 +2200,8 @@ class WikiPage implements Page, IDBAccessObject {
                Hooks::run( 'ArticleEditUpdates', array( &$this, &$editInfo, $options['changed'] ) );
 
                if ( Hooks::run( 'ArticleEditUpdatesDeleteFromRecentchanges', array( &$this ) ) ) {
-                       if ( 0 == mt_rand( 0, 99 ) ) {
-                               // Flush old entries from the `recentchanges` table; we do this on
-                               // random requests so as to avoid an increase in writes for no good reason
-                               RecentChange::purgeExpiredChanges();
-                       }
+                       // Flush old entries from the `recentchanges` table
+                       JobQueueGroup::singleton()->push( RecentChangesUpdateJob::newPurgeJob() );
                }
 
                if ( !$this->exists() ) {
index 886bc5a..3637781 100644 (file)
@@ -34,6 +34,8 @@ class TransactionProfiler {
        protected $dbLockThreshold = 3.0;
        /** @var float Seconds */
        protected $eventThreshold = .25;
+       /** @var integer */
+       protected $affectedThreshold = 500;
 
        /** @var array transaction ID => (write start time, list of DBs involved) */
        protected $dbTrxHoldingLocks = array();
@@ -71,14 +73,20 @@ class TransactionProfiler {
         *
         * This assumes that all queries are synchronous (non-overlapping)
         *
-        * @param string $query Function name
+        * @param string $query Function name or generalized SQL
         * @param float $sTime Starting UNIX wall time
         * @param bool $isWrite Whether this is a write query
+        * @param integer $n Number of affected rows
         */
-       public function recordQueryCompletion( $query, $sTime, $isWrite = false ) {
+       public function recordQueryCompletion( $query, $sTime, $isWrite = false, $n = 0 ) {
                $eTime = microtime( true );
                $elapsed = ( $eTime - $sTime );
 
+               if ( $isWrite && $n > $this->affectedThreshold && PHP_SAPI !== 'cli' ) {
+                       wfDebugLog( 'DBPerformance',
+                               "Query affected $n rows:\n" . $query . "\n" . wfBacktrace( true ) );
+               }
+
                if ( !$this->dbTrxHoldingLocks ) {
                        // Short-circuit
                        return;
index 25222f6..a2dcd59 100644 (file)
@@ -116,7 +116,8 @@ class ExtensionProcessor implements Processor {
                $this->extractConfig( $info );
                $this->extractHooks( $info );
                $dir = dirname( $path );
-               $this->extractMessageSettings( $dir, $info );
+               $this->extractExtensionMessagesFiles( $dir, $info );
+               $this->extractMessagesDirs( $dir, $info );
                $this->extractNamespaces( $info );
                $this->extractResourceLoaderModules( $dir, $info );
                if ( isset( $info['callback'] ) ) {
@@ -184,16 +185,35 @@ class ExtensionProcessor implements Processor {
        }
 
        protected function extractResourceLoaderModules( $dir, array $info ) {
+               $defaultPaths = isset( $info['ResourceFileModulePaths'] )
+                       ? $info['ResourceFileModulePaths']
+                       : false;
+               if ( isset( $defaultPaths['localBasePath'] ) ) {
+                       $defaultPaths['localBasePath'] = "$dir/{$defaultPaths['localBasePath']}";
+               }
+
                if ( isset( $info['ResourceModules'] ) ) {
                        foreach ( $info['ResourceModules'] as $name => $data ) {
                                if ( isset( $data['localBasePath'] ) ) {
                                        $data['localBasePath'] = "$dir/{$data['localBasePath']}";
                                }
+                               if ( $defaultPaths ) {
+                                       $data += $defaultPaths;
+                               }
                                $this->globals['wgResourceModules'][$name] = $data;
                        }
                }
        }
 
+       protected function extractExtensionMessagesFiles( $dir, array $info ) {
+               if ( isset( $info['ExtensionMessagesFiles'] ) ) {
+                       $this->globals["wgExtensionMessagesFiles"] += array_map( function( $file ) use ( $dir ) {
+                               return "$dir/$file";
+                       }, $info['ExtensionMessagesFiles'] );
+                       $this->processed[] = 'ExtensionMessagesFiles';
+               }
+       }
+
        /**
         * Set message-related settings, which need to be expanded to use
         * absolute paths
@@ -201,14 +221,14 @@ class ExtensionProcessor implements Processor {
         * @param string $dir
         * @param array $info
         */
-       protected function extractMessageSettings( $dir, array $info ) {
-               foreach ( array( 'ExtensionMessagesFiles', 'MessagesDirs' ) as $key ) {
-                       if ( isset( $info[$key] ) ) {
-                               $this->globals["wg$key"] += array_map( function( $file ) use ( $dir ) {
-                                       return "$dir/$file";
-                               }, $info[$key] );
-                               $this->processed[] = $key;
+       protected function extractMessagesDirs( $dir, array $info ) {
+               if ( isset( $info['MessagesDirs'] ) ) {
+                       foreach ( $info['MessagesDirs'] as $name => $files ) {
+                               foreach ( (array)$files as $file ) {
+                                       $this->globals["wgMessagesDirs"][$name][] = "$dir/$file";
+                               }
                        }
+                       $this->processed[] = 'MessagesDirs';
                }
        }
 
index 44855d8..8541e31 100644 (file)
@@ -96,6 +96,9 @@ class ExtensionRegistry {
                        foreach ( $this->queued as $path => $mtime ) {
                                $json = file_get_contents( $path );
                                $info = json_decode( $json, /* $assoc = */ true );
+                               if ( !is_array( $info ) ) {
+                                       throw new Exception( "$path is not a valid JSON file." );
+                               }
                                $autoload = $this->processAutoLoader( dirname( $path ), $info );
                                // Set up the autoloader now so custom processors will work
                                $GLOBALS['wgAutoloadClasses'] += $autoload;
@@ -232,29 +235,4 @@ class ExtensionRegistry {
                        return array();
                }
        }
-
-       /**
-        * @param string $filename absolute path to the JSON file
-        * @param int $mtime modified time of the file
-        * @return array
-        */
-       protected function loadInfoFromFile( $filename, $mtime ) {
-               $key = wfMemcKey( 'registry', md5( $filename ) );
-               $cached = $this->cache->get( $key );
-               if ( isset( $cached['mtime'] ) && $cached['mtime'] === $mtime ) {
-                       return $cached['info'];
-               }
-
-               $contents = file_get_contents( $filename );
-               $json = json_decode( $contents, /* $assoc = */ true );
-               if ( is_array( $json ) ) {
-                       $this->cache->set( $key, array( 'mtime' => $mtime, 'info' => $json ) );
-               } else {
-                       // Don't throw an error here, but don't cache it either.
-                       // @todo log somewhere?
-                       $json = array();
-               }
-
-               return $json;
-       }
 }
index 15bb13f..1922999 100644 (file)
@@ -35,6 +35,9 @@ class ResourceLoader {
        /** @var bool */
        protected static $debugMode = null;
 
+       /** @var array */
+       private static $lessVars = null;
+
        /**
         * Module name/ResourceLoaderModule object pairs
         * @var array
@@ -1557,9 +1560,13 @@ class ResourceLoader {
         * @return array Map of variable names to string CSS values.
         */
        public static function getLessVars( Config $config ) {
-               $lessVars = $config->get( 'ResourceLoaderLESSVars' );
-               // Sort by key to ensure consistent hashing for cache lookups.
-               ksort( $lessVars );
-               return $lessVars;
+               if ( !self::$lessVars ) {
+                       $lessVars = $config->get( 'ResourceLoaderLESSVars' );
+                       Hooks::run( 'ResourceLoaderGetLessVars', array( &$lessVars ) );
+                       // Sort by key to ensure consistent hashing for cache lookups.
+                       ksort( $lessVars );
+                       self::$lessVars = $lessVars;
+               }
+               return self::$lessVars;
        }
 }
index 0e43f65..6788c6f 100644 (file)
@@ -308,7 +308,7 @@ class ResourceLoaderImage {
                $svg = $this->massageSvgPathdata( $svg );
 
                if ( $wgSVGConverter === 'rsvg' ) {
-                       $command = 'rsvg-convert'; // Should be just 'rsvg'? T76476
+                       $command = 'rsvg-convert';
                        if ( $wgSVGConverterPath ) {
                                $command = wfEscapeShellArg( "$wgSVGConverterPath/" ) . $command;
                        }
index 7315538..4a0fff8 100644 (file)
@@ -137,7 +137,7 @@ class RevDelRevisionList extends RevDelList {
        public function doPostCommitUpdates() {
                $this->title->purgeSquid();
                // Extensions that require referencing previous revisions may need this
-               Hooks::run( 'ArticleRevisionVisibilitySet', array( &$this->title ) );
+               Hooks::run( 'ArticleRevisionVisibilitySet', array( $this->title, $this->ids ) );
                return Status::newGood();
        }
 }
index 2062da8..97b7038 100644 (file)
@@ -36,9 +36,7 @@ class SkinApiTemplate extends BaseTemplate {
                $this->html( 'headelement' ) ?>
 
                <div class="mw-body" role="main">
-                       <h1 class="firstHeading">
-                               <span dir="auto"><?php $this->html( 'title' ) ?></span>
-                       </h1>
+                       <h1 class="firstHeading"><?php $this->html( 'title' ) ?></h1>
                        <div class="mw-body-content">
                                <?php $this->html( 'bodytext' ) ?>
                        </div>
index 6749bb0..00e56c1 100644 (file)
@@ -39,11 +39,6 @@ class SpecialProtectedpages extends SpecialPage {
                $this->outputHeader();
                $this->getOutput()->addModuleStyles( 'mediawiki.special' );
 
-               // Purge expired entries on one in every 10 queries
-               if ( !mt_rand( 0, 10 ) ) {
-                       Title::purgeExpiredRestrictions();
-               }
-
                $request = $this->getRequest();
                $type = $request->getVal( $this->IdType );
                $level = $request->getVal( $this->IdLevel );
@@ -495,7 +490,7 @@ class ProtectedPagesPager extends TablePager {
        function getQueryInfo() {
                $conds = $this->mConds;
                $conds[] = 'pr_expiry > ' . $this->mDb->addQuotes( $this->mDb->timestamp() ) .
-                       'OR pr_expiry IS NULL';
+                       ' OR pr_expiry IS NULL';
                $conds[] = 'page_id=pr_page';
                $conds[] = 'pr_type=' . $this->mDb->addQuotes( $this->type );
 
index d25c2c8..dd9198c 100644 (file)
@@ -38,11 +38,6 @@ class SpecialProtectedtitles extends SpecialPage {
                $this->setHeaders();
                $this->outputHeader();
 
-               // Purge expired entries on one in every 10 queries
-               if ( !mt_rand( 0, 10 ) ) {
-                       Title::purgeExpiredRestrictions();
-               }
-
                $request = $this->getRequest();
                $type = $request->getVal( $this->IdType );
                $level = $request->getVal( $this->IdLevel );
@@ -252,7 +247,8 @@ class ProtectedTitlesPager extends AlphabeticPager {
         */
        function getQueryInfo() {
                $conds = $this->mConds;
-               $conds[] = 'pt_expiry>' . $this->mDb->addQuotes( $this->mDb->timestamp() );
+               $conds[] = 'pt_expiry > ' . $this->mDb->addQuotes( $this->mDb->timestamp() ) .
+                       ' OR pt_expiry IS NULL';
                if ( $this->level ) {
                        $conds['pt_create_perm'] = $this->level;
                }
index d4a06eb..1bafc61 100644 (file)
@@ -88,7 +88,7 @@ class SpecialRunJobs extends UnlistedSpecialPage {
 
                // Do all of the specified tasks...
                if ( in_array( 'jobs', explode( '|', $params['tasks'] ) ) ) {
-                       $runner = new JobRunner();
+                       $runner = new JobRunner( MWLoggerFactory::getInstance( 'runJobs' ) );
                        $response = $runner->run( array(
                                'type'     => $params['type'],
                                'maxJobs'  => $params['maxjobs'] ? $params['maxjobs'] : 1,
index b762728..ff263b6 100644 (file)
@@ -31,6 +31,10 @@ class SpecialTags extends SpecialPage {
         * @var array List of defined tags
         */
        public $definedTags;
+       /**
+        * @var array List of active tags
+        */
+       public $activeTags;
 
        function __construct() {
                parent::__construct( 'Tags' );
@@ -40,33 +44,108 @@ class SpecialTags extends SpecialPage {
                $this->setHeaders();
                $this->outputHeader();
 
+               $request = $this->getRequest();
+               switch ( $par ) {
+                       case 'delete':
+                               $this->showDeleteTagForm( $request->getVal( 'tag' ) );
+                               break;
+                       case 'activate':
+                               $this->showActivateDeactivateForm( $request->getVal( 'tag' ), true );
+                               break;
+                       case 'deactivate':
+                               $this->showActivateDeactivateForm( $request->getVal( 'tag' ), false );
+                               break;
+                       case 'create':
+                               // fall through, thanks to HTMLForm's logic
+                       default:
+                               $this->showTagList();
+                               break;
+               }
+       }
+
+       function showTagList() {
                $out = $this->getOutput();
                $out->setPageTitle( $this->msg( 'tags-title' ) );
                $out->wrapWikiMsg( "<div class='mw-tags-intro'>\n$1\n</div>", 'tags-intro' );
 
+               $user = $this->getUser();
+
+               // Show form to create a tag
+               if ( $user->isAllowed( 'managechangetags' ) ) {
+                       $fields = array(
+                               'Tag' => array(
+                                       'type' => 'text',
+                                       'label' => $this->msg( 'tags-create-tag-name' )->plain(),
+                                       'required' => true,
+                               ),
+                               'Reason' => array(
+                                       'type' => 'text',
+                                       'label' => $this->msg( 'tags-create-reason' )->plain(),
+                                       'size' => 50,
+                               ),
+                               'IgnoreWarnings' => array(
+                                       'type' => 'hidden',
+                               ),
+                       );
+
+                       $form = new HTMLForm( $fields, $this->getContext() );
+                       $form->setAction( $this->getPageTitle( 'create' )->getLocalURL() );
+                       $form->setWrapperLegendMsg( 'tags-create-heading' );
+                       $form->setHeaderText( $this->msg( 'tags-create-explanation' )->plain() );
+                       $form->setSubmitCallback( array( $this, 'processCreateTagForm' ) );
+                       $form->setSubmitTextMsg( 'tags-create-submit' );
+                       $form->show();
+
+                       // If processCreateTagForm generated a redirect, there's no point
+                       // continuing with this, as the user is just going to end up getting sent
+                       // somewhere else. Additionally, if we keep going here, we end up
+                       // populating the memcache of tag data (see ChangeTags::listDefinedTags)
+                       // with out-of-date data from the slave, because the slave hasn't caught
+                       // up to the fact that a new tag has been created as part of an implicit,
+                       // as yet uncommitted transaction on master.
+                       if ( $out->getRedirect() !== '' ) {
+                               return;
+                       }
+               }
+
+               // Whether to show the "Actions" column in the tag list
+               // If any actions added in the future require other user rights, add those
+               // rights here
+               $showActions = $user->isAllowed( 'managechangetags' );
+
                // Write the headers
                $html = Xml::tags( 'tr', null, Xml::tags( 'th', null, $this->msg( 'tags-tag' )->parse() ) .
                        Xml::tags( 'th', null, $this->msg( 'tags-display-header' )->parse() ) .
                        Xml::tags( 'th', null, $this->msg( 'tags-description-header' )->parse() ) .
+                       Xml::tags( 'th', null, $this->msg( 'tags-source-header' )->parse() ) .
                        Xml::tags( 'th', null, $this->msg( 'tags-active-header' )->parse() ) .
-                       Xml::tags( 'th', null, $this->msg( 'tags-hitcount-header' )->parse() )
+                       Xml::tags( 'th', null, $this->msg( 'tags-hitcount-header' )->parse() ) .
+                       ( $showActions ?
+                               Xml::tags( 'th', array( 'class' => 'unsortable' ),
+                                       $this->msg( 'tags-actions-header' )->parse() ) :
+                               '' )
                );
 
                // Used in #doTagRow()
-               $this->definedTags = array_fill_keys( ChangeTags::listDefinedTags(), true );
+               $this->explicitlyDefinedTags = array_fill_keys(
+                       ChangeTags::listExplicitlyDefinedTags(), true );
+               $this->extensionDefinedTags = array_fill_keys(
+                       ChangeTags::listExtensionDefinedTags(), true );
+               $this->extensionActivatedTags = array_fill_keys(
+                       ChangeTags::listExtensionActivatedTags(), true );
 
                foreach ( ChangeTags::tagUsageStatistics() as $tag => $hitcount ) {
-                       $html .= $this->doTagRow( $tag, $hitcount );
+                       $html .= $this->doTagRow( $tag, $hitcount, $showActions );
                }
 
                $out->addHTML( Xml::tags(
                        'table',
-                       array( 'class' => 'wikitable sortable mw-tags-table' ),
+                       array( 'class' => 'mw-datatable sortable mw-tags-table' ),
                        $html
                ) );
        }
 
-       function doTagRow( $tag, $hitcount ) {
+       function doTagRow( $tag, $hitcount, $showActions ) {
                $user = $this->getUser();
                $newRow = '';
                $newRow .= Xml::tags( 'td', null, Xml::element( 'code', null, $tag ) );
@@ -94,9 +173,23 @@ class SpecialTags extends SpecialPage {
                }
                $newRow .= Xml::tags( 'td', null, $desc );
 
-               $active = isset( $this->definedTags[$tag] ) ? 'tags-active-yes' : 'tags-active-no';
-               $active = $this->msg( $active )->escaped();
-               $newRow .= Xml::tags( 'td', null, $active );
+               $sourceMsgs = array();
+               $isExtension = isset( $this->extensionDefinedTags[$tag] );
+               $isExplicit = isset( $this->explicitlyDefinedTags[$tag] );
+               if ( $isExtension ) {
+                       $sourceMsgs[] = $this->msg( 'tags-source-extension' )->escaped();
+               }
+               if ( $isExplicit ) {
+                       $sourceMsgs[] = $this->msg( 'tags-source-manual' )->escaped();
+               }
+               if ( !$sourceMsgs ) {
+                       $sourceMsgs[] = $this->msg( 'tags-source-none' )->escaped();
+               }
+               $newRow .= Xml::tags( 'td', null, implode( Xml::element( 'br' ), $sourceMsgs ) );
+
+               $isActive = $isExplicit || isset( $this->extensionActivatedTags[$tag] );
+               $activeMsg = ( $isActive ? 'tags-active-yes' : 'tags-active-no' );
+               $newRow .= Xml::tags( 'td', null, $this->msg( $activeMsg )->escaped() );
 
                $hitcountLabel = $this->msg( 'tags-hitcount' )->numParams( $hitcount )->escaped();
                $hitcountLink = Linker::link(
@@ -109,9 +202,228 @@ class SpecialTags extends SpecialPage {
                // add raw $hitcount for sorting, because tags-hitcount contains numbers and letters
                $newRow .= Xml::tags( 'td', array( 'data-sort-value' => $hitcount ), $hitcountLink );
 
+               // actions
+               $actionLinks = array();
+               if ( $showActions ) {
+                       // delete
+                       if ( ChangeTags::canDeleteTag( $tag, $user )->isOK() ) {
+                               $actionLinks[] = Linker::linkKnown( $this->getPageTitle( 'delete' ),
+                                       $this->msg( 'tags-delete' )->escaped(),
+                                       array(),
+                                       array( 'tag' => $tag ) );
+                       }
+
+                       // activate
+                       if ( ChangeTags::canActivateTag( $tag, $user )->isOK() ) {
+                               $actionLinks[] = Linker::linkKnown( $this->getPageTitle( 'activate' ),
+                                       $this->msg( 'tags-activate' )->escaped(),
+                                       array(),
+                                       array( 'tag' => $tag ) );
+                       }
+
+                       // deactivate
+                       if ( ChangeTags::canDeactivateTag( $tag, $user )->isOK() ) {
+                               $actionLinks[] = Linker::linkKnown( $this->getPageTitle( 'deactivate' ),
+                                       $this->msg( 'tags-deactivate' )->escaped(),
+                                       array(),
+                                       array( 'tag' => $tag ) );
+                       }
+
+                       $newRow .= Xml::tags( 'td', null, $this->getLanguage()->pipeList( $actionLinks ) );
+               }
+
                return Xml::tags( 'tr', null, $newRow ) . "\n";
        }
 
+       public function processCreateTagForm( array $data, HTMLForm $form ) {
+               $context = $form->getContext();
+               $out = $context->getOutput();
+
+               $tag = trim( strval( $data['Tag'] ) );
+               $ignoreWarnings = isset( $data['IgnoreWarnings'] ) && $data['IgnoreWarnings'] === '1';
+               $status = ChangeTags::createTagWithChecks( $tag, $data['Reason'],
+                       $context->getUser(), $ignoreWarnings );
+
+               if ( $status->isGood() ) {
+                       $out->redirect( $this->getPageTitle()->getLocalURL() );
+                       return true;
+               } elseif ( $status->isOK() ) {
+                       // we have some warnings, so we show a confirmation form
+                       $fields = array(
+                               'Tag' => array(
+                                       'type' => 'hidden',
+                                       'default' => $data['Tag'],
+                               ),
+                               'Reason' => array(
+                                       'type' => 'hidden',
+                                       'default' => $data['Reason'],
+                               ),
+                               'IgnoreWarnings' => array(
+                                       'type' => 'hidden',
+                                       'default' => '1',
+                               ),
+                       );
+
+                       // fool HTMLForm into thinking the form hasn't been submitted yet. Otherwise
+                       // we get into an infinite loop!
+                       $context->getRequest()->unsetVal( 'wpEditToken' );
+
+                       $headerText = $this->msg( 'tags-create-warnings-above', $tag,
+                               count( $status->getWarningsArray() ) )->parseAsBlock() .
+                               $out->parse( $status->getWikitext() ) .
+                               $this->msg( 'tags-create-warnings-below' )->parseAsBlock();
+
+                       $subform = new HTMLForm( $fields, $this->getContext() );
+                       $subform->setAction( $this->getPageTitle( 'create' )->getLocalURL() );
+                       $subform->setWrapperLegendMsg( 'tags-create-heading' );
+                       $subform->setHeaderText( $headerText );
+                       $subform->setSubmitCallback( array( $this, 'processCreateTagForm' ) );
+                       $subform->setSubmitTextMsg( 'htmlform-yes' );
+                       $subform->show();
+
+                       $out->addBacklinkSubtitle( $this->getPageTitle() );
+                       return true;
+               } else {
+                       $out->addWikiText( "<div class=\"error\">\n" . $status->getWikitext() .
+                               "\n</div>" );
+                       return false;
+               }
+       }
+
+       protected function showDeleteTagForm( $tag ) {
+               $user = $this->getUser();
+               if ( !$user->isAllowed( 'managechangetags' ) ) {
+                       throw new PermissionsError( 'managechangetags' );
+               }
+
+               $out = $this->getOutput();
+               $out->setPageTitle( $this->msg( 'tags-delete-title' ) );
+               $out->addBacklinkSubtitle( $this->getPageTitle() );
+
+               // is the tag actually able to be deleted?
+               $canDeleteResult = ChangeTags::canDeleteTag( $tag, $user );
+               if ( !$canDeleteResult->isGood() ) {
+                       $out->addWikiText( "<div class=\"error\">\n" . $canDeleteResult->getWikiText() .
+                               "\n</div>" );
+                       if ( !$canDeleteResult->isOK() ) {
+                               return;
+                       }
+               }
+
+               $preText = $this->msg( 'tags-delete-explanation-initial', $tag )->parseAsBlock();
+               $tagUsage = ChangeTags::tagUsageStatistics();
+               if ( $tagUsage[$tag] > 0 ) {
+                       $preText .= $this->msg( 'tags-delete-explanation-in-use', $tag,
+                               $tagUsage[$tag] )->parseAsBlock();
+               }
+               $preText .= $this->msg( 'tags-delete-explanation-warning', $tag )->parseAsBlock();
+
+               // see if the tag is in use
+               $this->extensionActivatedTags = array_fill_keys(
+                       ChangeTags::listExtensionActivatedTags(), true );
+               if ( isset( $this->extensionActivatedTags[$tag] ) ) {
+                       $preText .= $this->msg( 'tags-delete-explanation-active', $tag )->parseAsBlock();
+               }
+
+               $fields = array();
+               $fields['Reason'] = array(
+                       'type' => 'text',
+                       'label' => $this->msg( 'tags-delete-reason' )->plain(),
+                       'size' => 50,
+               );
+               $fields['HiddenTag'] = array(
+                       'type' => 'hidden',
+                       'name' => 'tag',
+                       'default' => $tag,
+                       'required' => true,
+               );
+
+               $form = new HTMLForm( $fields, $this->getContext() );
+               $form->setAction( $this->getPageTitle( 'delete' )->getLocalURL() );
+               $form->tagAction = 'delete'; // custom property on HTMLForm object
+               $form->setSubmitCallback( array( $this, 'processTagForm' ) );
+               $form->setSubmitTextMsg( 'tags-delete-submit' );
+               $form->setSubmitDestructive(); // nasty!
+               $form->addPreText( $preText );
+               $form->show();
+       }
+
+       protected function showActivateDeactivateForm( $tag, $activate ) {
+               $actionStr = $activate ? 'activate' : 'deactivate';
+
+               $user = $this->getUser();
+               if ( !$user->isAllowed( 'managechangetags' ) ) {
+                       throw new PermissionsError( 'managechangetags' );
+               }
+
+               $out = $this->getOutput();
+               // tags-activate-title, tags-deactivate-title
+               $out->setPageTitle( $this->msg( "tags-$actionStr-title" ) );
+               $out->addBacklinkSubtitle( $this->getPageTitle() );
+
+               // is it possible to do this?
+               $func = $activate ? 'canActivateTag' : 'canDeactivateTag';
+               $result = ChangeTags::$func( $tag, $user );
+               if ( !$result->isGood() ) {
+                       $out->wrapWikiMsg( "<div class=\"error\">\n$1" . $result->getWikiText() .
+                               "\n</div>" );
+                       if ( !$result->isOK() ) {
+                               return;
+                       }
+               }
+
+               // tags-activate-question, tags-deactivate-question
+               $preText = $this->msg( "tags-$actionStr-question", $tag )->parseAsBlock();
+
+               $fields = array();
+               // tags-activate-reason, tags-deactivate-reason
+               $fields['Reason'] = array(
+                       'type' => 'text',
+                       'label' => $this->msg( "tags-$actionStr-reason" )->plain(),
+                       'size' => 50,
+               );
+               $fields['HiddenTag'] = array(
+                       'type' => 'hidden',
+                       'name' => 'tag',
+                       'default' => $tag,
+                       'required' => true,
+               );
+
+               $form = new HTMLForm( $fields, $this->getContext() );
+               $form->setAction( $this->getPageTitle( $actionStr )->getLocalURL() );
+               $form->tagAction = $actionStr;
+               $form->setSubmitCallback( array( $this, 'processTagForm' ) );
+               // tags-activate-submit, tags-deactivate-submit
+               $form->setSubmitTextMsg( "tags-$actionStr-submit" );
+               $form->addPreText( $preText );
+               $form->show();
+       }
+
+       public function processTagForm( array $data, HTMLForm $form ) {
+               $context = $form->getContext();
+               $out = $context->getOutput();
+
+               $tag = $data['HiddenTag'];
+               $status = call_user_func( array( 'ChangeTags', "{$form->tagAction}TagWithChecks" ),
+                       $tag, $data['Reason'], $context->getUser(), true );
+
+               if ( $status->isGood() ) {
+                       $out->redirect( $this->getPageTitle()->getLocalURL() );
+                       return true;
+               } elseif ( $status->isOK() && $form->tagAction === 'delete' ) {
+                       // deletion succeeded, but hooks raised a warning
+                       $out->addWikiText( $this->msg( 'tags-delete-warnings-after-delete', $tag,
+                               count( $status->getWarningsArray() ) )->text() . "\n" .
+                               $status->getWikitext() );
+                       $out->addReturnTo( $this->getPageTitle() );
+                       return true;
+               } else {
+                       $out->addWikiText( "<div class=\"error\">\n" . $status->getWikitext() .
+                               "\n</div>" );
+                       return false;
+               }
+       }
+
        protected function getGroupName() {
                return 'changes';
        }
index 3bf75a0..a5edcb0 100644 (file)
@@ -218,7 +218,7 @@ class UserrightsPage extends SpecialPage {
        /**
         * Save user groups changes in the database.
         *
-        * @param User $user
+        * @param User|UserRightsProxy $user
         * @param array $add Array of groups to add
         * @param array $remove Array of groups to remove
         * @param string $reason Reason for group change
@@ -228,7 +228,7 @@ class UserrightsPage extends SpecialPage {
                global $wgAuth;
 
                // Validate input set...
-               $isself = $user->equals( $this->getUser() );
+               $isself = $user->getName() == $this->getUser()->getName();
                $groups = $user->getGroups();
                $changeable = $this->changeableGroups();
                $addable = array_merge( $changeable['add'], $isself ? $changeable['add-self'] : array() );
index bbc111f..28be790 100644 (file)
@@ -177,7 +177,7 @@ class SpecialWhatLinksHere extends IncludableSpecialPage {
                        );
                        return $dbr->select(
                                array( 'page', 'temp_backlink_range' => "($subQuery)" ),
-                               array( 'page_id', 'page_namespace', 'page_title', 'rd_from' ),
+                               array( 'page_id', 'page_namespace', 'page_title', 'rd_from', 'page_is_redirect' ),
                                array(),
                                __CLASS__ . '::showIndirectLinks',
                                array( 'ORDER BY' => 'page_id', 'LIMIT' => $queryLimit ),
@@ -321,7 +321,7 @@ class SpecialWhatLinksHere extends IncludableSpecialPage {
                $link = Linker::linkKnown(
                        $nt,
                        null,
-                       array(),
+                       $row->page_is_redirect ? array( 'class' => 'mw-redirect' ) : array(),
                        $query
                );
 
index fbd4f6d..d203c0f 100644 (file)
@@ -3172,9 +3172,7 @@ class Language {
                        return;
                }
                $this->mMagicHookDone = true;
-               wfProfileIn( 'LanguageGetMagic' );
                Hooks::run( 'LanguageGetMagic', array( &$this->mMagicExtensions, $this->getCode() ) );
-               wfProfileOut( 'LanguageGetMagic' );
        }
 
        /**
index 2ec13d6..18f1eef 100644 (file)
@@ -11,7 +11,8 @@
                        "Spacebirdy",
                        "Tsepelcory",
                        "Wōdenhelm",
-                       "아라"
+                       "아라",
+                       "Dpk"
                ]
        },
        "tog-underline": "Mearc under hlencan:",
        "databaseerror": "Cȳþþuhordes wōh",
        "databaseerror-error": "Wōg: $1",
        "laggedslavemode": "'''Warnung:''' Wēnunga næbbe se tramet nīwlīca nīwunga.",
+       "readonly": "Ġifhord locen",
        "enterlockreason": "Wrīt race þǣre forwiernunge and apinsunge þæs tīman on þǣm bēo sēo forwiernung forlǣten",
        "missingarticle-rev": "(nīwung#: $1)",
        "internalerror": "Inweard wōh",
        "acct_creation_throttle_hit": "Nēosiende tō þissum wici, þe þīnne IP-Stōwe brȳcþ, hæfþ gesett {{PLURAL:$1|1 hordcleofan|$1 hordcleofan}} in þǣm læsten dæge. Þu ne canst settan ǣnige māran. Þǣrfram ne cunnon Nēosiende, þe þisne IP-Stōwe brȳcþ, settan ǣnige hordcleofan māran on þisse handhwīle.",
        "accountcreated": "Scōp reccinge",
        "loginlanguagelabel": "Sprǣc: $1",
+       "pt-login": "Inġelōgian",
+       "pt-login-button": "Inġelōgian",
+       "pt-createaccount": "Ūtġelōgian",
+       "pt-userlogout": "Ūtġelōgian",
+       "changepassword": "Andwendan þafungword",
        "oldpassword": "Eald þafungword:",
        "newpassword": "Nīwe þafungword:",
        "retypenew": "Wrīt nīwe þafungword eft:",
        "resetpass-submit-loggedin": "Andwendan þafungword",
        "resetpass-submit-cancel": "Undōn",
+       "passwordreset-legend": "Settan þafungword eft",
        "passwordreset-username": "Brūcendnama:",
        "bold_sample": "Þicce traht",
        "bold_tip": "Þicce traht",
        "cur": "nū",
        "next": "nīehst",
        "last": "ǣr",
+       "page_first": "ærost",
+       "page_last": "sƿift",
        "history-fieldset-title": "Sēcan stǣr",
        "histfirst": "ieldeste",
        "histlast": "nīwoste",
        "deletecomment": "Racu:",
        "deleteotherreason": "Ōðra/nīehst racu:",
        "deletereasonotherlist": "Ōðru racu",
-       "rollback_short": "Settan on bæc",
        "rollbacklink": "settan on bæc",
        "rollbackfailed": "Bæcsettung tōsǣlde",
        "editcomment": "Þǣre adihtunge se cwide wæs: \"''$1''\".",
index 01a0d29..d90c4ef 100644 (file)
@@ -14,7 +14,8 @@
                        "Reedy",
                        "Simbu123",
                        "Urhixidur",
-                       "아라"
+                       "아라",
+                       "Aftabuzzaman"
                ]
        },
        "tog-underline": "সংযোগসমূহ অধোৰেখিত কৰক:",
        "expandtemplates": "সাঁচবোৰ বহলাওক",
        "expand_templates_input": "পাঠ্য ভৰাওক",
        "expand_templates_output": "ফলাফল",
-       "expand_templates_ok": "à¦\93à¦\95ে",
+       "expand_templates_ok": "ঠিà¦\95 à¦\86à¦\9bে",
        "expand_templates_remove_comments": "মন্তব্য গু়চাওক",
        "expand_templates_preview": "খচৰা",
        "pagelanguage": "পৃষ্ঠাৰ ভাষা নিৰ্বাচক",
index d82ffbb..5cbed2e 100644 (file)
        "deleteprotected": "Nun pues desaniciar esta páxina porque ta protexida.",
        "deleting-backlinks-warning": "'''Avisu:''' [[Special:WhatLinksHere/{{FULLPAGENAME}}|Otres páxines]] enllacen a, o trescluyen de, la páxina que ta a piques de desaniciar.",
        "rollback": "Revertir ediciones",
-       "rollback_short": "Revertir",
        "rollbacklink": "revertir",
        "rollbacklinkcount": "revertir $1 {{PLURAL:$1|edición|ediciones}}",
        "rollbacklinkcount-morethan": "revertir más de $1 {{PLURAL:$1|edición|ediciones}}",
        "sp-contributions-newonly": "Amosar namái les ediciones que son creaciones de páxines",
        "sp-contributions-submit": "Buscar",
        "whatlinkshere": "Lo qu'enllaza equí",
-       "whatlinkshere-title": "Páxines qu'enllacien a \"$1\"",
+       "whatlinkshere-title": "Páxines qu’enllacien a «$1»",
        "whatlinkshere-page": "Páxina:",
        "linkshere": "Les páxines siguientes enllacien a '''[[:$1]]''':",
        "nolinkshere": "Nenguna páxina enllaza a '''[[:$1]]'''.",
        "import-logentry-interwiki": "treswikificada $1",
        "import-logentry-interwiki-detail": "$1 {{PLURAL:$1|revisión importada|revisiones importaes}} dende $2",
        "javascripttest": "Prueba de JavaScript",
-       "javascripttest-title": "Executando pruebes de $1",
        "javascripttest-pagetext-noframework": "Esta páxina ta acutada pa executar pruebes de javascript.",
        "javascripttest-pagetext-unknownframework": "L'entornu de pruebes «$1» ye desconocíu.",
        "javascripttest-pagetext-frameworks": "Escueyi un de los siguientes entornos de pruebes: $1",
        "javascripttest-pagetext-skins": "Escueyi una apariencia pa executar les pruebes:",
        "javascripttest-qunit-intro": "Ver la [$1 documentación de les pruebes] en mediawiki.org.",
-       "javascripttest-qunit-heading": "Conxuntu de pruebes JavaScript QUnit de MediaWiki",
        "tooltip-pt-userpage": "La to páxina d'usuariu",
        "tooltip-pt-anonuserpage": "La páxina d'usuariu de la IP cola que tas editando",
        "tooltip-pt-mytalk": "La to páxina d'alderique",
index d2802fa..0d9b3df 100644 (file)
        "qbedit": "सम्पादन",
        "qbpageoptions": "ई पन्ना",
        "qbmyoptions": "हमार पन्ना",
-       "faq": "बहà¥\81त  à¤ªà¥\82à¤\9bा à¤\9cाय à¤µà¤¾à¤²à¤¾ à¤ªà¥\8dरशà¥\8dन",
+       "faq": "साधारण à¤¸à¤µà¤¾à¤²",
        "faqpage": "Project:ढेर पूछा जाय वाला सवाल",
        "actions": "काम कुल",
        "namespaces": "नामस्थान",
        "articlepage": "सामग्री पन्ना देखा जाय",
        "talk": "चर्चा",
        "views": "दर्शाव",
-       "toolbox": "साधन à¤ªà¥\87à¤\9fà¥\80",
+       "toolbox": "à¤\94à¤\9cार à¤\95य à¤¬à¤\95à¥\8dसा",
        "userpage": "सदस्य पन्ना देखा जाय",
        "projectpage": "परियोजना पन्ना देखा जाय",
        "imagepage": "फ़ाइल पन्ना देखा जाय",
        "viewhelppage": "मदद पन्ना देखा जाय",
        "categorypage": "श्रेणी पन्ना  देखा जाय",
        "viewtalkpage": "चर्चा देखा जाय",
-       "otherlanguages": "à¤\85à¤\89र à¤­à¤¾à¤·à¤¾ à¤¸à¤¬",
+       "otherlanguages": "दà¥\81सर à¤­à¤¾à¤·à¤¾ à¤®à¥\87à¤\82",
        "redirectedfrom": "($1 से पुनर्निर्देशित)",
        "redirectpagesub": "पुनर्निर्देश पन्ना",
        "redirectto": "पुनर्निर्देश करा जाय:",
        "prefs-rc": "नँवा बदलाव",
        "prefs-watchlist": "अवलोकन सुची",
        "prefs-editwatchlist": "ध्यानसूची संपादन करा जाय",
+       "prefs-editwatchlist-label": "अपने धियान सुचीमा एन्ट्रि सम्पादन कीन जाय",
+       "prefs-editwatchlist-raw": "कच्चा निगरानी सूची सम्पादन करा जाय",
        "prefs-editwatchlist-clear": "आपन ध्यानसूची साफ करा जाय",
        "prefs-watchlist-days": "ध्यानसूची में दिखावै कय दिन:",
        "prefs-watchlist-days-max": "अधिकतम $1 {{PLURAL:$1|दिन}}",
        "gender-female": "एन सम्पादन करत अहिन।",
        "prefs-help-gender": "ई जानकारी देब वैकल्पिक होय।\nई सॉफ़्टवेयर में लिंग कय आधार पे आप कय लिए सही संबोधन कय नाते प्रयुक्त होत है।\nई जानकारी सार्वजनिक होइ।",
        "email": "ई-मेल",
+       "prefs-help-realname": "असली नाँव कय कवनो जरुरत नाइ है।यकर इस्तेमाल आप कय काम कय बडाइ करय में होइ सकत है ।",
        "prefs-help-email": "ई-मेल ठहर वैकल्पिक होय, लेकिन यदि आप आपन गुप्तकुंजी भूलाई गवा गय तव एकरे माध्यम से रीसेट कई सका जात है।",
        "prefs-help-email-others": "आप आपन पहिचान बिना देखाए, अउर सदस्यन् कय अपने सदस्य या बातचीत पन्ना से ,अपने आप से सम्पर्क कराय सका जात है।",
        "prefs-help-email-required": "ई-मेल ठहर जरुरी है।",
        "prefs-tokenwatchlist": "टोकन",
        "prefs-diffs": "अंतर",
        "prefs-help-prefershttps": "ई प्राथमिकता आप कय अगला लॉगिन मे प्रभावी होई।",
+       "prefswarning-warning": "आप अपने पसंद मा परिवर्तन करा गा है जवन अभिन अतक नाइ सहेजि गा है ।अगर आप \"$1\" कय किल्क किहे बिना इ पन्ना छोडा जाइ तव आप कय पसंद नाइ सहेजी जाइ।",
        "prefs-tabs-navigation-hint": "सुझाव: आप टैब्स सूची में टैब्स कय बीचे आवे-जाय खत्तीर बाँवा औ दहिना तीर कुंजिन् कय उपयोग कै सका जात है।",
        "email-address-validity-valid": "ई-मेल ठहर वैध नाइ लागत है",
        "email-address-validity-invalid": "एकठु वैध ई-मेल ठहर दिहा जाय",
        "right-deletedtext": "हटावल पाठ औ हटावल अवतरणन् कय बीचे अंतर देखा जाय",
        "right-browsearchive": "हटावल पन्ना खोजा जाय",
        "right-undelete": "ई पन्ना कय पुनर्स्थापित करा जाय।",
+       "right-viewsuppressed": "कवनो भि सदस्य कय लुकुआवल अवतरण देखा जाय",
        "right-suppressionlog": "खासगी लॉग देखा जाय",
        "right-block": "अउर सदस्यन् कय सम्पादन करय से ब्लॉक करा जाय",
        "right-blockemail": "अउर सदस्यन् कय ईमेल करै से रोका जाय",
        "right-protect": "सुरक्षा स्तर बदला जाय अव सीढ़ी-सुरक्षित पन्ना सम्पादन करा जाय",
        "right-editprotected": "अइसन सुरक्षित पन्नन कय सम्पादन करा जाय जवने कय सम्पादन कय \"{{int:protect-level-sysop}}\"",
        "right-editsemiprotected": "अइसन पन्नन् कय सम्पादन करा जाय जवने कय सुरक्षा स्तर होय \"{{int:protect-level-autoconfirmed}}\"",
+       "right-editcontentmodel": "पन्ना कय सामग्री नमुना कय बदला जाय",
        "right-editinterface": "सॉफ़्टवेयर इंटरफ़ेस सम्पादित करा जाय",
        "right-editusercssjs": "अउर सदस्यन् कय सी॰एस॰एस अव जावास्क्रिप्ट पन्ना कय सम्पादन करा जाय",
        "right-editusercss": "अउर सदस्यन् कय सी॰एस॰एस पन्ना सम्पादन करा जाय",
        "action-viewmywatchlist": "आपन ध्यानसूची देखा जाय",
        "action-viewmyprivateinfo": "आपन व्यक्तिगत जानकारी देखा जाय",
        "action-editmyprivateinfo": "आपन व्यक्तिगत जानकारी बदला जाय",
+       "action-editcontentmodel": "पन्ना कय सामग्री नमुना कय बदला जाय",
        "nchanges": "$1 {{PLURAL:$1|बदलाव}}",
        "enhancedrc-since-last-visit": "$1 {{PLURAL:$1|अंतिम दाइ देखय कय बाद से}}",
        "enhancedrc-history": "इतिहास",
        "upload-recreate-warning": "'''चेतावनी: उ नाँव कय फ़ाइल हटाई गय या घुस्काई गा है ।'''\n\nइ पन्ना कय हटावेक औ घुस्कावेक लॉग हिँया सन्दर्भ खत्तीर दिहा है:",
        "uploadtext": "फ़ाइल अपलोड करेक खत्तीर नीचे कय फ़ॉर्म कय प्रयोग कीन जाय।\n[[Special:FileList|अपलोड करल फ़ाइलन् कय सूची]] से आप पहिले अपलोड करल फ़ाइल कय देख सका जात है औ ओहमा खोज सका जात है। दोबारा अपलोड करल फ़ाइलन् कय [[Special:Log/upload|अपलोड सूची]] में देखा जाय, औ मिटावल फ़ाइलन् कय खत्तिर [[Special:Log/delete|हटावे कय सूची]] देखा जाय।\n\nकवनो पन्ना में फ़ाइल कय प्रयोग करेक लिए नीचे दिहा उदाहरणन् कय अनुसार कड़ि बनावा जाय।\n* '''<code><nowiki>[[</nowiki>{{ns:file}}<nowiki>:File.jpg]]</nowiki></code>''' फ़ाइल कय पूरा आकार प्रयोग करेक लिये\n* '''<code><nowiki>[[</nowiki>{{ns:file}}<nowiki>:File.png|200px|thumb|left|alt text]]</nowiki></code>''' पन्ना में बाँवा ओर फ़ाइल कय 200 पिक्सेल चौड़ा अवतरण \"alt text\" विवरण कय साथे एकठु बक्सा में प्रयोग करेक लिये\n* '''<code><nowiki>[[</nowiki>{{ns:media}}<nowiki>:File.ogg]]</nowiki></code>''' बिना फ़ाइल कय प्रयोग करे खालि ओकर कड़ी जोडेक लिये",
        "upload-permitted": "फाइल जवने कय इजाजत है कय {{PLURAL:$2|प्रकार}}: $1.",
+       "upload-preferred": "आप कय मन चाहा फाइल {{PLURAL:$2|प्रकार}}: $1.",
        "upload-prohibited": "फाइल जवने कय मिनाही है {{PLURAL:$2|प्रकार}}: $1.",
        "uploadlogpage": "अपलोड लॉग",
        "uploadlogpagetext": "नीचे हालिए अपलोड करल फ़ाइलन् कय सूची है।\nकृपया अउर द्रैश्यिक विवरण कय खत्तीर [[Special:NewFiles|नँवा फ़ाइलन् कय गैलरी]] देखा जाय।",
        "backend-fail-synced": "फ़ाइल \"$1\" आतंरिक भंडारण बैकेंड में असंगत स्थिति में है।",
        "backend-fail-connect": "\"$1\" भंडारण बैकेंड से सम्पर्क स्थापित नाई कई मिला।",
        "backend-fail-internal": "भंडारण बैकेंड \"$1\" में कवनो अज्ञात त्रुटि पैदा होइ गय।",
+       "backend-fail-contenttype": "\"$1\" मा सहेजै खत्तिर फाइल कय प्रकार नाइ निश्चित कै मिला ।",
+       "backend-fail-batchsize": "भंडारण बैकेंड कय $1 फ़ाइल {{PLURAL:$1|काम}} दिहा गा रहा; सीमा {{PLURAL:$2|$2 काम}} कय है।",
+       "backend-fail-usable": "फ़ाइल \"$1\" कय पर्याप्त अनुमति या अनुपस्थित डायरेक्ट्रीज़/कंटेनरन् कय कारण पढ़ा या लिखा नाइ जाय सकत है।",
+       "filejournal-fail-dbconnect": "भंडारण बैकेंड \"$1\" कय जर्नल डाटाबेस से सम्पर्क नाइ होइ पाय।",
+       "filejournal-fail-dbquery": "भंडारण बैकेंड \"$1\" कय जर्नल डाटाबेस कय अद्यतन नाइ कै मिला ।",
+       "lockmanager-notlocked": "\"$1\" कय अनलॉक नाइ कै मिला,इ बन्द नाइ है।",
        "lockmanager-fail-closelock": "\"$1\" कय लॉक फ़ाइल बंद नाइ कै सका गय।",
        "lockmanager-fail-deletelock": "\"$1\" कय लॉक फ़ाइल नाइ मिटाइ सका गय।",
        "lockmanager-fail-acquirelock": "\"$1\" के लिए लॉक नाइ मिला।",
        "uploadstash": "स्टैश अपलोड करा जाय",
        "uploadstash-clear": "स्टैश करल फ़ाइल साफ़ करा जाय",
        "uploadstash-nofiles": "आप कय लगे कवनो स्टैश करल फाइल नाइ है ।",
+       "uploadstash-badtoken": "इ काम असफल रहा ,लागत है आप कय सम्पादन प्रमाणपत्र कय अवधि खतम होइ गवा है ।",
        "uploadstash-errclear": "फाइल कय साफ करब असफल रहा ।",
        "uploadstash-refresh": "फाइल कय सुची रिफ्रेश करा जाय ।",
        "invalid-chunk-offset": "अग्राह्य चंक ऑफ़सेट",
        "img-auth-accessdenied": "पहुँच अस्वीकार",
+       "img-auth-nopathinfo": "PATH_INFO मौजूद नाइ है।\nआप कय सर्वर मा इ जानकारी भेजय खत्तीर जमाव नाइ है।\nइ सी॰जी॰आई-आधारित होइ सकत है औ img_auth कय स्वीकार नाइ करत है।\nhttps://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Image_Authorization देखें।",
+       "img-auth-notindir": "अनुरोधित पथ जमावल अपलोड डायरेक्टरी मा नाइ है।",
+       "img-auth-badtitle": "\"$1\" से एकठु वैध शीर्षक बनावे मा असमर्थ।",
+       "img-auth-nologinnWL": "आप लाग इन् नाइ करे हौ औ \"$1\" श्वेतसूची मा नाइ हौ।",
        "img-auth-nofile": "\"$1\" फाइल नाइ है।",
+       "img-auth-isdir": "आप डायरेक्टरी \"$1\" खोलेक कोशिश करा जात है ।\nखालि फ़ाइल खोली जा सकत है।",
        "img-auth-streaming": "\"$1\"  स्ट्रीम होत है।",
+       "img-auth-public": "img_auth.php निजी विकि से फ़ाइल देवै कय काम करत है।\nइ विकि सार्वजनिक विकि होय।\nउचित सुरक्षा खत्तीर img_auth.php अक्षम है।",
+       "img-auth-noread": "सदस्य कय \"$1\" पढै कय अनुमति नाइ है ।",
        "http-invalid-url": "अमान्य यू॰आर॰एल: $1",
        "http-invalid-scheme": "\"$1\" से शुरू होय वाले यू॰आर॰एल स्वीकार्य नाई हैं।",
        "http-request-error": "एच॰टी॰टी॰पी अनुरोध अज्ञात त्रुटि कय नाते असफल रहा।",
        "upload-curl-error6": "यू॰आर॰एल तक नाई पहुँच मिला।",
        "upload-curl-error6-text": "दिहल यू॰आर॰एल तक नाई पहुँचि मिला।\nकृपया एक दाइ फिर से जाँच लिहा जाय कि यू॰आर॰एल सही है औ उ साइट चलत है।",
        "upload-curl-error28": "अपलोड टाइम‍आउट",
+       "upload-curl-error28-text": "साइट कय जवाब देय मा बहुतय समय लागत है ।कृपया जाचा जाय कि साइट चलत है कि नाही अव फिरसे प्रयास कीन जाय ।आप कम भिड वाले समय प्रयास करय चाहा जाइ।",
        "license": "लाइसेन्सिंग:",
        "license-header": "लाइसेन्सिंग",
        "nolicense": "कवनो नाइ चुना गय",
        "filehist-comment": "टिप्पणी",
        "imagelinks": "फ़ाइल कय उपयोग",
        "linkstoimage": "निचे दिहा {{PLURAL:$1|पन्ना}} में इ फ़ाइल कय कड़ि हैं:",
+       "linkstoimage-more": "{{PLURAL:$1|$1}} से ढेर पन्ना एहमा जोडात है।\nनिम्नोक्त सूची फ़ाइल से जुड़य वाले {{PLURAL:$1|$1 पन्ना}} देखावत है।\n[[Special:WhatLinksHere/$2|पूरा सूची]] उपलब्ध है।",
        "nolinkstoimage": "इ फाइल से कवनो पन्ना नाइ जोडान है ।",
        "morelinkstoimage": "इ फ़ाइल कय [[Special:WhatLinksHere/$1|अउर कड़ि]] देखा जाय।",
        "linkstoimage-redirect": "$1(फ़ाइल पुनर्निर्देश) $2",
+       "duplicatesoffile": "निचे दिहा {{PLURAL:$1|फ़ाइल इ फ़ाइल कय प्रतिलिपि होय|$1 फ़ाइल इ फ़ाइल कय प्रतिलिपि होय}} ([[Special:FileDuplicateSearch/$2|ढेर जानकारी]]):",
+       "sharedupload": "इ फाइल $1 कय होए अव बहुत परियोजना मे इस्तेमाल होत है",
+       "sharedupload-desc-there": "इ फाईल $1 से है अव दुसर परियोजना मा प्रयोग कै सका जात है। ढेर जानकारी खातिर कृपया [$2 फाईल विवरण पन्ना] देखा जाय।",
+       "sharedupload-desc-here": "इ फाईल $1 से है अव दुसर परियोजना मा प्रयोग कै सका जात है। वँह एकर  [$2 फाईल विवरण पन्ना] कय विवरण निचे दिहा है।",
+       "sharedupload-desc-edit": "इ फाईल $1 से है अव दुसर परियोजना मा प्रयोग कै सका जात है। शाएद आप [$2 वँह ओकर फाईल विवरण पन्ना] कय सम्पादित करै चाहा जात है।",
+       "sharedupload-desc-create": "इ फाईल $1 से है अव दुसर परियोजना मा प्रयोग कै सका जात है। शाएद आप [$2 वँह ओकर फाईल विवरण पन्ना] कय सम्पादित करै चाहा जात है।",
        "filepage-nofile": "ई नाँव कय कवनो फाइल नाइ है ।",
        "filepage-nofile-link": "ई नाँव कय कवनो फाइल नाइ है,लेकिन आप [$1 कय अपलोड कई सका जात है]।",
        "uploadnewversion-linktext": "ई फाइल कय नँवा अवतरण अप्लोड करा जाय",
        "download": "डाउनलोड",
        "unwatchedpages": "ध्यान ना दिहल पन्ना",
        "listredirects": "पुनर्निर्देशन कय सूची",
+       "listduplicatedfiles": "डुप्लिकेट वाले फाइल",
+       "listduplicatedfiles-entry": "[[:फाइल:$1|$1]] कय लगे [[$3|{{PLURAL:$2|एक्ठु डुप्लिकेट|$2 डुप्लिकेट}}]].",
        "unusedtemplates": "अप्रयुक्त साँचा",
        "unusedtemplateswlh": "अउर कड़ि",
        "randompage": "कवनो एक पन्ना",
        "statistics-users-active-desc": "पिछला {{PLURAL:$1|दिन}} से जवन सदस्य सक्रिय हँय",
        "pageswithprop": "पन्ना जवनन में पन्ना गुण है",
        "pageswithprop-legend": "पन्ना जवनन में पन्ना गुण है",
+       "pageswithprop-text": "इ पन्ना पन्नन कय गुण कय उपयोग करय वाले पन्नन कय सुचिबद्ध करत है ।",
        "pageswithprop-prop": "गुण कय नाँव:",
        "pageswithprop-submit": "खोजा जाय",
+       "pageswithprop-prophidden-long": "लम्मा पाठ गुण मान लुकुआवा है ($1)",
+       "pageswithprop-prophidden-binary": "बाइनरी पाठ गुण मान लुकुआवा है ($1)",
        "doubleredirects": "दुईठु पुनर्निर्देश",
+       "double-redirect-fixed-move": "[[$1]] कय घुस्काइ गय । इ अपने आप अपडेट होइ गवा है अव [[$2]] पे पुनर्निर्देशीत होइ ।",
        "double-redirect-fixer": "पुनर्निर्देशन मिस्त्री",
        "brokenredirects": "टूटल पुनर्निर्देशन पन्ना",
        "brokenredirectstext": "ई कुल पुनर्निर्देश नामौजुद पन्नन मा लैजात हैं :",
        "booksources": "किताबीन कय स्रोत",
        "booksources-search-legend": "किताबीन कय स्रोत खोजा जाय",
        "booksources-search": "खोजा जाय",
+       "booksources-text": "निचँवा पुरान व नँवा किताब बेचय वाले वेबसाइट कय एड्रेस हैं,जवने मा आप कय खोजल किताबिन् कय बारे मे ढेर जानकारी मिलि सकत है :",
        "booksources-invalid-isbn": "इ ISBN सही नाइ लागत है ,मुल स्रोत से नकल करत कय कवनो गल्ती होइ गा होइ ,जाँचा लीन जाय ।",
        "specialloguserlabel": "करयवाला:",
        "speciallogtitlelabel": "प्रयोजन (शीर्षक या सदस्यनाँव):",
        "cachedspecial-viewing-cached-ts": "आप इ पन्ना कय कैश करल अवतरण देखा जात है ,जवन कि पुरै सही नाइ होइ सकत है ।",
        "cachedspecial-refresh-now": "हालिए कय देखा जाय ।",
        "categories": "श्रेणी",
+       "categoriespagetext": "निम्नोक्त {{PLURAL:$1|श्रेणी|श्रेणि}} मा पन्ना या मीडिया है।\nजवन श्रेणिन् कय [[Special:UnusedCategories|अप्रयुक्त श्रेणि]] यहँ नाइ देखाई गा हैं।\n[[Special:WantedCategories|वांछित श्रेणि]] भी देखा जाय।",
        "categoriesfrom": "इ अक्षर से शुरु होय वाला श्रेणी देखावा जाय:",
        "special-categories-sort-count": "संख्या कय अनुसार क्रमांकित करा जाय",
        "special-categories-sort-abc": "वर्णानुक्रम कय अनुसार देखावा जाय",
        "linksearch-pat": "खोजय खर्तीन पाठ:",
        "linksearch-ns": "नामस्थान:",
        "linksearch-ok": "खोजा जाय",
+       "linksearch-text": "\"*.wikipedia.org\" जैसन वाईल्ड-कार्ड्स प्रयोग कै सका जात है।\nकम-से-कम \".org\" जैसन कवनो top-level डोमेन कय आवश्यकता है।<br />\nस्वीकार्य {{PLURAL:$2|प्रोटोकॉल}}: <code>$1</code> (यदि कवनो प्रोटोकॉल ना दै जाए तव http:// कय प्रयोग कै सका जात है)",
        "linksearch-line": "$2 में से $1 जोडान है",
        "linksearch-error": "वाईल्डकार्ड्स होस्टनाम कय खालि शुरू में आइ सकत है।",
        "listusersfrom": "इ अक्षर से शुरु होय वाले सदस्य देखावा जाय:",
        "trackingcategories": "ट्रैक करय वाले श्रेणी",
        "trackingcategories-msg": "ट्रैक करय वाले श्रेणी",
        "trackingcategories-name": "सनेशा कय नाँव",
+       "trackingcategories-desc": "श्रेणी राखेक क्राइटेरिया",
        "trackingcategories-nodesc": "कवनो ढेर जानकारी नाइ है ।",
        "trackingcategories-disabled": "श्रेणी अक्षम करा है",
        "mailnologin": "कवनो पठवे वाला ठहर नाइ है",
        "noemailtitle": "कवनो ई-मेल एड्रेस नाइ है",
        "noemailtext": "इ सदस्य वैध ई-मेल ठहर नाइ दिहे हैं।",
        "nowikiemailtext": "इ सदस्य अउर सदस्यन से इमेल ना पावै कय फैसला करें हँय ।",
+       "emailnotarget": "प्राप्तकर्ता कय लिए अस्तित्वहीन या अमान्य सदस्यनाम।",
        "emailtarget": "पावै वाले कय सदस्यनाँव भरा जाय",
        "emailusername": "सदस्यनाँव",
        "emailusernamesubmit": "भेजो",
        "mywatchlist": "अवलोकन सुची",
        "watchlistfor2": "$1 $2 कय खत्तिर",
        "nowatchlist": "आप कय धियान सुची मा कवनो पन्ना नाइ है ।",
+       "watchlistanontext": "आपन धियान सुची कय देखय अव सम्पादन करय खत्तीर लाग इन कीन जाय ।",
        "watchnologin": "लॉग इन नाइ करा गा है",
        "addwatch": "ध्यानसूची में जोड़ा जाय",
+       "addedwatchtext": "आप कय [[Special:Watchlist|ध्यानसूची]] मा \"[[:$1]]\" पन्ना जोड़ाइ गय।\nभविष्य मा इ पन्ना अव एकर बातचीत पन्ना मा होवै वाला बदलाव आप कय ध्यानसूची मा देखाइ।",
        "addedwatchtext-short": "\"$1\" कय आप कय धियान सुची मा डारी गय ।",
        "removewatch": "ध्यानसूची से हटावा जाय",
        "removedwatchtext": "\"[[:$1]]\" नाँव कय पन्ना कय आपकय [[Special:Watchlist|ध्यानसूची]] से हटाय दिहा गा है।",
        "cantrollback": "पुरान अवतरण कय पहिले जैसन नाइ कै सका जात है ; इ पन्ना कय आखिरी योगदानकर्ता खालि इ लेख कय लिखे हैं ।",
        "editcomment": "संपादन सारांश रहा: \"''$1''\"।",
        "revertpage": "[[Special:Contributions/$2|$2]] ([[User talk:$2|बातचीत]])से [[User:$1|$1]] कय करल पिछला संशोधन उल्टाई कय पहिले जैसन कै गय",
+       "revertpage-nouser": "(सदस्य नाँव हटाइ गा है) कय संपादन कय हटाइकए {{GENDER:$1|[[User:$1|$1]]}} कय अन्तिम अवतरण कय पहिले जैसन कै गय।",
        "rollback-success": "$1 कय संपादन हटाइ गय;\n$2 कय संपादित अन्तिम अवतरण कय पुनर्स्थापित कै गय।",
        "sessionfailure-title": "सत्र विफलता",
        "protectlogpage": "सुरक्षा लॉग",
+       "protectlogtext": "नीचे पन्ना सुरक्षा कय बदलाव कय सूची है।\nवर्तमान सुरक्षित पन्नन कय सूची कय लिए [[Special:ProtectedPages|सुरक्षित पन्ना कय सूची]] देखा जाय।",
        "protectedarticle": "\"[[$1]]\" कय सुरक्षित कै गय",
        "modifiedarticleprotection": "\"[[$1]]\" कय सुरक्षा-स्तर बदलि गय",
        "unprotectedarticle": "\"[[$1]]\" से सुरक्षा हटाइ गय",
        "prot_1movedto2": "[[$1]] कय नाँव बदलि कय [[$2]] कै गय",
        "protect-badnamespace-title": "सुरक्षाहीन नामस्थान",
        "protect-badnamespace-text": "इ नामस्थान मा पन्ना सुरक्षित नाइ कै सका जात है।",
+       "protect-norestrictiontypes-text": "इ पन्ना कय सुरक्षित नाइ कै सका जात है काहे से कवनो सुरक्षा प्रकार नाइ है ।",
        "protect-norestrictiontypes-title": "सुरक्षाहीन पन्ना",
        "protect-legend": "सुरक्षा निर्धारित करा जाय",
        "protectcomment": "कारण :",
        "ipbsubmit": "इ सदस्य कय अउर बदलाव करय से रोका जाय",
        "ipbother": "अउर समय:",
        "ipboptions": "दुइ घंटा:2 hours,एक दिन:1 day,तीन दिन:3 days,एक हप्ता:1 week,दुइ हप्ता:2 weeks,एक महीना:1 month,तीन महीना:3 months,छः महीना:6 months,एक साल:1 year,हमेशा कय लिये:infinite",
+       "ipbhidename": "संपादन अव सूचिन् से सदस्य नाँव लुकुआवा जाय",
+       "ipbwatchuser": "इ सदस्य कय सदस्य पन्ना अव बातचीत पन्ना पे नजर रक्खा जाय",
+       "ipb-disableusertalk": "इ सदस्य कय अवरुद्ध होए पे आपन बातचीत पन्ना सम्पादन करै से रोका जाय",
+       "ipb-change-block": "इ सेटिङ कय इस्तेमाल कै कय सदस्य कय अवरोधित करा जाय",
        "ipb-confirm": "अवरोधण कय पुष्टि करा जाय",
        "badipaddress": "अमान्य आईपी ठहर।",
        "blockipsuccesssub": "अवरोधन सफल ।(संपादन करय से रोक दिहा गा है)",
        "unblocked": "[[User:$1|$1]] होइ गा हैं।",
        "unblocked-range": "$1 अनब्लॉक होइ गा हैं।",
        "unblocked-id": "अवरोध $1 निकारि दिहा गा है",
+       "unblocked-ip": "[[Special:Contributions/$1|$1]] कय ब्लाक कै गय",
        "blocklist": "अवरोधित उपयोक्ता",
        "ipblocklist": "अवरोधित आईपी ठहर या सदस्यनाँव",
        "ipblocklist-legend": "अवरोधित सदस्य कय खोजा जाय",
        "contribslink": "योगदान",
        "emaillink": "ईमेल पठवा जाय",
        "blocklogpage": "ब्लॉक सूची",
+       "blocklog-showlog": "इ सदस्य पहिलँहु ब्लाक कै गा हैं । संदर्भ खत्तीर अभिलेख निचे दिहा है ।",
+       "blocklog-showsuppresslog": "इ सदस्य कय पहिलँहु ब्लाक कै गा है ।दबावल लाग संदर्भ खत्तीर दै गा है ।",
+       "blocklogentry": "\"[[$1]]\" कय $2 $3 तक बदलाव करय से रोक दिहा गा है।",
+       "reblock-logentry": "[[$1]] कय अवरोध जमाव बदलि गय, मियाद अब $2 $3 पे खतम होइ",
+       "blocklogtext": "इ सदस्यन् कय ब्लॉक अव अनब्लॉक करेक काम कय लॉग होय।\nअपने से बाधित होवे वाले IP ठहर इ सूची मा उपलब्ध नाइ है।\nवर्तमान में क्रियाशील प्रतिबंध औ ब्लॉक कय सूची कय लिए [[Special:BlockList|ब्लॉक लॉग]] देखा जाय।",
        "unblocklogentry": "$1 अनवरोधित",
        "block-log-flags-anononly": "खाली बेनाम सदस्य",
        "block-log-flags-nocreate": "खाता बनावै से रोक",
        "block-log-flags-nousertalk": "आपन बातचीत पन्ना भी संपादन नाइ कै सकत हैँ ।",
        "block-log-flags-angry-autoblock": "उन्नत स्व-अवरोध लागू",
        "block-log-flags-hiddenname": "सदस्य नाँव लुकुआवा है",
+       "range_block_disabled": "प्रबंधकन कय अब रेंज ब्लॉक करेक अनुमति नाइ है।",
        "ipb_expiry_invalid": "अवैध समाप्ति कालावधी।",
+       "ipb_expiry_temp": "छुपायें हुए सदस्यनाम ब्लॉक्स हमेशा के लिये होने चाहिये।",
+       "ipb_hide_invalid": "इस खाते को छिपा नहीं पाए; इस से {{PLURAL:$1|एक सम्पादन किया गया है|$1 सम्पादन किये गये हैं}}।",
        "ipb_already_blocked": "\"$1\" पहिलवे से ब्लॉक हैं",
+       "ipb-needreblock": "$1 पहले ही अवरोधित है।\nक्या आप अवरोध के जमाव बदलना चाहेंगे?",
        "ipb-otherblocks-header": "अउर {{PLURAL:$1|ब्लॉक}}",
+       "unblock-hideuser": "आप इस प्रयोक्ता को अनवरोधित नहीं कर सकते, क्योंकि इनका प्रयोक्तानाम छिपा हुआ है।",
+       "ipb_cant_unblock": "समस्या: ब्लॉक ID $1 मिला नहीं। इसे पहले अनब्लॉक कर दिया गया हो सकता हैं।",
+       "ipb_blocked_as_range": "गलती: $1 यह आइपी सीधे बाधित नहीं है और अबाध्य नहीं किया जा सकता।\nफिर भी, $2 प्रकार को बाध्य किया जा सकता है, जिनको अबाध्य किया जा सकता है।",
        "ip_range_invalid": "गलत आईपी रेंज",
+       "ip_range_toolarge": "/$1 से अधिक बड़े रेञ्ज ब्लॉकों की अनुमति नहीं है।",
        "proxyblocker": "प्रॉक्सी ब्लॉकर",
+       "proxyblockreason": "आपका IP पता बाधित किया जा चुका है क्योंकि यह एक मुक्त प्रतिनिधि है।\nकृपया आप अपने इंटरनेट सेवा प्रदान करने वाले से या तकनीकी सहायक से सम्पर्क करें अथवा उन्हें इस भयावह सुरक्षा समस्या के बारे में सूचित करें।",
+       "sorbsreason": "{{SITENAME}} द्वारा इस्तेमालमें लाये जाने वाले DNSBL में आपके आईपी एड्रेसको ओपन प्रॉक्सीमें दर्शाया गया हैं।",
+       "sorbs_create_account_reason": "{{SITENAME}} के DNSBL ने आपका आईपी एड्रेस ओपन प्रोक्सी करके सूचित किया हैं। आप खाता खोल नहीं सकतें।",
+       "cant-see-hidden-user": "जिस सदस्य को आप अवरोधित करने की कोशिश कर रहे हैं उसे पहले ही अवरोधित कर के छुपाया जा चुका है।\nचूँकि आपके पास hideuser अधिकार नहीं है, आप इस सदस्य का अवरोधन ना देख सकते हैं और ना ही सम्पादित कर सकते हैं।",
+       "ipbblocked": "आप अन्य प्रयोक्ताओं को अवरोधित या अनवरोधित नहीं कर सकते, क्योंकि आप स्वयं अवरोधित हैं",
+       "ipbnounblockself": "आपको स्वयं को अनवरोधित करने की अनुमति नहीं है",
        "lockdb": "डाटाबेस लॉक करा जाय",
        "unlockdb": "डाटाबेस अनलॉक करा जाय",
+       "lockdbtext": "डेटाबेस में ताला लगाने से सभी सदस्य पृष्ठ संपादन, अपनी वरीयताओं में परिवर्तन, अपनी ध्यानसूची में संपादन, और अन्य चीजें जिनके लिए डेटाबेस में परिवर्तन करना होता है, उनसे वंचित हो जायेंगे।\nकृपया यह सुनिश्चित करे की आप यह करना चाहते हैं, और आप अनुरक्षण के पश्चात ताला खोल देंगे।",
+       "unlockdbtext": "डेटाबेस का ताला खोलने से सभी सदस्य पृष्ठ संपादन, अपनी वरीयताओं में परिवर्तन, अपनी ध्यानसूची में संपादन, और अन्य चीजें जिनके लिए डेटाबेस में परिवर्तन करना होता है, की सक्षमता को पुनर्स्थापित कर लेंगे।\nकृपया यह सुनिश्चित करे की आप यह करना चाहते हैं।",
+       "lockconfirm": "जी हां, मुझे सचमुच डाटाबेस को ताला लगाना हैं।",
+       "unlockconfirm": "जी हां, मुझे सचमुच डाटाबेस का ताला खोलना हैं।",
        "lockbtn": "डाटाबेस लॉक करा जाय",
        "unlockbtn": "डाटाबेस अनलॉक करा जाय",
+       "locknoconfirm": "आपने कन्फर्मेशन सन्दूकमें क्लिक नहीं किया हैं।",
        "lockdbsuccesssub": "डाटाबेस लाक सफल",
        "unlockdbsuccesssub": "डाटाबेस लाक हटाइ गय",
+       "lockdbsuccesstext": "डाटाबेस को ताला लगाया गया हैं।<br />\nआपके द्वारा मेंटेनन्स पूरा होने के बाद [[Special:UnlockDB|ताला खोलना]] याद रखें।",
+       "unlockdbsuccesstext": "डाटाबेसका ताला खोल दिया गया हैं।",
+       "lockfilenotwritable": "डाटाबेस के लॉक फ़ाईलमें लिख नहीं पा रहें हैं।\nडाटाबेस का ताला लगाने या खोलनेके लिये, इस फ़ाईलपर लिखा जाना जरूरी हैं।",
+       "databasenotlocked": "डाटाबेस को ताला नहीं लगाया गया हैं।",
        "lockedbyandtime": "(से {{GENDER:$1|$1}} पे $2 यँह $3)",
        "move-page": "$1 कय घुस्कावा जाय",
        "move-page-legend": "पन्ना घुसकावा जाय",
+       "movepagetext": "निचे दिहा फारम पन्ना कय नाँव बदल दी अव ओकर इतिहास नँवा नाँव से देखाए लागि ।\nपुरान शिर्षक कय नँवा नाँव मे पुनर्निर्देशन कै जाइ।\nमूल शीर्षक की ओर ले जाने वाले पुनार्निर्देशों को आप स्वचालित रूप से बदल सकते हैं।\nयदि आप ऐसा नहीं करते हैं तो कृपया [[Special:DoubleRedirects|दोहरे पुनर्निर्देशन]] या [[Special:BrokenRedirects|टूटे पुनर्निर्देशन]] के लिए ज़रूर जाँच करें।\nकड़ियाँ सही जगह इंगित करती रहें, यह सुनिश्चित करना आपकी ज़िम्मेदारी है।\n\nअगर नये शीर्षक का लेख पहले से है तो स्थानांतरण '''नहीं''' होगा। पर अगर नये शीर्षक वाला लेख कहीं और अनुप्रेषित करता है और साथ ही उसके पुराने संस्करण नहीं हैं तो स्थानांतरण हो जायेगा।\nइसका मतलब कि यदि आपसे गलती हो जाए तो आप वापस पुराने नाम पर इस पृष्ठ का स्थानांतरण कर सकेंगे, और साथ ही आप किसी मौजूदा पृष्ठ के बदले यह स्थानांतरण नहीं कर सकते हैं।\n\n'''चेतावनी!'''\nयदि पृष्ठ काफ़ी लोकप्रिय है तो उसके लिए यह एक बहुत बड़ा व अकस्मात् परिवर्तन हो सकता है;\nआगे बढ़ने से पहले इसका अंजाम अच्छी तरह समझ लें।",
        "movearticle": "पन्ना घुसकावा जाय:",
        "moveuserpage-warning": "<strong>चेतावनी:</strong> आप एकठु सदस्य पन्ना कय नाँव बदलय जावा जात है।तनि ध्यान दिहा जाय कि खालि पन्ना कय नाँव बदल जाइ औ सदस्यनाँव <em>नाई</em> बदलि।",
        "movenotallowed": "आप कय इ पन्ना घुस्कावे कय अनुमति नाई है ।",
        "cant-move-user-page": "आप कय सदस्य पन्ना घुस्कावे कय अनुमति नाई है (उप-पन्ना बादे) ।",
        "cant-move-to-user-page": "आप कय कवनो पन्नन कय सदस्य पन्ना पय लैजाएक अनुमति नाइ है (सिवाय सदस्य उप पन्नन कय)",
        "cant-move-category-page": "आप कय श्रेणी पन्ना घुस्कावे कय अनुमति नाई है ।",
+       "cant-move-to-category-page": "आप कय कवनो पन्ना कय श्रेणी पन्ना पे घुस्कावे कय अनुमति नाई है ।",
        "newtitle": "नवा शिर्षक पे :",
        "move-watch": "स्रोत पन्ना अव टार्गेट पन्ना पे ध्यान रक्खा जाय",
        "movepagebtn": "पन्ना घुसकावा जाय",
        "movepage-moved": "<strong>\"$1\" कय \"$2\" पे घुस्काइ गय</strong>",
        "movepage-moved-redirect": "एक्ठु पुनर्निर्देशन बनाइ गय।",
        "movepage-moved-noredirect": "पुनर्निर्देशन निर्माण दबाइ गय",
+       "articleexists": "इ नाँव कय पन्ना पहिल्वे से मौजुद है या तव आप कवनो गलत नावँ चुना गा है। कवनो दुसर नाँव चुना जाय",
+       "cantmove-titleprotected": "नँवा पन्ना बनावै से रोक होएक नाते आप कय इ जगही कवनो दुसर पन्ना घुस्कावै कय अनुमति नाइ है ।",
        "movetalk": "सम्बंधित बातचित पन्ना घुस्कावा जाय",
        "move-subpages": "उप पन्ना घुस्कावा जाय ($1 तक)",
        "move-talk-subpages": "बातचीत पन्ना कय उप पन्ना भी लई जावा जाय ($1 तक)",
        "movepage-page-exists": "$1 पन्ना पहिलवे से है अव आप ओहपर फिरसे नाइ लिखि सका जात है ।",
        "movepage-page-moved": "पन्ना $1 कय $2 पे घुस्काइ गय ।",
        "movepage-page-unmoved": "पन्ना $1 कय $2 पे नाइ घुस्काइ सका जात है ।",
+       "movepage-max-pages": "$1 की अधिकतम सीमा तक पृष्ठ स्थानांतरित कर {{PLURAL:$1|दिया गया है|दिये गये हैं}}, अब और पृष्ठ अपने-आप स्थानांतरित नहीं होंगे।",
        "movelogpage": "घुस्कावे कय ल़ाग",
        "movelogpagetext": "निचे घुस्कावल पन्नन् कय सुची हय",
        "movesubpage": "{{PLURAL:$1|उप-पन्ना}}",
        "immobile-source-page": "ई पन्ना नाइ घुस्की ।",
        "immobile-target-page": "इ गन्तव्य शिर्षक पय नाइ लैजाय सका जात अहै ।",
        "imagenocrossnamespace": "फाइल कय बिना-फाइल नेमस्पेस मा नाइ घुस्काय सका जात है",
+       "nonfile-cannot-move-to-file": "बिना-फाइल कय फाइल नेमस्पेस मा नाइ घुस्काय सका जात है ।",
+       "imagetypemismatch": "नँवा फाइल एक्सटेन्सन फाइल कय प्रकार से मेल नाइ खात है",
        "imageinvalidfilename": "लक्ष्यित फाइल नाँव अवैध है",
+       "fix-double-redirects": "मूल शीर्षक तक जाने वाले सभी पुनर्निर्देशनों को भी बदलें",
        "move-leave-redirect": "पिछे एक्ठु पुनर्निर्देशन छोडा जाय",
+       "protectedpagemovewarning": "'''चेतावनी: इ पन्ना कय सुरक्षित कई  गा है अव एका खालि प्रबंधक घुस्काय सकत हँय।'''\nनँवा लॉग प्रविष्टि संदर्भ कय लिये नीचे दीहा है:",
        "semiprotectedpagemovewarning": "'''सूचना:''' इ पन्ना सुरक्षित करा है औ खाली पंजीकृत सदस्य एका घुस्काय सकत हैं।\nनँवा लॉग प्रविष्टि संदर्भ खत्तीर नीचे दीहा है:",
        "move-over-sharedrepo": "== फ़ाइल मौजूद है ==\n[[:$1]] एकठु साझा भंडार पय मौजूद है। इ नाँव पय घुस्कावै से नँवा फ़ाइल साझा फ़ाइल कय ओवरराइड करी।",
+       "file-exists-sharedrepo": "चुनल फाइल नाँव पहिलेवे एकठु साझा भण्डार में प्रयुक्त है।\nकृपया दुसर नाव चुना जाय।",
        "export": "पन्ना निर्यात करा जाय",
+       "exporttext": "आप विशिष्ठ पृष्ठ के विषय वस्तु और संपादन इतिहास को निर्यात कर सकते हैं अथवा पृष्ठों के समूह को कुछ XML में लपेट सकते हैं।\nयह [[Special:Import|आयात पृष्ठ]] की सहायता से मीडियाविकी का प्रयोग करके दूसरी विकी से आयात किया जा सकता है।\n\nपृष्ठों को निर्यात करने के लिए, नीचे विषय वस्तु संदूक में शीर्षक प्रवेश करें, एक शीर्षक प्रति पंक्ति, और चुने कि आप वर्त्तमान अवतरण के साथ पुराने अवतरण भी चाहते हैं कि नहीं, या पिछले संपादन के बारे में जानकारी के साथ केवल वर्त्तमान अवतरण चाहते हैं।\n\nबाद वाली स्थिति के लिए आप एक सम्पर्क भी प्रयोग कर सकते हैं, उदाहरण के लिए, \"[[{{MediaWiki:Mainpage}}]]\" पृष्ठ के लिए [[{{#Special:Export}}/{{MediaWiki:Mainpage}}]]।",
        "exportall": "कुल पन्ना निर्यात करा जाय",
+       "exportcuronly": "पुरा इतिहास नाइ चाहि,खाली नँवा अवतरण करा जाय",
+       "exportnohistory": "----\n'''सूचना:''' इस फॉर्म का इस्तेमाल कर पृष्ठका पूरा इतिहास निर्यात करना परफॉर्मेन्स के चलते रोक दिया गया हैं।",
+       "exportlistauthors": "प्रत्येक पृष्ठ के लिए योगदानकर्ताओं की एक पूरी सूची शामिल करें ।",
        "export-submit": "निर्यात",
        "export-addcattext": "श्रेणी से पन्ना डारा जाय :",
        "export-addcat": "जोडव",
        "export-addns": "जोडा जाय",
        "export-download": "फ़ाइल रुप में सहेजा जाय",
        "export-templates": "टेम्प्लेटस भी जोडा जाय",
+       "export-pagelinks": "जिन पन्नों के हवाले यहाँ हैं, उन्हें भी इस गहराई तक शामिल करें:",
        "allmessages": "व्यवस्था संदेश",
        "allmessagesname": "नाँव",
        "allmessagesdefault": "सनेशा कय डिफ़ॉल्ट पाठ",
        "allmessagescurrent": "वर्तमान पाठ",
+       "allmessagestext": "ये मीडियाविकि नामस्थान में उपलब्ध प्रणाली संदेशों की एक सूची है। यदि आप सामान्य मीडियाविकि क्षेत्रीयकरण में योगदान देना चाहें तो कृपया [https://www.mediawiki.org/wiki/Special:MyLanguage/Localisation मीडियाविकि क्षेत्रीयकरण] व [//translatewiki.net translatewiki.net] को देखें।",
+       "allmessagesnotsupportedDB": "इस पृष्ठ का इस्तेमाल नहीं कर सकते क्योंकी '''$wgUseDatabaseMessages''' बंद हैं।",
        "allmessages-filter-legend": "फिल्टर",
        "allmessages-filter": "अनुकूलन स्थिति कय आधार पे छाना जाय:",
        "allmessages-filter-unmodified": "अपरिवर्तित",
        "djvu_no_xml": "DjVu फ़ाईल कय खत्तीर XML नाइ मिला",
        "thumbnail-temp-create": "अस्थायी थम्बनेल फ़ाइल बनावै में असफल",
        "thumbnail_invalid_params": "अमान्य थम्बनेल पैरामीटर",
+       "thumbnail_toobigimagearea": "$1 से बडा फाइल",
        "thumbnail_dest_directory": "गन्तव्य निर्देशिका बनावै में असमर्थ",
        "thumbnail_image-type": "चित्र कय प्रकार समर्थित नाइ है",
+       "thumbnail_gd-library": "अवैध जीडी लाइब्रेरी जमाव: कार्यसमूह $1 मौजूद नहीं है",
        "thumbnail_image-missing": "लागत है फाइल नामौजूद है: $1",
        "import": "पन्ना आयात करा जाय",
        "importinterwiki": "ट्रान्सविकि आयात",
+       "import-interwiki-text": "आयात करने के लिये एक विकि और एक पृष्ठ चुनें।\nअवतरण दिनांक और संपादक नाम ज्यों-के-त्यों रखे जाएँगे।\nसभी ट्रान्सविकि आयात क्रियाएँ [[Special:Log/import|आयात लॉग]] में डाली जाती हैं।",
        "import-interwiki-sourcewiki": "स्रोत विकि:",
        "import-interwiki-sourcepage": "स्रोत पन्ना:",
+       "import-interwiki-history": "इस पृष्ठ के सभी इतिहास अवतरण कॉपी करें",
        "import-interwiki-templates": "कुल साँचा शामिल करा जाय",
        "import-interwiki-submit": "आयात",
        "import-interwiki-namespace": "गंतव्य नामस्थान:",
        "import-interwiki-rootpage": "गंतव्य पृष्ठ उपसर्ग (वैकल्पिक):",
        "import-upload-filename": "फ़ाइल कय नाँव",
        "import-comment": "टिप्पणी:",
+       "importtext": "कृपया स्रोत विकि से संचिका निर्यातित करने के लिए [[Special:Export|निर्यात सुविधा]] का इस्तेमाल करें।\nइसे अपने संगणक पर सँजो के यहाँ चढ़ा दें।",
        "importstart": "पन्ना आयात होत है...",
        "import-revision-count": "$1 {{PLURAL:$1|अवतरण}}",
        "importnopages": "आयात करेक कवनो पन्ना नाइ है ।",
+       "imported-log-entries": "आयातित $1 {{PLURAL:$1|लॉग प्रविष्टि|लॉग प्रविष्टियाँ}}.\nजब कभी कोई फाइल आपको import करनी हो",
        "importfailed": "आयात विफल होइ गवा: <nowiki>$1</nowiki>",
        "importunknownsource": "अज्ञात आयात स्रोत प्रकार",
        "importcantopen": "आयात फ़ाइल खोल नाई खुला।",
        "importbadinterwiki": "अवैध अन्तरविकि कड़ी",
        "importsuccess": "आयात सफल होइ गवा!",
+       "importnosources": "कोई भी ट्रान्सविकी आयात स्रोत मिले नहीं और प्रत्यक्ष इतिहास अपलोड बन्द कर दिए गए हैं।",
+       "importnofile": "कवनो आयात फाइल नाइ अपलोड करा रहा ।",
+       "importuploaderrorsize": "आयात फ़ाईल अपलोड हुई नहीं। इसका आकार अनुमतिसे ज्यादा हैं।",
+       "importuploaderrorpartial": "आयात फ़ाईल अपलोड हुई नहीं। फ़ाईल आधी अधूरी अपलोड हुई।",
+       "importuploaderrortemp": "आयात फ़ाईल अपलोड हुई नहीं। एक अस्थायी डाइरेक्टरी नहीं मिल रहीं।",
+       "import-parse-failure": "XML आयात पार्स असफल",
+       "import-noarticle": "आयात करेक कवनो पन्ना नाइ है !",
+       "import-nonewrevisions": "कोई अवतरण आयात नहीं किये गये (या तो सभी अवतरण पहले से मौजूद हैं, या त्रुटियों के कारण छोड़े गये)।",
+       "xml-error-string": "$1 पंक्ति $2 मा, कॉलम $3 (बाईट $4): $5",
+       "import-upload": "XML डाटा अपलोड कीन जाय",
+       "import-token-mismatch": "सत्र सामग्री खो गई है। \nकृपया पुनः प्रयास करें।",
+       "import-invalid-interwiki": "इ विकि से आयात नाइ होइ सकत है।",
        "importlogpage": "आयात सूची",
        "import-logentry-interwiki": " $1 कय अन्तरविकिकरण कई गय",
        "javascripttest": "जावास्क्रिप्ट परीक्षण",
        "exif-stripoffsets": "चित्र डाटा स्थान",
        "exif-rowsperstrip": "हर स्ट्रीप मा कतार कय गिन्ती",
        "exif-stripbytecounts": "कॉम्प्रेस्स्ड स्ट्रीपमें बाईट्स",
+       "exif-jpeginterchangeformat": "अफसेट से JPEG SOI",
+       "exif-jpeginterchangeformatlength": "JPEG डेटा कय बाइट",
+       "exif-whitepoint": "उज्जर बिंदू क्रोमॅटिसिटी",
+       "exif-primarychromaticities": "क्रोमॅटिसिटीज ऑफ प्राईमारिटीज",
+       "exif-ycbcrcoefficients": "कलर स्पेस ट्रान्स्फॉर्मेशन मॅट्रीक्स कोएफिशीयंट्स",
+       "exif-referenceblackwhite": "करीया औ उज्जर संदर्भ मूल्यन कय जोड़ी",
+       "exif-datetime": "फ़ाईल बदलाव दिनांक औ समय",
        "exif-imagedescription": "चित्र शिर्षक",
        "exif-make": "क्यामेरा निर्माता",
        "exif-model": "क्यामरा मोडल",
        "exif-gpsdifferential": "GPS डिफरन्शियर करेक्शन",
        "exif-jpegfilecomment": "JPEG फ़ाइल टिप्पणी",
        "exif-keywords": "कीवर्ड",
+       "exif-worldregioncreated": "दुनिया क्षेत्र जहां इ चित्र लै ग रहा",
+       "exif-countrycreated": "देश जहां इ चित्र लै ग रहा",
+       "exif-countrycodecreated": "तस्विर खिचल देश कय कोड",
+       "exif-provinceorstatecreated": "प्रांत या राज्य जहां इ चित्र लै ग रहा",
+       "exif-citycreated": "शहर जहां इ चित्र लै ग रहा",
        "exif-worldregiondest": "दुनिया कय क्षेत्र देखाइ गा है",
        "exif-countrydest": "देश देखाइ गा है",
+       "exif-countrycodedest": "देखावल देश कय कोड",
+       "exif-provinceorstatedest": "देखावल प्रान्त या क्षेत्र",
        "exif-citydest": "देखावल शहर",
+       "exif-sublocationdest": "देखावल सहर भित्तर कय क्षेत्र",
        "exif-objectname": "छोट शीर्षक",
        "exif-specialinstructions": "विशेष निर्देश",
        "exif-headline": "शीर्षक",
        "exif-urgency": "तात्कालिकता",
        "exif-fixtureidentifier": "फिक्चर कय नाम",
        "exif-locationdest": "देखावल जगह",
+       "exif-locationdestcode": "देखावल जगहि कय कोड",
        "exif-contact": "संपर्क जानकारी",
        "exif-writer": "लेखक",
        "exif-languagecode": "भाषा",
        "exif-iimversion": "आईआईएम संस्करण",
        "exif-iimcategory": "श्रेणी",
        "exif-iimsupplementalcategory": "पुरक श्रेणी",
+       "exif-datetimeexpires": "एकरे बाद मा इस्तेमाल ना करा जाइ",
        "exif-datetimereleased": "पे जारी",
        "exif-originaltransmissionref": "मूल प्रसारण स्थान कोड",
        "exif-identifier": "पहचानकर्ता",
        "exif-serialnumber": "कैमरा कय क्रमांक नंबर",
        "exif-cameraownername": "कैमरा कय मालिक",
        "exif-label": "लेबल",
+       "exif-datetimemetadata": "मेटा जानकारी अन्तिम सम्पादन करल दिन",
        "exif-nickname": "छवि कय अनौपचारिक नाँव",
        "exif-rating": "दर्ज़ा (5 से)",
        "exif-rightscertificate": "अधिकार प्रबंधन प्रमाण पत्र",
        "exif-originaldocumentid": "मूल दस्तावेज़ कय अनन्य पहचान",
        "exif-licenseurl": "कॉपीराइट लाइसेंस कय लिए यूआरएल",
        "exif-morepermissionsurl": "वैकल्पिक सूचना लाइसेंस",
+       "exif-attributionurl": "जब इ काम दुबारा इश्तेमाल करा जाइ,तव कृपया लिंक करा जाइ",
+       "exif-preferredattributionname": "जब इ काम दुबारा इश्तेमाल करा जाइ,तव कृपया क्रेडिट दिहा जाइ",
        "exif-pngfilecomment": "PNG फ़ाइल टिप्पणी",
        "exif-disclaimer": "शर्त्त",
        "exif-contentwarning": "सामग्री चेतावनी",
        "exif-event": "चित्रित घटना",
        "exif-organisationinimage": "चित्रित संगठन",
        "exif-personinimage": "व्यक्ति चित्रण",
+       "exif-originalimageheight": "छोट करे कय पहिले चित्र कय उचाई",
+       "exif-originalimagewidth": "छोट करे कय पहिले चित्र कय चौडाई",
        "exif-compression-1": "अनकॉम्प्रेस्स्ड",
        "exif-compression-2": "CCITT समूह 3 1-Dimensional Modified Huffman संचालन इन्कोडिङ्ग",
        "exif-compression-3": "CCITT ग्रुप 3 फ़ैक्स एनकोडिंग",
        "exif-lightsource-2": "फ्लूरोसेंट",
        "exif-lightsource-3": "टंगस्ट्न (इनकॅन्‍डेसेंट प्रकाश)",
        "exif-lightsource-4": "फ्लॅश",
+       "exif-lightsource-9": "साफ मौसम",
+       "exif-lightsource-10": "बदरी",
+       "exif-lightsource-11": "छाँह",
+       "exif-lightsource-12": "डेलाईट फ्लूरोसेंट (D 5700 – 7100K)",
+       "exif-lightsource-13": "डे व्हाईट फ्लूरोसेंट (N 4600 – 5400K)",
+       "exif-lightsource-14": "कूल व्हाईट फ्लूरोसेंट (W 3900 – 4500K)",
+       "exif-lightsource-15": "व्हाईट फ्लूरोसेंट (WW 3200 – 3700K)",
+       "exif-lightsource-17": "प्रमाण प्रकाश A",
+       "exif-lightsource-18": "प्रमाण प्रकाश B",
+       "exif-lightsource-19": "प्रमाण प्रकाश C",
+       "exif-lightsource-24": "ISO स्टूडीयो टंगस्टन",
+       "exif-lightsource-255": "अउर प्रकाश स्रोत",
+       "exif-flash-fired-0": "फ़्लैश नाइ चला",
+       "exif-flash-fired-1": "फ़्लैश चला",
+       "exif-flash-return-0": "कवनो फ़्लैश वापसी पहिचान सुविधा नाइ",
+       "exif-flash-return-2": "फ़्लैश वापसी कय रोशनी नाइ मिला",
+       "exif-flash-return-3": "फ़्लैश वापसी कय रोशनी मिला",
+       "exif-flash-mode-1": "अत्यावश्यक प्रकाश फाएर",
+       "exif-flash-mode-2": "आवश्यक फ्ल्यास संकुचन",
+       "exif-flash-mode-3": "स्वचालित शैली",
+       "exif-flash-function-1": "कवनो फ़्लैश सुविधा नाइ है",
+       "exif-flash-redeye-1": "लाल-आँख घटाव शैली",
+       "exif-focalplaneresolutionunit-2": "इंच",
+       "exif-sensingmethod-1": "अव्यक्त",
+       "exif-sensingmethod-2": "वन चीप कलर एरीया सेन्सर",
+       "exif-sensingmethod-3": "टू चीप कलर एरीया सेन्सर",
+       "exif-sensingmethod-4": "थ्री चीप कलर एरीया सेन्सर",
+       "exif-sensingmethod-5": "कलर सिक्वेण्शीयल एरीया सेंसर",
+       "exif-sensingmethod-7": "ट्रायलिनीयर सेंसर",
+       "exif-sensingmethod-8": "कलर सिक्वेंशीयल लिनीयर सेन्सर",
+       "exif-filesource-3": "डिजिटल स्टिल कैमरा",
+       "exif-scenetype-1": "सिधै खिचल चित्र",
+       "exif-customrendered-0": "सामान्य प्रक्रिया",
+       "exif-customrendered-1": "व्यक्तिगत प्रक्रिया",
+       "exif-exposuremode-0": "ऑटो एक्स्पोज़र",
+       "exif-exposuremode-1": "मैन्युअल एक्पोज़र",
+       "exif-exposuremode-2": "ऑटो ब्रॅकेट",
+       "exif-whitebalance-0": "ऑटो व्हाईट बैलेन्स",
+       "exif-whitebalance-1": "मॅन्यूअल व्हाईट बॅलेन्स",
+       "exif-scenecapturetype-0": "स्टॅन्डर्ड",
+       "exif-scenecapturetype-1": "लैंडस्केप",
+       "exif-scenecapturetype-2": "पोर्ट्रेट",
+       "exif-scenecapturetype-3": "नाईट सीन",
+       "exif-gaincontrol-0": "बिल्कुल नाइ",
+       "exif-gaincontrol-1": "लो गेन अप",
+       "exif-gaincontrol-2": "हाय गेन अप",
+       "exif-gaincontrol-3": "लो गेन डाउन",
+       "exif-gaincontrol-4": "हाय गेन डाउन",
+       "exif-contrast-0": "सामान्य",
+       "exif-contrast-1": "हल्का",
+       "exif-contrast-2": "गाढा",
+       "exif-saturation-0": "सामान्य",
+       "exif-saturation-1": "निम्न सैचुरेशन",
+       "exif-saturation-2": "उच्च सैचुरेशन",
+       "exif-sharpness-0": "साधारण",
+       "exif-sharpness-1": "नरम",
+       "exif-sharpness-2": "कडा",
+       "exif-subjectdistancerange-0": "अज्ञात",
+       "exif-subjectdistancerange-1": "मैक्रो",
+       "exif-subjectdistancerange-2": "नजदीक से देखा जाय",
+       "exif-subjectdistancerange-3": "लम्मे से देखा जाय",
+       "exif-gpslatitude-n": "उत्तरी अक्षांश",
+       "exif-gpslatitude-s": "दक्खिनी अक्षांश",
+       "exif-gpslongitude-e": "पुरुबी रेखांश",
+       "exif-gpslongitude-w": "पच्छु रेखांश",
+       "exif-gpsaltitude-above-sealevel": "$1 {{PLURAL:$1|meter|meters}} समुद्र स्तर से ऊप्पर",
+       "exif-gpsaltitude-below-sealevel": "$1 {{PLURAL:$1|meter|meters}} समुद्र स्तर कय नीचे",
+       "exif-gpsstatus-a": "मेज़रमेंट चलत है",
+       "exif-gpsstatus-v": "मेज़रमेंट इन्टरोपरेबिलीटी",
+       "exif-gpsmeasuremode-2": "२-आयामीय मापन",
+       "exif-gpsmeasuremode-3": "३-आयामीय मापन",
+       "exif-gpsspeed-k": "किलोमिटर प्रति घण्टा",
+       "exif-gpsspeed-m": "मील प्रति घंटा",
+       "exif-gpsspeed-n": "नाट्स",
+       "exif-gpsdestdistance-k": "किलोमीटर",
+       "exif-gpsdestdistance-m": "मील",
+       "exif-gpsdestdistance-n": "समुद्री मील",
+       "exif-gpsdop-excellent": "उत्कृष्ट ( $1 )",
+       "exif-gpsdop-good": "निक ($1)",
+       "exif-gpsdop-moderate": "मध्यम ($1)",
+       "exif-gpsdop-fair": "ठिकय ($1)",
+       "exif-gpsdop-poor": "खराब ($1)",
+       "exif-objectcycle-a": "खाली भिन्नही",
+       "exif-objectcycle-p": "खाली सन्झा",
+       "exif-objectcycle-b": "दुनो भिन्नही अव सन्झा",
+       "exif-gpsdirection-t": "असली दिशा",
+       "exif-gpsdirection-m": "चुम्बकिय दिशा",
+       "exif-ycbcrpositioning-1": "केंद्रित",
+       "exif-ycbcrpositioning-2": "को-साइटेड",
+       "exif-dc-contributor": "योगदानकर्ता",
+       "exif-dc-coverage": "मीडिया कय स्थानिक या लौकिक स्कोप",
+       "exif-dc-date": "दिनांक",
+       "exif-dc-publisher": "प्रकाशक",
+       "exif-dc-relation": "सम्बधित मीडिया",
+       "exif-dc-rights": "अधिकार",
+       "exif-dc-source": "मीडिया स्रोत",
+       "exif-dc-type": "मीडिया कय प्रकार",
+       "exif-rating-rejected": "खारिज कै दिहा गय",
+       "exif-isospeedratings-overflow": "६५५३५ से ढेर",
+       "exif-iimcategory-ace": "कला, संस्कृति औ मनोरंजन",
+       "exif-iimcategory-clj": "अपराध औ कानून",
+       "exif-iimcategory-dis": "प्रकोप अव दुर्घटना",
+       "exif-iimcategory-fin": "अर्थव्यवस्था औ व्यापार",
+       "exif-iimcategory-edu": "शिक्षा",
+       "exif-iimcategory-evn": "पर्यावरण",
+       "exif-iimcategory-hth": "स्वास्थ्य",
+       "exif-iimcategory-hum": "मानवी रुचि",
+       "exif-iimcategory-lab": "श्रम",
+       "exif-iimcategory-lif": "जीवन शैली औ अवकाश",
+       "exif-iimcategory-pol": "राजनीति",
+       "exif-iimcategory-rel": "धर्म औ विश्वास",
+       "exif-iimcategory-sci": "विज्ञान औ प्रौद्योगिकी",
+       "exif-iimcategory-soi": "सामाजिक मुद्दा",
+       "exif-iimcategory-spo": "खेल",
+       "exif-iimcategory-war": "युद्ध, संघर्ष औ अशांति",
+       "exif-iimcategory-wea": "मौसम",
+       "exif-urgency-normal": "सामान्य ( $1 )",
+       "exif-urgency-low": "न्यूनतम ($1)",
+       "exif-urgency-high": "उच्चतम ($1)",
+       "exif-urgency-other": "यूज़र-डिफ़ाइंड प्राथमिकता ( $1 )",
        "namespacesall": "कुल",
        "monthsall": "कुल",
        "confirmemail": "आपन ई-मेल ठहर निश्चित करा जाय",
+       "confirmemail_noemail": "आप कय [[Special:Preferences|पसंद]] मा वैध इ-मेल एड्रेस नाइ दिहा है।",
+       "confirmemail_text": "{{SITENAME}} मा इमेल सुविधन कय लाभ उठावे खर्तीन आप कय आपन इमेल ठहर प्रमाणित करेक परि ।कन्फर्मेशन कोड भेजय खत्तीर निचे कय बटन पे क्लिक किन जाय। मेल मा कोड वाला लिन्क है ।उ लिन्क कय आप अपने ब्राउजर मा खोलि कय आपन इमेल ठहर प्रमाणित कै सका जात है ।",
+       "confirmemail_send": "कन्फर्मेशन कोड मेल करा जाय",
+       "confirmemail_sent": "कन्फर्मेशन इ-मेल भेज दिहा गा है।",
+       "confirmemail_oncreate": "आप कय इ-मेल  ठहर पे एकठु कन्फर्मेशन कोड भेजा गा है।\nलॉग इन करय खत्तीर एकर आवश्यकता नाइ है, लेकिन इ विकि पे उपलब्ध इ-मेल आधारित सुविधन् कय इस्तेमाल करय खत्तीर इ देब जरूरी है।",
+       "confirmemail_sendfailed": "{{SITENAME}} आप कय कन्फर्मेशन मेल नाइ पठै पाए । आप कय इमेल ठहर मा कवनो गलत अक्षर तव नाइ है ,जाँचा जाय ।\nमेलर कहिस :$1",
+       "confirmemail_invalid": "गलत कन्फर्मेशन कोड।\nकोड रद्द होएक संभावना है।",
+       "confirmemail_needlogin": "आप कय आपन इमेल ठहर प्रमाणित करय खत्तीर $1 करेक परि ।",
+       "confirmemail_success": "आप कय इमेल ठहर प्रमाणित होइ गवा है । अब आप [[Special:UserLogin|लाग इन]] कैकय विकि कय मजा लै सका जात है ।",
+       "confirmemail_loggedin": "आप कय इमेल ठहर प्रमाणित होइ गवा है ।",
+       "confirmemail_subject": "{{SITENAME}} इ-मेल एड्रेस प्रमाणिकरण",
+       "confirmemail_invalidated": "इ-मेल एड्रेस प्रमाणिकरण रद्द कै गय",
+       "invalidateemail": "इ-मेल प्रमाणिकरण रद्द करा जाय",
+       "scarytranscludedisabled": "[आंतरविकि ट्रान्स्क्लुडिंग बंद है]",
+       "scarytranscludefailed": "[$1 कय लिये साँचा नाइ मङाइ मिला]",
+       "scarytranscludefailed-httpstatus": "[$1 कय लिये साँचा नाइ मँगाइ मिला, त्रुटि: HTTP $2]",
+       "scarytranscludetoolong": "[यूआरएल बहुतय लम्मा है]",
+       "deletedwhileediting": "'''Warning''':आप जबसे सम्पादन शुर करा गा है तब से इ पन्ना मिटाइ दिहा है ।",
+       "recreate": "फिरसे बनावा जाय",
        "confirm_purge_button": "ठीक है",
        "confirm-purge-top": "पन्ना कय कैश साफ करा जाय ?",
        "confirm-watch-button": "ठीक है",
+       "confirm-watch-top": "इ पन्ना कय अपने ध्यान सुचि मा डारा जाय",
        "confirm-unwatch-button": "ठीक है",
+       "confirm-unwatch-top": "इ पन्ना कय अपने ध्यानसूची से हटावा जाय ?",
        "quotation-marks": "\"$1\"",
        "imgmultipageprev": "← पिछला पन्ना",
        "imgmultipagenext": "अगला पन्ना →",
        "imgmultigo": "जावा जाय",
        "imgmultigoto": "पन्ना $1 पे जावा जाय",
-       "img-lang-go": "जावा जाय"
+       "img-lang-default": "(डिफ़ॉल्ट भाषा)",
+       "img-lang-go": "जावा जाय",
+       "ascending_abbrev": "asc",
+       "descending_abbrev": "desc",
+       "table_pager_next": "अगला पन्ना",
+       "table_pager_prev": "पिछला पन्ना",
+       "table_pager_first": "पहिला पन्ना",
+       "table_pager_last": "आखिरी पन्ना",
+       "table_pager_limit": "एक पन्ना पे $1 आइटम देखावा जाय",
+       "table_pager_limit_label": "आइटम प्रति पन्ना:",
+       "table_pager_limit_submit": "जावा जाय",
+       "table_pager_empty": "रिज़ल्ट नाइ है",
+       "autosumm-blank": "पन्ना कय खाली कै गय",
+       "autosumm-replace": "पन्ना कय '$1' से बदलि जात है।",
+       "autoredircomment": "[[$1]] पे अनुप्रेषित",
+       "autosumm-new": "'$1' कय साथे नँवा पन्ना बनावा गय",
+       "autosumm-newblank": "खाली पन्ना बनावा गय",
+       "watchlistedit-normal-title": "ध्यानसूची बदला जाय",
+       "watchlistedit-normal-legend": "ध्यानसूची से शीर्षक हटावा जाय",
+       "watchlistedit-normal-submit": "शिर्षक हटावा जाय",
+       "watchlistedit-normal-done": "आप कय ध्यानसूचीसे {{PLURAL:$1|1शीर्षक|$1 शीर्षक}} हटाइ गय:",
+       "watchlistedit-raw-title": "कच्चा निगरानी सूची सम्पादन करा जाय",
+       "watchlistedit-raw-legend": "कच्चा निगरानी सूची सम्पादन करा जाय",
+       "watchlistedit-raw-titles": "शीर्षक:",
+       "watchlistedit-raw-submit": "ध्यानसूची अपडेट करा जाय",
+       "watchlistedit-raw-done": "आप कय ध्यान सुची अपडेट होइ गवा है ।",
+       "watchlistedit-raw-added": "{{PLURAL:$1|1शीर्षक|$1 शीर्षक}} बढाइ गय:",
+       "watchlistedit-raw-removed": "{{PLURAL:$1|1शीर्षक|$1 शीर्षक}} हटाइ गय:",
+       "watchlistedit-clear-title": "अवलोकन सूची खाली कै गय",
+       "watchlistedit-clear-legend": "अवलोकन सूची खाली कीन जाय",
+       "watchlistedit-clear-titles": "शिर्षक",
+       "watchlisttools-clear": "अवलोकन सूची खाली कीन जाय",
+       "watchlisttools-view": "आधारित बदलाव देखा जाय",
+       "watchlisttools-edit": "ध्यानसूची देखा जाय अव संपादित कीन जाय",
+       "watchlisttools-raw": "रॉ ध्यानसूची देखा जाय अव संपादित कीन जाय",
+       "signature": "[[{{ns:user}}:$1|$2]] ([[{{ns:user_talk}}:$1|वार्ता]])",
+       "version": "संस्करण",
+       "version-extensions": "इन्स्टॉल करल एक्स्टेंशन",
+       "version-skins": "इन्स्टॉल करल त्वचा",
+       "version-specialpages": "खाश पन्ना",
+       "version-parserhooks": "पार्सर हूक",
+       "version-variables": "चल राशी(variables)",
+       "version-antispam": "स्प्याम रोकथाम",
+       "version-other": "अउर",
+       "version-mediahandlers": "मीडिया संचालक",
+       "version-hooks": "हूक",
+       "version-parser-extensiontags": "पार्सर एक्स्टेंशन टैग",
+       "version-parser-function-hooks": "पार्सर कार्य हूक",
+       "version-hook-name": "हूक नाँव",
+       "version-hook-subscribedby": "ग्राह्यता करय वाले",
+       "version-no-ext-name": "[अज्ञात नाँव]",
+       "version-license": "मीडियाविकि अनुज्ञापत्र",
+       "version-ext-license": "लाइसेंस",
+       "version-ext-colheader-name": "एक्सटेंशन",
+       "version-skin-colheader-name": "स्किन",
+       "version-ext-colheader-version": "संस्करण",
+       "version-ext-colheader-license": "लाइसेंस",
+       "version-ext-colheader-description": "विवरण",
+       "version-ext-colheader-credits": "लेखक",
+       "version-license-title": "$1 के लिए लाइसेंस",
+       "version-credits-title": "$1 कय लिए श्रेय",
+       "version-poweredby-credits": "इ विकि  '''[https://www.mediawiki.org/ MediaWiki]''' से संचालित है, कॉपीराइट © 2001 - $1  $2 ।",
+       "version-poweredby-others": "अउर",
+       "version-poweredby-translators": "translatewiki.net अनुवादक",
+       "version-software": "इन्स्टॉल करल प्रणाली",
+       "version-software-product": "प्रोडक्ट",
+       "version-software-version": "संस्करण",
+       "version-entrypoints": "इन्ट्री प्वाइन्ट यु आर एल",
+       "version-entrypoints-header-entrypoint": "इन्ट्री प्वाइन्ट",
+       "version-entrypoints-header-url": "यू॰आर॰एल",
+       "version-libraries": "इन्स्टाल करल लाइब्रेरी",
+       "version-libraries-library": "लाइब्रेरी",
+       "version-libraries-version": "संस्करण",
+       "redirect-submit": "जावा जाय",
+       "redirect-lookup": "ढूँढा जाय:",
+       "redirect-value": "मूल्य:",
+       "redirect-user": "सदस्य आई॰डी",
+       "redirect-page": "पन्ना आइ॰डी",
+       "redirect-revision": "पन्ना अवतरण संख्या",
+       "redirect-file": "फ़ाइल कय नाँव",
+       "redirect-not-exists": "मुल्य नाइ मिला",
+       "fileduplicatesearch": "डुप्लिकेट फाइल खोजा जाय",
+       "fileduplicatesearch-summary": "हैश वैल्यू कय अनुसार डुप्लिकेट फाइल खोजा जाय ।",
+       "fileduplicatesearch-legend": "डुप्लिकेट खोजा जाय",
+       "fileduplicatesearch-filename": "फ़ाइल कय नाँव",
+       "fileduplicatesearch-submit": "खोजा जाय",
+       "fileduplicatesearch-info": "$1 × $2 पिक्सेल<br />फाइल आकार: $3<br />MIME प्रकार: $4",
+       "fileduplicatesearch-result-1": "फ़ाईल  \"$1\" मा डुप्लिकेट नाइ है।",
+       "fileduplicatesearch-result-n": "फाइल\"$1\" कय {{PLURAL:$2|1 दुरुस्त डुप्लिकेट|$2 दुरुस्त डुप्लिकेट}} हैं ।",
+       "fileduplicatesearch-noresults": "कवनो \"$1\" फाइल नाइ मिला।",
+       "specialpages": "खाश पन्ना",
+       "specialpages-note-top": "कुंजी",
+       "specialpages-note": "* साधारण विशेष पन्ना।\n* <span class=\"mw-specialpagerestricted\">प्रतिबंधित विशेष पन्ना।</span>",
+       "specialpages-group-maintenance": "अनुरक्षण रिपोर्ट",
+       "specialpages-group-other": "अउर खाश पन्ना",
+       "specialpages-group-login": "लाग इन / खाता खोला जाय",
+       "specialpages-group-changes": "नँवा बदलाव अव लाग",
+       "specialpages-group-media": "मीडिया रिपोर्ट अव अपलोड",
+       "specialpages-group-users": "सदस्य अव अधिकार",
+       "specialpages-group-highuse": "अत्यधिक उपयोगी पन्ना",
+       "specialpages-group-pages": "पन्नन् कय सूची",
+       "specialpages-group-pagetools": "पन्ना औज़ार",
+       "specialpages-group-wiki": "डाटा औ औज़ार",
+       "specialpages-group-redirects": "खाश पन्ना पे लैजात है",
+       "specialpages-group-spam": "स्पैम औज़ार",
+       "specialpages-group-developer": "डेवलपर औजार",
+       "blankpage": "खाली पन्ना",
+       "intentionallyblankpage": "इ पन्ना जानबुझी कय खाली छोडा है ।",
+       "tags": "वैध बदलाव चिप्पि",
+       "tag-filter": "[[Special:Tags|चिप्पी]] छननी:",
+       "tag-filter-submit": "फिल्टर",
+       "tag-list-wrapper": "([[Special:Tags|{{PLURAL:$1|टैग}}]]: $2)",
+       "tags-title": "चिप्पि",
+       "tags-tag": "चिप्पी कय नाँव",
+       "tags-display-header": "बदलाव सूचिन् मा प्रदर्शन",
+       "tags-description-header": "अर्थ कय पूरा वर्णन",
+       "tags-active-header": "सक्रिय?",
+       "tags-hitcount-header": "चिप्पी वाला बदलाव",
+       "tags-active-yes": "हाँ",
+       "tags-active-no": "नाहीँ",
+       "tags-edit": "सम्पादन",
+       "tags-hitcount": "$1 {{PLURAL:$1|बदलाव|बदलाव}}",
+       "comparepages": "पन्ना दाँजा जाय",
+       "compare-page1": "पन्ना १",
+       "compare-page2": "पन्ना २",
+       "compare-rev1": "संशोधन १",
+       "compare-rev2": "संशोधन २",
+       "compare-submit": "दाँजा जाय",
+       "compare-invalid-title": "आप कय दिहा शिर्षक अमान्य है ।",
+       "compare-title-not-exists": "आप कय दिहा शिर्षक नाइ है ।",
+       "compare-revision-not-exists": "आप कय दिहा संशोधन नाइ है ।",
+       "dberr-again": "कुछ मिन रुकि कय फिरसे लोड किन जाय",
+       "dberr-usegoogle": "इही बिंचे आप गूगल से खोज कै सका जात है ।",
+       "htmlform-submit": "जमा कीन जाय",
+       "htmlform-reset": "बदलाव फिरसे उही जगही लावा जाय",
+       "htmlform-selectorother-other": "अउर",
+       "htmlform-no": "नाहीँ",
+       "htmlform-yes": "हाँ",
+       "htmlform-chosen-placeholder": "एक्ठु विकल्प चुना जाय",
+       "htmlform-cloner-create": "अउर जोडा जाय",
+       "htmlform-cloner-delete": "हटावा जाय",
+       "sqlite-has-fts": "$1 पूर्ण पाठ खोज समर्थन कय साथ",
+       "sqlite-no-fts": "$1पूर्ण-पाठ खोज समर्थन कय बिना",
+       "logentry-delete-delete": "$1 ने पृष्ठ $3 {{GENDER:$2|हटा}} दिहा गय",
+       "logentry-delete-restore": "$1 ने पृष्ठ $3 कय {{GENDER:$2|पुनर्स्थापित}} कै गय",
+       "revdelete-content-hid": "सामग्री लुकुआवा है",
+       "revdelete-summary-hid": "सम्पादन सारांश लुकुआवा है",
+       "revdelete-uname-hid": "सदस्य नाँव लुकुआवा है",
+       "revdelete-content-unhid": "सामग्री देखावा है",
+       "revdelete-summary-unhid": "सम्पादन सारांश देखावा है",
+       "revdelete-uname-unhid": "सदस्य नाँव देखावा है",
+       "revdelete-restricted": "प्रबंधक पे प्रतिबंध लागू",
+       "revdelete-unrestricted": "प्रबंधक कय प्रबंधन हटावा जाय",
+       "logentry-move-move": "$1 ने $3 पृष्ठ $4 पर {{GENDER:$2|स्थानांतरित}} कै गय",
+       "rightsnone": "(कउनो नाहीं)",
+       "revdelete-summary": "संपादन सारांश",
+       "feedback-subject": "विषय:",
+       "feedback-message": "सनेशा:",
+       "feedback-cancel": "रद्द करा जाय",
+       "feedback-submit": "प्रतिक्रिया भेजा जाय",
+       "feedback-adding": "पृष्ठ पे प्रतिक्रिया जोडत है ...",
+       "feedback-error2": "त्रुटि: संपादन विफल रहा है",
+       "feedback-close": "होइ गवा",
+       "searchsuggest-search": "खोज",
+       "searchsuggest-containing": "...से युक्त",
+       "api-error-badaccess-groups": "इ विकि मा आप कय फाइल अपलोड करेक अनुमति नाइ है",
+       "api-error-badtoken": "आंतरिक त्रुटि: खराब टोकन।",
+       "api-error-duplicate-popup-title": "डुप्लिकेट {{PLURAL:$1| फ़ाइल | फ़ाइल}}",
+       "api-error-empty-file": "आप कय दीहल फ़ाइल खाली रहा।",
+       "api-error-emptypage": "नँवा अव खाली पन्ना बनावै कय अनुमति नाइ है",
+       "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-missing": "फाईल कय एक्सटेंशन लापता है ।",
+       "api-error-hookaborted": "आपके द्वारा प्रयासरत संशोधन किसी एक्स्टेंशन द्वारा निरस्त किया गया।",
+       "api-error-http": "आंतरिक त्रुटि: सर्वर से कनेक्ट करय में असमर्थ।",
+       "api-error-illegal-filename": "अइसन फ़ाइल कय इजाजत नाइ है।",
+       "api-error-missingparam": "आंतरिक त्रुटि: अनुरोध पे  पैरामीटर लापता",
+       "api-error-missingresult": "आन्तरिक त्रुटि: इ प्रतिलिपि सफल निर्धारित नाइ होइ सका",
+       "api-error-mustbeloggedin": "फाइल अपलोड करेक आप कय लाग इन करेक परि",
+       "api-error-mustbeposted": "आंतरिक त्रुटि: HTTP POST अनुरोध कय आवश्यकता है.",
+       "api-error-nomodule": "आंतरिक त्रुटि: कवनो अपलोड मॉड्यूल सेट नाइ है",
+       "api-error-ok-but-empty": "आंतरिक त्रुटि: सर्वर से कवनो जवाब नाइ है।",
+       "api-error-overwrite": "मौजुदा फाइल कय उप्पर नाइ लिखि सका जात अहै ।",
+       "api-error-stashfailed": "आन्तरिक त्रुटि: अस्थाई फाइल राखय मा सर्वर असफल रहा।",
+       "api-error-unclassified": "अज्ञात त्रुटि आइ गवा।",
+       "api-error-unknown-code": "अज्ञात त्रुटि: \"$1\"",
+       "api-error-unknown-error": "आंतरिक त्रुटि: आप कय फ़ाइल अपलोड प्रयास करत समय कुछ गलत होइ गवा रहा।",
+       "api-error-unknown-warning": "अज्ञात चेतावनी: $1",
+       "api-error-unknownerror": "अज्ञात त्रुटि: \"$1\"",
+       "api-error-uploaddisabled": "इ विकि मा अपलोड अक्षम है.",
+       "api-error-verification-error": "इ फाइल दुषित होइ सकत है या गलत एक्टेन्शन अहै ।",
+       "duration-seconds": "$1 {{PLURAL:$1|सॅकेंड}}",
+       "duration-minutes": "$1 {{PLURAL:$1|मिनट}}",
+       "duration-hours": "$1 {{PLURAL:$1|घंटा|घंटा}}",
+       "duration-days": "$1 {{PLURAL:$1|दिन}}",
+       "duration-weeks": "$1 {{PLURAL:$1|सप्ताह}}",
+       "duration-years": "$1 {{PLURAL:$1|साल}}",
+       "duration-decades": "$1 {{PLURAL:$1|दशक}}",
+       "duration-centuries": "$1 {{PLURAL:$1|शताब्दी}}",
+       "duration-millennia": "$1 {{PLURAL:$1|सहस्राब्दी}}",
+       "limitreport-title": "पार्सर प्रोफाइलिङ डाटा",
+       "limitreport-cputime": "सि.पि.यु समय खपत",
+       "limitreport-cputime-value": "$1 {{PLURAL:$1|सॅकेंड}}",
+       "limitreport-walltime": "असली समय खपत",
+       "limitreport-walltime-value": "$1 {{PLURAL:$1|सॅकेंड}}",
+       "limitreport-postexpandincludesize": "विस्तार उपरांत विकिपाठ आकार",
+       "limitreport-postexpandincludesize-value": "$1/$2 {{PLURAL:$2|बाइट}}",
+       "limitreport-templateargumentsize": "साँचा प्राचल आकार",
+       "limitreport-templateargumentsize-value": "$1/$2 {{PLURAL:$2|बाइट}}",
+       "limitreport-expansiondepth": "उच्चतम विस्तार गहराई",
+       "limitreport-expensivefunctioncount": "महंगा पार्सर फंक्शन कय संख्या",
+       "expandtemplates": "साँचा विस्तार",
+       "expand_templates_title": "कन्टेक्स्ट शीर्षक, जैसय {{FULLPAGENAME}} आदि कय लिए:",
+       "expand_templates_input": "इनपुट पाठ:",
+       "expand_templates_output": "परिणाम",
+       "expand_templates_xml_output": "XML आउटपुट",
+       "expand_templates_html_output": "रा HTML आउटपुट",
+       "expand_templates_ok": "ठीक है",
+       "expand_templates_remove_comments": "टिप्पणी हटावा जाय",
+       "expand_templates_remove_nowiki": "परिणाम मा <nowiki> टैग हटावा जाय",
+       "expand_templates_generate_xml": "XML कय पार्स (parse) वृक्ष देखावा जाय",
+       "expand_templates_generate_rawhtml": "सुद्ध HTML देखावा जाय",
+       "expand_templates_preview": "झलक",
+       "pagelang-name": "पन्ना",
+       "pagelang-language": "भाषा",
+       "pagelang-use-default": "डिफ़ॉल्ट भाषा इस्तेमाल कीन जाय",
+       "pagelang-select-lang": "भाषा चुना जाय",
+       "right-pagelang": "पन्ना कय भाषा चुना जाय",
+       "action-pagelang": "पन्ना कय भाषा बदला जाय",
+       "log-name-pagelang": "भाषा लाग बदला जाय",
+       "default-skin-not-found-row-enabled": "* <code>$1</code> / $2 (सक्षम)",
+       "default-skin-not-found-row-disabled": "* <code>$1</code> / $2 ('''अक्षम''')",
+       "mediastatistics": "मीडिया कय आँकड़ा",
+       "mediastatistics-nbytes": "{{PLURAL:$1|$1 बाईट}} ($2; $3%)",
+       "mediastatistics-table-mimetype": "MIME प्रकार",
+       "mediastatistics-table-extensions": "संभावित एक्श्टेंशन",
+       "mediastatistics-table-count": "फाइल कय गिन्ती",
+       "mediastatistics-table-totalbytes": "कुल साइज",
+       "mediastatistics-header-unknown": "अज्ञात",
+       "mediastatistics-header-bitmap": "बिटमैप चित्र",
+       "mediastatistics-header-audio": "आडियो",
+       "mediastatistics-header-video": "वीडियो",
+       "mediastatistics-header-office": "आफिस",
+       "mediastatistics-header-text": "शाब्दिक",
+       "json-error-unknown": "JSON से समस्या रहा । गल्ती: $1"
 }
index d9f72e5..c1b8944 100644 (file)
        "userlogin-loggedin": "Siz artıq {{GENDER:$1|$1}} kimi daxil olmusunuz.\nAşağıdakı formadan istifadə edərək, başqa bir istifadəçi kimi daxil ola bilərsiniz.",
        "userlogin-createanother": "Başqa bir istifadəçi hesabı yarat",
        "createacct-emailrequired": "E-poçt ünvanı",
-       "createacct-emailoptional": "E-poçt ünvanı (istəyə bağlı)",
+       "createacct-emailoptional": "E-poçt ünvanı (məcburi deyil)",
        "createacct-email-ph": "E-poçt ünvanınızı daxil edin",
        "createacct-another-email-ph": "E-poçt ünvanını daxil edin",
        "createaccountmail": "Müvəqqəti təsadüfi bir paroldan istifadə edə bilər və bu parolu göstərilən e-poçt ünvanına göndərə bilərsiniz",
-       "createacct-realname": "Gərçək adı (istəyə bağlı)",
+       "createacct-realname": "Əsl adınız (məcburi deyil)",
        "createaccountreason": "Səbəb:",
        "createacct-reason": "Səbəb",
        "createacct-reason-ph": "Niyə başqa bir hesab yaradırsınız",
        "pageinfo-header-edits": "Redaktə tarixçəsi",
        "pageinfo-header-restrictions": "Səhifə mühafizəsi",
        "pageinfo-header-properties": "Səhifə xüsusiyyətləri",
+       "pageinfo-display-title": "Göstərilən başlıq",
+       "pageinfo-length": "Səhifənin ölçüsü (baytla)",
+       "pageinfo-article-id": "Səhifə ID-si",
+       "pageinfo-language": "Səhifənin dili",
+       "pageinfo-content-model": "Səhifə məzmunu modeli",
+       "pageinfo-robot-noindex": "İcazə verilmədi",
        "pageinfo-watchers": "Səhifəyə baxışların sayı",
+       "pageinfo-few-watchers": "$1 {{PLURAL:$1|izləyicidən|izləyicilərdən}} az",
        "pageinfo-firstuser": "Səhifəni yaradan",
        "pageinfo-firsttime": "Səhifənin yaranma tarixi",
        "pageinfo-lastuser": "Sonuncu redaktor",
        "pageinfo-lasttime": "Sonuncu redaktənin tarixi",
        "pageinfo-edits": "Redaktələrin ümumi sayı",
        "pageinfo-authors": "Fərqli müəlliflərin ümumi sayı",
+       "pageinfo-recent-edits": "Sonuncu redaktə sayı ($1 ərzində)",
+       "pageinfo-recent-authors": "Sonuncu əhəmiyyətli dəyişiklik etmiş müəlliflər",
+       "pageinfo-magic-words": "Sehrli {{PLURAL:$1|1=söz|sözlər}} ($1)",
+       "pageinfo-templates": "{{PLURAL:$1|Şablon|Şablonlar}} ($1)",
        "pageinfo-toolboxlink": "Əsas məlumatlar",
        "pageinfo-redirectsto": "İstiqamətləndirmə",
        "pageinfo-redirectsto-info": "məlumat",
+       "pageinfo-contentpage": "Məzmunlu səhifə kimi sayılır",
        "pageinfo-contentpage-yes": "Bəli",
+       "pageinfo-protect-cascading": "Kaskad mühafizə burada qoşulub",
+       "pageinfo-category-pages": "Səhifələrin sayı",
+       "pageinfo-category-subcats": "Altkateqoriyaların sayı",
+       "pageinfo-category-files": "Faylların sayı",
        "markaspatrolleddiff": "Yoxlanıldı",
        "markaspatrolledtext": "Səhifəni patrullanmış kimi işarələ",
        "markedaspatrolled": "Yoxlanıldı",
index 401d4e7..85ed84b 100644 (file)
@@ -12,7 +12,8 @@
                        "Shirayuki",
                        "Microchip08",
                        "아라",
-                       "Koroğlu"
+                       "Koroğlu",
+                       "Baloch Afghanistan"
                ]
        },
        "tog-underline": "باغلانتیلارین آلتینی خطله:",
        "prefs-personal": "ایستیفاده‌چی پروفایلی",
        "prefs-rc": "سون دَییشیکلیکلر",
        "prefs-watchlist": "ایزله‌دیکلر",
+       "prefs-editwatchlist": "ایزله‌دیگیم صحیفه‌‌لری دَییشدیر",
        "prefs-watchlist-days": "ایزله‌دیکلرده گؤستریلن گونلر",
        "prefs-watchlist-days-max": "چوخو {{PLURAL:$1|بیر|$1}} گون",
        "prefs-watchlist-edits": "گنیشلنمیش ایزله‌مه‌لرده گؤستریلن دَییشیکلیکلرین چوخو:",
        "delete-toobig": "بو صحیفه، $1 {{PLURAL:$1 | دنه دییشیک‌لیک | دنه دییشیک‌لیک}} ایله چوخ اوزون بیر کئچمیشه مالیک‌دیر.\nبئله صحیفه‌لرین سیلینمه‌سی، {{SITENAME}} سایتینی پوزماماق اوچون مهدودلاشدیریلماقدا‌دیر.",
        "delete-warning-toobig": "بو صحیفه‌‌نین بؤيوک بیر ديَیشیکلیک کئچمیشی وار، $1 {{PLURAL:$1|نسخه| نسخه}} اوزرینده. \nبونو سیلمک {{SITENAME}} عملیاتلارینی مخدل‌ائده‌بیلیر؛ \nدیقتله داوام ائدین.",
        "rollback": "اوولکی نوسخه لر",
-       "rollback_short": "اوولکی حالینا قایتار",
        "rollbacklink": "گئری‌دؤندر",
        "rollbacklinkcount": "گیتیرلمه $1  {{PLURAL:$1|دییشمک |دییشمک}} دییشدیرمه",
        "rollbacklinkcount-morethan": "گیتیرلمه آرتیق $1 {{PLURAL:$1|دییشمک |دییشمک}} دییشدیرمه",
        "import-logentry-interwiki": "$1-ی ویکی‌آراسی ائتدی",
        "import-logentry-interwiki-detail": "$2-دن {{PLURAL:$1|بیر|$1}} نوسخه",
        "javascripttest": "جاوااسکریپت تِستی",
-       "javascripttest-title": "$1 تِستلری ایشله‌دیلیر",
        "javascripttest-pagetext-noframework": "بو صحیفه، جاوااسکریپت تِستلرینی ایشلدمگه ساخلانیلیب‌دیر.",
        "javascripttest-pagetext-unknownframework": "تانینمامیش تِست ائتمه سیستِمی «$1».",
        "javascripttest-pagetext-frameworks": "لوطفاً بو تِست ائتمه سیستِملرین بیرینی سئچین: $1",
        "javascripttest-pagetext-skins": "تِستلرین ایجرا ائتمک اوچون بیر قابیق سئچین:",
        "javascripttest-qunit-intro": "mediawiki.org-دا [$1 تِست ائتمه سندلندیرمه‌لری]نه باخین.",
-       "javascripttest-qunit-heading": "مئدیاویکی جاوااسکریپت QUnit تِست مجموعه‌سی",
        "tooltip-pt-userpage": "ایستیفاده‌چی صفحه‌نیز",
        "tooltip-pt-anonuserpage": "سیز او آی‌پی آدرسیله دَییشیکلیک ائتدیگینیز ایستیفاده‌چی صحیفه‌سی",
        "tooltip-pt-mytalk": "دانیشیق صحیفه‌نیز",
index 9a1c621..4651871 100644 (file)
        "externaldberror": "Адбылася памылка аўтэнтыфікацыі з дапамогай вонкавай базы зьвестак, ці Вам не дазволена абнаўляць свой рахунак.",
        "login": "Увайсьці",
        "nav-login-createaccount": "Уваход / стварэньне рахунку",
-       "userlogin": "Увайсьці ў сыстэму",
+       "userlogin": "Увайсьці ў сыстэму / стварыць рахунак",
        "userloginnocreate": "Увайсьці",
        "logout": "Выйсьці",
        "userlogout": "Выйсьці",
        "right-override-export-depth": "экспартаваньне старонак, уключаючы зьвязаныя старонкі з глыбінёй да 5",
        "right-sendemail": "адпраўка электронных лістоў іншым удзельнікам",
        "right-passwordreset": "прагляд электронных лістоў з ачысткай паролю",
+       "right-managechangetags": "ствараць і выдаляць [[Special:Tags|меткі]] з базы зьвестак",
        "newuserlogpage": "Журнал стварэньня рахункаў",
        "newuserlogpagetext": "Гэта журнал стварэньня рахункаў удзельнікаў і ўдзельніц.",
        "rightslog": "Журнал правоў удзельнікаў",
        "action-viewmyprivateinfo": "прагляд вашых прыватных зьвестак",
        "action-editmyprivateinfo": "рэдагаваньне вашых прыватных зьвестак",
        "action-editcontentmodel": "рэдагаваньне мадэлі зьместу старонкі",
+       "action-managechangetags": "стварэньне і выдаленьне метак з базы зьвестак",
        "nchanges": "$1 {{PLURAL:$1|зьмена|зьмены|зьменаў}}",
        "enhancedrc-since-last-visit": "$1 {{PLURAL:$1|з апошняга візыту}}",
        "enhancedrc-history": "гісторыя",
        "tags-tag": "Назва тэга",
        "tags-display-header": "Новыя запісы ў сьпісе зьменаў",
        "tags-description-header": "Поўнае апісаньне значэньня",
+       "tags-source-header": "Крыніца",
        "tags-active-header": "Актыўны?",
        "tags-hitcount-header": "Пазначаныя зьмены",
+       "tags-actions-header": "Дзеяньні",
        "tags-active-yes": "Так",
        "tags-active-no": "Не",
+       "tags-source-extension": "Вызначаецца пашырэньнем",
+       "tags-source-manual": "Ставіцца ўручную ўдзельнікамі і робатамі",
+       "tags-source-none": "Больш не выкарыстоўваецца",
        "tags-edit": "рэдагаваць",
        "tags-hitcount": "$1 {{PLURAL:$1|зьмена|зьмены|зьменаў}}",
        "comparepages": "Параўнаньне старонак",
index 6d63a9c..0b57887 100644 (file)
@@ -25,7 +25,8 @@
                        "StanProg",
                        "Bjankuloski06",
                        "Vodnokon4e",
-                       "ShadeOfGrey"
+                       "ShadeOfGrey",
+                       "PetaRZ"
                ]
        },
        "tog-underline": "Подчертаване на препратките:",
        "blocklog-showlog": "Потребителят е бил блокиран в миналото.\nЗа справка по-долу е дадено извлечение от дневника на блокиранията:",
        "blocklog-showsuppresslog": "Потребителят е бил блокиран и прикриван в миналото.\nЗа справка по-долу е дадено извлечение от дневника на прикриванията:",
        "blocklogentry": "блокира [[$1]] със срок на изтичане $2 $3",
-       "reblock-logentry": "промени параметрите на блокирането на [[$1]] със срок на изтричане $2 $3",
+       "reblock-logentry": "промени параметрите на блокирането на [[$1]] със срок на изтичане $2 $3",
        "blocklogtext": "Тази страница съдържа дневник на блокиранията и отблокиранията.\nАвтоматично блокираните IP-адреси не са показани.\nВижте [[Special:BlockList|списъка на блокираните IP-адреси]] за текущото състояние на блокиранията.",
        "unblocklogentry": "отблокира $1",
        "block-log-flags-anononly": "само анонимни потребители",
index d2b0944..a5d705f 100644 (file)
        "tog-watchlisthideown": "نی ایڈیٹ شه واچلیستی تا چیهر بیئنت",
        "tog-watchlisthidebots": "رباتئ ایڈیٹ شه واچلیستی تا چیهر بیئنت",
        "tog-watchlisthideminor": "کم ئین ایڈیٹ شه واچلیستی تا چیهر بیئنت",
+       "tog-watchlisthideliu": "لوگین بوته ئین کار زوروکانی ایڈیٹ شه نی واچلیست چیهر بیئنت",
+       "tog-watchlisthideanons": "نا دروستي ئین کار زوروکانی ایڈیٹ شه نی واچلیست چیهر بیئنت",
        "tog-watchlisthidepatrolled": "گشت وارته ئین ایڈیٹ شه واچلیستی تا چیهر بیئنت",
+       "tog-ccmeonemails": "په من یک کاپی شه آ ایمیلان که من په دیگران دیم ئه دهین ، دیم داته بیئت",
        "tog-diffonly": "جهلگی تاکدیمی محتوا تفاوت نشان داته مه بئینت",
        "tog-showhiddencats": "چیهرین تهرئانه نشان دهی",
        "tog-norollbackdiff": "بئد شه بیئرگردینتینا تفاوت نشان داته مه بیئت",
        "jumpto": "جوپ کورتین بی:",
        "jumptonavigation": "ناوبری",
        "jumptosearch": "گشتین",
+       "view-pool-error": "متاسفانه موچین سرویس بی انونین وختا باز مشغول انت.\nبازین شه کار گیروکان لوٹنت که ای تاکدیما بگیندنت. \nمهربانی بکنیت دیم شه ایشی که پدا په ای تاکدیمی دیستینا کوشش بکنیت یک کمی صبر بکنیت.\n\n$1",
        "generic-pool-error": "متاسفانه موچین سرویس بی انونین وختا باز مشغول انت.\nبازین شه کار گیروکان لوتنت که ای تاکدیما بگیندنت. \nمهربانی بکنیت دیم شه ایشی که پدا په ای تاکدیمی دیستینا کوشش بکنیت یک کمی صبر بکنیت.",
        "pool-timeout": "تمام بوتین انتظارمهلتئ په قُلپ کورتینئ خاتیرا",
        "pool-queuefull": "مخزن ئی صف پر اینت",
        "error": "خطا",
        "databaseerror": "مئلوماتین بانکئ خطا",
        "databaseerror-text": "مشکلی بی مئلوماتین بانکی تا رخ داته. \nای ممکن اینت شه مشکلا بی نرم افزاری تا بیئت .",
+       "databaseerror-textcl": "مشکلی بی مئلوماتین بانکی تا رخ داته.",
        "databaseerror-query": "پرس‌وجو: $1",
        "databaseerror-function": "تابع: $1",
        "databaseerror-error": "خطا: $1",
        "readonly": "مئلوماتئ بانک قُلپ بوت",
        "enterlockreason": "یک دلیلی په قُلپ کورتینا بیاریت، که آیی تا نشان داته بوته بیئت که چی وختی قُلپ پاچه ئه بیئت",
        "readonlytext": "انون مئلوماتئ بانک په تغیراتان و جوڑ\t کورتینئ تاکدیمانیا قُلپ بوته؛ای حالت احتمالآ په خاتیری تئمیراتان است و پدا شه آیی وضیئت بی حالت اول ئا بیئر ئه گردید.\n\nمدیری که آیرا قُلپ کورته وتی توضیئاتانا پیش کورته است : $1",
+       "missing-article": "مئلوماتین بانک تاکدیمی متنا گو «$1» $2 ئی ناما که باید ودي کورتین ، ودي کورته نه توانت.\n\nاین مشکل معمولاً وختی ئه کیت که شما یک کهنگین لینک ئی و یا پاک بوتگین تاکدیمیا پدا بگردیت.\n\nیا دیگه شاید بی سافٹ ایر تا مشکل بیئت.\nمهربانی بکنیت ای مشکلا گو انترنتی ئین ادرسئ گوشتینا بی یکی شه [[Special:ListUsers/sysop|مدیرئان]] راپور دهیت.",
        "missingarticle-rev": "(شمارهٔ نسخه: $1)",
        "missingarticle-diff": "(تفاوت: $1، $2)",
+       "readonly_lag": "مئلوماتین بانک بی انونین وختا اتوماتیکین رکما قُلپ بوته تا که پشتوانی ئی و بُنیادی ئین نخسه گو وت هماهنگ بیئنت",
        "internalerror": "داخلین خطا",
        "internalerror_info": "داخلین خطا: $1",
        "filecopyerror": "نه شه فایل «$1» بی «$2» کاپی بیئت.",
        "unexpected": "غیرمنتظرئین اندازه: «$1»=«$2».",
        "formerror": "خطا: نه توانن فرم ئا دیم دی ین.",
        "badarticleerror": "نه توانن ای ئملا په ای تاکدیما انجام دی ین .",
+       "cannotdelete": "«$1» ئی تاکدیم یا اکسئ پاک کورتینی امکان نه اینت .\nممکن اینت دیمتیرا دیگه کسی آیرا پاک کورته بیئت.",
        "cannotdelete-title": "نه توانیت که «$1» ئی تاکدیما ئا پاک کنیت",
        "delete-hook-aborted": "پاک بوتین شه قلاب ئی نیمگاه لغو بوت.\nبی ای باره ئا هیچ توضیحی داته نه بوته.",
        "no-null-revision": "پوچ ئین نخسه ئی جوڑ کورتینئ امکان  په  «$1» ئی تاکدیما موجود نه اینت",
        "badtitle": "خرابین ئنوان",
+       "badtitletext": "شمی درخواستین ئنوان نا موتبر،خالی،یا میان زبانین یا میان ویکی ئین ئنوان و یا شه خرابین لینکی ات.\nممکن اینت که یک یا چینکه نویسگ داشته بیئت که نتوانن آوانا بی ئنوانی تا استفاده کنن.",
+       "perfcached": "همراهی کنوکین دیتا شه نهانی ئین حافظهٔ ئا فراخوانی بوته و ممکن اینت کاملاً اپڈیٹ نه بوته. حداکثر {{PLURAL:$1|یک نتیجه| $1 نتیجه}} بي نهانی ئین حافظهٔ تا دسترس ئی وڈ اینت.",
+       "perfcachedts": "همرای کنوکین دیتا شه نهانی ئین حافظه ئا فرخوانی بوته و آخرین وار  بئ  $1 ئی تا اپڈیٹ بوته. حداکثر {{PLURAL:$4|یک نتیجه|$4 نتیجه}} بئ نهانی ئین حافظه تا دسترس ئی وڈ اینت.",
+       "querypage-no-updates": "ای تاکدیمی اپڈیٹ کورتین انون غیر فئال بوته.\nای تاکدیمی مئلومات ممکن اینت که نوک نه بوته انت.",
        "viewsource": "نشان داتین مبدائی",
        "viewsource-title": "مبدا ئی نشان داتین په $1",
        "actionthrottled": "شمی ئملی دیم گیپته بوت",
+       "actionthrottledtext": "په دیمگیری شه اسپم شینک بوتینی خاتیرا، په شما اجازه نه اینت که ایرنگین ئملی ئا چینکه وار بی یک کمین وختی تا انجام دهیت.\nمهربانی بکنیت پد شه چینکه دقیقه ئا کوشش بکنیت.",
+       "protectedpagetext": "ای تاکدیم په دیمگیری شه ایڈیٹ و یا دیگرین فئالیئتان قُلپ بوته.",
        "viewsourcetext": "شما ئه توانیت ای تاکدیمی مبدائا بگیندیت و یا کاپی بکنیت:",
+       "viewyourtext": "شما ئه تونیت که  '''وتئ ایڈیٹانی'''  منشاء ئا بی ای تاکدیمی تا بگیندیت و کاپی بکنیت:",
+       "protectedinterface": "ای تاکدیم یک متنی ئا ارایه ئه کنت که ای ویکی ئی تا یک سافٹ ایرئ  په واسط بی کار زوروکانی مانجینا اینت و په دیمگیری ئا شه خرابکاری ئی  خاتیرا قُلپ بوته.\nپه اضافه کورتین یا تغیر داتین ترجمه په موچین ویکی ئان ، مهربانی بکنیت شه [//translatewiki.net/ translatewiki.net]، میڈیا ویکی ئی محلی کورتینی پروژه ئا ، استفاده بکنیت.",
+       "editinginterface": "<strong>هشدار:</strong> تاکدیمی که ایڈیٹ ئه کنیت متنی ئا شامل ئه بیئت که بی ای کار زوروکئ واسط ئی سافت ایر تا به کار گیپته بوته.\nای تاکدیمی تغییر  منجر بئ کار زوروکئ واسط ئی  ظاهر ئین تغیر ای سافت ایر په دیگه کار زوروکان ئه بیئت.",
+       "translateinterface": "په اضافه کورتین یا تغیر داتین ترجمه ئی په موچین ویکی ئان،مهربانی بکنیت شه [//translatewiki.net/ translatewiki.net]، مییڈیا ویکی  محلی کورتینی پروژه ئا، استفاده بکنیت.",
+       "cascadeprotected": "ای تاکدیم بئ ایڈیٹتانی مقابلا قُلپ بوته چونکه بی جهلگین قُلپ بوته ئین  {{PLURAL:$1|تاکدیم|تاکدیمانئ}} تا بئ {{PLURAL:$1|آوان|آوانئ}} تا «آپشاری» ئی گزینه انتخاب بوته:\n$2",
+       "namespaceprotected": "شما '''$1''' ئی تاکدیمانئ فضای نامئ ایڈیٹ کورتین ئی اجازه ئا  نداریت.",
+       "customcssprotected": "شما ای سی اس اس ئی تاکدیمئ ایڈیٹ ئی اجازه ئا نداریت، په خاتیریکه ایشی تا یک کار زوروکئ شخصی ئین تنظیمات هستنت.",
+       "customjsprotected": "شما ای جاوااسکریپت ئی تاکدیمئ ایڈیٹ ئی اجازه ئا نداریت، په خاتیریکه ایشی تا یک کار زوروکئ شخصی ئین تنظیمات هستنت.",
+       "mycustomcssprotected": "شما ای سی اس اس ئی تاکدیمی ایڈیٹ ئی اجازه ئه نداریت.",
+       "mycustomjsprotected": "شما ای جاوااسکریپت ئی ایڈیٹ ئی اجازه ئه نداریت.",
+       "myprivateinfoprotected": "شما په وتئ شخصین مئلوماتانئ ایڈیٹ ئی اجازه ئه نداریت.",
+       "mypreferencesprotected": "شما په وتئ تنظیماتانئ ایڈیٹ ئی خاتیرا اجازه نداریت.",
+       "ns-specialprotected": "خاصین تاکدیم موچ غیر پئال انت.",
+       "titleprotected": "ای ئنوان شه [[User:$1|$1]] نیمگا په جوڑ کورتینئ مقابلا قُلپ بوته.\nوتئ دلیل ئا پیش کورته ایش اینت : «''$2''».",
+       "filereadonlyerror": "«$1» ئی فایلئ تغیر داتین ممکن نه اینت چون ه «$2» ئی فایلي مخزن فقط بی وانتینی ئین  حالت ئی تا قرار داریت.\n\nمدیری که آیرا قُلپ کورته ایرنگ توضیح داته:  «$3».",
+       "invalidtitle-knownnamespace": "نا موتبرین ئنوان گو نامئ فضای  «$2» و متن ئی  «$3»",
+       "invalidtitle-unknownnamespace": "ناموتبرین ئنوان گو نا زاتین نامئ فضای شماره  $1 و متن ئی «$2»",
        "exception-nologin": "لاگین نه بوته ئیت",
+       "exception-nologin-text": "مهربانی بئ [[Special:Userlogin|تا داخل بیئت]] تا بتوانیت بئ ای تاکدیما دسترسی داشته بئیت.",
+       "exception-nologin-text-manual": "مهربانئ بکنیت  $1  تا بتوانیت بئ ای تاکدیم یا عمل ئا دسترسی داشته بئیت .",
+       "virus-badscanner": "بدین پیکربندی: نازانتین ویروس ئی سکن کورتین: ''$1''",
        "virus-scanfailed": "ناکامین سکن  (کود $1)",
        "virus-unknownscanner": "نامئلومین انتی ویروس:",
        "welcomeuser": "وش آتیت $1!",
        "yourpasswordagain": "پاسوردی تکرار کورتین",
        "createacct-yourpasswordagain": "پاسوردا تایید کورتین",
        "createacct-yourpasswordagain-ph": "پاسوردا پدا داخل کورتین دومین وارا",
+       "remembermypassword": "پاسورد یا چیهرگال ئا (تا حداکثر $1 {{PLURAL:$1|روچ|روچ}}) بئ ای بروزیري تا بسات",
        "userlogin-remembermypassword": "نا داخل بوتگ بسات",
        "userlogin-signwithsecure": "شه امنیت ئا استفاده بکنیت",
        "yourdomainname": "شمی دامنهٔ:",
        "password-change-forbidden": "شما ئا نه توانیت که بی ای ویکی تا پاسوردا تغیر بدهیت",
+       "externaldberror": "بئ مئلوماتین بانکی تا یک اوتوماتیکین خطا ئی رخ داته و یا ایکه شما وتئ خارجی ئین حسابئ شما اپڈیٹ کورتینی ئی اجازه ئا نداریت.",
        "login": "داخل بوتین",
        "nav-login-createaccount": "داخل بوتین  / کار زوروکین حسابي جوڑ کورتین",
        "userlogin": "داخل بوتین  / کار زوروکین حسابي جوڑ کورتین",
        "loginerror": "خطا بی داخل بوتینی تا",
        "createacct-error": "کار زوروکین حسابئ جوڑ کورتینی خطا",
        "createaccounterror": "ای حسابئ جوڑ کورتین امکان نداریت: $1",
+       "noname": "شما یک موتبرین کار زوروکی ئین نامی ئا مشخص نه کورته ئیت.",
+       "loginsuccesstitle": "کامیابین لوگین",
+       "loginsuccess": "'''شما انون گو «$1» ئی نا بی {{SITENAME}} ئی تا داخل بوته ایت.'''",
+       "nosuchusershort": "هیچ کار زوروکئ بی نامئ  ''$1'' ئا وجود نداریت.\nوتئ املا ئا چیک بکنیت.",
+       "nouserspecified": "باید یک کار زوروکئ نام مشخص بکنیت.",
+       "login-userblocked": "ای کار زوروک بلاک بوته، په داخل بوتینا اجازه نه اینت.",
+       "wrongpassword": "ای پاسورد یا چیهر گالا که داخل کورته ایت صحیح نه اینت.\nمهربانی بکنیت، پدا امتحان بکینت.",
+       "wrongpasswordempty": "ای پاسورد یا چیهر گالا که داخل کورته ایت ، خالی اینت.\nمهربانی پدا کوشش بکنیت.",
        "passwordtooshort": "پاسورد باید کم شه کم {{PLURAL:$1|۱ حرف|$1 حرف}} داشته بیئت.",
+       "password-name-match": "شمی چیهرگال یا پاسورد باید شه شمی کار زورکی ئین ناما فرق داشته بیئت.",
+       "password-login-forbidden": "استفاده شه ای کار زوروکی ناما و شه ای چیهرگالا اجازه نه اینت.",
        "mailmypassword": "پاک کورتین پاسوردئ",
+       "passwordremindertitle": "نوکین موقتی ئین چیهرگال یا پاسورد په  {{SITENAME}}",
+       "noemail": "هیچ ایمیل ادرسئ په  «$1» کار زوروکا ثبت نه بوته.",
+       "noemailcreate": "باید یک موتبرین ایمیل ادرسئ داخل بکنیت",
+       "mailerror": "خطا بی ایمیلی داتینی تا: $1",
+       "emailauthenticated": "شمی ایمیلی ادرس بی $2 سائت $3  تا تصدیق ئه بیئت.",
+       "emailnotauthenticated": "شمی ایمیلئ ادرس تا انون قبول نه بوته.\nایمیل په هیچ یک شه ویژه گی ئان دیم داته ئه نه بیئت.",
+       "noemailprefs": "په ای قابلیت ئانی دیمبورتینا یک ایمیل ادرسئ مشخص بکنیت.",
+       "emailconfirmlink": "وتئ ایمیل ادرسی تائید کورتین",
+       "cannotchangeemail": "شمی حسابئ ایمیلئ تغیر داتین بی ای ویکی ئی تا تغیری وڈ نه اینت.",
        "emaildisabled": "ای ویبسایت ایمیل ئا دیم داته ئه نه کنت.",
        "accountcreated": "کار زوروکین حساب جوڑ بوت",
        "accountcreatedtext": "کار زوروکئ حساب په [[{{ns:User}}:$1|$1]] ([[{{ns:User talk}}:$1|هبر و گپ]]) جوڑ بوته.",
        "createaccount-title": "کار زوروکئ حساب جوڑ کورتین بی {{SITENAME}}",
        "createaccount-text": "یک نفری په شمی ایمیلا یک کار زوروکین حسابئ  بی {{SITENAME}} تا گو «$2» ناما جوڑ کورته ($4)، که آیی پاسورد ایش اینت : $3\nشما باید همی انون وتئ حسابئ تا داخل بئیت و وتئ پاسوردا تغیر بدهیت .\n\nاگه ای حساب اشتباهی جوڑ بوته ، ای پیام ئا نادیستگ بگیریت.",
+       "login-abort-generic": "شمی لوگین ناکام ات - ساکت بوت",
+       "login-migrated-generic": "شمی کار زوروکین نام انتقال بوته، و شمی کار زوروکین نام دیگه بی ای ویکی ئی تا وجود نداریت.",
        "loginlanguagelabel": "زبان: $1",
+       "suspicious-userlogout": "شمی ریکویست په دربوتینی خاتیرا رد بوت، بی خاتیریکه بی نظر ئه رسیئت که ای درخواست شه  خراب و یا پروکسی ئین بروزیرئ نیمگا دیم داته بوته.",
+       "createacct-another-realname-tip": "واقئین نام اختیاری اینت.\nاگه آیی را بنویسیت شه شما بی قدردانی ئی وختا شه شمی واقئین ناما استفاده بیئت",
        "pt-login": "داخل بوتین",
        "pt-login-button": "داخل بوتین",
        "pt-createaccount": "کار زوروکین حسابئ جوڑ کورتین",
        "pt-userlogout": "در بوتین",
+       "php-mail-error-unknown": "نا زانتین خطابی تابع  mail()‎ پی‌اچ‌پی",
+       "user-mail-no-addy": "کوشش په دیم داتین یک خط بی شه گوجام ایمیل ادرسئ  ئا.",
+       "user-mail-no-body": "کوشش په دیم داتین ئا یک گونڈین یا خالی ئین ایمیل ئی ئا.",
        "changepassword": "پاسوردی تغیر داتین",
        "resetpass_header": "پاسوردئ تغیر داتین",
        "oldpassword": "دیمئ پاسورد:",
        "resetpass-submit-cancel": "کنسیل",
        "resetpass-temp-password": "موقیئتین پاسورد:",
        "passwordreset": "پاک کورتین پاسوردئ",
+       "passwordreset-text-many": "{{PLURAL:$1|په موقتی ئین چیهرگال ئی گیپتین شه ایمیلئ راه ئا، یکی شه زمینه‌هان ئا پر کنیت.}}",
        "passwordreset-legend": "پاک کورتین پاسوردئ",
+       "passwordreset-disabled": "ای ویکی ئی تا پاسورد یا چیهرگالی پدا بیئر گردینتین غیر پئال اینت.",
+       "passwordreset-emaildisabled": "ایمیلی گزینه بی ای یکی ئی تا پئال نه ونت.",
        "passwordreset-username": "کار زوروکین نام:",
        "passwordreset-domain": "دامنه:",
+       "passwordreset-capture": "ایمیلی آخیر نشان داته بیئت؟",
+       "passwordreset-capture-help": "اگه ای گزینه ئا بگیندیت ، ایمیل (گو موقتین پاسوردا) بی شما نشان داته ئه بیئت و په کار زوروکا هم دیم داته ئه بیئت.",
        "passwordreset-email": "ایمیل ادرس:",
        "passwordreset-emailtitle": "حسابئ مئلومات بی {{SITENAME}}",
+       "passwordreset-emailelement": "کار زوروکئ نام: $1\nموقت ئین چیهرگال: $2",
+       "passwordreset-emailsent": "یک ایمیل په چیهر گالئ  پاک بوتین  خاتیرا دیم داته بوت.",
+       "passwordreset-emailsent-capture": "یک ایمیلئ په بیئرگردینتین ئا پاسوردئ خاتیرا، دیم داته بوت.",
        "changeemail": "ایمیل ادرسی تغیر داتین",
        "changeemail-oldemail": "انونین ایمیل ادرس:",
        "changeemail-newemail": "نوکین ایمیل ادرس:",
        "changeemail-none": "(هیچ)",
+       "changeemail-password": "شمی {{SITENAME}} ئی پاسورد یا چیهرگال:",
        "changeemail-submit": "ایمیل ادرسی تغیر",
+       "changeemail-throttled": "شما بیخی باز وار په لوگین بوتینا کوشش کورته ایت.\nمهربانئ بکنیت دیم شه آیی که پدا کوشش بکنیت $1 صبر کنیت.",
+       "resettokens": "بیئر گردینتین نشانگ ئانی",
        "resettokens-legend": "بیئر گردینتین نشانگ ئانی",
        "resettokens-tokens": "نشانگان:",
        "resettokens-token-label": "$1 (انونین اندازه گ: $2)",
        "link_tip": "داخلین لینک",
        "extlink_sample": "http://www.example.com خرابین ئنوان",
        "extlink_tip": "لینک په ڈنا (دیموند http://‎ ئا شه هوشا مه به ریت)",
+       "headline_sample": "متنئ سر ئنوان",
        "headline_tip": "ئنوان سطح ۲",
        "nowiki_sample": "ایدا چوکاٹ بندی نه بوته ئین متن ئه داخل کنیت",
        "nowiki_tip": "نادیده گیپتین ویکی ئی چوکاٹ بندیا",
        "image_tip": "متنی تئ اکس",
        "media_tip": "فایل لینک",
+       "sig_tip": "شمی دستنام گو وختئ مهرئا",
+       "hr_tip": "افقی ئین خط (په مصرفئ کم کورتینا استفاده بیئت)",
        "summary": "خلاصه:",
+       "subject": "موضو/ئنوان:",
+       "minoredit": "ای یک گونڈین ایڈیٹئ است",
        "watchthis": "دیستین ای تاکدیمی",
        "savearticle": "ای تاکدیم ذخیره بیئت",
        "preview": "دیم دیست",
        "showdiff": "تغیراتانئ نشان داتین",
        "blankarticle": "<strong>هشدار:</strong> شما انون یک خالین تاکدیمی جوڑ کورتینی حالا وَیت .\nاگر «{{int:savearticle}}» ئا پدا  کلیک کنیت، یک تاکدیمی بدون شه محتوائا جوڑ ئه بیئت.",
        "anoneditwarning": "<strong>هشدار:</strong> شما داخل نه بوته ئیت. شمی آی‌پی نشانگ ئا موچی ئه تواننت بگیندنت اگر شما هر تغیری بیاریت . اگر <strong>[$1 داخل بئیت]</strong> یا <strong>[$2 یک کار زوروکین حساب جوڑ بکنیت]</strong>، شمی ایڈیٹ\t بی شمی کار زوروکین ناما شینک ئه بیئنت و گون گو دیگرین مزایان .",
+       "anonpreviewwarning": "<em>شما لوگین نه بوته ئیت. ذخیره کورتین باعث ئه بیئت که شمی آی پی ادرس بی ای تاکدیمی تاریخچه ئی تا ثبت بیئت.</em>",
+       "missingcommenttext": "مهربانی بکنیت جهلگا توضیح دهیت.",
+       "summary-preview": "دیم دیست ئی خلاصه:",
        "blockedtitle": "کار زوروک بسته بوته",
        "blockednoreason": "دلیلی مشخص نه بوته",
+       "whitelistedittext": "په مقاله ئانی ایڈیٹ ئا باید $1.",
+       "nosuchsectiontitle": "ایرنگی بخشئ ودئ نه بوت",
        "loginreqtitle": "لوگین بوتین ضروری اینت",
        "loginreqlink": "داخل بوتین",
+       "loginreqpagetext": "په دیگه تاکدیمانئ دیستینا باید  $1.",
        "accmailtitle": "پاسورد دیم داته بوت.",
        "newarticle": "(نوکین)",
+       "noarticletext": "ای تاکدیم همی انون هیچ متنئ نداریت .\nشما ئه توانیت که بئ دیگه تاکدیمانئ [[Special:Search/{{PAGENAME}}|ای تاکدیمی ئنوانا بگردیت]]،\n<span class=\"plainlinks\">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} مربوطین سیاه چال ئا هم بگردیت ]،\nیا [{{fullurl:{{FULLPAGENAME}}|action=edit}} ای تاکدیما ایڈیٹ بکنیت]</span>.",
+       "noarticletext-nopermission": "ای تاکدیم همی انون هیچ متنی نداریت.\nشما ئه توانیت که دیگه تاکدیمانئ تا [[Special:Search/{{PAGENAME}}|ای ئنوانئ پدا بگردیت ]]،\nیا <span class=\"plainlinks\">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} مرتبطین سیاه چال ئانئ پدا بگردیت ]</span> ولی شما په ای تاکدیمئ جوڑ کورتینا اجازه نداریت.",
+       "missing-revision": "#$1 ئی ایڈیٹ شه  «{{FULLPAGENAME}}» ئی تاکدیما موجود نه اینت.\n\nمعمولاً بئ اثر لینک بئ تاریخچهٔ ئا اپڈیٹ نه بوته و تاکدیم پاک بوته.\nتوانیت ایدت مئلومات بئ  [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} پاک بوته ئین سیاه چال ئی] تا بگیندیت.",
+       "userpage-userdoesnotexist": "«<nowiki>$1</nowiki>» ئی کار زوروکین حساب راجستر نه بوته.\nمهربانی بکنیت مطمائین بئیت که لوٹیت ای تاکدیما جوڑ یا ایڈیٹ بکنیت.",
+       "userpage-userdoesnotexist-view": "«$1» ئی کار زوروکین حساب راجستر نه بوته.",
+       "blocked-notice-logextract": "ای کار زوروکئ دسترسی بی انونین وختا بسته بوته.\nآخرین مورد شه دسترسی ئی سیستین به جهلگا آته:",
+       "clearyourcache": "<strong>نکته:</strong> پد شه تغیراتان شاید په دیستینا ضرورت بیئت که بروزیزی نهانی ئین حافظه ئا پاک بکنیت.\n*<strong>په فایرفاکس / سافاری:</strong> خاتیرا <em>Shift</em> کیلی ئانه بساتیت و  <em>Reload</em> دکمه ئی سرا کلیک بکینت، یا  <em>Ctrl-F5</em> کیلی ئانه یا <em>Ctrl-R</em> ئا یکجا پرینچیت (بئ اپل مکینتاش ئی کامپیوتراني تا <em>⌘-R</em>) کیلی ئانه\n*<strong>گوگل کروم:</strong> خاتیرا <em>Ctrl+Shift+R</em> کیلی ئانه گو وت یکجا پرینچیت (بئ  اپل مکینتاش ئی کامپیوتراني تا  <em>⌘-Shift-R</em>) کیلی ئانه\n*<strong>اینترنت اکسپلورر:</strong> خاتیرا <em>Ctrl</em> کیلی ئانه  بساتیت و بئ <em>Refresh</em> دکمه یا کوچکئ سرا کلیک بکینت، <em>Ctrl-F5</em> ئی کیلی ئانه گو وت یکجا پرینچیت\n*<strong>اپرا:</strong> بروزیری نهانی ئین حافظهٔ ئا شه  <em>Tools &rarr; Preferences</em> ئی مینوی طریقه پاک بکینت",
+       "usercssyoucanpreview": "'''نکته:''' پد شه وتئ سی‌اس‌اس ئی فایلی ذخیره کورتینا، گو '''{{int:showpreview}}''' ئی دکمه ئا آیرا امتحان بکنیت .",
+       "userjsyoucanpreview": "'''نکته:''' پد شه وتئ جاوااسکریپت ئی ذخیره کورتینا،گو '''{{int:showpreview}}''' ئی دکمه ئا آیرا امتحان بکنیت.",
+       "usercsspreview": "'''شه هوشا بورته ایت که شما فقط وتئ کار زوروکئ سی اس اس ئی دیم دیست ئا گیندیت.'''\n'''ای سی‌اس‌اس تا انون ذخیره نه بوته!'''",
+       "sitecsspreview": "'''شه هوشا مه بَریت که شما فقط وتئ کار زوروکئ سی اس اس ئی دیم دیست ئا گیندیت.'''\n'''ای سی‌اس‌اس تا انون ذخیره نه بوته!'''",
+       "sitejspreview": "'''شه هوشا مه بَریت که شما فقط جاوااسکریپت ئی دیم دیست ئا گیندیت.'''\n'''ای جاوااسکریپت تا انون ذخیره نه بوته!'''",
        "updated": "(نوک بوته ئین)",
        "note": "'''نکته:'''",
        "continue-editing": "شوتین بی ایڈ\tیٹ\tی نیمگا",
        "editing": "بی ایڈ\tیٹ\t کورتینی حالا $1",
        "creating": "بی جوڑ کورتینی حالا $1",
+       "editingsection": "بئ $1 ئی ایڈیٹ کورتینئ حالا (بخش)",
+       "editingcomment": "بئ $1 ئی ایڈیٹ کورتینئ حالا (نوکین بخش)",
+       "editconflict": "هجومین ایڈیٹ: $1",
        "yourtext": "شمی متن",
+       "storedversion": "ذخیره بوته ئین نخسه",
        "yourdiff": "تفاوت‌هان",
        "templatesused": "{{PLURAL:$1|تراشوان|تراشوانان}} استفاده بوته انت بی ای تاکدیمئ تا:",
        "template-protected": "(قُلپ بوته)",
        "template-semiprotected": "(نیمه‌ گ قُلپ بوته)",
        "hiddencategories": "ای تاکدیم بی {{PLURAL:$1|یک چیهرین تهر|$1 چیهرین تهر}} تا قرار داریت:",
+       "sectioneditnotsupported-text": "ای تاکدیم شه بخشانی ایڈیٹ ئا پُشتوانی ئه نه کنت.",
        "permissionserrors": "دسترسی ئی خطا",
        "permissionserrorstext": "شما ای کارئ اجازه ئا په ای {{PLURAL:$1|دلیلا|دلیلان}} نداریت:",
        "permissionserrorstext-withaction": "شما اجازهٔ $2 ئا بی ای {{PLURAL:$1|دلیلا|دلیلان}} نداریت:",
        "recreate-moveddeleted-warn": "<strong>هشدار: شما یک تاکدیمی ئا جوڑ\t ئه کنیت که دیمتیرا پاک کورته بوته.</strong>\n\nبی نظر داشته بئیت که آیا ایڈ\tیٹ ای تاکدیمی جوانین کاری است یانه.\nای تاکدیمی پاک بوتینئ و انتقالئ کورم ئا جهلگا توانیت بگیندیت:",
        "moveddeleted-notice": "ای تاکدیم پاک بوته.\nای تاکدیمی پاک بوتینئ و انتقالئ کورم ئا جهلگا توانیت بگیندیت.",
        "log-fulllog": "دیستین کامیلین کورمئ",
+       "edit-hook-aborted": "ایڈیٹ شه قلاب ئی نیمگاه لغو بوت.\nبی ای باره ئا هیچ توضیحی داته نه بوته.",
+       "edit-gone-missing": "اپڈیٹ ئی امکان وجود نداریت.\nبی نظر ئه رسیت که تاکدیم پاک بوته.",
        "edit-conflict": "هجومئ ایڈیٹ\t.",
+       "edit-no-change": "شمی ایڈیٹ مهم گیپته نه بوته، بی خاتیریکه متنئ تا هیچ تغیرئ داته نه بوتتت.",
        "postedit-confirmation-created": "ای تاکدیم جوڑ بوته.",
        "postedit-confirmation-restored": "ای تاکدیم بیئرگردینته بوته.",
        "postedit-confirmation-saved": "شمی ایڈ\tیٹ ذخیره بوت.",
+       "edit-already-exists": "نوکین تاکدیمئ جوڑ کورتین امکان نه داریت.\nای تاکدیم شه دیما وجود داشتت.",
        "content-model-wikitext": "ویکی‌متن",
        "content-model-text": "ساده گین متن",
        "content-model-javascript": "جاوااسکریپت",
        "content-json-empty-object": "خالین چیز",
        "content-json-empty-array": "خالین صف",
+       "duplicate-args-category": "تاکدیمان گو تکرارین آرگومینتان بی تراشونئ لوٹیتنا",
+       "duplicate-args-category-desc": "تاکدیمان که تکرارین آرگومینت دارنت ، چو <code><nowiki>{{foo|bar=1|bar=2}}</nowiki></code> یا <code><nowiki>{{foo|bar|1=baz}}</nowiki></code>.",
+       "expensive-parserfunction-warning": "'''هشدار:''' ای تاکدیم باز تجزیه گرین فراخوانئ دستور داریت .\n\nآوانئ اندازه گ باید کمتر شه $2 {{PLURAL:$2|لوٹیتین|لوٹیتین}} ئا بیئت، و اینک {{PLURAL:$1|$1 لوٹیتین|$1 لوٹیتین}} اینت.",
+       "expensive-parserfunction-category": "تاکدیمان که باز سکین تجزیه گرین فراخوانئ دستور دارنت",
+       "post-expand-template-inclusion-warning": "هشدار: تراشوان بی شه اندزه ئا ٹوو اینت.\nبرخی شه تراشوانان شاید شامل مه بیئنت.",
+       "post-expand-template-inclusion-category": "آ تاکدیمان که آوانئ تا تراشوانانئ اندزه گ شه حد ئا گیشتیر اینت.",
+       "post-expand-template-argument-warning": "'''هشدار:''' ای تاکدیم یک تراشوانئ پارامیتر اینت که شه اندازه ئا ٹوو.\nای پارامیتران نادیسته گیپته بوتنت.",
+       "post-expand-template-argument-category": "تاکدیمان که حاوی تراشوانان گو پارامیتران نادیده گیپته بوته انت",
+       "parser-template-loop-warning": "حلقه بی تراشوان ئا تا ودی نه بوت: [[$1]]",
+       "parser-template-recursion-depth-warning": "تراشوانئ بیئرگشتی عمق رد بوت ($1)",
+       "language-converter-depth-warning": "مبدل زبانی ئی محدودیت عمق  رد بوت ($1)",
+       "node-count-exceeded-category": "تاکدیمان که شه حداکثر گروپ ئا تجاوز کورته انت",
+       "node-count-exceeded-category-desc": "ای تاکدیم شه حداکثر پرابلمان گیشتیر بوته",
+       "node-count-exceeded-warning": "تاکدیم شه حداکثر گرینان گیشتیر بوته",
+       "expansion-depth-exceeded-category": "تاکدیمان که شه حداکثر بسط داتین عمق ئا تجاوز کورته انت",
+       "expansion-depth-exceeded-category-desc": "تاکدیم که که آیی پراخئ جُهلئ شه اندازه گ ئا گیشتیر بوته.",
+       "expansion-depth-exceeded-warning": "تاکدیم شه حداکثر بسط داتین عمق ئا تجاوز کورت",
+       "parser-unstrip-loop-warning": "حلقه بی دستور unstrip ئی تا ودی نه بوت",
+       "parser-unstrip-recursion-limit": "شه حداکثر ارجاع بئ دستور unstrip ئی تا تجاوز بوت ($1)",
+       "converter-manual-rule-error": "خطا بئ زانئ دستی ئین بدل کورتینی قوانین ئی تا",
+       "undo-success": "ای ایڈیٹ ئا توانیت شه بین بَریت.\nمهربانی بکنیت جهلگی فرق ئا بگنیدیت و قبول بکنیت که آ چیزی است که شما ئه لوٹیت انجام دهیت،پدا جهلگئ تغیراتانا ذخیره بکنیت تا که ایڈیٹ ئی شه بین بورتینئ کار الاس بکنیت.",
+       "undo-failure": "ایڈیٹ ئا نتوانتیت شه بین بَریت، بی خاتیرئ بعضی تعرض ئان یا میانئ ئین ایڈیٹان.",
+       "undo-norev": "ای ایڈیٹ ئا نتوانتیت شه بین بَریت بخاتیریکه یا اصلان وجود نداریت یا که پاک بوته.",
+       "undo-nochange": "بئ نظر ئه رسیئت که ایڈیٹ بیئرگردینته بوته.",
+       "undo-summary": " $1 ئی ایڈیٹ شه [[Special:Contributions/$2|$2]] ([[User talk:$2|حبر و گپ]]) نیمگا شه بَیْن بورته بوت",
+       "undo-summary-username-hidden": " $1 نخسه ئی شه بین بورتین بی یک کار زوروکئ دستا چیهر بوته",
+       "cantcreateaccounttitle": "نه توانیت حسابئ پاچ کنیت",
+       "viewpagelogs": "ای تاکدیمئ سیاه چال ئی دیستین",
+       "nohistory": "ای تاکدیم ایڈیٹ ئی تاریخچه نداریت.",
        "currentrev": "انونین نخسه یی نشان داتین",
        "currentrev-asof": "انونین نسخه تا $1",
        "revisionasof": "نسخهٔ $1",
        "last": "دیمتیرین",
        "page_first": "اولین",
        "page_last": "آخیرین",
+       "history-fieldset-title": "تاریخچه ئی مرور کورتین",
        "history-show-deleted": "فقط پاک بوته ئین",
        "histfirst": "کهنگتیرین",
        "histlast": "نوکتیرین",
        "historysize": "({{PLURAL:$1|۱ بایٹ|$1 بایٹ}})",
        "historyempty": "(خالی)",
        "history-feed-title": "ایڈ\tیٹانئ دپتر یا تاریخچه گ",
+       "history-feed-description": "ای تاکدیمی ایڈیٹ ئی تاریخچه بئ ویکی ئی تا",
        "history-feed-item-nocomment": "$1 بی $2",
+       "rev-deleted-comment": "(ایڈیٹ ئی خلاصه پاک بوت)",
        "rev-deleted-user": "(کار زوروکین نام پاک بوت)",
+       "rev-deleted-event": "(سیاه چال ئی جزئیات پاک بوته انت)",
+       "rev-deleted-user-contribs": "[کار زوروکئ نام یا آی پی ادرس پاک بوته - چیهر بوته ئین ایڈیٹ بئ مشارکتانئ تا]",
+       "rev-deleted-text-permission": "ای ایڈیٹ شه ای تاکدیما '''پاک بوته'''.\nممکن اینت آیی باره ها مئلومات بئ [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} پاک بوته ئین سیاه چال] ئی تا موجود بیئت.",
+       "rev-suppressed-text-permission": "ای ایڈیٹ شه ای تاکدیما '''پاک بوته'''.\nشما توانیت آیرا بگیندیت؛ ممکن اینت آی باره ئا مئلومات بئ [{{fullurl:{{#Special:Log}}/suppress|page={{FULLPAGENAMEE}}}} پاک بوته ئین سیاه چال] ئی تا موجود بیئت.",
+       "rev-deleted-text-view": "ای ایڈیٹ شه ای تاکدیما '''پاک بوته'''.\nشما توانیت آیرا بگیندیت؛ ممکن اینت آیی مربوتین مئلوماتانا بئ [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} پاک بوته ئین سیاه چال ] تا ودئ بکنیت.",
        "rev-delundel": "نمایش/نهفتن",
        "rev-showdeleted": "نشان داتین",
        "revdelete-show-file-submit": "هان",
+       "revdelete-selected-text": "{{PLURAL:$1|انتخاب بوته ئین نخسه هان|انتخابین نخسه هان}} [[:$2]]:",
+       "revdelete-selected-file": "{{PLURAL:$1|انتخاب بوته ئین نخسه|انتخابین نخسه}} [[:$2]]:",
+       "logdelete-selected": "شه سیاه چال ئا {{PLURAL:$1|مورد|مورد هان}} انتخاب بوته:",
+       "revdelete-text-others": "دیگه مدیرهان تا انون هم ئه تواننت که چیهرین محتواهانه بگیندینت و شه همی راه ئا تواننت پاک بوته ئین مواردانا بیئرگردیننت، مگر ای که دیگه محدودیت ئی آته بیئت.",
+       "revdelete-legend": "پیدای ئین محدودیت ئانی تنظیم",
+       "revdelete-hide-text": "نخسه ئی متن",
+       "revdelete-hide-image": "فایلی محتویاتانئ چیهرداتین",
+       "revdelete-hide-name": "چیهر داتین متغیر هانی و هدف",
+       "revdelete-hide-comment": "ایڈیٹانی خلاصه",
+       "revdelete-hide-user": "کار زوروکئ نام/آی‌پی ادرس",
+       "revdelete-hide-restricted": "مئلوماتئ سرکوب په مدیران گو دیگران لۆڑ",
+       "revdelete-radio-same": "(بی شه تغیر ئا)",
        "revdelete-radio-set": "چیهر داتین",
        "revdelete-radio-unset": "نمایان",
+       "revdelete-suppress": "مدیرانئ دسترسی په دتا ئا چو دیگه کار زوروکان بسته بیئت.",
+       "revdelete-unsuppress": "محدودیتانئ پاک بوتین بئ پدا دیستین ئی تا ترمیم بوته",
        "revdelete-log": "دلیل:",
+       "revdelete-submit": "اعمال بئ {{PLURAL:$1|نخسه|نخسه هان}} ئی سرا انتخاب بوته",
+       "revdelete-success": "'''نخسه ئی ودی بوتین گو کامیابیا اپڈیٹ بوت.'''",
+       "revdelete-failure": "'''نخسه ئی ودی بوتینئ اپڈیٹ بوتن امکان وجود نداریت :'''\n$1",
+       "logdelete-success": "<strong>لوگین ئی قابلیت دیست گو کامیابیا انجام بوت.</strong>",
+       "logdelete-failure": "'''لوگین ئی قابلیت دیست تنظیم ئه نه بیئنت:'''\n$1",
        "revdel-restore": "نمایش/نهفتن",
        "pagehist": "تاکدیمی تاریخچه",
        "deletedhist": "پاک بوتگینانی تاریخچه",
+       "revdelete-no-change": "'''هشدار:''' $2 تاریخ ئی و سائت $1 مورد شه دیما پیدائین ریکویست ئی  تنظیمات ئا داشت.",
+       "revdelete-otherreason": "دیگرین دلیل/اضافی:",
        "revdelete-reasonotherlist": "دیگرین دلیل",
+       "revdelete-edit-reasonlist": "پاک بوتینئ دلیلانئ ایڈیٹ",
+       "revdelete-offender": "نخسه ئی نویسوک:",
+       "suppressionlog": "سیاه چالئ نادینتین",
+       "mergehistory": "تاکدیمانئ تاریخچه ئی ادغام",
+       "mergehistory-box": "دو تاکدیمئ نخسه ئانی ادغام:",
+       "mergehistory-from": "تاکدیمئ منشا:",
+       "mergehistory-into": "تاکدیمئ مخصد:",
+       "mergehistory-list": "قابل ادغامئ تاریخچه",
+       "mergehistory-go": "قابل ادغامئ تاریخچه ئی نشان داتین",
+       "mergehistory-submit": "نخسه ئانی ادغام",
+       "mergehistory-empty": "هیچ یک شه نخسه ئان ادغامی ئی وڈ نه ونت.",
+       "mergehistory-success": "$3 ئی نخسه  شه [[:$1]]  ئا گو کامیابیا بی  [[:$2]] تا ادغام {{PLURAL:$3|بوت}}.",
+       "mergehistory-fail": "تاریخچه ئی ادغام ممکن نه اینت، مهربانی بکنیت تاکدیمئ گزینه ئانه و وختا بگیندیت.",
        "mergehistory-no-source": " $1 منشائی تاکدیم موجود نه اینت.",
        "mergehistory-no-destination": "$1 مخصدی تاکدیم موجود نه اینت .",
        "mergehistory-invalid-source": "منشائی تاکدیم باید یک موتبرین ئنوان ئی داشته بیئت.",
        "difference-title-multipage": "$1 و $2:تاکدیمانئ مانجینی فرق",
        "difference-multipage": "(تاکدیمانی مانجینا فرق)",
        "lineno": "سطر $1:",
+       "compareselectedversions": "انتخاب بوته ئین نخسه ئانی مقایسه",
+       "showhideselectedversions": "انتخاب بوته ئین نخسه ئانی پدیداری تغیر",
        "editundo": "خنثی‌ کورتین",
        "diff-empty": "(بدون تفاوت)",
+       "diff-multi-sameuser": "(ای کار زوروکئ {{PLURAL:$1|یک میانی نخسه|$1 میانی نخسه}}ِ نمایش داته بوته)",
        "searchresults": "گشتین ئی  نتیجه",
        "searchresults-title": "گشتینئ نتایج په «$1»",
+       "titlematches": "مقاله ئی ئنوانئ یکی کورتین",
+       "textmatches": "مقاله ئی متنئ یکی کورتین",
+       "notextmatches": "هیچ یک شه مقاله ئانی متن مطابقت ندارنت",
+       "prevn": "{{PLURAL:$1|$1}}دیمتیری",
+       "nextn": "{{PLURAL:$1|$1}}پدتیری",
+       "prevn-title": "$1 {{PLURAL:$1|نتیجهٔ|نتیجهٔ}} دیمی",
+       "nextn-title": "$1 {{PLURAL:$1|نتیجهٔ|نتیجهٔ}} پدئ",
+       "shown-title": "نشان داتین $1 ئی {{PLURAL:$1|نتیجه|نتیجه}} بی هر تاکدیمی تا",
+       "viewprevnext": "نشان داتین ($1 {{int:pipe-separator}} $2) ($3)",
+       "searchmenu-exists": "'''تاکدیمئ گو «[[:$1]]» ئی ئنوانا بی ای ویکی تا وجود داریت .'''",
+       "searchmenu-new": "<strong> «[[:$1]]» ئی تاکدیما بی ای ویکی تا جوڑ بکنیت!</strong> {{PLURAL:$2|0=همچنان آ تاکدیما کی گو وتئ گشتینا ودئ کورته ایت، بگیندیت.|و همچنان وتئ گشتینئ ودئ بوته ئین نتیجه ئانا بگیندیت.}}",
+       "searchprofile-articles": "تاکدیمانی محتوا",
+       "searchprofile-images": "چینکه رسانه ئی",
+       "searchprofile-everything": "موچی چیز",
+       "searchprofile-advanced": "پیشرفته",
        "searchprofile-articles-tooltip": "گشتین بی $1",
        "searchprofile-images-tooltip": "گشتین په فایلان",
+       "searchprofile-everything-tooltip": "گشتین په موچین محتوا ئان (شاملئ گپ ئی تاکدیمان)",
+       "searchprofile-advanced-tooltip": "گشتین بی فضای نام دلخواه",
+       "search-result-size": "$1 ({{PLURAL:$2|یک کلیمه|$2 کلیمه}})",
        "search-redirect": "(تغییرمسیر $1)",
        "search-section": "(بخش $1)",
        "search-category": "(تهر  $1)",
+       "search-file-match": "(فایلی محتوایی یکرنگی)",
        "search-suggest": "آیا شمی منظور ایش ات: $1",
        "search-interwiki-caption": "گوارین پروژه ئان",
        "search-interwiki-default": "نتایج شه $1 :",
        "search-relatedarticle": "مرتبط",
        "searchrelated": "مرتبط",
        "searchall": "موچ",
+       "showingresults": "نشان داتین حداکثر {{PLURAL:$1|'''۱''' نتیجه|'''$1''' نتیجه}} بی جهلگا، شرو شه شماره ئی  '''$2'''.",
+       "showingresultsinrange": "نمایش بی جهلگا {{PLURAL:$1|<strong>1</strong> نتیجه|<strong>$1</strong> نتیجه}} بی محدودهٔ ئی #<strong>$2</strong> تا #<strong>$3</strong>.",
+       "search-showingresults": "{{PLURAL:$4|نتیجه ئان <strong>$1</strong> شه <strong>$3</strong>|نتیجه ئان <strong>$1 - $2</strong> شه <strong>$3</strong>}}",
        "search-nonefound": "نتیجه په چیزی که شما لوٹیته تیت بی دست نه یات.",
        "powersearch-legend": "پیشرفته ئین گشتین",
        "powersearch-ns": "گشتین بی نامئ فضائان:",
        "powersearch-togglelabel": "چیک کورتین:",
        "powersearch-toggleall": "موچ",
        "powersearch-togglenone": "هیچ‌گوجام",
+       "powersearch-remember": "اتنخاب په دیگرین گشتین ئان بی خاتیر داشته بئیت",
        "search-external": "خارجی ئین گشتین",
        "searchdisabled": "گشتین بی {{SITENAME}} ئی تا فعال نه اینت.\nموقتاً توانیت شه Google ئی گردگ ئا استفاده کنیت.\nتوجه کنیت که بدست آته ئین نتایج شه گردگا بی آ ممکینین طریقه ئا مه بیئنت.",
+       "search-error": "یک خطایی بی گردگئ وختا رخ داته : $1",
        "preferences": "تنظیمات",
        "mypreferences": "تنظیمات",
        "prefs-edits": "ایڈ\tیٹانی اندازه گ:",
        "prefs-rc": "آخیرین تغیراتان",
        "prefs-watchlist": "واچلیست",
        "prefs-editwatchlist": "واچلیستی ایڈیٹ کورتین",
+       "prefs-editwatchlist-label": "وتئ واچلیست ئی موچین لڑلیستانئ ایڈیٹ:",
+       "prefs-editwatchlist-edit": "پاک کورتین و دیستین ئنوانانئ شه وتئ واچلیستا",
+       "prefs-editwatchlist-raw": "واچلیستئ آمگین لیستانی ایڈیٹ",
+       "prefs-editwatchlist-clear": "وتئ واچلیستئ پاک کورتین",
+       "prefs-watchlist-days-max": "حداکثر $1 {{PLURAL:$1|روچ}}",
+       "prefs-watchlist-edits": "شمی ایڈیٹانئ اندازه گ بئ واچلیست ئي تا پراخ بوته:",
        "prefs-watchlist-edits-max": "حداکثر اندازه گ: ۱۰۰۰",
+       "prefs-watchlist-token": "واچلیستئ کوڈ:",
        "prefs-misc": "متفرقه",
        "prefs-resetpass": "پاسوردی تغیر داتین",
        "prefs-changeemail": "ایمیل ادرسی تغیر داتین",
        "rows": "تعداد سطرها:",
        "columns": "تعداد ستون‌ها:",
        "searchresultshead": "گشتین",
+       "stub-threshold": "ایڈیٹانئ لینک <a href=\"#\" class=\"stub\">ناقص</a> (بایٹ):",
        "stub-threshold-disabled": "غیرفعال",
+       "recentchangesdays": "روچانی اندازه گ بئ آخیر ئین تغیراتانئ تا نشان داته بوته انت:",
+       "recentchangesdays-max": "حداکثر $1 {{PLURAL:$1|روچ}}",
+       "savedprefs": "شمی تنظیمات ذخیره بوتنت.",
        "timezonelegend": "منطقهٔ زمانی:",
        "localtime": "محلی ئن وخت:",
+       "timezoneuseserverdefault": "استفاده شه  پیش‌فرض ئین ویکی ($1)",
+       "timezoneuseoffset": "دیگر (اختلاف ئا مشخص کنیت)",
+       "servertime": "سرور ئی وخت:",
+       "guesstimezone": "شه بروزیر ئه گیپته بیئت",
        "timezoneregion-africa": "آفریقا",
        "timezoneregion-america": "آمریکا",
+       "timezoneregion-antarctica": "جنوبی ئین قطب",
        "timezoneregion-arctic": "قطب شمالی",
        "timezoneregion-asia": "آسیا",
        "timezoneregion-atlantic": "بحر اتلانتیک",
        "timezoneregion-europe": "اروپا",
        "timezoneregion-indian": "بحر هند",
        "timezoneregion-pacific": "بحر آرام",
+       "allowemail": "آتین ایملئ شه دیگه کار زوروکان",
        "prefs-searchoptions": "گشتین",
+       "prefs-namespaces": "نامانی فضاهان",
        "default": "پیش‌فرض",
        "prefs-files": "فایل ئان",
        "prefs-custom-css": "سی‌اس‌اس شخصی",
+       "prefs-custom-js": "شخصی ئین جاوااسکریپت",
+       "prefs-common-css-js": "سی‌اس‌اس/جاوااسکریپت مشترک په موچین پوسته‌ئان:",
+       "prefs-emailconfirm-label": "ایمیلئ تائید کورتین:",
        "youremail": "ایمیل:",
+       "username": "{{GENDER:$1|کار زوروکئ نام}}:",
+       "prefs-memberingroups": "{{GENDER:$2|عضو}} {{PLURAL:$1|گروپ|گروپ}}:",
        "prefs-registration": "راجیسترئ وخت",
        "yourrealname": "واقیئین نام:",
        "yourlanguage": "زبان:",
+       "yourvariant": "گوشتین محتوائی زبانی:",
+       "yournick": "نوکین دستنام:",
+       "prefs-help-signature": "نیوشته بوته ئین نظرئان باید بی گپ و حبر ئی تاکدیمئ تا گو «<nowiki>~~~~</nowiki>» ئا دستنام یا امضا بیئنت ؛ ای علامت بی اوتوماتیکین رقما بی شمی دستنام یا امضا آ و تاریخ آ بدل ئه بیت.",
+       "badsig": "حامگین یا خرابین دستنام یا امضا.\nمهربانی بکنیت اچ‌تی‌ام‌ال ئا بگیندیت.",
+       "badsiglength": "شمی دستنام شه اندازه ئا مزن و تچک اینت.\nدستنام باید کمتر شه $1 {{PLURAL:$1|نویسه}} ئا طول داشته بیئت.",
        "yourgender": "لوٹیت که شما را چون بزاننت؟",
        "gender-unknown": "لوٹین که هیچ ئی مه گوشین",
        "gender-male": "مردینزاگ",
        "prefs-displaywatchlist": "نمایش ئین کیلی ئان",
        "prefs-tokenwatchlist": "نشانه گ",
        "prefs-diffs": "تفاوت‌ئان",
+       "prefs-help-prefershttps": "ای تنظیمی تاثیر پد شه لوگین بوتینا بی شما اعمال ئه بیئت.",
+       "prefswarning-warning": "شمی تغیرات بی تنظیماتانی تا تا انون ذخیره نه بوته انت.\nاگه ای تاکدیما بي شه کلیک کورتین به  «$1» ئا بیلیئت شمی تنظیمات ذخیره ئه نه بیئنت.",
+       "email-address-validity-valid": "شمی ایمیلئ ادرس موتبر بی نظر ئه رسیت",
        "email-address-validity-invalid": "موتبرین ایمیل ادرسی داخل بکنیت",
        "userrights": "کار گیروکی اختیارانی مدیریت",
        "userrights-lookup-user": "کار گیروکی گروپانی مدیریت",
        "userrights-user-editname": "کار زوروکین ناما داخل بکنیت:",
        "editusergroup": "کار زوروکی گروپانی ایڈیٹ",
+       "editinguser": "کار زوروکئ اختیارانی تغییر  '''[[User:$1|$1]]''' $2",
        "userrights-editusergroup": "کار زوروکی گروپانی ایڈیٹ",
+       "saveusergroups": "کار زوروکی گروپانی ثبت کورتین",
        "userrights-groupsmember": "عضو:",
+       "userrights-groupsmember-auto": "ضمنی ئین عضو:",
        "userrights-reason": "دلیل:",
+       "userrights-no-interwiki": "شما دیگه ویکی هانی کار زوروکانئ اختیارانی تغیر داتینی اجازه ئا نداریت.",
+       "userrights-nodatabase": " $1 مئلوماتئ بانک وجود نداریت یا محلی نه اینت.",
+       "userrights-nologin": "شما باید گو یک مدیرئی  [[Special:UserLogin|کار زوروکین حسابا لوگین بیئیت]] تا که بتوانیت دیگه کار زوروکانئ اختیارانا تعین بکنیت.",
+       "userrights-notallowed": "شما په کار زوروکئ حقوق ئی پاک کورتین یا افاضه کورتینی اجازه ئه نداریت.",
        "userrights-changeable-col": "ئا گروپان که شما توانیت آوانا ٹگل بدهیت",
        "userrights-unchangeable-col": "ئا گروپان که شما نتوانیت آوانا ٹگل بدهیت",
+       "userrights-conflict": "حمله بئ کار زوروکئ حقان! مهربانی بکنیت بگیندیت و تغیرانا تائید بکنیت.",
+       "userrights-removed-self": "شما وتئ دسترسی ئانه سیستیت. انون شما دیگه بئ ای تاکدیما دسترسی نداریت.",
        "group": "گروپ:",
        "group-user": "کار زوروکان",
        "group-autoconfirmed": "تائید بُوته ئین کار زوروکان",
        "right-createpage": "تاکدیمی جوڑ\t کورتین (بی غیر گپ ئین موردی تاکدیمان )",
        "right-createtalk": "گپ ئی تاکدیمی جوڑ\t کورتین",
        "right-createaccount": "کار زوروکئ حسابئ جوڑ\t کورتین",
+       "right-minoredit": "نشانی کورتین ایڈیٹانی بئ ئنوان کم ئین",
        "right-move": "تاکدیمی انتقال",
+       "right-move-subpages": "تاکدیمانئ انتقال گو آوان گونڈدیم ئان",
+       "right-move-rootuserpages": "کار زوروکین سرشاخه ئین تاکدیمانئ انتقال",
        "right-move-categorypages": "تهر تاکدیمئ انتکال",
        "right-movefile": "فایلی انتقال",
+       "right-suppressredirect": "تاکدیمئ انتقال بیدون شه دیمین نامی تغیرمسیر ئی جوڑ کورتین",
        "right-upload": "فایلی بُرز کورتین",
+       "right-reupload": "پدا نیویشتین موجودین فایلئ",
+       "right-reupload-shared": "مشترکین فایلانئ محلی ئین باطل کورتین",
+       "right-upload_by_url": "یک فایلئ بُرز کورتین یا اپلوڈ شه اینٹرنٹ ئا",
+       "right-autoconfirmed": "شه آی پی ئی محدودیت تیزی ئا محور تاسیر ئه نه گیت",
+       "right-writeapi": "استفاده شه نیویشتینی API",
+       "right-delete": "تاکدیمی پاک کورتین",
+       "right-bigdelete": "ٹوهین تاریخچه والا ئین تاکدیمانئ پاک کورتین",
+       "right-browsearchive": "گشتین په پاک بوته ئین تاکدیمان",
+       "right-undelete": "بی جاه آورتین  تاکدیمانئ",
+       "right-viewsuppressed": "آ نخسه هانی دیستین که شه کار زوروکان چیهر داته بوته انت",
+       "right-suppressionlog": "دیستین شخصین سیاه چال ئانی",
+       "right-unblockself": "وتي دسترسی ئی پاچ کورتین",
+       "right-protect": "قُلپ بوته تاکدیمانئ قلپی میزانی تغیر داتین و آوانی ایڈیٹ کورتین",
+       "right-editprotected": "ایڈیٹ کورتین قُلپ بوته ئین تاکدیمانی بئ ئنوانئ «{{int:protect-level-sysop}}»",
+       "right-editsemiprotected": "ایڈیٹ کورتین قُلپ بوته ئین تاکدیمانی بئ ئنوانی \"{{int:protect-level-autoconfirmed}}\"",
+       "right-editcontentmodel": "یک تاکدیمی محتوایی مدل یی ایڈیٹ کورتین",
+       "right-editinterface": "ای\tڈیٹ کورتین کار زوروکانئ رابطه",
+       "right-editusercssjs": "ایڈیٹ کورتین دیگه کار زوروکانئ  CSS و JS ئی تاکدیمانئ",
+       "right-editusercss": "ایڈیٹ کورتین دیگه کار زوروکانئ  CSS ئی تاکدیمانئ",
+       "right-edituserjs": "ایڈیٹ کورتین دیگه کار زوروکانئ  JS ئی تاکدیمانئ",
+       "right-editmyusercss": "وتئ  سی‌اس‌اس کار زوروکئ فایلانا ایڈیٹ بکینت",
+       "right-editmyuserjs": "وتئ جاوااسکریپت کار زوروکي فایلانا ایڈیٹ بکنیت",
+       "right-viewmywatchlist": "وتئ واچلیست ئا بگیندیت",
+       "right-viewmyprivateinfo": "وتي خصوصین دیتا ئه بگیندیت (چو ایمیل و واقئین ناما)",
+       "right-editmyprivateinfo": "وتي حصوثین دیتا ئه ایڈیٹ بکنیت (چو ایمیل و واقئین ناما)",
+       "right-editmyoptions": "وتئ تنظیماتانا ایڈیٹ بکنیت",
+       "right-rollback": "عاجل ئین بیئرگردینتین آخیر ئین کار زوروکئ ایڈیٹانئ که ای تاکدیما ایڈیٹ کورته",
+       "right-markbotedits": "ای بیئرگردینته بوته ئین ایڈیٹانی علامت جتین بئ ئنوانئ رباتئ ایڈیٹا",
+       "right-noratelimit": "تاثیر نه گیپتین شه سرعتئ محدودیت ئا",
+       "right-import": "تاکدیمئ داخل کورتین شه دیگه ویکی ئا",
+       "right-importupload": "تاکدیمئ داخل کورتین شه فایلئ اپلوڈ کورتین ئا",
+       "right-patrol": "دیگرانئ ایڈیٹانی مارک جتین",
+       "right-autopatrol": "اوتوماتیکین مارک وارتین ایڈیٹ ئانی",
+       "right-mergehistory": "تاکدیمانی تاریخچه ئی ادغام کورتین",
+       "right-userrights": "ایڈیٹ کورتین کار زوروکئ موچین اختیارانئ",
+       "right-userrights-interwiki": "دیگه ویکی ئی کار زوروکانئ اختیارانی ایڈیٹ کورتین",
+       "right-siteadmin": "مئلومات ئین بانکئ قُلپ و یا پاچ کورتین",
+       "right-sendemail": "دیم داتین ایمل په دیگه کار زوروکان",
+       "right-passwordreset": "پاسوردی نوک تنظیم کورتینی ایمیل",
+       "newuserlogpage": "کار زوروکئ جوڑ کورتینی سیاه چال",
+       "newuserlogpagetext": "ای سیاه چال شه نوکین کار زوروکئ ناما جوڑ بوته.",
+       "rightslog": "کار زوروکی اختیارانئ سیاه چال",
+       "rightslogtext": "ای سیاه چال کار زوروکئ تغیراتانی اینت.",
        "action-read": "وانتین ای تاکدیمئ",
        "action-edit": "ایڈ\tیٹ کورتین ای تاکدیمئ",
        "action-createpage": "تاکدیم جوڑ کورتین",
+       "action-createtalk": "گپ ئی تاکدیمانی جوڑ\t کورتین",
+       "action-createaccount": "ای کار زوروکئ حسابئ جوڑ\t کورتین",
+       "action-history": "ای تاکدیمی تاریخچه ئی دیستین",
+       "action-minoredit": "ای ایڈیٹ ئی نشانی کورتین بئ ئنوانئ کم ئین",
+       "action-move": "ای تاکدیمی انتقال",
+       "action-move-subpages": "ای تاکدیمئ و آیی گونڈدیمانی انتقال",
+       "action-move-rootuserpages": "کار زوروکین سرشاخه ئین تاکدیمانئ انتقال",
        "action-move-categorypages": "تهر تاکدیمئ انتکال",
        "action-movefile": "ای فایلی انتقال داتین",
        "action-upload": "ای فایلی اپلود یا بُرز کورتین",
+       "action-reupload": "ای موجودین فایلئ سرا نیویشتین",
+       "action-reupload-shared": "ای فایل ئی باطل کورتین شه یک مشترکین مخزن ئا",
+       "action-upload_by_url": "ای فایلئ بُرز کورتین شه یک انترنتین ادرسا",
        "action-writeapi": "استفاده شه نیویشتینی API",
        "action-delete": "پاک کورتین ای تاکدیمئ",
        "action-deleterevision": "ای نخسه یی پاک کورتین",
+       "action-deletedhistory": "ای تاکدیمی پاک بوتینئ تاریخچه ئی دیستین",
+       "action-browsearchive": "گشتین په پاک بوته ئین تاکدیمان",
+       "action-undelete": "بی جاه آورتین ای تاکدیمئ",
+       "action-suppressrevision": "بی جاه آورتین و دیستین پاک بوته ئین ایڈیٹانئ",
+       "action-suppressionlog": "ای خصوصین سیاه چالی دیستین",
+       "action-block": "ای کار زوروکئ دسترسی ئی قطع کورتین شه ایڈیٹ ئا",
+       "action-protect": "ای تاکدیمی ساتیتینئ رکم",
+       "action-rollback": "عاجل ئین بیئرگردینتین آخیر ئین کار زوروکئ ایڈیٹانئ که ای تاکدیما ایڈیٹ کورته",
+       "action-import": "تاکدیمئ داخل کورتین شه دیگه ویکی ئا",
+       "action-importupload": "تاکدیمئ داخل کورتین شه فایلئ اپلوڈ کورتین ئا",
+       "action-patrol": "دیگرانئ ایڈیٹانی مارک جتین",
+       "action-autopatrol": "وتئ ایڈیٹانئ نشاني کورتین",
+       "action-unwatchedpages": "دیسته نه بوته ئین تاکدیمانئ دیستین",
+       "action-mergehistory": "ای تاکدیمی تاریخچه ئی ادغام",
+       "action-userrights": "ایڈیٹ کورتین کار زوروکئ موچین اختیارانئ",
+       "action-userrights-interwiki": "یک دیگه ویکی ئی کار زوروکانئ اختیارانی ایڈیٹ کورتین",
+       "action-siteadmin": "مئلومات ئین بانکئ قُلپ و یا پاچ کورتین",
        "action-sendemail": "ایمیلی دیم داتین",
+       "action-editmywatchlist": "وتئ واچلیستا ایڈیٹ بکنت",
+       "action-viewmywatchlist": "وتئ واچلیست ئا بگیندیت",
+       "action-viewmyprivateinfo": "وتئ خصوصین مئلوماتانا بگیندیت",
+       "action-editmyprivateinfo": "وتئ خصوصین مئلوماتانا ایڈیٹ بکنیت",
+       "action-editcontentmodel": "یک تاکدیمی محتوائین مدل ئی ایڈیٹ کورتین",
        "nchanges": "$1 {{PLURAL:$1|ٹگل|ٹگل}}",
        "enhancedrc-since-last-visit": "$1 {{PLURAL:$1|شه اخر ئین دیستینا}}",
        "enhancedrc-history": "تاریخچه",
        "recentchanges": "آخیرین تغیراتان",
+       "recentchanges-legend": "آخیر ئین تغیراتانئ آپشن",
+       "recentchanges-summary": "ویکی ئی آخیر ئین تغیرانا بئ تاکدیمی تا بچاریت.",
+       "recentchanges-noresult": "هیچ تغیری بئ تعین بوته ئین دوره ئی تا گۆ ای معیاران هموانی نداشت.",
+       "recentchanges-feed-description": "ای ویکی ئی آخیر ئین تغیرانا بئ ای وارگ ئی تا بچاریت.",
+       "recentchanges-label-newpage": "ای ایڈیٹ نوکین تاکدیمی ئا جوڑ کورت",
+       "recentchanges-label-minor": "ای یک گونڈین ایڈیٹئ است",
+       "recentchanges-label-bot": "ای ایڈیٹا یک ربات ئی کورته",
+       "recentchanges-label-unpatrolled": "ای ایڈیٹ تا انون گشت وارته نه بوته",
+       "recentchanges-label-plusminus": "تاکدیمئ حجم بئ ای اندازگ بایٹ ئا تغیر کورته",
+       "recentchanges-legend-heading": "'''اختصارئان:'''",
+       "recentchanges-legend-newpage": "{{int:recentchanges-label-newpage}} (همیرنگ بی [[Special:NewPages|نوکین تاکدیمانئ لڑ لیست]] ئا سیل بکنیت)",
+       "rcnotefrom": "بئ جهلگا تغیرات شه <strong>$3, $4</strong> (تا <strong>$1</strong> {{PLURAL:$5|نشان داته بوته|نشان داته انت}}).",
+       "rclistfrom": "نوکین تغیراتانئ نشان داتین شرو شه $3 $2",
+       "rcshowhideminor": "$1 ئی کمین ایڈیٹان",
        "rcshowhideminor-show": "نشان داتین",
        "rcshowhideminor-hide": "چیهر داتین",
        "rcshowhidebots": "$1 ربات‌هان",
        "rcshowhidebots-show": "نشان داتین",
        "rcshowhidebots-hide": "چیهر داتین",
+       "rcshowhideliu": "$1 راجستر بوته ئین کار زوروکان",
        "rcshowhideliu-show": "نشان داتین",
        "rcshowhideliu-hide": "چیهر داتین",
+       "rcshowhideanons": "$1 نادروستئ ئین کار زوروکان",
        "rcshowhideanons-show": "نشان داتین",
        "rcshowhideanons-hide": "چیهر داتین",
+       "rcshowhidepatr": "$1 گشت وارته ئین ایڈیٹ ئان",
        "rcshowhidepatr-show": "نشان داتین",
        "rcshowhidepatr-hide": "چیهر داتین",
+       "rcshowhidemine": "$1 نی ایڈیٹان",
        "rcshowhidemine-show": "نشان داتین",
        "rcshowhidemine-hide": "چیهر داتین",
+       "rclinks": "نشان داتین $1 آخیر ئین تغییر بئ $2 اخیرین روچا<br />$3",
        "diff": "تفاوت",
        "hist": "تاریخچه",
        "hide": "چیهر داتین",
        "minoreditletter": "جز",
        "newpageletter": "نوک",
        "boteditletter": "ر",
+       "number_of_watching_users_pageview": "[$1 {{PLURAL:$1|کار زوروک}} دیستینوک]",
+       "rc_categories": "ای تهرهانی حد ئا (گۆ «|» ئا جیتا کنیت)",
        "rc_categories_any": "هر گوجام",
+       "rc-change-size-new": "$1 {{PLURAL:$1|بایٹ}} پد شه تغیرا",
+       "newsectionsummary": "/* $1 */ نوکین بخش",
+       "rc-enhanced-expand": "جزئیات ئی نشان داتین",
+       "rc-enhanced-hide": "جزئیات ئی چیهر داتین",
+       "rc-old-title": "جوڑ بوته گو بُنیادی ئنوانا «$1»",
+       "recentchangeslinked": "مربوتین تغیراتان",
+       "recentchangeslinked-feed": "مربوتین تغیراتان",
+       "recentchangeslinked-toolbox": "مربوتین تغیراتان",
+       "recentchangeslinked-title": "مربوتین تغیراتان گو $1",
        "recentchangeslinked-page": "تاکدیم نام:",
+       "recentchangeslinked-to": "نشان داتین تاکدیماني تغیرات که گۆ ای تاکدیما لینک دارنت",
        "upload": "فایلی بُرز کورتین",
        "uploadbtn": "فایلی بُرز کورتین",
+       "reuploaddesc": "بُرز کورتیني کنسیل و بیئرگشت په بُرز کورتیني فرما",
+       "upload-tryagain": "فایلئ تغیر ئی شرح ئی دیم داتین",
+       "uploadnologin": "لوگین نه بوته بی",
+       "uploadnologintext": "په فایلي بُرز کورتینا باید $1.",
+       "upload_directory_missing": "($1) ئی بُرز کنۆکین شاخه موجود نه اینت و جۆڑ بوتینئ وڑ نه اینت .",
+       "upload_directory_read_only": "($1) بُرز کنۆکین شاخه شه ویت سرور نیمگا نیویشتین ئی وڑ نه اینت.",
        "uploaderror": "خطا بی اپلودی تا",
+       "upload-recreate-warning": "'''هشدار:فایلی گۆ\t ای ناما یا پاک بوته یا دیگه جای جابجا بوته.'''\n\nپه آسانی خاتیرا، ای تاکدیمی پاک بوتین و جابجایی سیاهه بئ جهلگا آته:",
+       "uploadtext": "شه جهلگین فرما په نوکین فایلانئ بُرز کورتینا استفاده بکنیت.\nپه آ فایلان که دیمتیرا بُرز کورته بوته انت بئ  [[Special:FileList|فایلانئ لڑ لیست]] ئی تا برَۆیت. شه سري نوکین بُرز کورتین  بئ [[Special:Log/upload|بُرز کنۆکین کۆرم]] و پاک کورتین فایلانئ بئ [[Special:Log/delete|deletion log]] ئی تا راجستر ئه بیئنت.\n\nپد شه آیی که یک فایلئ ئا بُرز کورتیت، بئ ای سه رقم توانیت آیرا بئ تاکدیمانئ تا استفاده بکنیت:\n*'''<code><nowiki>[[</nowiki>{{ns:file}}<nowiki>:File.jpg]]</nowiki></code>''' په فایلئ کامیلین نخسه ئی استفاده کورتینی خاتیرا\n*'''<code><nowiki>[[</nowiki>{{ns:file}}<nowiki>:File.png|200px|thumb|left|alt text]]</nowiki></code>''' په استفاده کورتین شه یک ۲۰۰ پیکسیل ئین نخسه شه فایل بی یک بکس ئی تا بئ چپ ئین نیمگا یک متن که آیی تا alt text بئ ئنوان شرح استفاده بوته\n*'''<code><nowiki>[[</nowiki>{{ns:media}}<nowiki>:File.ogg]]</nowiki></code>''' په جۆڑ کورتین یک یک مستقیمین لینک بئ فایلا بی شه آیی که فایل نشان داته بیئت",
+       "upload-permitted": "مجاز ئین فایل ئی {{PLURAL:$2|نوع|انواع}}: $1.",
+       "upload-preferred": "ترجیح داته بوته ئین فایل ئی {{PLURAL:$2|نوع|انواع}} : $1.",
+       "upload-prohibited": "نا مجاز ئین فایل ئی {{PLURAL:$2|نوع|انواع}}: $1.",
+       "uploadlogpage": "بُرز کورتینئ سیاه چاله",
+       "uploadlogpagetext": "جهلگی لڑلیست آخیرین لڑلیست شه بُرز بوته ئین فایلان اینت.\nپه دیدارین مرواریدا [[Special:NewFiles|نوکین فایلانی نگارخانه]] ئا بگیندیت.",
        "filename": "فایلئ نام",
        "filedesc": "خلاصه",
        "fileuploadsummary": "خلاصه:",
+       "filereuploadsummary": "فایلی تغیرات:",
+       "filestatus": "کاپی رایٹ ئی وضیعت",
        "filesource": "منبع:",
+       "ignorewarning": "چشم چیهرداتین شه هشدارا و ذخیره کورتین فایلئ.",
+       "ignorewarnings": "چم پوشی شه موچین هشداران",
+       "minlength1": "فایلئ نام باید کم شه کم یک حرف بیئت.",
+       "filetype-missing": "ای فایل پدوندی (مثلاً «‎.jpg») نداریت.",
+       "empty-file": "فایلی که دیم داته بوت خالی ات.",
+       "file-too-large": "فایلی که دیم داتیت بئ حد ٹوو ات.",
+       "filename-tooshort": "فایلی نام بئ شه اندازگ ئا گۆنڈ ات.",
+       "filetype-banned": "ایرنگین فایل ئی اجازه نه اینت.",
+       "verification-error": "فایل شه تائید ئی امتحانا در نه بوت.",
+       "hookaborted": "تغیر که شما لۆٹیت جۆڑ کنیت شه یک جنگک یی نیمگا بند بوت.",
+       "illegal-filename": "فایل ئی نام غیرمجاز اینت.",
+       "overwrite": "یک موجودین فایلی سرا نیویشتین ئی اجازه نه اینت.",
+       "unknown-error": "یک نا زانتین خطائی رخ دات.",
+       "tmp-create-error": "موقتین فایلی جۆڑ کورتین ممکن نه اینت.",
+       "tmp-write-error": "خطا بئ موقتین فایلی نیویشتینا.",
+       "uploadwarning": "بُرز کورتینئ هشدار",
        "savefile": "فایلی ذخیره کورتین",
+       "uploaddisabled": "بُرز کورتین غیر پئال اینت.",
+       "copyuploaddisabled": "بُرز کورتین شه اینترنیتی ادرسا غیرفعال اینت.",
+       "uploaddisabledtext": "فایل ئی بُرز کورتین غیر فعال اینت.",
+       "upload-source": "فایلی منشا",
+       "sourcefilename": "منشائی فایلی نام:",
+       "sourceurl": "منشائی ادرس:",
+       "destfilename": "فایلئ مخصدی نام:",
+       "upload-maxfilesize": "فایلی حداکثر اندازه گ: $1",
+       "upload-description": "فایلی توضیحات",
+       "upload-options": "بُرز کورتین یا آپلوڈئ اپشن",
+       "watchthisupload": "دیستین ای فایلی",
+       "upload-success-subj": "بُرز کورتین یا آپلوڈ گو کامیابی ئا انجام بوت",
+       "upload-failure-subj": "بُرز کنوکی پرابلم",
+       "upload-warning-subj": "بُرز کورتینئ هشدار",
+       "upload-proto-error": "نادروستین پروتوکول",
+       "upload-proto-error-text": "بُرز کورتین شه دوردستا به ادرس ئان که گو <code dir=ltr>http://</code> یا <code dir=ltr>ftp://</code>  ئی شرو بیئنت ضرورت داریت .",
+       "upload-file-error": "داخلین خطا",
+       "upload-misc-error": "نامئلومین خطا بی بُرزکورتینئ تا",
+       "upload-too-many-redirects": "انترنیتی ادرس به شه اندازه ئا تغیرمسیر داریت",
+       "upload-http-error": "یک  اچ‌تی‌تی‌پی خطا رخ داته: $1",
+       "upload-copy-upload-invalid-domain": "بُرز بوته فایلانی کاپی کورتین شه ای ڈومین ئا امکان نداریت.",
+       "backend-fail-stream": "نه توانن $1 ئی فایلا دیم دهین.",
+       "backend-fail-backup": "نتنوانن پُشتوانی نخسه یی په $1 فایلا جۆڑ کنن.",
+       "backend-fail-notexists": " $1 ئی فایل وجود نداریت.",
+       "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-connect": "ارتباط گۆ «$1» ئی ذخیره ئی پُشتیوانا برقرار نه بوت.",
+       "backend-fail-internal": "نامئلومین خطایی بئ «$1» ئی ذخیره پُشتیوانی تا رخ دات.",
+       "lockmanager-notlocked": "نه توان که «$1» ئی قُلپا پاچ کورت؛ چون که قُلپ نه بوته.",
+       "lockmanager-fail-closelock": "\"$1\" ئی قُلپ بوته ئین فایلی بستین امکان نه داریت.",
+       "lockmanager-fail-deletelock": "\"$1\" ئی قُلپ بوته ئین فایلی پاک کورتین،امکان نداریت.",
+       "lockmanager-fail-acquirelock": "نه توانیت «$1» ئی قُلپ ئا کسب کنیت.",
+       "lockmanager-fail-openlock": "\"$1\" ئی قُلپ بوته ئین فایلی پاچ کورتین امکان نه داریت.",
+       "lockmanager-fail-releaselock": "نه توانیت «$1» ئی قُلپ ئا پاچ کنیت.",
+       "lockmanager-fail-db-release": "$1 ئی مئلوماتی بانکی قُلپئ پاچ کورتین امکان نه داریت.",
+       "lockmanager-fail-svr-acquire": "$1 ئی سرور ئی قُلپانی گیپتین امکان نه داریت.",
+       "lockmanager-fail-svr-release": "$1 ئی سرور ئی قُلپانی پاچ کورتین ئی امکان نه اینت.",
+       "zip-file-open-error": "بئ زیپ ئی فایلی پاچ کورتینی وختا، په آیی محتوایی دیستینی خاتیرا، یک خطا ئی رخ دات.",
+       "zip-wrong-format": "مشخص بوته ئین فایل، زیپ ئی یک فایلی نه اینت.",
+       "uploadstash": "بُرز کورتین انبار ئی",
+       "uploadstash-clear": "پاک کورتین انبارشده ئین فایلانئ",
+       "uploadstash-nofiles": "شما هیچ انبارشده ئین فایلئ نداریت.",
+       "uploadstash-errclear": "فایلانئ پاک کورتین ناکام ات.",
+       "uploadstash-refresh": "فایلانئ لڑلیستئ نوک کورتین",
+       "invalid-chunk-offset": "قطعه ئی ناموتبرین جابجايی",
+       "img-auth-accessdenied": "دسترسی ئی منشا",
+       "img-auth-streaming": "بئ حال جاری کورتینی «$1» ئا.",
+       "http-read-error": "اچ‌تی‌تی‌پی ئی وانتینئ خطا.",
+       "http-timed-out": "اچ‌تی‌تی‌پی ئی ریکویست ئی وخت الاس بوت.",
+       "upload-curl-error28": "بُرز کورتین ئی وخت الاس بوت",
        "license": "اجازه‌نامه:",
        "license-header": "اجازه‌نامه",
        "nolicense": "هیچگوجام انتخاب نه بوته",
+       "licenses-edit": "ایڈیٹ ئی  مجوزین آپشن ئان",
+       "license-nopreview": "(دیم دیست ئی وجود نداریت)",
+       "upload_source_file": "(شمی انتخابی ئین فایل شه شمی کامپیوتیرا)",
        "listfiles-delete": "پاک کورتین",
+       "listfiles-summary": "ای خاصین تاکدیم موچین بُرز بوته ئین فایلانه نشان ئه دنت.",
+       "listfiles_search_for": "گشتین په میڈیا نام ئا:",
        "imgfile": "فایل",
        "listfiles": "فایل لیست",
        "listfiles_thumb": "ناحُننک",
        "listfiles-latestversion-no": "نه",
        "file-anchor-link": "فایل",
        "filehist": "فایلی تاریخچه",
+       "filehist-help": "تاریخ/وخت ئانی سرا کلیک کنیت تا آ وختی مربوتین نخسه ئانه بگیندیت.",
        "filehist-deleteall": "موچانی پاک کورتین",
        "filehist-deleteone": "پاک کورتین",
        "filehist-revert": "بیرگردینتین",
        "filehist-current": "انونین نسخه",
        "filehist-datetime": "تاریخ/ساعت",
        "filehist-thumb": "ناحُننک",
+       "filehist-thumbtext": "ناحُنین اکس شه مورخ $1 ئی نخسه ئا",
        "filehist-nothumb": "بی ناحُننک",
        "filehist-user": "کار زوروک",
        "filehist-dimensions": "ابعاد",
        "filehist-comment": "کومنیت",
        "imagelinks": "بی کار گیپتین فایلئ",
        "linkstoimage": "{{PLURAL:$1|تاکدیم|تاکدیمان}} جهلگین بی اکسا لینک {{PLURAL:$1|داریت|دارنت}}:",
+       "nolinkstoimage": "ای فایل بئ هیچ تاکدیمی تا بئ کار گیپته نه بوته.",
+       "morelinkstoimage": "ای فایلئ [[Special:WhatLinksHere/$1|دیگرین لینکانا]] بگیندیت.",
+       "linkstoimage-redirect": "$1 (فایلی تغیرمسیر) $2",
+       "filepage-nofile": "فایلی گۆ ای ناما موجود نه اینت.",
+       "filepage-nofile-link": "فایلی گۆ ای ناما موجود نه اینت، اما شما ئه توانیت آیرا [$1 بُرز کنیت].",
+       "uploadnewversion-linktext": "نوکین نخسه ئی بُرز کورتین شه فایلا",
        "shared-repo-from": "شه $1",
+       "shared-repo": "یک مشترکین مخزن",
+       "upload-disallowed-here": "شما نه توانیت ای فایلا بازنویسی بکنیت.",
        "filerevert": "بیئرگردینتین $1",
        "filerevert-legend": "بیئرگردینتین فایلی",
        "filerevert-intro": "شما بی حالی بیئرگردینتینا '''[[Media:$1|$1]]''' بی [$4 نخسه تاریخ $2 سائت $3] هستیت.",
+       "filerevert-comment": "دلیل:",
+       "filerevert-defaultcomment": "بیئرگردینتین بئ $1 ئی نخسه ئا سائت $2",
        "filerevert-submit": "بیئرگشت",
        "filerevert-success": "<strong>[[Media:$1|$1]]</strong> بی [$4 نخسه ئی بی تاریخی $2 سائت $3] ئا بیئرگشتینته بوت.",
        "filerevert-badversion": "قدیمیتیرین نخسه شه ای فایلا موجود نه اینت.",
        "filedelete": "پاک کورتین $1",
        "filedelete-legend": "فایلی پاک کورتین",
+       "filedelete-intro-old": "شما بئ حال پاک کورتین نخسه ئی '''[[Media:$1|$1]]''' مورخ [$4 $2 سائت $3] هستیت.",
        "filedelete-comment": "دلیل:",
        "filedelete-submit": "پاک کورتین",
+       "filedelete-success": "'''$1''' پاک بوت.",
+       "filedelete-success-old": "نخسه  '''[[Media:$1|$1]]''' مورخ $2 سائت $3 پاک بوت.",
+       "filedelete-nofile": "'''$1''' موجود نه اینت.",
+       "filedelete-nofile-old": "ارشیف  بوته ئین نخسه شه  '''$1''' گۆ داته بوته ئین مشخصاتان، موجود نه اینت.",
+       "filedelete-otherreason": "دیگرین دلیل/اضافی:",
+       "filedelete-reason-otherlist": "دیگرین دلیل",
+       "filedelete-maintenance-title": "نه توانیت فایلا پاک بکنیت",
        "mimesearch": "گشتین بی اساس MIME",
+       "mimetype": "MIME ئی رکم:",
        "download": "ائیر کورتین",
+       "unwatchedpages": "دیسته نه یوته ئین تاکدیمان",
+       "unusedtemplateswlh": "دیگه لینک ئان",
+       "randompage": "تصادفی مقاله",
        "randomincategory-category": "تهر:",
+       "randomincategory-legend": "تصادفین تاکدیم بئ تهرئی تا",
+       "randomredirect": "تغییرمسیر تصادفی",
+       "statistics": "ارقام",
+       "statistics-header-pages": "ای تاکدیمئ ارقام",
+       "statistics-header-edits": "ایڈیٹانی ارقام",
        "statistics-header-users": "کار زوروکانئ ارقام",
        "statistics-header-hooks": "دیگرین ارقام",
        "statistics-articles": "تاکدیمانی محتوا",
        "statistics-pages": "تاکدیمان",
        "statistics-pages-desc": "ای ویکی ئی موچین تاکدیمان ٬ هبر و گپ ئی تاکدیمان ٬ و تغیر مسیر و دیگرین",
        "statistics-files": "بُرز بوته ئین فایلان",
+       "statistics-edits-average": "متوسطین ایڈیٹ شه هر یکین تاکدیما",
+       "statistics-users": "راجستر بوته ئین [[Special:ListUsers|کار زوروکان]]",
+       "statistics-users-active": "پئال ئین کار زوروکان",
+       "pageswithprop": "تاکدیم گۆ تاکدیمانئ خاصیتا",
+       "pageswithprop-legend": "تاکدیم گۆ تاکدیمانئ خاصیتا",
+       "pageswithprop-prop": "خاصیت ئی نام:",
        "pageswithprop-submit": "برا",
        "brokenredirects-edit": "ایڈیٹ",
        "brokenredirects-delete": "پاک کورتین",
        "withoutinterwiki-legend": "دیموند",
        "withoutinterwiki-submit": "نشان داتین",
+       "fewestrevisions": "مقاله ئان گۆ کم ئین ایڈیٹ ئی اندازگ ئا",
        "nbytes": "$1 {{PLURAL:$1|بایٹ|بایٹ}}",
        "ncategories": "$1 {{PLURAL:$1|تهر|تهرئان}}",
+       "ninterwikis": "$1 {{PLURAL:$1|میان‌ویکی|میان‌ویکی}}",
+       "nlinks": "$1 {{PLURAL:$1|لینک|لینک}}",
        "nmembers": "$1 {{PLURAL:$1|عضو|عضو}}",
        "nmemberschanged": "$1 → $2   {{PLURAL:$2| عضو|عضو}}",
        "nrevisions": "$1 {{PLURAL:$1|نخسه|نخسه}}",
        "nviews": "$1 {{PLURAL:$1|دیست|دیست}}",
        "nimagelinks": "استفاده بوته بی  $1 {{PLURAL:$1|تاکدیم|تاکدیم}} ئی تا",
        "ntransclusions": "استفاده بوته بی  $1 {{PLURAL:$1|تاکدیم|تاکدیم}} ئی تا",
+       "specialpage-empty": "نتیجه په راپور ئا موجود نه اینت.",
        "lonelypages": "آتیمین تاکدیمان",
+       "uncategorizedpages": "تاکدیمان که کتیگوری بندی نه بوته انت",
+       "uncategorizedcategories": "تهرهان که کتیگوری بندی نه بوته انت",
+       "uncategorizedimages": "کتیگوری بندی نه بوته ئین فایلان",
+       "uncategorizedtemplates": "کتیگوری بندی نه بوته ئین تراشوانان",
+       "unusedcategories": "استفاده نه بوته ئین تهرهان",
+       "unusedimages": "استفاده نه بوته ئین فایلان",
+       "wantedcategories": "ضرورتین تهرهان",
+       "wantedpages": "ضرورتین تاکدیمان",
+       "wantedpages-badtitle": "نامجازین ئنوانی بی مجموعه نتایج: $1",
+       "wantedfiles": "ضرورتین فایلان",
+       "wantedtemplates": "ضرورتین تراشوانان",
+       "mostlinked": "تاکدیمان که گیشتیر شه دیگران بئ آوان لینک داته بوته",
+       "mostlinkedcategories": "تهرهان که گیشتیر شه دیگران بئ آوان لینک داته بوته",
+       "mostcategories": "تاکدیمان گۆ بازین تهرهان",
+       "mostimages": "فایلان که گیشتیر شه دیگران بئ آوان لینک داته بوته",
+       "mostinterwikis": "تاکدیمان گۆ بازین میان ویکی هان",
+       "mostrevisions": "تاگدیمان گۆ بازێن نخسه ئان",
+       "prefixindex": "موچین تاکدیمان گۆ پدوندی",
        "shortpages": "گونڈ\tین تاکدیمان",
        "longpages": "تچکین تاکدیمان",
        "deadendpages": "بن بستین تاکدیمان",
+       "protectedpages": "قُلپ بوتگین تاکدیمان",
+       "protectedpages-timestamp": "وختی برچسپ",
        "protectedpages-page": "تاکدیم",
+       "protectedpages-expiry": "الاسی وخت",
+       "protectedpages-performer": "قُلپ کنۆوکین کار زوروک",
+       "protectedpages-params": "قُلپ بوته ئین پارامیتران",
+       "protectedpages-reason": "دلیل",
+       "protectedpages-unknown-timestamp": "نامئلوم",
+       "protectedpages-unknown-performer": "نادروستئ ئین کار زوروک",
+       "protectedtitles": "قُلپ بوته ئین ئنوانان",
+       "listusers": "کار زوروکانئ لڑلیست",
+       "listusers-editsonly": "فقط آ کار زوروکان که ایڈیٹ کورته انت نشان ب دئ",
+       "listusers-creationsort": "مرتب کورتین بئ اساس جۆڑ کورتینی تاریخا",
+       "listusers-desc": "نزولی ترتیب",
+       "usereditcount": "$1 {{PLURAL:$1|ایڈیٹ|ایڈیٹ}}",
+       "usercreated": "{{GENDER:$3|جوڑ بوته}} بئ تاریخ $1 بئ سائت $2",
+       "newpages": "نوکین تاکدیم",
        "newpages-username": "کار زوروکین نام:",
+       "ancientpages": "کهنگین تاکدیمان",
+       "move": "انتقال",
+       "movethispage": "ای تاکدیمی انتقال",
+       "notargettitle": "بی شه هدفا",
+       "nopagetitle": "ایرنگی تاکدیمئ وجود نداریت",
+       "pager-newer-n": "{{PLURAL:$1|یک نوکتیرین مورد|$1 نوکتیرین مورد}}",
+       "pager-older-n": "{{PLURAL:$1|یک دیمتیرین مورد|$1 دیمتیرین مورد}}",
+       "suppress": "گیندوک ئان",
+       "apihelp": "API کومک",
+       "apihelp-no-such-module": "موڈیل \" $1 \" ودی نه بوت.",
+       "booksources": "کتابئ منبه ئان",
+       "booksources-search-legend": "په کتایئ منابی ئان خاتیرا گشتین",
        "booksources-search": "گشتین",
        "specialloguserlabel": "مجری:",
+       "speciallogtitlelabel": "هدف (ئنوان یا کار زوروک):",
        "log": "سیاهه‌ها",
+       "all-logs-page": "عمومین موچین سیاه چال هان",
+       "logempty": "شمی منطبقین آیتم بی سیاه چالئ تا ودی نه بوت.",
+       "allpages": "موچین تاکدیمان",
+       "nextpage": "بعدین تاکدیم ($1)",
+       "prevpage": "دیمی تاکدیم ($1)",
+       "allpagesfrom": "تاکدیمانئ نشان داتین شرو شه:",
+       "allpagesto": "تاکدیمانئ نشان داتین الاسئ گو:",
        "allarticles": "موچین تاکدیمان",
+       "allinnamespace": "موچین تاکدیمان ($1 نامی فضا)",
        "allpagessubmit": "برا",
+       "allpages-hide-redirects": "تغیرمسیرانی چیهرداتین",
+       "cachedspecial-refresh-now": "دیستین آخرین ئانی.",
        "categories": "تهرئان",
+       "special-categories-sort-count": "ترتیت کورتین بئ اساس اندازگ",
+       "special-categories-sort-abc": "ترتیب کورتین سیاهگانی",
+       "deletedcontributions": "پاک بوته ئین مشارکتانی",
+       "deletedcontributions-title": "پاک بوته ئین مشارکتانی",
+       "sp-deletedcontributions-contribs": "مشارکت ئان",
+       "linksearch": "گشتین په ڈنئ لینکا",
+       "linksearch-pat": "گشتین په نمونه ئا:",
+       "linksearch-ns": "نامی فضا:",
        "linksearch-ok": "گشتین",
        "listusers-submit": "نشان داتین",
+       "listusers-noresult": "هیچ کار زوروکئ ودی نه بوت.",
+       "listusers-blocked": "(بلاک بوته)",
+       "activeusers": "پئالین کار زوروکانئ لڑ لیست",
+       "activeusers-from": "نمایش داتین کار زوروکان شرو شه:",
+       "activeusers-hidebots": "رباتانی چیهر داتین",
+       "activeusers-hidesysops": "مدیرانئ چیهرداتین",
+       "activeusers-noresult": "هیچ کار زوروکئ ودی نه بوت.",
+       "listgrouprights": "کار زوروکین گروپانئ اختیاران",
        "listgrouprights-group": "گروپ",
+       "listgrouprights-rights": "حقوق",
+       "listgrouprights-helppage": "Help:گروپانئ حقوق",
+       "listgrouprights-members": "(اعضائانی لڑلیست)",
+       "listgrouprights-addgroup": "توانیت ای {{PLURAL:$2|گروپ|گروپ ئان}} ئا اضافه بکینت: $1",
+       "listgrouprights-removegroup": "توانیت ای {{PLURAL:$2|گروپ|گروپ ئان}} ئه پاک بکنیت: $1",
+       "listgrouprights-addgroup-all": "توانیت موچین گروپانا اضافه بکنیت",
+       "listgrouprights-removegroup-all": "توانیت موچین گروپانا پاک بکنیت",
+       "listgrouprights-addgroup-self": "توانیت وتئ حسابا بی ای  {{PLURAL:$2|گروپ|گروپان}} ئی تا اضافه بکنیت: $1",
+       "listgrouprights-removegroup-self": "توانیت وتئ حسابا شه ای  {{PLURAL:$2|گروپ|گروپان}} پاک بکنیت: $1",
+       "listgrouprights-addgroup-self-all": "توانیت وتئ حسابا بی موچین گروپان اضافه بکینت",
+       "listgrouprights-removegroup-self-all": "توانیت وتئ حسابا شه موچین گروپان پاک بکنیت",
+       "listgrouprights-namespaceprotection-header": "فضای نام ئی محدودیت",
+       "listgrouprights-namespaceprotection-namespace": "نامی فضا",
+       "trackingcategories": "ردیابی کنۆکین تهرهان",
+       "trackingcategories-msg": "ردیابئ تهر",
        "trackingcategories-name": "پیامی نام",
+       "trackingcategories-desc": "تهرئ کنجایش ئی معیاران",
+       "trackingcategories-nodesc": "هیچ توضیحی موجود نه اینت.",
+       "trackingcategories-disabled": "تهر غیر پئال بوته",
+       "mailnologin": "ادرسئ شه دیم دهۆک ئا موجود نه اینت",
+       "emailuser": "ای کار زوروکئ ایمیل",
+       "emailuser-title-target": "ایمیل په {{GENDER:$1|کار زوروکا}}",
        "emailuser-title-notarget": "کار زوروکی ایمیل",
        "emailpage": "کار زوروکی ایمیل",
+       "defemailsubject": "{{SITENAME}} ایمیل شه کار زوروکئ نیمگا «$1»",
+       "usermaildisabled": "کار زوروکئ ایمیل غیر پئال اینت",
+       "noemailtitle": "ایمیل ئی ادرس موجود نه اینت",
+       "noemailtext": "ای کار زوروک موتبرین ایمیل ئی مشخص نه کورته.",
+       "nowikiemailtext": "ای کار زوروک انتخاب کورته که شه دیگه کار زوروکان په آیی ایمیل مه آینت.",
+       "emailnotarget": "کار زورکین نام موجود نه اینت یا ناموتبر په گیرنده ئا.",
+       "emailtarget": "گیرنده ئی کار زوروکین ناما وارد بکنیت",
        "emailusername": "کار زوروکین نام:",
        "emailusernamesubmit": "ثبت کورتین",
+       "email-legend": "یک ایمیلی داتین په دیگرین {{SITENAME}} کار زوروکا",
        "emailfrom": "شه:",
        "emailto": "بی:",
        "emailsubject": "ئنوان:",
        "emailmessage": "پیام:",
        "emailsend": "دیم دئ",
+       "emailccme": "پیامی رونیویشت ئا په من دیم دی.",
+       "emailccsubject": "شمی پیامی رونیویشت په $1: $2",
        "emailsent": "ایمیل دیم دئ",
+       "emailsenttext": "شمی ایمیل پیام دیم داته بوت",
+       "usermessage-summary": "سیستم یی پیامی ایشتین.",
+       "usermessage-editor": "سیستم یی پیام رسان",
        "watchlist": "واچلیست",
        "mywatchlist": "واچلیست",
        "watchlistfor2": "په $1 $2",
+       "watchnologin": "داخل نه بوته ئیت",
+       "addwatch": "افاضه کورتین بئ واچلیستا",
+       "removewatch": "پاک کورتین شه واچلیستا",
        "watch": "دیستین",
        "watchthispage": "دیستین ای تاکدیمی",
        "unwatch": "اوشتارین تین دیستینی",
+       "watchlist-options": "واچلیستئ آپشن",
+       "watching": "بئ دیستینئ حالا...",
+       "unwatching": "دیستینئ اوشتارینتین...",
        "enotif_impersonal_salutation": "کار زوروک {{SITENAME}}",
        "enotif_subject_deleted": "{{SITENAME}} تاکدیم $1 شه {{gender:$2|$2}} نیمگا پاک بوت.",
        "enotif_subject_created": "{{SITENAME}} تاکدیم $1 شه {{gender:$2|$2}} نیمگا جوڑ بوته.",
        "enotif_subject_restored": "{{SITENAME}} تاکدیم $1 شه {{gender:$2|$2}} نیمگا نوک بوت.",
        "enotif_subject_changed": "{{SITENAME}} تاکدیم $1 شه {{gender:$2|$2}} نیمگا تغیر بوت.",
        "enotif_body_intro_deleted": "$1 تاکدیم {{SITENAME}} $PAGEEDITDATE بی تاریخی شه{{gender:$2|$2}} نیمگا پاک بُوت ، $3 ئا بگیندیت .",
+       "enotif_body_intro_moved": "{{SITENAME}} $1 ئی تاکدیم بئ تاریخ $PAGEEDITDATE شه {{gender:$2|$2}} ئی نیمگا انتقال بوت، $3 ئا په انونین نخسه ئا بگیندیت.",
+       "enotif_body_intro_restored": "{{SITENAME}} $1 تاکدیم بئ تاریخ $PAGEEDITDATE شه {{gender:$2|$2}} ئی نیمگا پدا جۆڑ بوت، $3 ئا په انونین نخسه ئا بگیندیت.",
+       "enotif_body_intro_changed": "{{SITENAME}} $1 ئی تاکدیم بئ تاریخ $PAGEEDITDATE شه {{gender:$2|$2}} ئی نیمگا تغیر داته بوت، $3 ئا په انونین نخسه ئا بگیندیت.",
+       "enotif_lastvisited": "په موچین تغیران شه آخیرئین واری که سر جته ئیت  ایدا $1 بگنیت.",
+       "enotif_lastdiff": "په ای تغیری دیستینا $1 ئا بگیندیت.",
+       "enotif_anon_editor": "$1 نا دروستی ئین کار زوروک",
+       "enotif_body": "$WATCHINGUSERNAME گرامی،\n\n$PAGEINTRO $NEWPAGE\n\n\nایڈیٹ کنۆکێ توضیحات: $PAGESUMMARY $PAGEMINOREDIT\n\nتماس گۆ ایڈیٹ کنۆکا:\nایمیل: $PAGEEDITOR_EMAIL\nویکی: $PAGEEDITOR_WIKI\n\nتا وختی که بئ ای دیما سر نه جته ئیت ، بئ شمی احتمالی ئین فعالیتی گیشتیرین بوتین ئی سورتا، تا وختی که گۆ وتئ کار زوروکین حسابا بی سایت تا وێت ، شما جار دیم داته ئه نه بیێت.\nشما همچنین توانتیت وتئ چاریێتین لیست ئی تا موچین بیراکانه سیپر کنیت و هم توانیت آوانا پدا بیئرگردی نیت.\n\nشمی دوستدارۆک، {{SITENAME}} ئی نوتیپیشن ئی سیستم\n\n--\nپه ای ایمیل ئی مئلومات رسانی ئی تنظیماتانی تغیری خاتیرا بئ {{canonicalurl:{{#special:EditWatchlist}}}} ئی تا برۆیت.\n\nپه وتئ واچلیستی تنظماتانی تغیر بئ  {{canonicalurl:{{#special:EditWatchlist}}}} ئی تا برۆیت\n\nپه دیمی پاک کورتین ئی خاتیرا شه وتئ واچلیستا بئ $UNWATCHURL ئی تا برۆیت.\n\nپه گیشتیرین کومک ئی خاتیرا:\n$HELPPAGE",
        "deletepage": "تاکدیمی پاک کورتین",
        "confirm": "تأیید کورتین",
+       "excontent": "تاکدیمی محتوا ایش ات: «$1»",
+       "excontentauthor": "تاکدیمی محتوا ایش ات: «$1» (و تانا مشارکت کنۆک «[[Special:Contributions/$2|$2]]» ات)",
+       "exbeforeblank": "تاکدیمی محتوا دیم شه خالی کورتینا ایش ات: «$1»",
        "delete-confirm": "پاک کورتین «$1»",
        "delete-legend": "پاک کورتین",
+       "historywarning": "<strong>هشدار:</strong> تاکدیمی ئا که پاک ئه کنیت تاریخچه داریت گۆ  $1 {{PLURAL:$1|پدا دیسته بوتین|پدا دیسته بوتین ئان}} اینت:",
+       "actioncomplete": "کار بوت",
+       "actionfailed": "کار نه بوت",
+       "deletedtext": "«$1» پاک بوت.\nپه آخیرین پاک بوتینین سابقه ئا بئ $2 ئی تا مراجعه بکنیت.",
+       "dellogpage": "سیاه چال ئی پاک کورتین",
+       "dellogpagetext": "جهلگین لڑلیست شه آخیرین پاک بوته ئین ئانی لڑا اینت.\nموچین ئانی نشان داته بته ئین وخت خادم وخت (گرینویچ ئی وخت) انت.",
+       "deletionlog": "سیاه چال ئی پاک کورتین",
+       "reverted": "بی دیمتیرین نخسه ئا بیئرگردینته بوت",
        "deletecomment": "دلیل:",
+       "deleteotherreason": "دیگرین دلیل/اضافی:",
+       "deletereasonotherlist": "دیگرین دلیل",
+       "deletereason-dropdown": "*پاک بوتینئ متدوالین دلیل\n** سپم\n** خرابکاری\n** کاپی رایت ئی نقض\n** کار زوروکئ خواهش\n** پروشته ئین تغیر میسر",
+       "delete-edit-reasonlist": "پاک بوتینئ دلیلانئ ایڈیٹ",
+       "deleteprotected": "شما نه توانیت که ای تاکدیما پاک کنیت چون که شه آیی محافظت بوته.",
+       "deleting-backlinks-warning": "''' هشدار:''' [[Special:WhatLinksHere/{{FULLPAGENAME}}|دیگرین تاکدیم]] هستنت که گۆ ای تاکدیما که شما ئه لوٹیت آیرا پاک بکنیت لینک بوته انت.",
+       "rollback": "ایڈیٹئ بیئرگردینتین",
        "rollbacklink": "بیجا آورتین",
+       "rollbacklinkcount": "بیئرگردینتین $1 {{PLURAL:$1|ایڈیٹ|ایڈیٹ هانئ}}",
+       "rollbacklinkcount-morethan": "بیئرگردینتین گیشتیر شه $1 ایڈیٹا",
+       "rollbackfailed": "بیئرگردینته نه بوت",
+       "cantrollback": "نه توانیت که ایڈیٹ ئا بیئرگردینیت؛\nآخرین مشارکت‌کنۆک ای مقاله ئی تانائین مولف اینت.",
+       "editcomment": "ایڈیٹ ئی خلاصه ایش ات: «''$1''».",
+       "rollback-success": "$1 ئی ایڈیٹ بیئرگردینته بوتنت؛\nتاکدیم بئ اخیرین ایڈیٹ شه $2 ئا بیئرگردینته بوت.",
+       "sessionfailure-title": "کار زوروکئ نشست ئی خطا",
+       "protectlogpage": "سیاهگئ قُلپ",
+       "protectedarticle": "«[[$1]]» ئا قُلپ کورت",
+       "modifiedarticleprotection": "«[[$1]]» قُلپ ئی وزيیتا گردینت",
+       "unprotectedarticle": "«[[$1]]» ئی تاکدیمئ قُلپ يا پاچ کورت",
+       "movedarticleprotection": "قُلپ ئی تنظیماتاشه «[[$2]]» ئا بئ  «[[$1]]» ئا جابجا کورت",
+       "protect-title": "«$1»  ئی قُلپ ئی وزئتئ گردینتین",
+       "protect-title-notallowed": "\" $1 \" ئی قُلپ ئی سطح دیستین",
+       "prot_1movedto2": "[[$1]] بئ [[$2]] ئا جابجا بوت",
+       "protect-badnamespace-title": "نام فضا بی شه قُلپا",
+       "protect-badnamespace-text": "ای فضای نامی تا موجودین تاکدیمان نه توانن قُلپ کنن.",
+       "protect-norestrictiontypes-title": "غیر قابل قُلپ ئین تاکدیم",
+       "protect-legend": "قُلپ کورتین ئی تائیدی",
        "protectcomment": "دلیل:",
+       "protectexpiry": "الاسی وخت:",
+       "protect_expiry_invalid": "الاسی وخت صحیح نه اینت.",
+       "protect_expiry_old": "الاسی وخت بئ دیما.",
+       "protect-unchain-permissions": "قُلپی دیگرین بخشانی پاچ کورتین",
+       "protect-default": "اجازه داتین بئ موچین کار زوروکان",
+       "protect-fallback": "فقط بئ آ کار زوروکان که بئ  «$1» ئا دسترسی دارنت، اجازه داته ئه بیئت",
+       "protect-level-autoconfirmed": "تانا اجازه په تائید بوته ئین کار زوروکان",
+       "protect-level-sysop": "فقط مدیر هان",
+       "protect-summary-cascade": "آپشاری",
+       "protect-expiring": "پوره بوتین ئی وخت $1 (UTC)",
+       "protect-expiring-local": "پوره بوته ئین $1",
+       "protect-expiry-indefinite": "بی‌پایان",
+       "protect-cantedit": "شما ئه نه توانیت ای تاکدیمی قُلپئ وضیعتا تغیر بدهیت، چون که شما آیی ایڈیٹ ئی اجازه ئا نداریت.",
+       "protect-othertime": "دیگه وخت:",
+       "protect-othertime-op": "دیگه وخت",
+       "protect-existing-expiry": "موجودین انقضای وخت: $2، $3",
+       "protect-existing-expiry-infinity": "موجودین انقضای وخت: بی‌نهایت",
+       "protect-otherreason": "دیگرین دلیل/اضافی:",
+       "protect-otherreason-op": "دیگرین دلیل",
+       "protect-edit-reasonlist": "قُلپی دلیلانی ایڈیٹ کورتین",
+       "protect-expiry-options": "۱ سائت:1 hour,۱ روچ:1 day,۱ هپتگ:1 week,۲ هپتگ:2 weeks,۱ ماه:1 month,۳ ماه:3 months,۶ ماه:6 months,۱ سال:1 year,بی‌پایان:infinite",
+       "restriction-type": "دسترسی:",
+       "restriction-level": "محدودیت ئی سطح:",
+       "minimum-size": "حداقل اندازه",
+       "maximum-size": "حداکثر اندازه:",
+       "pagesize": "(بایٹ)",
        "restriction-edit": "ایڈیٹ",
        "restriction-move": "انتقال",
        "restriction-create": "جوڑ\t کورتین",
        "restriction-upload": "بُرز کورتین",
+       "restriction-level-sysop": "کاملآ قُلپ بوته",
+       "restriction-level-autoconfirmed": "نیمه‌ گ قُلپ بوته",
+       "restriction-level-all": "هر سطحی",
+       "undelete": "پاک بوته ئین تاکدیمانی دیستین",
+       "undeletepage": "پاک بوته ئین تاکدیمانی دیستین و پدا جۆڑ کورتین",
+       "undeletepagetitle": "'''آن چه که دیمتیرا کاینت شامل شه [[:$1|$1]] ئی پاک بوته ئین نخسه ئان انت'''.",
+       "viewdeletedpage": "پاک بوته ئین تاکدیمانی دیستین",
+       "undelete-fieldset-title": "نخسه ئانی پدا جۆڑ کورتین",
+       "undeleterevisions": "$1 آرشیف {{PLURAL:$1|بوته|بوته انت}}",
+       "undelete-revision": "$1 ئی پاک بوته ئین نخسه (بئ تاریخ $4 سائت $5) شه $3 ئی نیمگا:",
+       "undelete-nodiff": "قدیمیتیرین نخسه ئی ودئ نه بوت.",
        "undeletebtn": "احیا",
+       "undeletelink": "نمایش/احیا",
        "undeleteviewlink": "دیستین",
+       "undeleteinvert": "انتخاب سرچپی بیئت",
        "undeletecomment": "دلیل:",
        "undeletedrevisions": "$1 ئی نخسه احیا {{PLURAL:$1|بوت}}",
+       "undeletedrevisions-files": "$1 نخسه و $2 فایل پداجۆڑ {{PLURAL:$1|بوت|بوتنت}}.",
+       "undeletedfiles": "$1 ئی فایل پدا جۆڑ {{PLURAL:$1|بوت|بوتنت}}.",
+       "cannotundelete": "پدا جۆڑ کورتین ناکام ات:\n$1",
+       "undeletedpage": "'''$1 پدا جۆڑ بوت'''\n\nپه پاک بوته ئین و پدا جۆڑ بوته ئین سیاهه ئی خاتیرا بئ [[Special:Log/delete|پاک بوته ئین ئانی سیاهه]] ئی تا برۆیت.",
+       "undelete-header": "په آ دیما که بئ ای آخیرا پاک بوته انت بئ   [[Special:Log/delete|پاک بوته ئین ئانی سیاهه]] ئا بگیندیت.",
+       "undelete-search-title": "گشتین په پاک بوته ئین تاکدیمان",
+       "undelete-search-box": "گشتین په پاک بوته ئین تاکدیمان",
+       "undelete-search-prefix": "نشان داتین تاکدیمانی شرو شه:",
        "undelete-search-submit": "گشتین",
+       "undelete-no-results": "هیچ مطابقت ئی تاکدیمی بئ پاک بوته ئین ئانی آرشیف ئی تا ودئ نه بوت.",
+       "undelete-cleanup-error": "خطا بئ «$1» پاک بوتین ئانی تاریخچه ئی تا استفاده نه بوته.",
+       "undelete-error": "خطا تاکدیم غیر قابل پاک کورتین اینت",
+       "undelete-error-short": "خطا پدا جۆڑ کورتین بئ فایل: $1",
+       "undelete-error-long": "بی پدا  جۆڑ کورتین ئی وختا خطا رخ دات:\n\n$1",
+       "undelete-show-file-confirm": "آیا شما مطمئن وێت که لوٹیت یک پاک بوته ئین نخسه شه فایل \"<nowiki>$1</nowiki>\" مورخ $2 سائت $3 ئا بگیندیت؟",
        "undelete-show-file-submit": "هان",
+       "namespace": "نامی فضا:",
+       "invert": "انتخاب سرچپی بیئت",
+       "namespace_association": "Associated namespace",
        "blanknamespace": "(بُنیادی)",
+       "contributions": "{{GENDER:$1|کار زوروک}} ئی شراکت ئان",
+       "contributions-title": "$1 ئی کار زوروکئ شراکت ئان",
+       "mycontris": "شراکت ئان",
+       "contribsub2": "په {{GENDER:$3|$1}} ($2)",
+       "contributions-userdoesnotexist": "«$1» ئی کار زوروکین حساب راجستر نه بوته.",
+       "nocontribs": "هیچ تغیری گۆ ای مشخصات ئان ودێ نه بوت",
        "uctop": "(انونین نخسه)",
        "month": "بی ای ماه ئی تا (و دیمتیر شه آیی):",
        "year": "بی ای سال ئی تا (و دیمتیر شه آیی):",
        "sp-contributions-newbies": "فقط نوکین مشارکتان نشان داته بیئنت",
        "sp-contributions-newbies-sub": "په نوک کاران",
+       "sp-contributions-newbies-title": "په نوک کارین حسابانی خاتیرا کار زوروکئ شراکت ئان",
+       "sp-contributions-blocklog": "بلاک بوته ئین ئانی سیاهه",
+       "sp-contributions-suppresslog": "کار زوروکئ کومک اوشتاته انت",
+       "sp-contributions-deleted": "کار زوروکئ پاک بوئین شراکت ئان",
+       "sp-contributions-uploads": "بُرز بوته هان",
        "sp-contributions-logs": "سیاهه‌ها",
        "sp-contributions-talk": "گپ",
+       "sp-contributions-userrights": "کار گیروکی اختیارانی مدیریت",
+       "sp-contributions-blocked-notice": "ای کار زوروکئ دسترسی بی انونین وختا بسته بوته.\nآخرین مورد شه دسترسی ئی سیستین به جهلگا آته:",
+       "sp-contributions-blocked-notice-anon": "ای کار زوروکئ دسترسی بی انونین وختا بسته بوته.\nآخرین مورد شه دسترسی ئی سیستین به جهلگا آته:",
+       "sp-contributions-search": "گشتین په شراکتان",
+       "sp-contributions-username": "آی‌پی ادرس یا کار زوروکئ نام:",
+       "sp-contributions-toponly": "فقط آخیرین نخسه ئانی  ایڈیٹ نشان داته بئنت",
        "sp-contributions-submit": "گشتین",
+       "whatlinkshere": "لینک بئ ای تاکدیما",
+       "whatlinkshere-title": "تاکدیمان که گو  «$1» لینک دارنت",
        "whatlinkshere-page": "تاکدیم:",
+       "linkshere": "جهلگین دیم بئ  '''[[:$1]]''' ئا لینک داریت:",
+       "nolinkshere": "هیچ دیمی بئ  '''[[:$1]]''' ئا لینک نه داریت.",
+       "nolinkshere-ns": "هیچ دیمی شه انتخاب بوته ئین نامی فضائان بئ  '''[[:$1]]''' ئا لینک نداریت.",
+       "isredirect": "تاکدیمی تغییرمسیر داتین",
+       "istemplate": "تراگنجانش‌هان",
+       "isimage": "فایل لینک",
+       "whatlinkshere-prev": "{{PLURAL:$1|دیمئ|$1 دیمئ مورد}}",
+       "whatlinkshere-next": "{{PLURAL:$1|پدئ|$1 پدئ مورد}}",
        "whatlinkshere-links": "→ لینک",
+       "whatlinkshere-hideredirs": "$1 تغییرمسیر",
+       "whatlinkshere-hidetrans": "$1 تراگنجانش‌هان",
        "whatlinkshere-hidelinks": "$1 لینک",
        "whatlinkshere-hideimages": "$1 فایلی لینکان",
        "whatlinkshere-filters": "فیلتر ئان",
+       "autoblockid": "#$1 ئی اوتو بلاک",
+       "block": "کار زوروکئ بلاک کورتین",
+       "unblock": "کار زوروکئ انبلاک یا پاچ کورتین",
+       "blockip": "{{GENDER:$1|کار زورکئ}} بستین",
+       "blockip-legend": "کار زوروکئ بلاک کورتین",
+       "ipaddressorusername": "آی‌پی ادرس یا کار زوروکئ نام:",
+       "ipbexpiry": "الاسی وخت:",
        "ipbreason": "دلیل:",
+       "ipb-hardblock": "دیمگیری شه ایڈیٹ کورتین ئا کار زوروکانئ که شه آی پی نیمگا راجستر بوته انت",
+       "ipbcreateaccount": "دیمگیری شه حسابئ جوڑ کورتینا",
+       "ipbemailban": "دیمگیری شه ایمیلی دیم داتینا",
+       "ipbsubmit": "ای کار زوروک بسته بیئت",
+       "ipbother": "دیگه وخت:",
+       "ipboptions": "۲ سائت:2 hours,۱ روچ:1 day,۳ روچ:3 days,۱ هپتگ:1 week,۲ هپتگ:2 weeks,۱ ماه:1 month,۳ ماه:3 months,۶ ماه:6 months,۱ سال:1 year,بی‌پایان:infinite",
+       "ipbwatchuser": "ای کار زوروکئ ، کارزوروکین و حبر وگپ ئی دیمانی دیستین",
+       "ipb-confirm": "بستینئ تائید کورتین",
+       "badipaddress": "آی‌پی نامجازین ادرس",
+       "blockipsuccesssub": "بستین گو کامیابیا انجام بوت",
+       "ipb-edit-dropdown": "بلاک ئی دلیلانی ایڈیٹ کورتین",
+       "ipb-unblock-addr": " $1 پاچ کورتین",
+       "ipb-unblock": "کار زوروکئ یا آی پی ادرس ئی بلاک ئی پاچ کورتین",
+       "ipb-blocklist": "موجودین بلاک ئی دیستین",
+       "ipb-blocklist-contribs": "مشارکتان په {{GENDER:$1|$1}}",
+       "unblockip": "کار زوروکئ انبلاک یا پاچ کورتین",
+       "ipusubmit": "ای بلاک ئی پاک کورتین",
+       "unblocked": "[[User:$1|$1]] ئی دسترسی پدا پئال بوت",
+       "unblocked-range": "$1 پاچ بوت",
+       "unblocked-id": "بلاک شماره $1 الاس بوت",
+       "unblocked-ip": "[[Special:Contributions/$1|$1]] انبلاک بوت.",
+       "blocklist": "بلاک بوته ئین کار زوروکان",
+       "ipblocklist": "بلاک بوته ئین کار زوروکان",
+       "ipblocklist-legend": "گشتین په بلاک بوته ئین کار زوروکا",
+       "blocklist-userblocks": "چیهرداتین بسته بوتین ئانی حسابئ",
+       "blocklist-tempblocks": "موقتین بستینانی چیهرداتین",
+       "blocklist-addressblocks": "چیهرداتین یک آی پی بسته بوته ئین",
+       "blocklist-rangeblocks": "رینج ئی بلاک هانئ چیهرداتین",
+       "blocklist-timestamp": "وختی برچسپ",
        "blocklist-target": "هدف",
+       "blocklist-expiry": "الاسی وخت",
+       "blocklist-by": "بلاک کورتین ئی مدیر",
+       "blocklist-params": "بلاک ئی پارامیتران",
        "blocklist-reason": "دلیل",
        "ipblocklist-submit": "گشتین",
+       "ipblocklist-localblock": "محلین دسترسی ئی بستین",
+       "ipblocklist-otherblocks": "دیگرین {{PLURAL:$1|بستین‌هان|بستین‌هان}}",
+       "infiniteblock": "بی‌پایان",
+       "expiringblock": "بئ $1 سائت $2 ئا الاس ئه بێت",
+       "anononlyblock": "فقط زیان نامین کار زوروکان",
+       "noautoblockblock": "اوتوماتیکبلاک غیرفعال اینت",
+       "createaccountblock": "حسابئ جوڑ کورتینئ قابلیت غیر پئال بوت",
+       "emailblock": "ایمیل بسته بوته",
+       "blocklist-nousertalk": "وتئ گپ ئی تاکدیما نتوان ایڈیٹ کورت",
+       "blocklink": "بلاک یا بستین",
+       "unblocklink": "پاچ یا انبلاک بێت",
+       "change-blocklink": "بلاک ئی تغیرداتین",
+       "contribslink": "مشارکت ئان",
        "emaillink": "ایمیلی دیم داتین",
        "blocklogpage": "کورمئ بستین",
+       "unblocklogentry": "$1 ئا پاچ کورت",
+       "block-log-flags-anononly": "فقط زیان نامین کار زوروکان",
+       "block-log-flags-nocreate": "حسابئ جوڑ کورتینئ قابلیت غیر پئال بوت",
+       "block-log-flags-noautoblock": "اوتوماتیکبلاک غیرفعال اینت",
+       "block-log-flags-noemail": "ایمیل بسته بوته",
+       "block-log-flags-nousertalk": "وتئ گپ ئی تاکدیما نتوان ایڈیٹ کورت",
+       "block-log-flags-angry-autoblock": "پیشرفته ئین اتوماتیکین بلاک فعال بوت",
+       "block-log-flags-hiddenname": "چیهرین کار زوروکئ نام",
+       "ipb_expiry_invalid": "الاسی وخت صحیح نه اینت.",
+       "ipb_already_blocked": "«$1» همی انون بسته بوته",
+       "ipb-otherblocks-header": "دیگرین {{PLURAL:$1|بلاک|بلاک ئان}}",
+       "ip_range_invalid": "ناموتبرین آی پی ئی رینج",
+       "proxyblocker": "پروکسی ئی بلاک کنۆک",
+       "lockdb": "مئلوماتئ بانکی قُلپ کورتین",
+       "unlockdb": "مئلوماتئ بانکی قُلپئ پروشتێن",
+       "lockconfirm": "هان، من جدآن لوٹین که مئلومانئ بانکا قُلپ کنین.",
+       "unlockconfirm": "هان، من جدآن لوٹین که مئلوماتئ بانکی قُلپا پاچ کنین.",
+       "lockbtn": "مئلوماتئ بانکی قُلپ کورتین",
+       "unlockbtn": "مئلوماتئ بانکی قُلپئ پروشتێن",
+       "locknoconfirm": "شما بئ تائیدی جئبه ئی تا چیک مه جنیت",
+       "lockdbsuccesssub": "مئلوماتئ بانک قُلپ بوت",
+       "unlockdbsuccesssub": "مئلوماتئ بانکئ قُلپ پاچ بوت",
+       "lockdbsuccesstext": "مئلوماتئ بانک قُلپ بوت.\n<br />شه هوشا مه برێیت که پد شه الاس بوتینا قُلپا پاچ بکنیت.",
+       "unlockdbsuccesstext": "مئلوماتئ بانکی قُلپ پاچ بوت.",
+       "databasenotlocked": "مئلوماتئ بانک قُلپ نه اینت.",
+       "lockedbyandtime": "(بواسطه $1 ئا بئ $2 سائت $3)",
+       "move-page": "انتقال $1",
+       "move-page-legend": "تاکدیمی انتقال",
        "movearticle": "تاکدیمی انتقال:",
+       "newtitle": "گۆ نوکین ئنوانا:",
+       "movepagebtn": "تاکدیمی انتقال",
+       "pagemovedsub": "جابجایی گۆ کامیابیا بوت",
+       "movepage-moved": "'''«$1» بئ «$2» انتقال بوت'''",
+       "movepage-moved-redirect": "یک تغیرمسیر جۆڑ بوت.",
+       "movetalk": "حبر و گپ ئی دیم جابجا بیئت",
+       "movepage-page-exists": "$1 ئی تاکدیم شه دیما موجود اینت ، نه توان که آیرا بئ اوتوماتیکین رقما جایگیر بکنت.",
+       "movepage-page-moved": "$1 ئی دیم بئ $2 ئا انتکا بوت.",
+       "movesubpage": "{{PLURAL:$1|گۆنڈدیم|گۆنڈدیم هان}}",
+       "movenosubpage": "ای تاکدیم هیچ گۆنڈدیم ئی نداریت.",
        "movereason": "دلیل:",
+       "revertmove": "بیرگردینتین",
+       "delete_and_move": "پاک کورتین یا جابیجا",
+       "delete_and_move_confirm": "هان،تاکدیم پاک بیئت",
+       "delete_and_move_reason": "پاک کورتین  «[[$1]]» جابجایی امکانا",
+       "export": "ڈن کورتین  تاکدیمانئ",
+       "exportall": "ڈن کورتین موچین تاکدیمانئ",
+       "exportcuronly": "فقط انونین نخسه شامل بیئت، نه موچین تاریخچه",
+       "export-submit": "دَر کورتین",
+       "export-addcattext": "افاضه کورتین تاکدیمان شه تهر ئا:",
        "export-addcat": "اڈ\tڈ\t کورتین",
        "export-addns": "اڈ\tڈ\t کورتین",
+       "export-download": "ذخیره کورتین بئ فایلئ رقما",
+       "export-templates": "شامل بوتین تراشوانانئ",
        "allmessagesname": "نام",
+       "allmessages-filter-legend": "فیلتر",
+       "allmessages-filter-unmodified": "تغیر نه کورته",
        "allmessages-filter-all": "موچ",
+       "allmessages-filter-modified": "تغیر نه کورته",
        "allmessages-language": "زبان:",
        "allmessages-filter-submit": "برا",
        "allmessages-filter-translate": "ترجمه",
        "thumbnail-more": "ٹُوه کورتین",
        "filemissing": "فایل وجود نداریت",
+       "import": "تاکدیمانێ بێ تێ کورتین",
+       "import-interwiki-sourcewiki": "ویکی زێ منشا:",
+       "import-interwiki-sourcepage": "تاکدیمئ منشا:",
+       "import-interwiki-templates": "موچین تراشوانانا شامل بیئت",
+       "import-interwiki-submit": "بێ تێ کورتین",
        "import-upload-filename": "فایلئ نام:",
        "import-comment": "کومنیت:",
+       "import-revision-count": "$1 {{PLURAL:$1|نخسه|نخسه}}",
        "import-logentry-interwiki": "$1 ئا ترانس ویکی کورت",
        "import-logentry-interwiki-detail": "$1 {{PLURAL:$1|نسخه|نسخه}} داخل بوته شه $2",
        "javascripttest": "جاوا اسکریپتی آزمایش",
        "javascripttest-pagetext-noframework": "ای تاکدیم په جاوا اسکریپتی آزمایشی خاتیرا ایشته بوته.",
+       "tooltip-pt-userpage": "شمی کار زوروکئ تاکدیم",
        "tooltip-pt-mytalk": "شمی هبر و گپئ تاکدیم",
        "tooltip-pt-preferences": "نئ تنظیمات",
        "tooltip-pt-logout": "در بوتین",
        "tooltip-n-mainpage-description": "بُنیاد ئین تاکدیمی دیستین",
        "tooltip-n-portal": "بی پروژه ئی موریدا٬ آنچه که توانیت انجام دهیت و ای که چی چیزی ئا شه گوجا ودی بکنیت",
        "tooltip-t-upload": "فایلی بُرز کورتین",
+       "tooltip-ca-nstab-main": "تاکدیمێ محتویاتێ دیستین",
+       "tooltip-ca-nstab-user": "کارزوروکین تاکدیمی دیستین",
+       "tooltip-ca-nstab-media": "میدیایی تاکدیمێ دیستین",
        "tooltip-ca-nstab-special": "ای یک خاصین تاکدیمی است٬ شما ئه توانیت که ای تاکدیما ایڈیٹ بکنیت",
        "tooltip-ca-nstab-project": "پروژه ئی تاکدیمی دیستین",
        "tooltip-ca-nstab-image": "دیستین فایلی تاکدیمی",
+       "tooltip-ca-nstab-template": "دیستین تراشوانئ",
+       "tooltip-ca-nstab-help": "دیستین کومکی تاکدیمئ",
+       "tooltip-ca-nstab-category": "دیستین تهری تاکدیمی",
+       "tooltip-save": "وتئ تغیرانا ذخیره بکنیت",
        "tooltip-watchlistedit-normal-submit": "ئنوانانی پاک کورتین",
        "tooltip-upload": "بُرز کورتینی شرو",
        "tooltip-preferences-save": "تنظیماتانی ذخیره کورتین",
        "siteusers": "$1، {{PLURAL:$2|کار زوروک|کار زوروکان}} {{SITENAME}}",
        "anonusers": " {{SITENAME}} نادروست ئین {{PLURAL:$2|کار زوروک|کار زوروکان}} $1",
        "creditspage": "ای تاکدیمی کریدیت ئان",
+       "pageinfo-header-basic": "بُنادین مئلومات",
+       "pageinfo-header-edits": "تاریخچه ئی ایڈیٹ",
+       "pageinfo-header-restrictions": "ساتیتین تاکدیمئ",
        "pageinfo-article-id": "تاکدیمی آی دی",
        "pageinfo-robot-noindex": "نامجاز",
        "pageinfo-firstuser": "ای تاکدیمئ جوڑ کنوک",
        "pageinfo-lasttime": "آخرین ایڈیٹئ تاریخ",
        "pageinfo-edits": "موچین ایڈیٹانئ اندازه گ",
        "pageinfo-authors": "موچین نویسوکانئ اندازه گ",
+       "pageinfo-magic-words": "{{PLURAL:$1|حرف|حروف}} جادویی ($1)",
+       "pageinfo-hidden-categories": "چیهرین {{PLURAL:$1| تهر|تهر هان}} ( $1 )",
+       "pageinfo-toolboxlink": "تاکدیمئ مئلومات",
+       "pageinfo-redirectsto": "تغییر مسیر بی",
+       "pageinfo-redirectsto-info": "مئلومات",
        "pageinfo-contentpage-yes": "هان",
        "pageinfo-protect-cascading-yes": "هان",
        "pageinfo-category-pages": "تاکدیمانی نمبر",
+       "patrol-log-page": "گشتئ سیاه چال",
+       "previousdiff": "→دیمتیرین ئی فرق",
+       "nextdiff": "نۆکتیرین ئی فرق ←",
+       "widthheightpage": "$1×$2، $3 {{PLURAL:$3|تاکدیم|تاکدیم}}",
+       "file-info": "فایلئ اندازه گ: $1، نوع  MIME $2",
+       "file-info-size": "<span dir=\"ltr\">$1 × $2</span> پیکسل، فایلئ اندازه گ: $3، نوع MIME فایلئ: $4",
+       "file-info-size-pages": "<span style=\"direction:ltr\">$1 × $2</span> نقطه، فایلئ حجم: $3، نوع MIME فایل: $4، $5 تاکدیم",
+       "show-big-image-other": "دیگرین {{PLURAL:$2|کیفیت|کیفیت‌هان}}: $1.",
+       "show-big-image-size": "<span dir=\"ltr\">$1 × $2</span> پیکسل",
+       "file-info-gif-looped": "چرخش‌دار",
+       "file-info-gif-frames": "$1 {{PLURAL:$1|قاب|قاب}}",
+       "file-info-png-looped": "چرخش‌دار",
+       "file-info-png-repeat": "$1 {{PLURAL:$1|وار|وار}} پخش بوت",
+       "file-info-png-frames": "$1 {{PLURAL:$1|قاب|قاب}}",
+       "newimages-legend": "فیلتر",
+       "noimages": "چیزی په دیستینا نه اینت.",
        "ilsubmit": "گشتین",
        "bydate": "شه تاریخی رُوگا",
+       "sp-newimages-showfrom": "نشان‌داتین نۆکین اکسانی شه $2، $1 بئ بعد",
+       "seconds": "{{PLURAL:$1|$1ثانیه| $1  ثانیه}}",
+       "minutes": "{{PLURAL:$1|دقیقه|دقیقه}}",
+       "hours": "{{PLURAL:$1|سائت|سائت}}",
+       "days": "{{PLURAL:$1|روچ|روچ}}",
+       "weeks": "{{PLURAL:$1|$1 هپتگ|$1 هپتگ ئان}}",
+       "months": "{{PLURAL:$1|$1 ماه|}}",
+       "years": "{{PLURAL:$1|$1 سال|$1 سال ئان}}",
+       "ago": "$1دیما",
        "just-now": "همی انون",
        "hours-ago": "$1 سائت دیما",
        "minutes-ago": "$1 دقیقه دیما",
        "saturday-at": "بی شنبی $1",
        "sunday-at": "یک‌شنبی $1",
        "yesterday-at": "زئ  بی $1",
+       "metadata": "فرادیتا",
+       "exif-imagewidth": "گوور، عرض",
+       "exif-imagelength": "تَچکي",
+       "exif-photometricinterpretation": "ٹیک ئانی ترکیب",
+       "exif-orientation": "نیمگ ، جهت",
+       "exif-ycbcrpositioning": "Y و C موقیعتان",
+       "exif-imagedescription": "اکسئ ئنوان",
+       "exif-artist": "اکس گيروک/هنرمند",
+       "exif-pixelydimension": "اکسئ گۆر",
+       "exif-pixelxdimension": "اکسئ بُرزی",
+       "exif-usercomment": "کار زوروکئ توضیحات",
+       "exif-fnumber": "اف ئی نمبر",
+       "exif-exposureprogram": "نوردهئ پروگرام",
+       "exif-spectralsensitivity": "طیفئ ئین حساسیت",
+       "exif-isospeedratings": "ایزو ئی سرعت ئی درجه بندی",
+       "exif-shutterspeedvalue": "شاتر ئی آپکس ئی سرعت",
+       "exif-aperturevalue": "دیافراگم آپکس ئی اندازه گ",
+       "exif-brightnessvalue": "آپکس روشنائی",
+       "exif-exposurebiasvalue": "نوردهئ خطا",
+       "exif-subjectdistance": "سوژه ئی فاصله",
+       "exif-lightsource": "نور ئی منشا",
+       "exif-flash": "پلاش",
+       "exif-subjectarea": "جسم ئی مساحت",
+       "exif-flashenergy": "پلاش ئی قدرت",
+       "exif-subjectlocation": "سوژه ئی مکان",
+       "exif-filesource": "فایلئ منشا",
+       "exif-contrast": "کنتراست",
+       "exif-gpsareainformation": "جی‌پی‌اس ئی ناحیه ئی نام",
+       "exif-gpsdatestamp": "جی پی اس ئی تاریخ",
+       "exif-worldregiondest": "جهانئ منطقه نشان داته بوته",
+       "exif-countrydest": "مُلک نشان داته بوته",
+       "exif-countrycodedest": "مُلکی کود نشان داته بوته",
+       "exif-provinceorstatedest": "ولایت یا ایالت نشان داته بوته",
+       "exif-citydest": "شار نشان داته بوته",
+       "exif-sublocationdest": "شاری یک بخش نشان داته بوته",
+       "exif-objectname": "گۆنڈین ئینوان",
+       "exif-headline": "ئنوان",
+       "exif-source": "منشا",
        "exif-writer": "نویسوک",
        "exif-languagecode": "زبان",
        "exif-iimversion": "IIM ئی نخسه",
        "exif-iimsupplementalcategory": "تکمیلین تهر ئان",
        "exif-datetimereleased": "منتشر بوته بی",
        "exif-label": "برچسب",
+       "exif-copyrighted-true": "کاپی رایت بوت",
+       "exif-unknowndate": "نامئلومین تاریخ",
+       "exif-orientation-1": "نورمال",
+       "exif-orientation-3": "۱۸۰ درجه چرخ وارته",
+       "exif-exposureprogram-1": "دستی",
+       "exif-exposureprogram-2": "عادی ئین پروگرام",
+       "exif-exposureprogram-4": "شاتر ئی اولویت",
+       "exif-subjectdistance-value": "$1 متر",
+       "exif-meteringmode-0": "نامئلوم",
+       "exif-meteringmode-1": "میانگین",
+       "exif-meteringmode-2": "میانگین گو سنگین ئین مرکزا",
+       "exif-meteringmode-3": "یک ٹیکی",
+       "exif-meteringmode-4": "چینکه ٹیکئ",
+       "exif-meteringmode-5": "طرح‌والا",
+       "exif-meteringmode-6": "کم ئین",
+       "exif-meteringmode-255": "دیگرین",
+       "exif-lightsource-0": "نامئلوم",
+       "exif-lightsource-1": "روچی روشنائی",
+       "exif-lightsource-2": "فلورسانت",
+       "exif-lightsource-4": "پلاش",
+       "exif-lightsource-9": "جوانین هوا",
+       "exif-lightsource-10": "جمری ئین آسمان",
+       "exif-lightsource-11": "سیاهیگ",
+       "exif-lightsource-12": "ماهتاپئ بی روچئ تا (D 5700 – 7100K)",
+       "exif-lightsource-13": "سپیتین ماهتاپئ بئ روچئ تا (N 4600 – 5400K)",
+       "exif-lightsource-14": "سپیتین ماهتاپئ سرد (W 3900 – 4500K)",
+       "exif-lightsource-15": "سپیتین ماهتاپئ (WW 3200 – 3700K)",
+       "exif-lightsource-17": "A سٹاندارتین نور",
+       "exif-lightsource-18": "B سٹاندارتین نور",
+       "exif-lightsource-19": "C سٹاندارتین نور",
+       "exif-lightsource-24": "ISO ئی کارخانه ئي تنگستن ئی لامپ",
+       "exif-lightsource-255": "نور ئی دیگه منشا ئان",
+       "exif-flash-fired-0": "پلاش جته نه بوت",
+       "exif-flash-fired-1": "گو پلاش جتینا",
+       "exif-customrendered-0": "عادین ظهور",
+       "exif-customrendered-1": "سفارشین ظهور",
+       "exif-exposuremode-0": "اوتوماتیکین نوردهی",
+       "exif-exposuremode-1": "دستئ نور دهی",
+       "exif-scenecapturetype-0": "سٹاندارت",
+       "exif-scenecapturetype-1": "چم چران",
+       "exif-scenecapturetype-2": "پرتره",
+       "exif-scenecapturetype-3": "شپئ چم گیند",
+       "exif-gaincontrol-0": "هیچ‌گوجام",
+       "exif-contrast-0": "نورمال",
+       "exif-contrast-1": "نرم",
+       "exif-contrast-2": "سک",
+       "exif-saturation-0": "نورمال",
+       "exif-saturation-1": "کم ئین اشباع",
+       "exif-saturation-2": "بازین اشباع",
        "exif-sharpness-0": "ساددگ",
        "exif-sharpness-1": "نرم",
        "exif-sharpness-2": "سک",
        "exif-subjectdistancerange-0": "نامئلوم",
        "exif-subjectdistancerange-1": "ماکرو",
+       "exif-subjectdistancerange-2": "نزینک گیند",
+       "exif-subjectdistancerange-3": "دور گیند",
+       "exif-gpsspeed-m": "مایل بئ سائت",
+       "exif-gpsspeed-n": "گرین",
+       "exif-gpsdestdistance-k": "کیلومتر",
+       "exif-gpsdestdistance-m": "مایل",
+       "exif-gpsdestdistance-n": "دریا ئین مایل",
+       "exif-gpsdop-excellent": "باز جووان ($1)",
+       "exif-gpsdop-good": "زبر ($1)",
+       "exif-gpsdop-moderate": "متوسط ($1)",
+       "exif-gpsdop-fair": "نه باز جووان ($1)",
+       "exif-gpsdop-poor": "ضعیف ($1)",
+       "exif-objectcycle-a": "تانا سوب",
+       "exif-objectcycle-p": "تانا دیگرونواشام",
+       "exif-objectcycle-b": "سوب و نواشام",
+       "exif-gpsdirection-t": "جوانین نیمگ",
        "exif-dc-date": "تاریخ(ئان)",
        "exif-dc-publisher": "ناشر",
        "exif-dc-rights": "حقوق",
+       "exif-iimcategory-edu": "یادگیپتین",
+       "exif-iimcategory-evn": "محیط زیست",
+       "exif-iimcategory-hth": "سلامت",
+       "exif-iimcategory-lab": "کار",
+       "exif-iimcategory-pol": "سیاست",
+       "exif-iimcategory-rel": "مذهب و باور",
+       "exif-iimcategory-sci": "علم و تخنیک",
+       "exif-iimcategory-soi": "اجتمائین مسائل",
        "exif-iimcategory-spo": "سپورت",
        "exif-iimcategory-war": "جنگ ، لٹ و کوٹ و ناآرامی",
        "exif-iimcategory-wea": "آپ و هوا",
        "namespacesall": "موچ",
        "monthsall": "موچ",
        "confirmemail": "ایمیل ادرسی تائید کورتین",
+       "recreate": "پدا جۆڑ کورتین",
        "confirm_purge_button": "قبول داشتین",
        "confirm-watch-button": "قبول داشتین",
        "confirm-unwatch-button": "قبول داشتین",
        "table_pager_first": "اولین تاکدیم",
        "table_pager_last": "آخرین تاکدیم",
        "table_pager_limit_submit": "برا",
+       "watchlistedit-raw-titles": "ئنوانان:",
+       "version": "نخسه",
+       "version-specialpages": "خاصین تاکدیمان",
+       "version-other": "دیگرین",
+       "version-no-ext-name": "[بی نام]",
+       "version-ext-license": "اجازه نامه ئان",
+       "version-ext-colheader-name": "پراخئ ئان",
+       "version-skin-colheader-name": "پوست",
+       "version-ext-colheader-version": "نخسه",
+       "version-ext-colheader-license": "اجازه نامه ئان",
+       "version-ext-colheader-description": "توضیح",
+       "version-ext-colheader-credits": "مؤلفان",
+       "version-license-title": "مجوز په $1",
+       "version-credits-title": "کریدیت په $1",
+       "version-poweredby-credits": "ای ویکی شه '''[https://www.mediawiki.org/ میڈیا ویکی]''' ئی نیمگا پُشتیوانی ئه بیئت، موچین حقوق محفوظ انت © 2001-$1 $2.",
+       "version-poweredby-others": "دیگران",
+       "version-poweredby-translators": "translatewiki.net مترجم ئان",
+       "version-software": "لچیته ئین نخسه هان",
+       "version-software-product": "محصول",
+       "version-software-version": "نخسه",
+       "version-entrypoints-header-url": "انترننئ ئین ادرس",
+       "version-libraries-library": "کتابجاه",
+       "version-libraries-version": "نخسه",
        "redirect-submit": "برا",
        "redirect-lookup": "گشتین:",
        "redirect-value": "اندازه گ:",
        "fileduplicatesearch-filename": "فایلئ نام:",
        "fileduplicatesearch-submit": "گشتین",
        "fileduplicatesearch-info": "<span dir=\"ltr\">$1 × $2</span> پیکسل<br />فایلئ اندازه گ: $3<br />نوع MIME: $4",
+       "fileduplicatesearch-result-n": " «$1» ئی فایل یک {{PLURAL:$2|تکراری موردئ|$2 تکرارئ مورئ}} داریت.",
+       "fileduplicatesearch-noresults": "فایلئ گو «$1» ئی ناما ودئ نه بوت.",
+       "specialpages": "خاصین تاکدیمان",
+       "specialpages-note-top": "شرح علائم",
+       "specialpages-note": "* عادی ئین خاصین تاکدیمان.\n* <span class=\"mw-specialpagerestricted\">خاصین تاکدیمان محدود بوته انت.</span>",
+       "specialpages-group-maintenance": "ساتیتینئ راپور",
+       "specialpages-group-other": "دیگه خاصین تاکدیمان",
+       "specialpages-group-login": "داخل بوتین  / حسابي جوڑ کورتین",
+       "specialpages-group-pages": "تاکدیمانی لڑ\t لیست",
+       "specialpages-group-pagetools": "تاکدیمانئ وسایلان",
+       "specialpages-group-wiki": "دتا و وسایلان",
+       "tags": "مجازین تغیرانئ برچسپ",
+       "tag-filter": "[[Special:Tags|برچسپ هاني]] فیلتر:",
+       "tag-filter-submit": "فیلتر",
+       "tag-list-wrapper": "([[Special:Tags|{{PLURAL:$1|برچسپ|برچسپ هان}}]]: $2)",
+       "tags-title": "برچسپ هان",
+       "tags-tag": "برچسپئ نام",
        "tags-active-header": "پئال؟",
+       "tags-actions-header": "عملکردهان",
        "tags-active-yes": "هان",
        "tags-active-no": "نه",
        "tags-edit": "ایڈیٹ",
+       "tags-delete": "پاک کورتین",
+       "tags-activate": "پئال کورتین",
+       "tags-deactivate": "غیرپئال کورتین",
        "tags-hitcount": "$1 {{PLURAL:$1|ٹگل|ٹگل}}",
+       "tags-create-tag-name": "برچسپئ نام:",
+       "tags-create-reason": "دلیل:",
+       "tags-create-submit": "جوڑ\t کورتین",
+       "tags-activate-reason": "دلیل:",
+       "tags-activate-submit": "پئال کورتین",
+       "tags-deactivate-reason": "دلیل:",
+       "tags-deactivate-submit": "غیرپئال کورتین",
        "comparepages": "تاکدیمانئ مقایسه",
        "compare-page1": "تاکدیم ۱",
        "compare-page2": "تاکدیم ۲",
        "compare-rev1": "نخسه ۱",
        "compare-rev2": "نخسه ۲",
        "compare-submit": "مقایسه",
+       "htmlform-required": "ای اندازه گ ضرورت اینت",
+       "htmlform-submit": "ثبت کورتین",
+       "htmlform-reset": "تغیرانئ خنثا کورتین",
        "htmlform-selectorother-other": "دیگرین",
        "htmlform-no": "نه",
        "htmlform-yes": "هان",
        "htmlform-chosen-placeholder": "یک گذینه ئی انتخاب بکنیت",
        "htmlform-cloner-create": "گیشتیر اضافه کورتین",
        "htmlform-cloner-delete": "پاک کورتین",
+       "htmlform-cloner-required": "حداقل ضرورت انداره گ.",
+       "logentry-delete-delete": "$1 ، $3 تاکدیما {{GENDER:$2|پاک کورت}}",
+       "logentry-delete-restore": "$1 ، $3 ئی تاکدیما {{GENDER:$2|پدا جۆڑ کورت}}",
+       "logentry-delete-event": "$1 پیدایی {{PLURAL:$5|یک مورد سیاه چال|$5 مورد سیاه چال}} ئا بئ $3 {{GENDER:$2|تا تغیر دات}}: $4",
+       "logentry-delete-revision": "$1 پیدایی {{PLURAL:$5|یک نخسه|$5 نخسه}} تاکدیم $3 ئا {{GENDER:$2|تغییر دات}}: $4",
+       "revdelete-content-hid": "محتوائانه چیهر کورت",
+       "revdelete-uname-hid": "چیهرین کار زوروکئ نام",
+       "revdelete-content-unhid": "محتوائانه سر درا کورت",
+       "revdelete-uname-unhid": "کار زوروکئ ناما سر درا کورت",
+       "revdelete-restricted": "مدیر ئانه محدود کورت",
+       "revdelete-unrestricted": "مدیرئانی محدودیت ئا پروشت",
+       "logentry-merge-merge": "$1  $3  را بئ  $4 {{GENDER:$2| ادغام کورت}} (نخسه تا  $5)",
+       "logentry-move-move": "$1، $3 ئی تاکدیما بئ $4 {{GENDER:$2|جابجا کورت}}",
+       "logentry-newusers-newusers": "$1 ئی کار زوروکئ حساب {{GENDER:$2|جۆڑ بوت}}",
+       "logentry-newusers-create": "$1 ئی کار زوروکئ حساب {{GENDER:$2|جۆڑ بوت}}",
+       "logentry-newusers-create2": "$3 ئی کار زوروکئ حساب شه $1 ئی نیمگا {{GENDER:$2|جۆڑ بوت}}",
+       "logentry-newusers-byemail": "$3 ئی کار زوروکئ حساب شه $1 ئی نیمگا {{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|ارتقاء دات}}",
+       "logentry-upload-upload": "$1 $3 ئا {{GENDER:$2|بُرز کورت}}",
+       "logentry-upload-overwrite": "$1 نوکین نخسه ئی شه $3 ئا {{GENDER:$2|بُرز کورت}}",
+       "logentry-upload-revert": "$1 {{GENDER:$2|بُرز کورت}} $3 ئا",
        "rightsnone": "(هیچ)",
        "revdelete-summary": "ایڈیتی خاصه",
        "feedback-subject": "ئنوان:",
        "feedback-cancel": "کنسیل",
        "feedback-close": "کار بوت",
        "searchsuggest-search": "گشتین",
+       "api-error-unclassified": "یک نا زانتین خطائی رخ دات.",
+       "api-error-unknown-code": "نازانتین خطای: \" $1 \"",
        "duration-seconds": "$1 ثانیه",
        "duration-minutes": "$1 دقیقه",
        "duration-hours": "$1 سائت",
        "duration-decades": "$1 دههگ",
        "duration-centuries": "$1 قرن",
        "duration-millennia": "{{PLURAL:$1|هزار سال |$1 هزار سال}}",
+       "limitreport-walltime": "واقئین مصرفئ مدت",
+       "limitreport-walltime-value": "$1 {{PLURAL:$1|ثانیه|ثانیه}}",
+       "limitreport-postexpandincludesize-value": "$1/$2 {{PLURAL:$2|بایٹ|بایٹ}}",
+       "limitreport-templateargumentsize": "ارگومان ئی تراشوانی اندازگ",
+       "limitreport-templateargumentsize-value": "$1/$2 {{PLURAL:$2|بایٹ|بایٹ}}",
+       "limitreport-expansiondepth": "گیشتیرین پراخی جُهلی",
+       "expandtemplates": "تراشوانی اکسپاند کورتین",
+       "expand_templates_title": "موضوع ئی ئنوان، په {{FULLPAGENAME}} ئا و غیره:",
+       "expand_templates_input": "ورودین متن:",
        "expand_templates_output": "نتیجه",
        "expand_templates_xml_output": "خروجی XML",
+       "expand_templates_html_output": "اچ‌تی‌ام‌ال حامگین خروجی",
        "expand_templates_ok": "قبول داشتین",
+       "expand_templates_remove_comments": "ملاحظاتانئ پاک کورتین",
+       "expand_templates_remove_nowiki": "خنثی کورتین <nowiki> تگ هانی بئ  نتیجه ئی",
+       "expand_templates_generate_xml": "XML تجزیه ئی درختی نشان داتین",
+       "expand_templates_generate_rawhtml": "حامیگین اچ تی ام ال ئی نشان داتین",
+       "expand_templates_preview": "دیم دیست",
        "pagelang-name": "تاکدیم",
        "pagelang-language": "زبان",
        "pagelang-use-default": "استفاده کورتین شه پیش فرض ئین زبانا",
        "pagelang-select-lang": "زبانی انتخاب",
        "mediastatistics-table-mimetype": "مایم ئی رکم",
+       "mediastatistics-table-totalbytes": "ترکیبین حجم",
        "mediastatistics-header-unknown": "نامئلوم",
        "mediastatistics-header-bitmap": "بیت مپ ئی اکسان",
        "mediastatistics-header-drawing": "طراحی‌هان (اکس برداری ئان)",
        "mediastatistics-header-office": "آفیس",
        "mediastatistics-header-text": "متنی",
        "mediastatistics-header-executable": "اجرایی",
+       "json-error-unknown": "مشکلی گو جی‌سن ات. خطا: $1",
+       "json-error-state-mismatch": "جن سن جووان نه اینت یا ناقض اینت",
        "json-error-syntax": "نحوی ئین خطا",
        "json-error-inf-or-nan": "INF یا NAN ئی مقادیر یک یا گیشتیر بی مقداری که کدگذاری ئا بیئنت",
        "json-error-unsupported-type": "یک اندازه که نتوانت کد گذاری بیئت داته بوته"
index fdb5e4e..397c7b2 100644 (file)
@@ -22,7 +22,9 @@
                        "Wikitanvir",
                        "Zaheen",
                        "לערי ריינהארט",
-                       "Aftabuzzaman"
+                       "Aftabuzzaman",
+                       "Wikisagnik",
+                       "Aashaa"
                ]
        },
        "tog-underline": "সংযোগগুলির নিচে দাগ দেখানো হোক:",
        "cancel": "বাতিল",
        "moredotdotdot": "আরও...",
        "morenotlisted": "এটি একটি অসম্পূর্ণ তালিকা।",
-       "mypage": "আমার পাতা",
+       "mypage": " পাতা",
        "mytalk": "আলোচনা",
        "anontalk": "এই বেনামী ব্যবহারকারীর আলাপের পাতা",
        "navigation": "পরিভ্রমণ",
        "prefs-personal": "ব্যবহারকারীর বৃত্তান্ত",
        "prefs-rc": "সাম্প্রতিক পরিবর্তনসমূহ",
        "prefs-watchlist": "নজরতালিকা",
+       "prefs-editwatchlist": "নজরতালিকা সম্পাদনা করো",
+       "prefs-editwatchlist-raw": "অশোধিত নজরতালিকা সম্পাদনা করুন",
+       "prefs-editwatchlist-clear": "নজরতালিকা পরিস্কার করুন",
        "prefs-watchlist-days": "যত দিনের নজরতালিকা দেখানো হবে:",
        "prefs-watchlist-days-max": "সর্বোচ্চ $1 {{PLURAL:$1|দিন|দিন}}",
        "prefs-watchlist-edits": "সম্প্রসারিত নজর তালিকায় সর্বোচ্চ সংখ্যার পরিবর্তন দেখানোর জন্য:",
        "confirm-watch-top": "এই পাতাটি আপনার নজরতালিকায় যুক্ত করা হবে?",
        "confirm-unwatch-button": "ঠিক আছে",
        "confirm-unwatch-top": "এই পাতাটি আপনার নজরতালিকা থেকে সরিয়ে ফেলতে ইচ্ছুক?",
+       "quotation-marks": "\"$1\"",
        "imgmultipageprev": "← পূর্ববর্তী পাতা",
        "imgmultipagenext": "পরবর্তী পাতা →",
        "imgmultigo": "চলো!",
        "version-entrypoints": "শুরুর ইউআরএল",
        "version-entrypoints-header-entrypoint": "শুরু",
        "version-entrypoints-header-url": "ইউআরএল",
+       "version-libraries": "ইনস্টল লাইব্রেরি",
+       "version-libraries-library": "লাইব্রেরী",
        "version-libraries-version": "সংস্করণ",
        "redirect": "পাতা, ফাইল, ব্যবহারকরী, অথবা সংশোধন আইডি দ্বারা পুনঃনির্দেশ করা হয়েছে",
        "redirect-legend": "একটি ফাইল অথবা পাতায় পুনঃনির্দেশ করা হয়েছে",
        "tags-tag": "ট্যাগ নাম",
        "tags-display-header": "পরিনর্তন পাতার বৈশিষ্ট",
        "tags-description-header": "অর্থের পূর্ণ বণনা",
+       "tags-source-header": "উৎস",
        "tags-active-header": "সক্রিয়?",
        "tags-hitcount-header": "ট্যাগকৃত পরিবর্সতনমূহ",
+       "tags-actions-header": "কার্যসমূহ",
        "tags-active-yes": "হ্যাঁ",
        "tags-active-no": "না",
        "tags-edit": "সম্পাদনা",
+       "tags-delete": "অপসারণ",
+       "tags-deactivate": "নিষ্ক্রিয়",
        "tags-hitcount": "$1টি {{PLURAL:$1|পরিবর্তন}}",
+       "tags-create-reason": "কারণ:",
+       "tags-create-submit": "তৈরি করুন",
+       "tags-delete-reason": "কারণ:",
+       "tags-activate-reason": "কারণ:",
+       "tags-activate-submit": "চালু",
+       "tags-deactivate-submit": "নিষ্ক্রিয়",
        "comparepages": "পাতার তুলনা",
        "compare-page1": "পাতা ১",
        "compare-page2": "পাতা ২",
index 18ba747..8e2e187 100644 (file)
        "prefs-personal": "Korisnički podaci",
        "prefs-rc": "Podešavanja nedavnih izmjena",
        "prefs-watchlist": "Moji praćeni članci",
+       "prefs-editwatchlist": "Uredi spisak praćenja",
        "prefs-watchlist-days": "Broj dana za prikaz u spisku praćenja:",
        "prefs-watchlist-days-max": "Maximum $1 {{PLURAL:$1|dan|dana}}",
        "prefs-watchlist-edits": "Najveći broj izmjena za prikaz u proširenom spisku praćenja:",
index 215064c..cd900ba 100644 (file)
        "changeemail-text": "Completeu el següent formulari per canviar la vostra adreça de correu electrònic. Haureu d'introduir la contrasenya per confirmar el canvi.",
        "changeemail-no-info": "Heu d'entrar en un compte d'usuari per accedir directament a aquesta pàgina.",
        "changeemail-oldemail": "Adreça de correu electrònic actual:",
-       "changeemail-newemail": "Nova adreça de correu electrònic:",
+       "changeemail-newemail": "Adreça electrònica nova:",
        "changeemail-none": "(cap)",
        "changeemail-password": "La vostra contrasenya a {{SITENAME}}:",
        "changeemail-submit": "Canvia de correu electrònic",
        "prefs-watchlist": "Llista de seguiment",
        "prefs-editwatchlist": "Edita la llista de seguiment",
        "prefs-editwatchlist-label": "Editeu les entrades de la vostra llista de seguiment:",
+       "prefs-editwatchlist-edit": "Mostra i suprimeix títols de la llista de seguiment",
+       "prefs-editwatchlist-raw": "Edita la llista de seguiment crua",
+       "prefs-editwatchlist-clear": "Neteja la llista de seguiment",
        "prefs-watchlist-days": "Nombre de dies per mostrar en la llista de seguiment:",
        "prefs-watchlist-days-max": "Màxim $1 {{PLURAL:$1|dia|dies}}",
        "prefs-watchlist-edits": "Nombre de modificacions a mostrar en una llista estesa de seguiment:",
        "expand_templates_generate_xml": "Mostra l'arbre XML",
        "expand_templates_generate_rawhtml": "Mostra l'HTML sense filtrar",
        "expand_templates_preview": "Previsualitza",
+       "expand_templates_preview_fail_html": "<em>Atès que {{SITENAME}} té HTML cru i hi ha hagut una pèrdua de dades de la sessió, s'ha amagat la vista prèvia com a mesura de precaució contra atacs en JavaScript.</em>\n\n<strong>Si això és un intent de previsualització legítim, torneu-ho a provar.</strong>\nSi encara no funciona, intenteu [[Special:UserLogout|finalitzar la sessió]] i iniciar-la de nou.",
+       "expand_templates_preview_fail_html_anon": "<em>Atès que {{SITENAME}} té l'HTML cru habilitat i no heu iniciat una sessió, s'ha amagat la previsualització com a prevenció d'atacs en JavaScript.</em>\n\n<strong>Si això és un intent de previsualització legítim, [[Special:UserLogin|inicieu una sessió]] i torneu-ho a provar.</strong>",
        "pagelanguage": "Selector de l'idioma de les pàgines",
        "pagelang-name": "Pàgina",
        "pagelang-language": "Idioma",
index fba767f..501be30 100644 (file)
        "prefs-help-prefershttps": "И хийцам болх байта юхугӀо системин чу.",
        "prefs-tabs-navigation-hint": "Хьехам: Шу йиш ю аьрру а, аьтту а цхьамзан пиллигаш лелаян цхьана юкъадиллинарг тӀера вукхун тӀе долуш.",
        "email-address-validity-valid": "Го нийса",
-       "userrights": "Декъашхочун бакъона урхалладар",
-       "userrights-lookup-user": "Декъашхошан бакъонашан урхалладар",
+       "userrights": "Декъашхочун бакъонашна урхалладар",
+       "userrights-lookup-user": "Декъашхойн бакъонашна урхалладар",
        "userrights-user-editname": "Язъе цӀе:",
        "editusergroup": "Хийца декъашхочун бакъо",
        "editinguser": "Хийца декъашхочуьна бакъо '''[[User:$1|$1]]''' ([[User talk:$1|{{int:talkpagelinktext}}]]{{int:pipe-separator}}[[Special:Contributions/$1|{{int:contribslink}}]])",
        "right-override-export-depth": "агӀонаш экспорт ян, 5 кхаччалц къорга агӀонаш цхьан",
        "right-sendemail": "кхечу декъашхошка электронан хаамаш кхехьийта",
        "right-passwordreset": "пароль хийцарца электроннан хаамашка хьажар",
+       "right-managechangetags": "Хаамийн базан чохь [[Special:Tags|билгалонаш]] кхолла а дӀаяха а",
        "newuserlogpage": "Декъашхой дӀабазбина тептар",
        "newuserlogpagetext": "Дукху хан йоцуш дӀабазбелла декъашхойн могӀам",
        "rightslog": "Декъашхочун бакъона тéптар",
        "action-viewmywatchlist": "шен тергаме могӀане хьажар",
        "action-viewmyprivateinfo": "хьан долара хааме хьажар",
        "action-editmyprivateinfo": "хьан долара хаам табар",
+       "action-managechangetags": "хаамийн базан чохь билгалонаш кхоллар а дӀаяхар а",
        "nchanges": "$1 {{PLURAL:$1|хийцам|хийцамаш}}",
        "enhancedrc-since-last-visit": "$1 {{PLURAL:$1|тӀеххьара чудаларца}}",
        "enhancedrc-history": "истори",
        "uploaddisabled": "Чуяккхар магийна дац",
        "copyuploaddisabled": "URL тӀера чуяккхар дӀадайина ду.",
        "uploaddisabledtext": "Файлаш чуяхар дӀадайина ду.",
-       "uploadscriptednamespace": "Ð¥Ó\80окÑ\85Ñ\83 SVG-Ñ\84айлан Ñ\86Ó\80еÑ\80ийн Ð¼ÐµÑ\82Ñ\82иг нийса яц '$1'",
+       "uploadscriptednamespace": "Ð¥Ó\80окÑ\85Ñ\83 SVG-Ñ\84айлан Ñ\86Ó\80еÑ\80ийн Ð°Ð½Ð° нийса яц '$1'",
        "upload-source": "ДIайолалун файл",
        "sourcefilename": "ДIайолалун файл:",
        "sourceurl": "Хьостан URL-адрес:",
        "protect-title": "ГӀоралла хӀоттор: «$1»",
        "protect-title-notallowed": "ГӀораллин бараме хьажар «$1»",
        "prot_1movedto2": "«[[$1]]» цӀе хийцина → «[[$2]]»",
-       "protect-badnamespace-title": "Ð\93Ó\80оÑ\80аладан Ñ\86алÑ\83Ñ\88 Ð¹Ð¾Ð»Ñ\83 Ñ\86Ó\80еÑ\80ийн Ð¼ÐµÑ\82Ñ\82иг",
+       "protect-badnamespace-title": "Ð\93Ó\80оÑ\80аладан Ñ\86алÑ\83Ñ\88 Ð¹Ð¾Ð»Ñ\83 Ñ\86Ó\80еÑ\80ийн Ð°Ð½Ð°",
        "protect-badnamespace-text": "ХӀокху цӀерийн меттигехь йолу агӀонашна гӀараладан цало.",
        "protect-norestrictiontypes-title": "ГӀараладан цалуш йолу агӀо",
        "protect-legend": "Бакъде гӀоралла дар",
        "namespace": "Цlерийн ана:",
        "invert": "Хаьржинарг къайлаяккха",
        "tooltip-invert": "ХӀоттае хӀара билгало, хаьржинчу цӀерийн меттиган агӀонийн хийцамаш къайлабаха (кхин дихкина цӀерийн меттигаш, гайтина елахь)",
-       "namespace_association": "Ð\99иÑ\85кина Ð¼ÐµÑ\82Ñ\82иг",
-       "tooltip-namespace_association": "Ð¥Ó\80оÑ\82Ñ\82ае Ñ\85Ó\80аÑ\80а Ð±Ð¸Ð»Ð³Ð°Ð»Ð¾, Ð¸Ñ\88Ñ\82Ñ\82а Ð´Ð¸Ð¹Ñ\86аÑ\80ийн (Ñ\8f ÐºÑ\85ин) Ñ\86Ó\80еÑ\80ийн Ð¼ÐµÑ\82Ñ\82иг юкъахь хилийта",
+       "namespace_association": "Ð\99иÑ\85кина Ð°Ð½Ð°",
+       "tooltip-namespace_association": "Ð¥Ó\80оÑ\82Ñ\82ае Ñ\85Ó\80аÑ\80а Ð±Ð¸Ð»Ð³Ð°Ð»Ð¾, Ð¸Ñ\88Ñ\82Ñ\82а Ð´Ð¸Ð¹Ñ\86аÑ\80ийн (Ñ\8f ÐºÑ\85ин) Ñ\86Ó\80еÑ\80ийн Ð°Ð½Ð° юкъахь хилийта",
        "blanknamespace": "(Коьрта)",
        "contributions": "{{GENDER:$1|Декъашхочун}} къинхьегам",
        "contributions-title": "{{GENDER:$1|Декъашхочун}} къинхьегам $1",
        "sp-contributions-uploads": "Файлаш",
        "sp-contributions-logs": "тéптарш",
        "sp-contributions-talk": "дийцаре",
-       "sp-contributions-userrights": "декъашхочун бакъона урхалладар",
+       "sp-contributions-userrights": "декъашхочун бакъонашна урхалладар",
        "sp-contributions-blocked-notice": "ХӀара декъашхочун дӀаяздар блоктоьхна ду.\nЛахахь гойту блоктохарийн тептар чура тӀаьхьарлера дӀаяздар:",
        "sp-contributions-blocked-notice-anon": "ХӀара IP-адрес хӀинца блоктоьхна ду.\nЛахахь гойту блоктохарийн тептар чура тӀаьхьарлера дӀаяздар:",
        "sp-contributions-search": "Къинхьегам лахар",
        "import-interwiki-history": "ХӀокху агӀона ерриг хийцаман истори копи ян",
        "import-interwiki-templates": "Юкъайихка массо кепаш",
        "import-interwiki-submit": "Импорт ян",
-       "import-interwiki-namespace": "Ð\9aоÑ\8cÑ\80Ñ\82а Ñ\86Ó\80еÑ\80ийн Ð¼ÐµÑ\82Ñ\82иг:",
+       "import-interwiki-namespace": "Ð\9aоÑ\8cÑ\80Ñ\82а Ñ\86Ó\80еÑ\80ийн Ð°Ð½Ð°:",
        "import-interwiki-rootpage": "Коьрта агӀо (тӀехь дац):",
        "import-upload-filename": "Файлан цӀе:",
        "import-comment": "Билгалдаккхар:",
        "tags-tag": "Билгалона цӀе",
        "tags-display-header": "МогӀам чохь хийцамаш гар",
        "tags-description-header": "МаьӀнан дуьззина сурт хӀоттор",
+       "tags-source-header": "Хьост",
        "tags-active-header": "Жигара?",
        "tags-hitcount-header": "Къастам бина нисдарш",
+       "tags-actions-header": "Дийраш",
        "tags-active-yes": "ХӀаъ",
        "tags-active-no": "ХӀахӀа",
+       "tags-source-extension": "Билгалйо шоралица",
+       "tags-source-none": "Кхий лелош яц",
        "tags-edit": "нисъе",
+       "tags-delete": "дӀаяккха",
+       "tags-activate": "активациян",
+       "tags-deactivate": "дӀаяйа",
        "tags-hitcount": "$1 {{PLURAL:$1|хийцам|хийцамаш}}",
+       "tags-create-heading": "Кхолла керла билгало",
+       "tags-create-tag-name": "Билгалонна цӀе:",
+       "tags-create-reason": "Бахьна:",
+       "tags-create-submit": "Кхолла",
+       "tags-create-no-name": "Ахьа билгалонан цӀе язъян езаш.",
+       "tags-create-already-exists": "«$1» билгало яц.",
+       "tags-create-warnings-below": "Лаьий хьуна билгало кхоллар чекхдакха?",
+       "tags-delete-title": "ДӀаяккха билгало",
+       "tags-delete-explanation-initial": "Хьо гӀерта «$1» базан чура билгало дӀаяккха.",
+       "tags-delete-reason": "Бахьна:",
+       "tags-activate-title": "Билгалона активациян",
+       "tags-activate-question": "Хьо гӀерта «$1» билгалонан активациян.",
+       "tags-activate-reason": "Бахьна:",
+       "tags-activate-not-allowed": "«$1» билгалонан активациян цало.",
+       "tags-activate-not-found": "«$1» билгало яц.",
+       "tags-activate-submit": "Активациян",
+       "tags-deactivate-title": "ДӀаяйа билгало",
+       "tags-deactivate-reason": "Бахьна:",
+       "tags-deactivate-submit": "ДӀаяйа",
        "comparepages": "АгӀонаш юстар",
        "compare-page1": "Дуьххьаралера агӀо",
        "compare-page2": "ШолгӀа агӀо",
        "logentry-upload-upload": "$1 {{GENDER:$2|чуяьккхина}} $3",
        "logentry-upload-overwrite": "$1 {{GENDER:$2|чуяьккхина}} керла верси $3",
        "logentry-upload-revert": "$1 {{GENDER:$2|чуяьккхина}} $3",
+       "log-name-managetags": "Билгалонашан урхалладаран тептар",
+       "logentry-managetags-create": "$1 {{GENDER:$2|Кхоьллина}} билгало «$4»",
        "rightsnone": "(яц)",
        "revdelete-summary": "хийцамах лаьцна",
        "feedback-bugornote": "Хьайн техникин халонах лаьцна яздан хӀума делахь, дехар до, [$1 хаам бе тхоьга].\nДацахь хьан йиш ю хӀокху атта кепаца «[$3 $2]» агӀонг къамел тӀетоха хьан декъашхочун цӀарца, кхин лелош йолу браузер билгал еш.",
index 00a200e..9f9ca0b 100644 (file)
        "right-override-export-depth": "Exportovat stránky včetně odkazovaných stránek až do hloubky 5",
        "right-sendemail": "Odesílání e-mailů ostatním uživatelům",
        "right-passwordreset": "Prohlížení e-mailů pro znovunastavení hesla",
+       "right-managechangetags": "Vytváření [[Special:Tags|značek]] a jejich mazání z databáze",
        "newuserlogpage": "Kniha nových uživatelů",
        "newuserlogpagetext": "Toto je záznam nově zaregistrovaných uživatelů.",
        "rightslog": "Kniha práv uživatelů",
        "action-viewmyprivateinfo": "prohlížet si své soukromé údaje",
        "action-editmyprivateinfo": "změnit své soukromé údaje",
        "action-editcontentmodel": "editovat model obsahu stránky",
+       "action-managechangetags": "vytvářet a mazat značky z databáze",
        "nchanges": "$1 {{PLURAL:$1|změna|změny|změn}}",
        "enhancedrc-since-last-visit": "$1 {{PLURAL:$1|od poslední návštěvy}}",
        "enhancedrc-history": "historie",
        "movepage-moved-noredirect": "Přesměrování nebylo vytvořeno.",
        "articleexists": "Takto nazvaná stránka již existuje, nebo Vámi zvolený název je neplatný. Zvolte jiný název.",
        "cantmove-titleprotected": "Stránku nelze přesunout na zadané místo, protože název je uzamčen proti vytváření",
-       "movetalk": "Přesunout příslušnou diskusní stránku",
+       "movetalk": "Přesunout související diskusní stránku",
        "move-subpages": "Přesunout i podstránky (maximálně $1)",
        "move-talk-subpages": "Přesunout i podstránky diskusní stránky (maximálně $1)",
        "movepage-page-exists": "Stránka $1 již existuje a nemůže být automaticky přepsána.",
        "tags-tag": "Název značky",
        "tags-display-header": "Zobrazení na seznamech změn",
        "tags-description-header": "Úplný popis významu",
+       "tags-source-header": "Zdroj",
        "tags-active-header": "Aktivní?",
        "tags-hitcount-header": "Označené změny",
+       "tags-actions-header": "Akce",
        "tags-active-yes": "Ano",
        "tags-active-no": "Ne",
+       "tags-source-extension": "Definována rozšířením",
+       "tags-source-manual": "Přidávána ručně uživateli a boty",
+       "tags-source-none": "Už nepoužívána",
        "tags-edit": "editovat",
+       "tags-delete": "smazat",
+       "tags-activate": "aktivovat",
+       "tags-deactivate": "deaktivovat",
        "tags-hitcount": "$1 {{PLURAL:$1|změna|změny|změn}}",
+       "tags-manage-no-permission": "Nemáte oprávnění spravovat značky pro změny.",
+       "tags-create-heading": "Vytvořit novou značku",
+       "tags-create-explanation": "Nově vytvořené značky jsou implicitně k dispozici uživatelům a botům.",
+       "tags-create-tag-name": "Název značky:",
+       "tags-create-reason": "Důvod:",
+       "tags-create-submit": "Vytvořit",
+       "tags-create-no-name": "Musíte uvést název značky.",
+       "tags-create-invalid-chars": "Názvy značek nesmí obsahovat čárky (<code>,</code>) ani dopředná lomítka (<code>/</code>).",
+       "tags-create-invalid-title-chars": "Názvy značek nesmí obsahovat znaky, které nelze používat v názvech stránek.",
+       "tags-create-already-exists": "Značka „$1“ již existuje.",
+       "tags-create-warnings-above": "Při pokusu o vytvoření značky „$1“ {{PLURAL:$1|bylo zjištěno|byla zjištěna}} následující varování:",
+       "tags-create-warnings-below": "Chcete i přesto značku vytvořit?",
+       "tags-delete-title": "Smazat značku",
+       "tags-delete-explanation-initial": "Chystáte se smazat značku „$1“ z databáze.",
+       "tags-delete-explanation-in-use": "Bude odstraněna z {{PLURAL:$2|$2 revize nebo protokolovacího záznamu|$2 revizí nebo protokolovacích záznamů}}, kde je momentálně přiřazena.",
+       "tags-delete-explanation-warning": "Tato akce je <strong>nevratná</strong> a <strong>nelze ji vrátit</strong>, ani databázovými správci. Ujistěte se, že toto je značka, kterou chcete smazat.",
+       "tags-delete-explanation-active": "<strong>Značka „$1“ je stále aktivní a bude se i nadále přidávat.</strong> Abyste tomu zabránili, přejděte na místo či místa, kde se značka používá, a vypněte ji tam.",
+       "tags-delete-reason": "Důvod:",
+       "tags-delete-submit": "Nevratně smazat tuto značku",
+       "tags-delete-not-allowed": "Značky definované rozšířeními nelze smazat, leda by to příslušné rozšíření výslovně umožnilo.",
+       "tags-delete-not-found": "Značka „$1“ neexistuje.",
+       "tags-delete-too-many-uses": "Značkou „$1“ {{PLURAL:$2|je označena více než $2 revize|jsou označeny více než $2 revize|je označeno více než $2 revizí}}, což znamená, že ji nelze smazat.",
+       "tags-delete-warnings-after-delete": "Značka „$1“ byla úspěšně smazána, ale {{PLURAL:$1|bylo zjištěno|byla zjištěna}} následující varování:",
+       "tags-activate-title": "Aktivovat značku",
+       "tags-activate-question": "Chystáte se aktivovat značku „$1“.",
+       "tags-activate-reason": "Důvod:",
+       "tags-activate-not-allowed": "Značku „$1“ nelze aktivovat.",
+       "tags-activate-not-found": "Značka „$1“ neexistuje.",
+       "tags-activate-submit": "Aktivovat",
+       "tags-deactivate-title": "Deaktivovat značku",
+       "tags-deactivate-question": "Chystáte se deaktivovat značku „$1“.",
+       "tags-deactivate-reason": "Důvod:",
+       "tags-deactivate-not-allowed": "Značku „$1“ nelze deaktivovat.",
+       "tags-deactivate-submit": "Deaktivovat",
        "comparepages": "Porovnání stránek",
        "compare-page1": "Stránka 1",
        "compare-page2": "Stránka 2",
        "logentry-upload-upload": "$1 {{GENDER:$2|načetl|načetla}} $3",
        "logentry-upload-overwrite": "$1 {{GENDER:$2|načetl|načetla}} novou verzi $3",
        "logentry-upload-revert": "$1 {{GENDER:$2|načetl|načetla}} $3",
+       "log-name-managetags": "Kniha správy značek",
+       "log-description-managetags": "Tato stránka obsahuje seznam správcovských úkonů týkajících se [[Special:Tags|značek]]. Protokol obsahuje pouze akce, které provedl ručně správce; značky může vytvářet či mazat přímo software wiki, aniž by v tomto protokolu vznikl záznam.",
+       "logentry-managetags-create": "$1 {{GENDER:$2|vytvořil|vytvořila}} značku „$4“",
+       "logentry-managetags-delete": "$1 {{GENDER:$2|smazal|smazala}} značku „$4“ (odstraněna z $5 {{PLURAL:$5|revize nebo protokolovacího záznamu|revizí nebo protokolovacích záznamů}})",
+       "logentry-managetags-activate": "$1 {{GENDER:$2|aktivoval|aktivovala}} značku „$4“ pro uživatele a boty",
+       "logentry-managetags-deactivate": "$1 {{GENDER:$2|deaktivoval|deaktivovala}} značku „$4“ pro uživatele a boty",
        "rightsnone": "(žádné)",
        "revdelete-summary": "shrnutí editace",
        "feedback-bugornote": "Pokud dokážete podrobně popsat technický problém, můžete [$1 nahlásit chybu].\nJinak můžete využít jednoduchý formulář níže. Váš komentář bude přidán na stránku „[$3 $2]“ spolu s vaším uživatelským jménem a informací o tom, jaký prohlížeč používáte.",
index 4cdf68f..8eb03b6 100644 (file)
        "right-override-export-depth": "Exportiere Seiten einschließlich verlinkter Seiten bis zu einer Tiefe von 5",
        "right-sendemail": "E-Mails an andere Benutzer senden",
        "right-passwordreset": "Passwort eines Benutzers zurücksetzen und die dazu verschickte E-Mail einsehen",
+       "right-managechangetags": "[[Special:Tags|Markierungen]] erstellen und aus der Datenbank löschen",
        "newuserlogpage": "Neuanmeldungs-Logbuch",
        "newuserlogpagetext": "Dies ist ein Logbuch der neu erstellten Benutzerkonten.",
        "rightslog": "Rechte-Logbuch",
        "action-viewmyprivateinfo": "deine privaten Informationen einzusehen",
        "action-editmyprivateinfo": "deine privaten Informationen zu bearbeiten",
        "action-editcontentmodel": "das Inhaltsmodell einer Seite zu bearbeiten",
+       "action-managechangetags": "Markierungen zu erstellen und aus der Datenbank zu löschen",
        "nchanges": "$1 {{PLURAL:$1|Änderung|Änderungen}}",
        "enhancedrc-since-last-visit": "$1 {{PLURAL:$1|seit dem letzten Besuch}}",
        "enhancedrc-history": "Versionsgeschichte",
        "tags-tag": "Markierungsname",
        "tags-display-header": "Benennung auf den Änderungslisten",
        "tags-description-header": "Vollständige Beschreibung",
+       "tags-source-header": "Quelle",
        "tags-active-header": "Aktiv?",
        "tags-hitcount-header": "Markierte Änderungen",
+       "tags-actions-header": "Aktionen",
        "tags-active-yes": "Ja",
        "tags-active-no": "Nein",
+       "tags-source-extension": "Definiert von einer Erweiterung",
+       "tags-source-manual": "Manuell von Benutzern und Bots eingesetzt",
+       "tags-source-none": "Nicht mehr in Verwendung",
        "tags-edit": "bearbeiten",
+       "tags-delete": "löschen",
+       "tags-activate": "aktivieren",
+       "tags-deactivate": "deaktivieren",
        "tags-hitcount": "$1 {{PLURAL:$1|Änderung|Änderungen}}",
+       "tags-manage-no-permission": "Du hast keine Berechtigung, Änderungsmarkierungen zu verwalten.",
+       "tags-create-heading": "Eine neue Markierung erstellen",
+       "tags-create-explanation": "Standardmäßig werden neu erstellte Markierungen für die Verwendung durch Benutzer und Bots verfügbar gemacht.",
+       "tags-create-tag-name": "Name der Markierung:",
+       "tags-create-reason": "Grund:",
+       "tags-create-submit": "Erstellen",
+       "tags-create-no-name": "Du musst einen Markierungsnamen angeben.",
+       "tags-create-invalid-chars": "Markierungsnamen dürfen keine Kommas (<code>,</code>) oder Schrägstriche (<code>/</code>) enthalten.",
+       "tags-create-invalid-title-chars": "Markierungsnamen dürfen keine Zeichen enthalten, die nicht in Seitennamen verwendet werden können.",
+       "tags-create-already-exists": "Die Markierung „$1“ ist bereits vorhanden.",
+       "tags-create-warnings-above": "Die {{PLURAL:$2|folgende Warnung ist|folgenden Warnungen sind}} beim Versuch, die Markierung „$1“ zu erstellen, aufgetreten:",
+       "tags-create-warnings-below": "Möchtest du mit dem Erstellen der Markierung fortfahren?",
+       "tags-delete-title": "Markierung löschen",
+       "tags-delete-explanation-initial": "Du bist dabei, die Markierung „$1“ aus der Datenbank zu löschen.",
+       "tags-delete-explanation-in-use": "Sie wird von {{PLURAL:$2|einer Version oder einem Logbucheintrag|allen $2 Versionen und/oder Logbucheinträgen}} entfernt, bei {{PLURAL:$2|der/m|denen}} sie derzeit eingesetzt wird.",
+       "tags-delete-explanation-warning": "Diese Aktion ist <strong>unwiderruflich</strong> und <strong>kann nicht rückgängig gemacht werden</strong>, auch nicht von Datenbankadministratoren. Sei dir sicher, dass dies die Markierung ist, die du löschen möchtest.",
+       "tags-delete-explanation-active": "<strong>Die Markierung „$1“ ist noch aktiv und wird auch in Zukunft eingesetzt werden.</strong> Um dies zu beenden, gehe zu den Orten, wo die Anwendung der Markierung festgelegt wird und deaktiviere sie dort.",
+       "tags-delete-reason": "Grund:",
+       "tags-delete-submit": "Diese Markierung unwiderruflich löschen",
+       "tags-delete-not-allowed": "Markierungen, die von einer Erweiterung definiert werden, können nicht gelöscht werden, außer die Erweiterung erlaubt es ausdrücklich.",
+       "tags-delete-not-found": "Die Markierung „$1“ ist nicht vorhanden.",
+       "tags-delete-too-many-uses": "Die Markierung „$1“ wird bei mehr als {{PLURAL:$2|einer Version|$2 Versionen}} verwendet und kann deshalb nicht gelöscht werden.",
+       "tags-delete-warnings-after-delete": "Die Markierung „$1“ wurde erfolgreich gelöscht, aber die {{PLURAL:$2|folgende Warnung ist|folgenden Warnungen sind}} aufgetreten:",
+       "tags-activate-title": "Markierung aktivieren",
+       "tags-activate-question": "Du bist dabei, die Markierung „$1“ zu aktivieren.",
+       "tags-activate-reason": "Grund:",
+       "tags-activate-not-allowed": "Es ist nicht möglich, die Markierung „$1“ zu aktivieren.",
+       "tags-activate-not-found": "Die Markierung „$1“ ist nicht vorhanden.",
+       "tags-activate-submit": "Aktivieren",
+       "tags-deactivate-title": "Markierung deaktivieren",
+       "tags-deactivate-question": "Du bist dabei, die Markierung „$1“ zu deaktivieren.",
+       "tags-deactivate-reason": "Grund:",
+       "tags-deactivate-not-allowed": "Es ist nicht möglich, die Markierung „$1“ zu deaktivieren.",
+       "tags-deactivate-submit": "Deaktivieren",
        "comparepages": "Seiten vergleichen",
        "compare-page1": "Seite 1",
        "compare-page2": "Seite 2",
        "logentry-upload-upload": "$1 {{GENDER:$2|lud}} $3 hoch",
        "logentry-upload-overwrite": "$1 {{GENDER:$2|lud}} eine neue Version von $3 hoch",
        "logentry-upload-revert": "$1 {{GENDER:$2|lud}} $3 hoch",
+       "log-name-managetags": "Markierungsverwaltungs-Logbuch",
+       "log-description-managetags": "Diese Seite listet Verwaltungsaufgaben bezüglich der [[Special:Tags|Markierungen]] auf. Das Logbuch enthält nur Aktionen, die manuell von einem Administrator ausgeführt wurden; Markierungen können auch von der Wikisoftware erstellt oder gelöscht werden, ohne dass ein aufgezeichneter Eintrag in diesem Logbuch vorliegt.",
+       "logentry-managetags-create": "$1 {{GENDER:$2|erstellte}} die Markierung „$4“",
+       "logentry-managetags-delete": "$1 {{GENDER:$2|löschte}} die Markierung „$4“ (entfernt von {{PLURAL:$5|einer Version oder einem Logbucheintrag|$5 Versionen und/oder Logbucheinträgen}})",
+       "logentry-managetags-activate": "$1 {{GENDER:$2|aktivierte}} die Markierung „$4“ zur Verwendung durch Benutzer und Bots",
+       "logentry-managetags-deactivate": "$1 {{GENDER:$2|deaktivierte}} die Markierung „$4“ zur Verwendung durch Benutzer und Bots",
        "rightsnone": "(–)",
        "revdelete-summary": "Zusammenfassungskommentar",
        "feedback-bugornote": "Sofern du detailliert ein technisches Problem beschreiben möchtest, melde bitte [$1 einen Fehler].\nAnderenfalls kannst du auch das untenstehende einfache Formular nutzen. Dein Kommentar wird, zusammen mit deinem Benutzernamen und der Version des von dir verwendeten Webbrowsers sowie Betriebssystems, auf der Seite „[$3 $2]“ hinzugefügt.",
index 176ed1c..271e675 100644 (file)
        "filehist-nothumb": "Thumbnail çin o.",
        "filehist-user": "Karber",
        "filehist-dimensions": "Ebati",
-       "filehist-filesize": "Ebata dosya",
+       "filehist-filesize": "Eba dosya",
        "filehist-comment": "Mışewre",
        "imagelinks": "Gurenayışê dosya",
        "linkstoimage": "Ena {{PLURAL:$1|pela|$1 pela}} gıreye ena dosya:",
        "statistics": "İstatistiki",
        "statistics-header-pages": "İstatistikê pele",
        "statistics-header-edits": "Îstatistikê vurnayîşî",
-       "statistics-header-users": "Îstatistiksê karberî",
+       "statistics-header-users": "İstatistikê karberi",
        "statistics-header-hooks": "Îstatistiksê binî",
        "statistics-articles": "Pelanê tedesteyî",
        "statistics-pages": "Peli",
        "exif-bitspersample": "yew parçe de biti",
        "exif-compression": "Planê kompresyoni",
        "exif-photometricinterpretation": "Compozisyonê pixeli",
-       "exif-orientation": "Oriyentasyon",
+       "exif-orientation": "Berhetkerdış",
        "exif-samplesperpixel": "teneyê parçeyi",
        "exif-planarconfiguration": "Rezeyê datayi",
        "exif-ycbcrsubsampling": "Subsampleyi ebatê Y heta C",
        "exif-locationdest": "Tarifê cay",
        "exif-locationdestcode": "Lokasyon kodi vaciya",
        "exif-objectcycle": "Qandê medyay deme u roce cı",
-       "exif-contact": "Zanışiya irtibati",
+       "exif-contact": "Melumatê irtıbati",
        "exif-writer": "Nuştekar",
        "exif-languagecode": "Zıwan",
        "exif-iimversion": "Verqaydê IIM",
index 822d426..d67a809 100644 (file)
        "prefs-personal": "Prufîl utèint",
        "prefs-rc": "Ûltmi mudéfichi",
        "prefs-watchlist": "Tgnîr sòt ôc",
+       "prefs-editwatchlist": "Mudéfica la lésta 'd qui da tgnîr sòt ôc",
+       "prefs-editwatchlist-raw": "Mudéfica la lésta in furmê tèst",
        "prefs-watchlist-days": "Nómer ed dé da fêr vèder int i tgnû 'd ôc specêl:",
        "prefs-watchlist-days-max": "Mâsim $1 {{PLURAL:$1|dé}}",
        "prefs-watchlist-edits": "Nómer 'd mudéfichi da fêr vèder cun al funsiòun pió şvilupêdi:",
        "upload_directory_read_only": "Al prugrâma dal sît an n'é bòun de scréver int la cartèla 'd cargamèint dal j infurmasiòun ($1).",
        "uploaderror": "Erōr int al cargamèint",
        "upload-recreate-warning": "<strong>Atèint: un file cun cól nòm ché l'é stê scanşlê o spustê. </strong> L' elèinch dal scanşladûri e di spustamèint ed cla pàgina ché al vîn scrét ché sòta per cumditê:",
+       "uploadtext": "Druvêr al mudèl ché sòta per scarghêr di file nōv. Per guardêr o serchêr i file bèle scarghê, consultêr la [[Special:FileList| lésta di file scarghê]]. Al câregh di file e dal versiòun nōvi di file în registrê int la [[Special:Log/upload|lésta di file salvê]], al scanşladûri in còl [[Special:Log/delete|apôsta]].\n\nPer mèter un file dèinter 'na pàgina, fêr un colegamèint ed cól gèner ché:\n* '''<code><nowiki>[[</nowiki>{{ns:file}}<nowiki>:File.jpg]]</nowiki></code>''' per druvêr la versiòun intēra dal file\n* '''<code><nowiki>[[</nowiki>{{ns:file}}<nowiki>:File.png|200px|thumb|left|tèst divêrs]]</nowiki></code>''' per druvêr 'na versiòun lêrga 200pixel dèinter int 'na scâtla, in rîga a mansèina e cun 'tèst divêrs' cme tétol\n* '''<code><nowiki>[[</nowiki>{{ns:media}}<nowiki>:File.ogg]]</nowiki></code>''' per fêr un colegamèint dirèt al file sèinsa vèdrel",
        "upload-permitted": "{{PLURAL:$2|Gèner ed file permés}}: $1.",
        "upload-preferred": "{{PLURAL:$2| Gèner ed file cunsiliê}}: $1.",
        "upload-prohibited": "{{PLURAL:$2|Gèner ed file mìa permés}}: $1.",
        "ignorewarning": "Trascûra l'avîş e a tóti 'l manēri sêlva al file",
        "ignorewarnings": "An badêr mìa a i mesâg dal sistēma",
        "minlength1": "Al nòm dal file al dēv èser fât d' almēno 'na lètra.",
+       "illegalfilename": "Al nòm \"$1\" al gh'à dèinter di carâter mìa permés int i tétol dal pàgini. \nDêr al file un nòm divêrs e pruvêr a carghêrel ed nōv.",
+       "filename-toolong": "I nòm di file an pōlen mìa andêr d'ed sōver î 240 byte.",
+       "badfilename": "Al nòm dal file l'é stê cunvertî in \"$1\".",
+       "filetype-mime-mismatch": "La zûnta dal file \".$1\" an n'é m'a cumpâgna 'l gèner MIME vésta dal file ($2).",
+       "filetype-badmime": "An n'é mìa permés carghê file 'd gèner MIME \"$1\".",
+       "filetype-bad-ie-mime": "Impusébil carghêr al file perché Internet Explorer  l'al vedré cme \"$1\", ch'lé un gèner ed file mìa permés e al pré èser ânca periculōş.",
+       "filetype-unwanted-type": "Carghêr un file dal gèner '''''.$1''''' l'é scunsiliê. {{PLURAL:$3|Al gèner ed file cunsiliê l'é|I gèner di file cunsiliê în }} $2.",
+       "filetype-banned-type": "'''\".$1\"''' {{PLURAL:$4|an n'é mìa un gèner ed file permés| în mìa gèner ed file permés}}.\n{{PLURAL:$3|Al gèner ed file permés l'é|I gèner ed file permés în}} $2.",
+       "filetype-missing": "Al file l'é sèinsa la zûnta (per es. \".jpg\").",
+       "empty-file": "Al file che t'é spidî l'é vōd.",
+       "file-too-large": "Al file che t'é spidî l'é trôp grôs.",
+       "filename-tooshort": "Al nòm dal file l'é trôp cûrt.",
+       "filetype-banned": "Cól gèner ed file ché an n'é mìa permés.",
+       "verification-error": "Cól file ché an n'à mìa pasê la veréfica.",
+       "hookaborted": "La mudéfica che s'é pruvê ed fêr l'é stêda fermêda da un gânc ed 'na zûnta a la fîn dal nòm dal file .",
+       "illegal-filename": "Al nòm dal file an n'é mia acetê.",
+       "overwrite": "Scréver inséma 'n file che al gh'é bèle an n'é mìa permés.",
+       "unknown-error": "É sucès un erōr mìa cgnusû.",
+       "tmp-create-error": "L'é impusébil fêr un file pruvişôri.",
+       "tmp-write-error": "Erōr de scritûra dal file pruvişôri.",
+       "large-file": "A 's arcmânda d' andêr d'ed sōver la larghèsa ed $1 per ógni file; còst l'é grôs $2.",
+       "largefileserver": "Al file al và fōra dal j amzûri permési da l'impustasiòun dal prugrâma.",
        "license": "Licèinsa:",
        "license-header": "Licèinsa",
        "nolicense": "Nisóna licèinsa sgnêda",
index e701137..cff74b4 100644 (file)
        "right-override-export-depth": "Export pages including linked pages up to a depth of 5",
        "right-sendemail": "Send email to other users",
        "right-passwordreset": "View password reset emails",
+       "right-managechangetags": "Create and delete [[Special:Tags|tags]] from the database",
        "newuserlogpage": "User creation log",
        "newuserlogpagetext": "This is a log of user creations.",
        "rightslog": "User rights log",
        "action-viewmyprivateinfo": "view your private information",
        "action-editmyprivateinfo": "edit your private information",
        "action-editcontentmodel": "edit the content model of a page",
+       "action-managechangetags": "create and delete tags from the database",
        "nchanges": "$1 {{PLURAL:$1|change|changes}}",
        "enhancedrc-since-last-visit": "$1 {{PLURAL:$1|since last visit}}",
        "enhancedrc-history": "history",
        "tags-tag": "Tag name",
        "tags-display-header": "Appearance on change lists",
        "tags-description-header": "Full description of meaning",
+       "tags-source-header": "Source",
        "tags-active-header": "Active?",
        "tags-hitcount-header": "Tagged changes",
+       "tags-actions-header": "Actions",
        "tags-active-yes": "Yes",
        "tags-active-no": "No",
+       "tags-source-extension": "Defined by an extension",
+       "tags-source-manual": "Applied manually by users and bots",
+       "tags-source-none": "No longer in use",
        "tags-edit": "edit",
+       "tags-delete": "delete",
+       "tags-activate": "activate",
+       "tags-deactivate": "deactivate",
        "tags-hitcount": "$1 {{PLURAL:$1|change|changes}}",
+       "tags-manage-no-permission": "You do not have permission to manage change tags.",
+       "tags-create-heading": "Create a new tag",
+       "tags-create-explanation": "By default, newly created tags will be made available for use by users and bots.",
+       "tags-create-tag-name": "Tag name:",
+       "tags-create-reason": "Reason:",
+       "tags-create-submit": "Create",
+       "tags-create-no-name": "You must specify a tag name.",
+       "tags-create-invalid-chars": "Tag names must not contain commas (<code>,</code>) or forward slashes (<code>/</code>).",
+       "tags-create-invalid-title-chars": "Tag names must not contain characters that cannot be used in page titles.",
+       "tags-create-already-exists": "The tag \"$1\" already exists.",
+       "tags-create-warnings-above": "The following {{PLURAL:$2|warning was|warnings were}} encountered when attempting to create the tag \"$1\":",
+       "tags-create-warnings-below": "Do you wish to continue creating the tag?",
+       "tags-delete-title": "Delete tag",
+       "tags-delete-explanation-initial": "You are about to delete the tag \"$1\" from the database.",
+       "tags-delete-explanation-in-use": "It will be removed from {{PLURAL:$2|$2 revision or log entry|all $2 revisions and/or log entries}} to which it is currently applied.",
+       "tags-delete-explanation-warning": "This action is <strong>irreversible</strong> and <strong>cannot be undone</strong>, not even by database administrators. Be certain this is the tag you mean to delete.",
+       "tags-delete-explanation-active": "<strong>The tag \"$1\" is still active, and will continue to be applied in the future.</strong> To stop this from happening, go to the place(s) where the tag is set to be applied, and disable it there.",
+       "tags-delete-reason": "Reason:",
+       "tags-delete-submit": "Irreversibly delete this tag",
+       "tags-delete-not-allowed": "Tags defined by an extension cannot be deleted unless the extension specifically allows it.",
+       "tags-delete-not-found": "The tag \"$1\" does not exist.",
+       "tags-delete-too-many-uses": "The tag \"$1\" is applied to more than $2 {{PLURAL:$2|revision|revisions}}, which means it cannot be deleted.",
+       "tags-delete-warnings-after-delete": "The tag \"$1\" was deleted successfully, but the following {{PLURAL:$2|warning was|warnings were}} encountered:",
+       "tags-activate-title": "Activate tag",
+       "tags-activate-question": "You are about to activate the tag \"$1\".",
+       "tags-activate-reason": "Reason:",
+       "tags-activate-not-allowed": "It is not possible to activate the tag \"$1\".",
+       "tags-activate-not-found": "The tag \"$1\" does not exist.",
+       "tags-activate-submit": "Activate",
+       "tags-deactivate-title": "Deactivate tag",
+       "tags-deactivate-question": "You are about to deactivate the tag \"$1\".",
+       "tags-deactivate-reason": "Reason:",
+       "tags-deactivate-not-allowed": "It is not possible to deactivate the tag \"$1\".",
+       "tags-deactivate-submit": "Deactivate",
        "comparepages": "Compare pages",
        "comparepages-summary": "",
        "compare-page1": "Page 1",
        "logentry-upload-upload": "$1 {{GENDER:$2|uploaded}} $3",
        "logentry-upload-overwrite": "$1 {{GENDER:$2|uploaded}} a new version of $3",
        "logentry-upload-revert": "$1 {{GENDER:$2|uploaded}} $3",
+       "log-name-managetags": "Tag management log",
+       "log-description-managetags": "This page lists management tasks related to [[Special:Tags|tags]]. The log contains only actions carried out manually by an administrator; tags may be created or deleted by the wiki software without an entry being recorded in this log.",
+       "logentry-managetags-create": "$1 {{GENDER:$2|created}} the tag \"$4\"",
+       "logentry-managetags-delete": "$1 {{GENDER:$2|deleted}} the tag \"$4\" (removed from $5 {{PLURAL:$5|revision or log entry|revisions and/or log entries}})",
+       "logentry-managetags-activate": "$1 {{GENDER:$2|activated}} the tag \"$4\" for use by users and bots",
+       "logentry-managetags-deactivate": "$1 {{GENDER:$2|deactivated}} the tag \"$4\" for use by users and bots",
        "rightsnone": "(none)",
        "revdelete-logentry": "changed revision visibility of \"[[$1]]\"",
        "logdelete-logentry": "changed event visibility of \"[[$1]]\"",
index e601e4b..bdc98d2 100644 (file)
        "mywatchlist": "Atentaro",
        "watchlistfor2": "Por $1 $2",
        "nowatchlist": "Vi ne jam elektis priatenti iun ajn paĝon.",
-       "watchlistanontext": "Bonvolu ensaluti por vidi aŭ redakti erojn en via atentaro.",
+       "watchlistanontext": "Bonvolu ensaluti por vidi aŭ redakti vian atentaron.",
        "watchnologin": "Ne ensalutinta",
        "addwatch": "Aldoniĝi al atentaro",
        "addedwatchtext": "La paĝo \"[[:$1]]\" aldoniĝis al via [[Special:Watchlist|atentaro]]. Estontaj ŝanĝoj de tiu paĝo kaj de ĝia rilata diskutpaĝo aperos tie.",
        "wlnote": "Jen la {{PLURAL:$1|lasta redakto|lastaj <strong>$1</strong> redaktoj}} dum la {{PLURAL:$2|lasta horo|lastaj <strong>$2</strong> horoj}}, ekde $3, $4.",
        "wlshowlast": "Montri el lastaj $1 horoj $2 tagoj",
        "watchlist-options": "Opcioj por atentaro",
-       "watching": "Aldonante al la atentaro...",
+       "watching": "Aldonata al la atentaro...",
        "unwatching": "Malatentante...",
        "watcherrortext": "Eraro okazis ŝanĝinte vian agordojn de atentaro por \"$1\".",
        "enotif_reset": "Marki ĉiujn paĝojn vizititaj",
index 9065b4f..d51a433 100644 (file)
                        "Gleki",
                        "Jonathan rrr",
                        "Paynekiller92",
-                       "Kroji"
+                       "Kroji",
+                       "JasterTDC"
                ]
        },
        "tog-underline": "Subrayar los enlaces:",
        "tog-hideminor": "Ocultar las ediciones menores en los cambios recientes",
        "tog-hidepatrolled": "Ocultar las ediciones patrulladas en los cambios recientes",
-       "tog-newpageshidepatrolled": "Ocultar las páginas patrulladas de la lista de páginas nuevas",
-       "tog-extendwatchlist": "Expandir la lista de seguimiento a todos los cambios, no sólo a los más recientes",
+       "tog-newpageshidepatrolled": "Ocultar las páginas patrulladas en la lista de páginas nuevas",
+       "tog-extendwatchlist": "Mostrar todos los cambios en la lista de seguimiento, no solo los más recientes",
        "tog-usenewrc": "Agrupar los cambios por página en los cambios recientes y en la lista de seguimiento",
        "tog-numberheadings": "Numerar automáticamente los encabezados",
        "tog-showtoolbar": "Mostrar la barra de edición",
        "tog-previewontop": "Mostrar previsualización antes del cuadro de edición",
        "tog-previewonfirst": "Mostrar previsualización en la primera edición",
        "tog-enotifwatchlistpages": "Enviarme un correo electrónico cuando se modifique una página o un archivo de mi lista de seguimiento",
-       "tog-enotifusertalkpages": "Enviarme un correo electrónico cuando se modifique mi página de discusión",
+       "tog-enotifusertalkpages": "Enviarme un mensaje de correo electrónico cuando se modifique mi página de discusión",
        "tog-enotifminoredits": "Notificarme también por correo electrónico los cambios menores de las páginas y archivos",
        "tog-enotifrevealaddr": "Revelar mi dirección de correo electrónico en los correos de notificación",
        "tog-shownumberswatching": "Mostrar el número de usuarios que la vigilan",
        "underline-always": "Siempre",
        "underline-never": "Nunca",
        "underline-default": "Configuración predeterminada del tema o el navegador",
-       "editfont-style": "Tipografía del área de edición:",
-       "editfont-default": "Predeterminada del navegador",
+       "editfont-style": "Tipo de letra del área de edición:",
+       "editfont-default": "Predeterminado del navegador",
        "editfont-monospace": "Tipo de letra monoespaciado",
        "editfont-sansserif": "Tipo de letra de palo seco",
        "editfont-serif": "Tipo de letra con serifas",
        "noindex-category": "Páginas no indizadas",
        "broken-file-category": "Páginas con enlaces rotos a archivos",
        "about": "Acerca de",
-       "article": "Artículo",
+       "article": "Página de contenido",
        "newwindow": "(se abre en una ventana nueva)",
        "cancel": "Cancelar",
        "moredotdotdot": "Más...",
        "badaccess-group0": "No estás autorizado a ejecutar la acción solicitada.",
        "badaccess-groups": "La acción que has solicitado está restringida a los usuarios {{PLURAL:$2|del grupo|de uno de estos $2 grupos}}: $1.",
        "versionrequired": "Se requiere la versión $1 de MediaWiki.",
-       "versionrequiredtext": "Se necesita la versión $1 de MediaWiki para utilizar esta página. Para más información, consultar [[Special:Version|la página de versión]]",
+       "versionrequiredtext": "Se necesita la versión $1 de MediaWiki para utilizar esta página. Para más información, consulta [[Special:Version|la página de versión]].",
        "ok": "Aceptar",
        "retrievedfrom": "Obtenido de «$1»",
        "youhavenewmessages": "{{PLURAL:$3|Tienes}} $1 ($2).",
        "directorynotreadableerror": "La carpeta «$1» no tiene permisos de lectura.",
        "filenotfound": "No se ha encontrado el archivo «$1».",
        "unexpected": "Valor inesperado: «$1»=«$2».",
-       "formerror": "Error: no se pudo enviar el formulario",
+       "formerror": "Error: no se ha podido enviar el formulario.",
        "badarticleerror": "Esta acción no se puede llevar a cabo en esta página.",
        "cannotdelete": "No se ha podido borrar la página o archivo «$1».\nPuede que ya haya sido borrado por otro usuario.",
        "cannotdelete-title": "No se puede borrar la página «$1»",
        "createacct-imgcaptcha-ph": "Escribe el texto de arriba",
        "createacct-submit": "Crea tu cuenta",
        "createacct-another-submit": "Crear otra cuenta",
-       "createacct-benefit-heading": "{{SITENAME}} es hecha por gente como tú.",
+       "createacct-benefit-heading": "Personas como tú son las que construyen {{SITENAME}}.",
        "createacct-benefit-body1": "{{PLURAL:$1|edición|ediciones}}",
        "createacct-benefit-body2": "{{PLURAL:$1|página|páginas}}",
        "createacct-benefit-body3": "{{PLURAL:$1|colaborador reciente|colaboradores recientes}}",
        "loginerror": "Error de inicio de sesión",
        "createacct-error": "Error al crear la cuenta",
        "createaccounterror": "No se pudo crear la cuenta: $1",
-       "nocookiesnew": "La cuenta de usuario ha sido creada, pero no has iniciado sesión.\n{{SITENAME}} usa <em>cookies</em> para identificar a los usuarios registrados.\nTu navegador tiene desactivadas las cookies.\nPor favor, actívalas e inicia sesión con tu nuevo nombre de usuario y contraseña.",
+       "nocookiesnew": "Se ha creado la cuenta de usuario, pero aún no has iniciado sesión.\n{{SITENAME}} usa <em>cookies</em> para identificar a los usuarios registrados.\nTu navegador tiene desactivadas las cookies.\nPor favor, actívalas e inicia sesión con tu nuevo nombre de usuario y contraseña.",
        "nocookieslogin": "{{SITENAME}} utiliza <em>cookies</em> para la autenticación de usuarios. Las <em>cookies</em> están desactivadas en tu navegador. Por favor, actívalas e inténtalo de nuevo.",
        "nocookiesfornew": "No se pudo crear la cuenta de usuario, porque no pudimos confirmar su origen.\nAsegúrate de que tienes las cookies activadas, luego recarga esta página e inténtalo de nuevo.",
        "noname": "No se ha especificado un nombre de usuario válido.",
        "password-login-forbidden": "El uso de este nombre de usuario y contraseña han sido prohibidos.",
        "mailmypassword": "Restablecer la contraseña",
        "passwordremindertitle": "Nueva contraseña temporal para {{SITENAME}}",
-       "passwordremindertext": "Alguien (probablemente tú, desde la dirección IP $1) solicitó que te enviáramos una nueva contraseña para tu cuenta en {{SITENAME}} ($4).\nSe ha creado la siguiente contraseña temporal para el usuario «$2»: «$3»\nAhora deberías iniciar sesión y cambiar tu contraseña. Tu contraseña temporal expirará en {{PLURAL:$5|un día|$5 días}}.\n\nSi fue otro quien solicitó este mensaje o has recordado tu contraseña y ya no deseas cambiarla, puedes ignorar este mensaje y seguir usando tu contraseña original.",
+       "passwordremindertext": "Alguien (probablemente tú, desde la dirección IP $1) solicitó el envío de una contraseña nueva para tu cuenta en {{SITENAME}} ($4). Se ha creado la siguiente contraseña temporal para el usuario «$2»: «$3». Si efectivamente la solicitaste, ahora puedes iniciar sesión y cambiar tu contraseña. Tu contraseña temporal caducará en {{PLURAL:$5|un día|$5 días}}.\n\nSi fue otro quien realizó esta solicitud, o has recordado tu contraseña y ya no deseas cambiarla, puedes ignorar este mensaje y seguir usando tu contraseña original.",
        "noemail": "No hay una dirección de correo electrónico registrada para «$1».",
-       "noemailcreate": "Necesitas proveer una dirección de correo electrónico válida",
+       "noemailcreate": "Necesitas proporcionar una dirección de correo electrónico válida.",
        "passwordsent": "Se ha enviado una nueva contraseña al correo electrónico de «$1».\nPor favor, identifícate de nuevo tras recibirla.",
        "blocked-mailpassword": "Tu dirección IP está bloqueada, y no se te permite el uso de la función de recuperación de contraseñas para prevenir abusos.",
        "eauthentsent": "Se ha enviado un correo electrónico de confirmación a la dirección especificada.\nAntes de que se envíe cualquier otro correo a la cuenta tienes que seguir las instrucciones enviadas en el mensaje para así confirmar que la dirección te pertenece.",
        "noemailprefs": "Especifica una dirección electrónica para habilitar estas características.",
        "emailconfirmlink": "Confirmar dirección de correo electrónico",
        "invalidemailaddress": "La dirección electrónica no puede ser aceptada, pues parece que tiene un formato no válido.\nPor favor, escribe una dirección en el formato adecuado o deja el campo en blanco.",
-       "cannotchangeemail": "Las direcciones de la correo electrónico de las cuentas de usuario no pueden cambiarse en esta wiki.",
+       "cannotchangeemail": "En este wiki no se pueden cambiar las direcciones de correo electrónico de las cuentas de usuario.",
        "emaildisabled": "Este sitio no puede enviar correos electrónicos.",
        "accountcreated": "Se ha creado la cuenta",
-       "accountcreatedtext": "La cuenta de usuario de [[{{ns:User}}:$1|$1]] ([[{{ns:User talk}}:$1|talk]]) ha sido creada.",
+       "accountcreatedtext": "Se ha creado la cuenta de usuario de [[{{ns:User}}:$1|$1]] ([[{{ns:User talk}}:$1|discusión]]).",
        "createaccount-title": "Creación de cuenta para {{SITENAME}}",
-       "createaccount-text": "Alguien creó en {{SITENAME}} ($4) una cuenta asociada a este correo electrónico con el nombre «$2» y contraseña «$3». Por favor entra ahora y cambia tu contraseña.\n\nPuedes ignorar este mensaje si esta cuenta fue creada por error.",
-       "login-throttled": "Has intentado demasiadas veces iniciar sesión recientemente. Por favor espera $1 antes de intentarlo nuevamente.",
-       "login-abort-generic": "Tu inicio de sesión no fue exitoso - Cancelado",
-       "login-migrated-generic": "Tu cuenta se ha migrado y tu nombre de usuario ya no existen en este wiki.",
+       "createaccount-text": "Alguien creó en {{SITENAME}} ($4) una cuenta asociada a este correo electrónico con el nombre «$2» y contraseña «$3». Por favor, accede ahora y cambia tu contraseña.\n\nSi esta cuenta fue creada por error, ignora este mensaje.",
+       "login-throttled": "Has intentado iniciar sesión demasiadas veces seguidas. Por favor espera $1 antes de intentarlo nuevamente.",
+       "login-abort-generic": "Se ha intentado acceder sin éxito - Cancelado",
+       "login-migrated-generic": "Se ha trasladado tu cuenta. Tu nombre de usuario ya no existe en este wiki.",
        "loginlanguagelabel": "Idioma: $1",
        "suspicious-userlogout": "Tu solicitud de desconexión ha sido denegada, pues parece haber sido enviada desde un navegador defectuoso o un proxy caché.",
-       "createacct-another-realname-tip": "El nombre real es opcional.\nSi se proporciona, se usará para dar al usuario la atribución de su trabajo.",
+       "createacct-another-realname-tip": "El nombre real es opcional.\nSi lo proporcionas, se usará para dar atribución al trabajo del usuario.",
        "pt-login": "Acceder",
        "pt-login-button": "Acceder",
        "pt-createaccount": "Crear una cuenta",
        "pt-userlogout": "Salir",
        "php-mail-error-unknown": "Error desconocido en la función mail() de PHP.",
-       "user-mail-no-addy": "Se ha intentado enviar correo electrónico sin una dirección de correo electrónico.",
-       "user-mail-no-body": "Trató de enviar un correo electrónico con un cuerpo vacío o excesivamente corto.",
+       "user-mail-no-addy": "Se ha intentado enviar un mensaje de correo electrónico sin una dirección de correo electrónico.",
+       "user-mail-no-body": "Trató de enviar un mensaje de correo electrónico sin contenido o excesivamente corto.",
        "changepassword": "Cambiar contraseña",
-       "resetpass_announce": "Para completar el inicio de sesión, debes definir una contraseña nueva.",
+       "resetpass_announce": "Para completar el inicio de sesión debes definir una contraseña nueva.",
        "resetpass_text": "<!-- Añada texto aquí -->",
        "resetpass_header": "Cambiar la contraseña de la cuenta",
        "oldpassword": "Contraseña antigua:",
        "resetpass-submit-cancel": "Cancelar",
        "resetpass-wrong-oldpass": "La contraseña actual, o temporal, no es correcta.\nPuede que ya hayas cambiado exitosamente tu contraseña o que hayas pedido una nueva contraseña temporal.",
        "resetpass-recycled": "Restablece tu contraseña a algo distinto de tu contraseña actual.",
-       "resetpass-temp-emailed": "Has iniciado sesión con un código temporal por correo electrónico.\nPara terminar el acceso, debes establecer una nueva contraseña aquí:",
+       "resetpass-temp-emailed": "Has iniciado sesión con una contraseña temporal enviada por correo electrónico.\nPara continuar, debes establecer una nueva contraseña aquí:",
        "resetpass-temp-password": "Contraseña temporal:",
        "resetpass-abort-generic": "Una extensión ha cancelado el cambio de la contraseña.",
        "resetpass-expired": "Tu contraseña ha caducado. Por favor, establece una nueva contraseña para iniciar sesión.",
-       "resetpass-expired-soft": "Tu contraseña ha caducado y necesita restablecerse. Elije una nueva contraseña ahora, o haga clic en \"{{int:resetpass-submit-cancel}}\" para restaurarla más adelante.",
+       "resetpass-expired-soft": "Tu contraseña ha caducado, por lo que debes restablecerla. Cámbiala ahora por una nueva, o haz clic en \"{{int:resetpass-submit-cancel}}\" para restablecerla más adelante.",
        "resetpass-validity-soft": "Tu contraseña no es válida: $1\n\nCámbiala ahora por una nueva, o haz clic en \"{{int:resetpass-submit-cancel}}\" para cambiarla más tarde.",
        "passwordreset": "Restablecer contraseña",
        "passwordreset-text-one": "Completa este formulario para recibir una contraseña temporal por correo electrónico.",
-       "passwordreset-text-many": "{{PLURAL:$1|Rellena uno de los campos para  recibir una contraseña temporal por correo electrónico.}}",
+       "passwordreset-text-many": "{{PLURAL:$1|Elige una de las opciones para recibir una contraseña temporal por correo electrónico.}}",
        "passwordreset-legend": "Restablecer contraseña",
        "passwordreset-disabled": "Se ha desactivado el restablecimiento de contraseñas en este wiki.",
-       "passwordreset-emaildisabled": "Las funciones de correo electrónico han sido desactivadas en esta wiki.",
+       "passwordreset-emaildisabled": "Se han desactivado las funciones de correo electrónico en este wiki.",
        "passwordreset-username": "Nombre de usuario:",
        "passwordreset-domain": "Dominio:",
        "passwordreset-capture": "¿Ver el mensaje resultante?",
        "passwordreset-capture-help": "Si marcas esta casilla, se te mostrará el correo electrónico (con la contraseña temporal) además de enviarse al usuario.",
        "passwordreset-email": "Dirección de correo electrónico:",
        "passwordreset-emailtitle": "Detalles de la cuenta en {{SITENAME}}",
-       "passwordreset-emailtext-ip": "Alguien (probablemente tú, desde la dirección IP $1) ha solicitado la renovación de tu clave para {{SITENAME}} ($4). {{PLURAL:$3|La siguiente cuenta está asociada|Las siguientes cuentas están asociadas}}\ncon esta dirección de correo electrónico:\n\n$2\n\n{{PLURAL:$3|Esta contraseña temporal|Estas contraseñas temporales}} caducarán en {{PLURAL:$5|un día|$5 días}}.\nDeberías iniciar sesión y establecer una contraseña nueva ahora. Si otra persona ha realizado este solicitud\no si recuerdas tu contraseña original y no deseas cambiarla, puedes\nignorar este mensaje y continuar usando tu contraseña anterior.",
-       "passwordreset-emailtext-user": "El usuario $1 en {{SITENAME}} pidió un restablecer tu contraseña para {{SITENAME}}\n($4). {{PLURAL:$3|La siguiente cuenta está asociada|Las siguientes cuentas están asociadas}} con esta dirección de correo electrónico:\n\n$2\n\n{{PLURAL:$3|Esta contraseña temporal|Estas contraseñas temporales}} expirarán en {{PLURAL:$5|un día|$5 días}}.\nDeberías iniciar sesión y establecer una contraseña nueva ahora. Si alguien más hizo este pedido,\no recuerdas tu contraseña original, y no deseas cambiarla, puedes\nignorar este mensaje y continuar usando tu contraseña anterior.",
+       "passwordreset-emailtext-ip": "Alguien (probablemente tú, desde la dirección IP $1) ha solicitado el restablecimiento de tu contraseña en {{SITENAME}} ($4). {{PLURAL:$3|La siguiente cuenta está asociada|Las siguientes cuentas están asociadas}}\na esta dirección de correo electrónico:\n\n$2\n\n{{PLURAL:$3|Esta contraseña temporal|Estas contraseñas temporales}} caducarán en {{PLURAL:$5|un día|$5 días}}.\nAhora puedes iniciar sesión y establecer una nueva contraseña. Si fue otra persona la que realizó esta solicitud, o si ya recuerdas tu contraseña original y, por tanto, no deseas cambiarla, puedes ignorar este mensaje y continuar usando tu contraseña anterior.",
+       "passwordreset-emailtext-user": "El usuario $1 de {{SITENAME}} solicitó el restablecimiento de tu contraseña en {{SITENAME}}\n($4). {{PLURAL:$3|La siguiente cuenta está asociada|Las siguientes cuentas están asociadas}} a esta dirección de correo electrónico:\n\n$2\n\n{{PLURAL:$3|Esta contraseña temporal|Estas contraseñas temporales}} caducarán en {{PLURAL:$5|un día|$5 días}}.\nAhora puedes iniciar sesión y establecer una nueva contraseña. Si fue otra persona la que realizó esta solicitud, o si ya recuerdas tu contraseña original y, por tanto, no deseas cambiarla, puedes ignorar este mensaje y continuar usando tu contraseña anterior.",
        "passwordreset-emailelement": "Nombre de usuario: $1\nContraseña temporal: $2",
        "passwordreset-emailsent": "Se ha enviado un correo electrónico para el restablecimiento de tu contraseña.",
        "passwordreset-emailsent-capture": "Se ha enviado un correo para el restablecimiento de la contraseña, el cual se muestra a continuación.",
-       "passwordreset-emailerror-capture": "Se generó un correo electrónico de restablecimiento de contraseña, que se muestra a continuación, pero el envío {{GENDER:$2|al usuario|a la usuaria}} falló: $1",
+       "passwordreset-emailerror-capture": "Se ha generado un correo electrónico de restablecimiento de contraseña, que se muestra a continuación, pero ha fallado el envío {{GENDER:$2|al usuario|a la usuaria}}: $1",
        "changeemail": "Cambiar la dirección de correo electrónico",
-       "changeemail-text": "Rellena este formulario para cambiar tu dirección de correo electrónico. Debes introducir la contraseña para confirmar este cambio.",
+       "changeemail-text": "Rellena este formulario para cambiar tu dirección de correo electrónico. Debes introducir tu contraseña para confirmar este cambio.",
        "changeemail-no-info": "Debes iniciar sesión para acceder directamente a esta página.",
-       "changeemail-oldemail": "Dirección electrónica actual:",
-       "changeemail-newemail": "Dirección electrónica nueva:",
+       "changeemail-oldemail": "Dirección de correo electrónico actual:",
+       "changeemail-newemail": "Dirección de correo electrónico nueva:",
        "changeemail-none": "(ninguna)",
        "changeemail-password": "Tu contraseña en {{SITENAME}}:",
        "changeemail-submit": "Cambiar correo electrónico",
        "changeemail-throttled": "Has intentado acceder demasiadas veces.\nEspera $1 antes de intentarlo de nuevo.",
        "resettokens": "Restablecer claves",
-       "resettokens-text": "Aquí puedes restablecer las fichas que permiten el acceso a ciertos datos privados asociados con tu cuenta.\n\nDeberías hacerlo si accidentalmente los has compartido o si tu cuenta ha sido intervenida.",
+       "resettokens-text": "Aquí puedes restablecer las claves que permiten el acceso a ciertos datos privados asociados a tu cuenta.\n\nDeberías hacerlo si los has compartido por accidente, o si ha habido intrusiones en tu cuenta.",
        "resettokens-no-tokens": "No hay claves para restablecer.",
        "resettokens-legend": "Restablecer claves",
        "resettokens-tokens": "Claves:",
        "resettokens-token-label": "$1 (valor actual: $2)",
-       "resettokens-watchlist-token": "Clave para la lista de seguimiento (RSS/Atom) de los [[Special:Watchlist|cambios a las páginas en tu lista de seguimiento]]",
+       "resettokens-watchlist-token": "Clave para el canal (RSS/Atom) de los [[Special:Watchlist|cambios a las páginas en tu lista de seguimiento]]",
        "resettokens-done": "Restablecimiento de claves.",
        "resettokens-resetbutton": "Restablecer las claves",
        "bold_sample": "Texto en negrita",
        "showpreview": "Mostrar previsualización",
        "showdiff": "Mostrar los cambios",
        "blankarticle": "<strong>Aviso:</strong> estás a punto de crear una página vacía.\nSi pulsas en «{{int:savearticle}}» de nuevo, se creará la página sin ningún contenido.",
-       "anoneditwarning": "<strong>Advertencia:</strong> No has iniciado sesión. Tu dirección IP será visible públicamente si haces cualquier edición. Si <strong>[$1 inicias sesión]</strong> o <strong>[$2 creas una cuenta]</strong>, tus ediciones se atribuirán a tu nombre de usuario, junto con otros beneficios.",
+       "anoneditwarning": "<strong>Advertencia:</strong> no has iniciado sesión. Tu dirección IP se hará pública si haces cualquier edición en estas condiciones. Si <strong>[$1 inicias sesión]</strong> o <strong>[$2 creas una cuenta]</strong>, tus ediciones se atribuirán a tu nombre de usuario, además de otros beneficios.",
        "anonpreviewwarning": "<em>No has iniciado sesión. Al guardar los cambios se almacenará tu dirección IP en el historial de edición de esta página.</em>",
-       "missingsummary": "<strong>Recordatorio:</strong> No has escrito un resumen de edición.\nSi haces clic nuevamente en «{{int:savearticle}}» tu edición se grabará sin él.",
-       "selfredirect": "<strong>Advertencia:</strong> estás redirigiendo esta página a sí misma.\nPuedes haber especificado erróneamente el destino de la redirección o puedes estar editando la página equivocada.\nSi haces clic de nuevo en \"{{int:savearticle}}\", la redirección se creará de todas maneras.",
+       "missingsummary": "<strong>Atención:</strong> No has escrito un resumen de edición.\nSi haces clic nuevamente en «{{int:savearticle}}» tu edición se grabará sin él.",
+       "selfredirect": "<strong>Advertencia:</strong> estás redirigiendo esta página a sí misma.\nPuede que hayas especificado erróneamente el destino de la redirección, o quizá estés editando la página equivocada. En cualquier caso, si haces clic de nuevo en \"{{int:savearticle}}\", se creará la redirección.",
        "missingcommenttext": "Escribe un comentario a continuación.",
-       "missingcommentheader": "<strong>Recordatorio:</strong> No has escrito un asunto/encabezado para este comentario.\nSi haces clic nuevamente en \"{{int:savearticle}}\" tu edición se grabará sin él.",
+       "missingcommentheader": "<strong>Atención:</strong> No has escrito un asunto/encabezado para este comentario.\nSi haces clic nuevamente en \"{{int:savearticle}}\" tu edición se grabará sin él.",
        "summary-preview": "Previsualización del resumen:",
        "subject-preview": "Previsualización del asunto/encabezado:",
        "blockedtitle": "El usuario está bloqueado",
        "blockedtext": "<strong>Tu nombre de usuario o dirección IP ha sido bloqueada.</strong>\n\nEl bloqueo fue hecho por $1.\nLa razón dada es <em>$2</em>.\n\n* Inicio del bloqueo: $8\n* Caducidad del bloqueo: $6\n* Bloqueo destinado a: $7\n\nPuedes contactar a $1 u otro [[{{MediaWiki:Grouppage-sysop}}|administrador]] para discutir el bloqueo.\nNo puedes utilizar la función «enviar correo electrónico a este usuario»  a menos que tengas una dirección de correo electrónico válida registrada en tus [[Special:Preferences|preferencias de usuario]] y que el bloqueo no haya inhabilitado esta función.\n\nTu dirección IP actual es $3, y el identificador del bloqueo es #$5.\nPor favor incluye todos los datos aquí mostrados en cualquier consulta que hagas.",
-       "autoblockedtext": "Tu dirección IP ha sido bloqueada automáticamente porque fue utilizada por otro usuario que fue bloqueado por $1.\nLa razón dada es esta:\n\n:<em>$2</em>\n\n* Inicio del bloqueo: $8\n* Caducidad del bloqueo: $6\n* Bloqueo destinado a: $7\n\nPuedes contactar con $1 o con otro de los [[{{MediaWiki:Grouppage-sysop}}|administradores]] para discutir el bloqueo.\n\nTen en cuenta que no podrás utilizar la herramienta de «enviar correo electrónico a este usuario» a menos que tengas una dirección de correo electrónico válida registrada en tus [[Special:Preferences|preferencias de usuario]] y que el bloqueo no haya inhabilitado esta función.\n\nTu actual dirección IP es $3, y el identificador del bloqueo es #$5.\nPor favor, incluye todos los datos mostrados aquí en cualquier consulta que hagas.",
+       "autoblockedtext": "Tu dirección IP ha sido bloqueada automáticamente porque fue utilizada por otro usuario, que resultó bloqueado por $1.\nLa explicación proporcionada es la siguiente:\n\n:<em>$2</em>\n\n* Inicio del bloqueo: $8\n* Caducidad del bloqueo: $6\n* Bloqueo destinado a: $7\n\nPuedes contactar con $1 o con otro de los [[{{MediaWiki:Grouppage-sysop}}|administradores]] para discutir el bloqueo.\n\nTen en cuenta que no podrás utilizar la herramienta de «enviar correo electrónico a este usuario» a menos que tengas una dirección de correo electrónico válida registrada en tus [[Special:Preferences|preferencias de usuario]] y la función no haya sido también bloqueada.\n\nTu actual dirección IP es $3, y el identificador del bloqueo es #$5.\nPor favor, incluye todos los datos aquí mostrados en cualquier consulta que hagas al respecto.",
        "blockednoreason": "no se ha especificado el motivo",
        "whitelistedittext": "Tienes que $1 para editar artículos.",
-       "confirmedittext": "Debes confirmar tu dirección electrónica antes de editar páginas. Por favor, establece y valida una dirección electrónica a través de tus [[Special:Preferences|preferencias de usuario]].",
+       "confirmedittext": "Debes confirmar tu dirección de correo electrónico antes de poder editar páginas. Por favor, configura y confirma tu dirección de correo a través de tus [[Special:Preferences|preferencias de usuario]].",
        "nosuchsectiontitle": "Sección no encontrada",
        "nosuchsectiontext": "Has intentado editar una sección que no existe.\nQuizá ha sido movida o borrada mientras visitabas la página.",
        "loginreqtitle": "Es necesario iniciar sesión",
        "loginreqlink": "acceder",
        "loginreqpagetext": "Debes $1 para ver otras páginas.",
        "accmailtitle": "Se ha enviado la contraseña",
-       "accmailtext": "Se ha enviado a $2 una contraseña generada aleatoriamente para [[User talk:$1|$1]]. Puede cambiarse en la página [[Special:ChangePassword|destinada para ello]] después de haber iniciado sesión.",
+       "accmailtext": "Se ha enviado a $2 una contraseña generada aleatoriamente para [[User talk:$1|$1]]. Una vez iniciada la sesión, se puede cambiar en la página [[Special:ChangePassword|destinada para ello]].",
        "newarticle": "(Nuevo)",
-       "newarticletext": "Has seguido un enlace a una página que aún no existe.\nPara crear esta página, escribe en el campo a continuación. Para más información, consulta la [$1 página de ayuda].\nSi llegaste aquí por error, vuelve a la página anterior.",
-       "anontalkpagetext": "---- ''Esta es la página de discusión de un usuario anónimo que aún no ha creado una cuenta, o no la usa. Por lo tanto, tenemos que usar su dirección IP para identificarlo. Una dirección IP puede ser compartida por varios usuarios. Si eres un usuario anónimo y crees que se han dirigido a ti con comentarios improcedentes, por favor [[Special:UserLogin/signup|crea una cuenta]] o si ya la tienes [[Special:UserLogin|identifícate]] para evitar confusiones futuras con otros usuarios anónimos.''",
+       "newarticletext": "Has seguido un enlace a una página que aún no existe.\nPara crear esta página, escribe en el cuadro que aparece a continuación. Para más información, consulta la [$1 página de ayuda].\nSi llegaste aquí por error, vuelve a la página anterior.",
+       "anontalkpagetext": "---- ''Esta es la página de discusión de un usuario anónimo que aún no ha creado una cuenta, o no la usa. Por lo tanto, tenemos que usar su dirección IP para identificarlo. Puede que varios usuarios compartan una misma dirección IP. Si eres un usuario anónimo y crees que se han dirigido a ti con comentarios improcedentes, por favor [[Special:UserLogin/signup|crea una cuenta]] o, si ya la tienes, [[Special:UserLogin|identifícate]] para evitar confusiones futuras con otros usuarios anónimos.''",
        "noarticletext": "En este momento no hay texto en esta página.\nPuedes [[Special:Search/{{PAGENAME}}|buscar el título de esta página]] en otras páginas,\n<span class=\"plainlinks\">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} buscar en los registros],\no [{{fullurl:{{FULLPAGENAME}}|action=edit}} editar esta página]</span>.",
        "noarticletext-nopermission": "Actualmente no hay texto en esta página.\nPuedes [[Special:Search/{{PAGENAME}}|buscar este título de página]] en otras páginas, o <span class=\"plainlinks\">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} buscar en los registros relacionados]</span>, pero no tienes permiso para crear esta página.",
-       "missing-revision": "La revisión n.º $1 de la página llamada «{{FULLPAGENAME}}» no existe.\n\nNormalmente esto ocurre cuando se sigue un enlace de historial obsoleto que apunta a una página ya borrada.\nPuedes encontrar detalles en el [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} registro de borrados].",
-       "userpage-userdoesnotexist": "La cuenta de usuario «<nowiki>$1</nowiki>» no está registrada. Por favor comprueba si quieres crear o editar esta página.",
-       "userpage-userdoesnotexist-view": "La cuenta de usuario «$1» no está registrada.",
-       "blocked-notice-logextract": "Este usuario está actualmente bloqueado.\nLa última entrada del registro de bloqueos se proporciona debajo para mayor referencia:",
-       "clearyourcache": "'''Nota:''' después de guardar, quizás necesites refrescar la caché de tu navegador para ver los cambios.\n* '''Firefox / Safari:''' Mantén presionada ''Mayús'' mientras pulsas el botón ''Actualizar'', o presiona ''Ctrl+F5'' o ''Ctrl+R'' (''⌘+R'' en Mac)\n* '''Google Chrome:''' presiona ''Ctrl+Shift+R'' (''⌘+Mayús+R'' en Mac)\n* '''Internet Explorer:''' mantén presionada ''Ctrl'' mientras pulsas ''Actualizar'', o presiona ''Ctrl+F5''\n* '''Opera:''' vacía la caché en ''Herramientas → Preferencias''",
-       "usercssyoucanpreview": "'''Consejo:''' Usa el botón «{{int:showpreview}}» para probar el nuevo CSS antes de guardarlo.",
-       "userjsyoucanpreview": "'''Consejo:''' Usa el botón «{{int:showpreview}}» para probar el nuevo JS antes de guardarlo.",
-       "usercsspreview": "'''Recuerda que sólo estás previsualizando tu CSS de usuario.'''\n'''¡Aún no se ha guardado!'''",
-       "userjspreview": "'''¡Recuerda que solo estás previsualizando tu JavaScript de usuario.'''\n'''¡Aún no se ha guardado!'''",
-       "sitecsspreview": "'''Recuerda que sólo estás previsualizando este CSS'''\n'''¡Aún no se ha guardado!'''",
-       "sitejspreview": "'''Recuerda que sólo estás previsualizando este código JavaScript.'''\n'''¡Aún no se ha guardado!'''",
-       "userinvalidcssjstitle": "'''Aviso:''' No existe la apariencia «$1». Recuerda que las páginas personalizadas ''.css'' y ''.js'' tienen un título en minúsculas. Por ejemplo, {{ns:user}}:Ejemplo/vector.css en vez de {{ns:user}}:Ejemplo/Vector.css.",
+       "missing-revision": "La revisión n.º $1 de la página «{{FULLPAGENAME}}» no existe.\n\nEsto suele ocurrir cuando se sigue un enlace de historial obsoleto que apunta a una página ya borrada.\nPuedes encontrar detalles en el [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} registro de borrados].",
+       "userpage-userdoesnotexist": "El usuario «$1» no está registrado. Por favor, asegúrate de que realmente quieres crear o editar esta página.",
+       "userpage-userdoesnotexist-view": "El usuario «$1» no está registrado.",
+       "blocked-notice-logextract": "Este usuario se encuentra actualmente bloqueado.\nA continuación se muestra la última entrada del registro de bloqueos para más información:",
+       "clearyourcache": "<strong>Nota:</strong> tras guardar, quizás necesites actualizar la caché de tu navegador para ver los cambios.\n* <strong>Firefox/Safari:</strong> Mantén presionada la tecla <em>Mayús</em> mientras pulsas el botón <em>Actualizar</em>, o presiona <em>Ctrl+F5</em> o <em>Ctrl+R</em> (<em>⌘+R</em> en Mac)\n* <strong>Google Chrome:</strong> presiona <em>Ctrl+Shift+R</em> (<em>⌘+Mayús+R</em> en Mac)\n* <strong>Internet Explorer:</strong> mantén presionada <em>Ctrl</em> mientras pulsas <em>Actualizar</em>, o presiona <em>Ctrl+F5</em>\n* <strong>Opera:</strong> vacía la caché en <em>Herramientas → Preferencias</em>",
+       "usercssyoucanpreview": "<strong>Consejo:</strong> Usa el botón «{{int:showpreview}}» para probar el nuevo CSS antes de guardarlo.",
+       "userjsyoucanpreview": "<strong>Consejo:</strong> Usa el botón «{{int:showpreview}}» para probar el nuevo código JavaScript antes de guardarlo.",
+       "usercsspreview": "<strong>Recuerda que solo estás previsualizando tu CSS de usuario. ¡Aún no se ha guardado!</strong>",
+       "userjspreview": "<strong>¡Recuerda que solo estás previsualizando tu JavaScript de usuario. ¡Aún no se ha guardado!</strong>",
+       "sitecsspreview": "<strong>Recuerda que solo estás previsualizando este CSS. ¡Aún no se ha guardado!</strong>",
+       "sitejspreview": "<strong>Recuerda que solo estás previsualizando este código JavaScript. ¡Aún no se ha guardado!</strong>",
+       "userinvalidcssjstitle": "<strong>Advertencia:</strong> No existe la apariencia «$1». Recuerda que las páginas personalizadas .css y .js tienen un título en minúsculas. Por ejemplo, se usa {{ns:user}}:Ejemplo/vector.css en vez de {{ns:user}}:Ejemplo/Vector.css.",
        "updated": "(Actualizado)",
        "note": "<strong>Nota:</strong>",
-       "previewnote": "<strong>Recuerda que esta es una previsualización.</strong>\nTodavía no se han guardado tus cambios.",
+       "previewnote": "<strong>Recuerda que esto no es más que una previsualización.</strong>\nAún no se han guardado tus cambios.",
        "continue-editing": "Ir al área de edición",
-       "previewconflict": "Esta previsualización refleja el texto en el área de edición superior como aparecerá una vez guardados los cambios.",
-       "session_fail_preview": "'''No se pudo procesar la edición debido a una pérdida de los datos de sesión.'''\nInténtalo de nuevo.\nSi el problema persiste, [[Special:UserLogout|cierra la sesión]] y vuelve a identificarte.",
-       "session_fail_preview_html": "'''Lo sentimos, no hemos podido procesar tu cambio debido a una pérdida de datos de sesión.'''\n\n''Puesto que este wiki tiene el HTML puro habilitado, la visión preliminar está oculta para prevenirse contra ataques en JavaScript.''\n\n'''Si éste es un intento legítimo de modificación, por favor, inténtalo de nuevo. Si aún así no funcionase, [[Special:UserLogout|cierra la sesión]] e ingresa de nuevo.'''",
-       "token_suffix_mismatch": "'''Tu edición ha sido rechazada porque tu cliente ha mezclado los signos de puntuación en el token de edición.\nSe rechazó la edición para evitar que el texto de la página se corrompa.\nEsto sucede en ocasiones cuando se usa un servicio de proxy anónimo defectuoso.'''",
-       "edit_form_incomplete": "'''Algunas partes del formulario de edición no llegaron al servidor, comprueba que tus ediciones están intactas e inténtalo de nuevo'''.",
+       "previewconflict": "Esta previsualización muestra cómo aparecerá el texto en el área de edición superior una vez guardados los cambios.",
+       "session_fail_preview": "<strong>Lo sentimos, no hemos podido procesar tu edición debido a una pérdida de los datos de sesión.</strong>\nPor favor, inténtalo de nuevo.\nSi el problema persiste, prueba a [[Special:UserLogout|cerrar sesión]] y volver a acceder.",
+       "session_fail_preview_html": "<strong>Lo sentimos, no hemos podido procesar tu edición debido a una pérdida de datos de sesión.</strong>\n\n<em>La previsualización está oculta como prevención frente a ataques JavaScript, puesto que este wiki tiene habilitado el HTML en bruto.</em>\n\n<strong>Si se trata de un intento legítimo de modificación, por favor, inténtalo de nuevo.</strong>\nSi aún así no funcionase, prueba a [[Special:UserLogout|cerrar sesión]] y volver a acceder.",
+       "token_suffix_mismatch": "<strong>Tu edición ha sido rechazada porque tu cliente ha mezclado los signos de puntuación en la clave de edición.\nSe rechazó la edición para evitar la corrupción del texto de la página.\nEsto sucede en ocasiones si se usa un servicio de proxy anónimo defectuoso.</strong>",
+       "edit_form_incomplete": "<strong>Una parte del formulario de edición no ha llegado al servidor. Comprueba que tus cambios están intactos e inténtalo de nuevo.</strong>",
        "editing": "Edición de «$1»",
-       "creating": "Crear la página $1",
-       "editingsection": "Editar $1 (sección)",
+       "creating": "Creación de «$1»",
+       "editingsection": "Edición de «$1» (sección)",
        "editingcomment": "Edición de «$1» (sección nueva)",
        "editconflict": "Conflicto de edición: $1",
-       "explainconflict": "Alguien más ha cambiado esta página desde que empezaste a editarla.\nEl área de texto superior contiene el texto de la página como existe actualmente.\nTus cambios se muestran en el área de texto inferior.\nSi quieres grabar tus cambios, has de trasladarlos al área superior.\n'''Sólo''' el texto en el área de texto superior será grabado cuando pulses «{{int:savearticle}}».",
+       "explainconflict": "Alguien ha realizado cambios en esta página desde que empezaste a editarla.\nEl cuadro de texto superior contiene el texto de la página tal como está guardado en este momento.\nTus cambios sobre la versión que editaste se muestran en el cuadro de texto inferior.\nSi quieres guardar tus cambios, has de trasladarlos al cuadro superior.\nAl pulsar «{{int:savearticle}}», se guardará <strong>solo</strong> el texto del cuadro superior.",
        "yourtext": "Tu texto",
-       "storedversion": "Versión almacenada",
-       "nonunicodebrowser": "'''Atención: Tu navegador no cumple la norma Unicode.'''\nSe ha activado un sistema de edición alternativo que te permitirá editar artículos con seguridad: los caracteres no ASCII aparecerán en la caja de edición como códigos hexadecimales.",
-       "editingold": "'''Aviso: Estás editando una versión antigua de esta página.'''\nSi la guardas, se perderán los cambios realizados desde esta revisión.",
+       "storedversion": "Versión guardada",
+       "nonunicodebrowser": "<strong>Advertencia: tu navegador no es compatible con los caracteres Unicode.</strong>\nSe ha activado un sistema de edición alternativo que te permitirá editar artículos con seguridad: los caracteres no pertenecientes al estándar ASCII aparecerán como códigos hexadecimales en el cuadro de edición.",
+       "editingold": "<strong>Advertencia: estás editando sobre una revisión antigua de esta página.</strong>\nSi la guardas, se perderá cualquier otro cambio realizado desde esa revisión.",
        "yourdiff": "Diferencias",
-       "copyrightwarning": "Por favor observa que todas las contribuciones a {{SITENAME}} se consideran hechas públicas bajo la $2 (véase $1 para más detalles). Si no deseas la modificación y distribución libre de tu obra, entonces no la pongas aquí.<br />También nos aseguras que tú escribiste esto y te pertenecen de los derechos de autor, o lo copiaste desde el dominio público u otra fuente libre. '''¡No uses escritos con copyright sin permiso!'''",
-       "copyrightwarning2": "Por favor, ten en cuenta que todas las contribuciones a {{SITENAME}} pueden ser editadas, modificadas o eliminadas por otros colaboradores. Si no deseas que las modifiquen sin limitaciones y las distribuyan libremente, entonces no las pongas aquí.<br />También nos aseguras que tú escribiste esto y te pertenecen de los derechos de autor, o lo copiaste desde el dominio público u otra fuente libre. (véase $1 para más detalles).\n'''¡No uses escritos con copyright sin permiso!'''",
-       "longpageerror": "'''Error: El texto que has enviado ocupa {{PLURAL:$1|un kilobyte|$1 kilobytes}}, que excede el máximo de {{PLURAL:$2|un kilobyte|$2 kilobytes}}.''' \nNo se lo puede guardar.",
-       "readonlywarning": "'''Advertencia: La base de datos ha sido bloqueada para mantenimiento, así que no podrás guardar tus ediciones en este momento.'''\nQuizás quieras copiar y pegar tu texto en un archivo de texto y guardarlo para después.\n\nEl administrador que lo bloqueó ofreció esta explicación: $1",
-       "protectedpagewarning": "'''Aviso: Esta página ha sido protegida de manera que solo usuarios con permisos de administrador puedan editarla.'''\nA continuación se muestra la última entrada de registro para referencia:",
-       "semiprotectedpagewarning": "'''Nota:''' Esta página ha sido protegida para que solo usuarios registrados puedan editarla.\nA continuación se provee la última entrada de registro para referencia:",
-       "cascadeprotectedwarning": "'''Aviso:''' Esta página está protegida, solo los administradores pueden editarla porque está incluida en  {{PLURAL:$1|la siguiente página protegida|las siguientes páginas protegidas}} en cascada:",
+       "copyrightwarning": "Ten en cuenta que todas las contribuciones a {{SITENAME}} se consideran publicadas bajo la $2 (véase $1 para más información). Si no deseas que las modifiquen sin limitaciones y las distribuyan libremente, no las publiques aquí.<br />Al mismo tiempo, asumimos que eres el autor de lo que escribiste, o lo copiaste de una fuente en el dominio público o con licencia libre. <strong>¡No uses textos con copyright sin permiso!</strong>",
+       "copyrightwarning2": "Ten en cuenta que todas las contribuciones a {{SITENAME}} pueden ser editadas, modificadas o eliminadas por otros colaboradores. Si no deseas que las modifiquen sin limitaciones, no las publiques aquí.<br />Al mismo tiempo, asumimos que eres el autor de lo que escribiste, o lo copiaste de una fuente en el dominio público o con licencia libre (véase $1 para más detalles).\n<strong>¡No uses textos con copyright sin permiso!</strong>",
+       "longpageerror": "<strong>Error: el texto que has enviado ocupa {{PLURAL:$1|un kilobyte|$1 kilobytes}}, que excede el máximo de {{PLURAL:$2|un kilobyte|$2 kilobytes}}.</strong>\nPor tanto, no lo podemos guardar.",
+       "readonlywarning": "<strong>Advertencia: La base de datos ha sido bloqueada por labores de mantenimiento, así que en este momento no puedes guardar tus ediciones.</strong>\nQuizás quieras copiar y pegar tu texto en un archivo de texto y guardarlo para después.\n\nEl administrador que la bloqueó ha dado esta explicación: $1",
+       "protectedpagewarning": "<strong>Advertencia: Esta página ha sido protegida para que solo puedan editarla los usuarios con permisos de administrador.</strong>\nA continuación se muestra la última entrada de registro para más información:",
+       "semiprotectedpagewarning": "<strong>Nota:</strong> Esta página ha sido protegida para que solo puedan editarla los usuarios registrados.\nA continuación se muestra la última entrada de registro para más información:",
+       "cascadeprotectedwarning": "<strong>Aviso:</strong> esta página está protegida y solo los administradores pueden editarla porque está incluida en {{PLURAL:$1|la siguiente página protegida|las siguientes páginas protegidas}} en cascada:",
        "titleprotectedwarning": "<strong>Aviso: esta página está protegida de modo que se necesitan [[Special:ListGroupRights|permisos específicos]] para crearla.</strong>\nA continuación se muestra la última entrada del registro como referencia:",
        "templatesused": "{{PLURAL:$1|Plantilla usada|Plantillas usadas}} en esta página:",
        "templatesusedpreview": "{{PLURAL:$1|Plantilla usada|Plantillas usadas}} en esta previsualización:",
        "templatesusedsection": "{{PLURAL:$1|Plantilla usada|Plantillas usadas}} en esta sección:",
        "template-protected": "(protegida)",
        "template-semiprotected": "(semiprotegida)",
-       "hiddencategories": "Esta página es un miembro de {{PLURAL:$1|1 categoría oculta|$1 categorías ocultas}}:",
+       "hiddencategories": "Esta página pertenece a {{PLURAL:$1|1 categoría oculta|$1 categorías ocultas}}:",
        "edittools": "<!-- Este texto aparecerá bajo los formularios de edición y subida. -->",
-       "nocreatetext": "{{SITENAME}} ha restringido la posibilidad de crear nuevas páginas.\nPuede volver atrás y editar una página existente, [[Special:UserLogin|identificarte o crear una cuenta]].",
+       "nocreatetext": "{{SITENAME}} ha restringido la posibilidad de crear nuevas páginas.\nPuedes volver atrás y editar una página existente, [[Special:UserLogin|identificarte o crear una cuenta]].",
        "nocreate-loggedin": "No tienes permiso para crear páginas nuevas.",
-       "sectioneditnotsupported-title": "Edición de sección no compatible",
-       "sectioneditnotsupported-text": "La edición de sección no es compatible con esta página.",
+       "sectioneditnotsupported-title": "Edición de sección no admitida",
+       "sectioneditnotsupported-text": "No se admite la edición de secciones en esta página.",
        "permissionserrors": "Error de permiso",
        "permissionserrorstext": "No tienes permiso para hacer eso, por {{PLURAL:$1|el siguiente motivo|los siguientes motivos}}:",
        "permissionserrorstext-withaction": "No tienes permiso para $2, por {{PLURAL:$1|el siguiente motivo|los siguientes motivos}}:",
-       "recreate-moveddeleted-warn": "'''Atención: estás volviendo a crear una página que ha sido borrada anteriormente.'''\n\nDeberías considerar si es apropiado continuar editando esta página.\nEl registro de borrado y traslados para esta página están provistos aquí por conveniencia:",
-       "moveddeleted-notice": "Esta página ha sido borrada.\nEl registro de borrados y traslados para la página están provistos debajo como referencia.",
+       "recreate-moveddeleted-warn": "<strong>Atención: estás volviendo a crear una página que ha sido borrada anteriormente.</strong>\n\nPiensa si es adecuado continuar editando la página.\nA continuación, se proporciona el registro de borrado y traslados de esta página para más información:",
+       "moveddeleted-notice": "Esta página ha sido borrada.\nA continuación, se proporciona el registro de borrados y traslados de la página para más información.",
        "log-fulllog": "Ver el registro completo",
-       "edit-hook-aborted": "Edición cancelada por la extensión.\nNo se aportaron explicaciones.",
-       "edit-gone-missing": "No se pudo actualizar la página.\nParece que ha sido borrada.",
+       "edit-hook-aborted": "Una extensión ha evitado la edición.\nNo hay explicación disponible.",
+       "edit-gone-missing": "No se ha podido actualizar la página.\nParece haber sido borrada.",
        "edit-conflict": "Conflicto de edición.",
        "edit-no-change": "Se ignoró tu edición porque no se hizo ningún cambio en el texto.",
        "postedit-confirmation-created": "Se ha creado la página.",
        "postedit-confirmation-saved": "Se ha guardado tu edición.",
        "edit-already-exists": "No se pudo crear una página nueva.\nYa existe.",
        "defaultmessagetext": "Texto de mensaje predeterminado",
-       "content-failed-to-parse": "No se pudo analizar el contenido $2 del modelo $1: $3",
-       "invalid-content-data": "Datos de contenido inválidos",
+       "content-failed-to-parse": "No se ha podido procesar el contenido $2 del modelo de $1: $3",
+       "invalid-content-data": "Datos de contenido incorrectos",
        "content-not-allowed-here": "El contenido «$1» no está permitido en la página [[$2]]",
        "editwarning-warning": "Se perderán los cambios si se cierra esta página.\nSi has iniciado sesión, puedes desactivar este aviso en la sección «{{int:prefs-editing}}» de las preferencias.",
-       "editpage-notsupportedcontentformat-title": "Formato de contenido no admitido",
-       "editpage-notsupportedcontentformat-text": "El formato de contenido $1 no es compatible con el modelo de contenido  $2.",
+       "editpage-notsupportedcontentformat-title": "Formato de contenido no compatible",
+       "editpage-notsupportedcontentformat-text": "El formato de contenido $1 no es compatible con el modelo de contenido $2.",
        "content-model-wikitext": "texto wiki",
-       "content-model-text": "Texto sin formato",
+       "content-model-text": "texto sin formato",
        "content-model-javascript": "JavaScript",
        "content-model-css": "CSS",
        "content-json-empty-object": "Objeto vacío",
        "duplicate-args-category-desc": "La página contiene invocaciones de plantillas que utilizan argumentos duplicados, como <code><nowiki>{{foo|bar=1|bar=2}}</nowiki></code> o <code><nowiki>{{foo|bar|1=baz}}</nowiki></code>.",
        "expensive-parserfunction-warning": "Aviso: Esta página contiene demasiadas llamadas a funciones sintácticas costosas (#ifexist: y similares)\n\nTiene {{PLURAL:$1|una llamada|$1 llamadas}}, pero debería tener menos de $2.",
        "expensive-parserfunction-category": "Páginas con llamadas a funciones sintácticas demasiado costosas",
-       "post-expand-template-inclusion-warning": "Aviso: El tamaño de las plantillas incluidas es muy grande.\nAlgunas plantillas no serán incluidas.",
+       "post-expand-template-inclusion-warning": "<strong>Aviso:</strong> El tamaño de las plantillas incluidas es muy grande.\nAlgunas de ellas no se incluirán.",
        "post-expand-template-inclusion-category": "Páginas con sobrecarga de plantillas",
-       "post-expand-template-argument-warning": "Aviso: Esta página contiene al menos un parámetro de plantilla que tiene un tamaño de expansión demasiado grande.\nEse o esos parámetros han sido omitidos.",
+       "post-expand-template-argument-warning": "Aviso: Esta página contiene al menos un parámetro de plantilla con un tamaño de expansión demasiado grande.\nSe han descartado esos parámetros.",
        "post-expand-template-argument-category": "Páginas que contienen plantillas con parámetros descartados",
-       "parser-template-loop-warning": "Detectado bucle de plantilla: [[$1]]",
-       "parser-template-recursion-depth-warning": "Se ha excedido el límite de recursión de plantillas ($1)",
-       "language-converter-depth-warning": "El límite de profundidad del convertidor de idioma ha excedido ($1)",
-       "node-count-exceeded-category": "Páginas donde se supera el número de nodos",
-       "node-count-exceeded-category-desc": "La página supera el número máximo de nodos.",
-       "node-count-exceeded-warning": "Página que ha superado el número de nodos",
-       "expansion-depth-exceeded-category": "Páginas donde se supera la profundidad de expansión",
-       "expansion-depth-exceeded-category-desc": "Esta página supera el límite de extensión.",
-       "expansion-depth-exceeded-warning": "Página que ha superado la profundidad de expansión",
-       "parser-unstrip-loop-warning": "Se ha detectado un bucle \"unstrip\"",
-       "parser-unstrip-recursion-limit": "Se ha superado el límite de recursión de \"unstrip\" ($1)",
-       "converter-manual-rule-error": "Error detectado en la regla de conversión manual del lenguaje",
+       "parser-template-loop-warning": "Se ha detectado un bucle de plantilla: [[$1]]",
+       "parser-template-recursion-depth-warning": "Se ha superado el límite de profundidad de la recursividad de plantillas ($1)",
+       "language-converter-depth-warning": "Se ha superado el límite de profundidad del convertidor de idioma ($1)",
+       "node-count-exceeded-category": "Páginas que sobrepasan la cantidad de nodos",
+       "node-count-exceeded-category-desc": "Esta página sobrepasa la cantidad máxima de nodos permitida.",
+       "node-count-exceeded-warning": "La página supera la cantidad de nodos",
+       "expansion-depth-exceeded-category": "Páginas que sobrepasan la profundidad de expansión",
+       "expansion-depth-exceeded-category-desc": "Esta página sobrepasa la profundidad de expansión máxima.",
+       "expansion-depth-exceeded-warning": "La página ha superado la profundidad de expansión",
+       "parser-unstrip-loop-warning": "Se ha detectado un bucle en la función \"unstrip\"",
+       "parser-unstrip-recursion-limit": "Se ha superado el límite de recursividad de la función \"unstrip\" ($1)",
+       "converter-manual-rule-error": "Se ha detectado un error en una regla de conversión de lenguaje manual",
        "undo-success": "La edición puede deshacerse. Antes de deshacer la edición, comprueba la siguiente comparación para verificar que realmente es lo que quieres hacer, y entonces guarda los cambios para así deshacer la edición.",
        "undo-failure": "No se puede deshacer la edición ya que otro usuario ha realizado una edición intermedia.",
-       "undo-norev": "La edición no puede ser deshecha porque no existe o ha sido borrada.",
-       "undo-nochange": "Parece que ya se ha deshecho la modificación.",
-       "undo-summary": "Deshecha la revisión $1 de [[Special:Contributions/$2|$2]] ([[User talk:$2|disc.]])",
-       "undo-summary-username-hidden": "Deshacer revisión $1 por usuario oculto",
+       "undo-norev": "No se ha podido deshacer la edición porque no existe o ha sido borrada.",
+       "undo-nochange": "Parece que ya se había deshecho la edición.",
+       "undo-summary": "Se ha deshecho la revisión $1 de [[Special:Contributions/$2|$2]] ([[User talk:$2|disc.]])",
+       "undo-summary-username-hidden": "Se ha deshecho la revisión $1 de un usuario oculto",
        "cantcreateaccounttitle": "No se puede crear la cuenta",
-       "cantcreateaccount-text": "La creación de cuentas desde esta dirección IP ('''$1''') ha sido bloqueada por [[User:$3|$3]].\n\nEl motivo dado por $3 es ''$2''",
-       "cantcreateaccount-range-text": "La creación de cuentas de usuario desde direcciones IP en el rango '''$1''', que incluye tu dirección IP ('''$4'''), ha sido bloqueada por [[User:$3|$3]].\n\nEl motivo dado por $3 es ''$2''",
+       "cantcreateaccount-text": "[[User:$3|$3]] ha bloqueado la creación de cuentas desde esta dirección IP ('''$1''').\n\nEl motivo dado por $3 es <em>$2</em>",
+       "cantcreateaccount-range-text": "[[User:$3|$3]] ha bloqueado la creación de cuentas de usuario desde direcciones IP en el rango '''$1''', en el que se encuentra tu dirección IP ('''$4''').\n\nEl motivo dado por $3 es ''$2''",
        "viewpagelogs": "Ver los registros de esta página",
        "nohistory": "No hay historial de ediciones para esta página.",
        "currentrev": "Revisión actual",
        "right-override-export-depth": "Exporta páginas incluyendo aquellas enlazadas hasta una profundidad de 5",
        "right-sendemail": "Enviar un correo electrónico a otros usuarios",
        "right-passwordreset": "Ver os correos electrónicos de restablecimiento de contraseñas",
+       "right-managechangetags": "Crear y eliminar [[Special:Tags|etiquetas]] en la base de datos",
        "newuserlogpage": "Registro de creación de usuarios",
        "newuserlogpagetext": "Este es un registro de creación de usuarios.",
        "rightslog": "Cambios de perfil de usuario",
        "action-viewmyprivateinfo": "ver tu información privada",
        "action-editmyprivateinfo": "Editar tu información privada",
        "action-editcontentmodel": "editar el modelo de contenido de una página",
+       "action-managechangetags": "crear y eliminar etiquetas en la base de datos",
        "nchanges": "$1 {{PLURAL:$1|cambio|cambios}}",
        "enhancedrc-since-last-visit": "$1 {{PLURAL:$1|desde la última visita}}",
        "enhancedrc-history": "historial",
        "delete-confirm": "Borrar «$1»",
        "delete-legend": "Borrar",
        "historywarning": "<strong>Atención:</strong> la página que estás a punto de borrar tiene un historial con $1 {{PLURAL:$1|revisión|revisiones}}:",
-       "confirmdeletetext": "Estás a punto de borrar una página en forma permanente, así como todo su historial.\nPor favor, confirma que realmente quieres hacer eso, que entiendes las\nconsecuencias, y que lo estás haciendo de acuerdo con [[{{MediaWiki:Policy-url}}|las políticas]].",
+       "confirmdeletetext": "Estás a punto de borrar una página, así como todo su historial.\nPor favor, confirma que realmente quieres hacer eso, que entiendes las consecuencias, y que lo estás haciendo de acuerdo con [[{{MediaWiki:Policy-url}}|las políticas]].",
        "actioncomplete": "Acción completada",
        "actionfailed": "Acción fallida",
        "deletedtext": "«$1» ha sido borrado.\nVéase $2 para un registro de los borrados recientes.",
        "tags-tag": "Nombre de etiqueta",
        "tags-display-header": "Apariencia de la lista de cambios",
        "tags-description-header": "Descripción completa de significado",
+       "tags-source-header": "Fuente",
        "tags-active-header": "¿Activo?",
        "tags-hitcount-header": "Cambios etiquetados",
+       "tags-actions-header": "Acciones",
        "tags-active-yes": "Sí",
        "tags-active-no": "No",
+       "tags-source-extension": "Definida por una extensión",
+       "tags-source-manual": "Aplicada manualmente por usuarios y bots",
+       "tags-source-none": "No se utiliza más",
        "tags-edit": "editar",
+       "tags-delete": "eliminar",
+       "tags-activate": "activar",
+       "tags-deactivate": "desactivar",
        "tags-hitcount": "$1 {{PLURAL:$1|cambio|cambios}}",
+       "tags-manage-no-permission": "No tienes permiso para gestionar las etiquetas de cambios.",
+       "tags-create-heading": "Crear una etiqueta",
+       "tags-create-explanation": "De manera predeterminada, las etiquetas nuevas estarán disponibles para su uso por usuarios y bots.",
+       "tags-create-tag-name": "Nombre de la etiqueta:",
+       "tags-create-reason": "Motivo:",
+       "tags-create-submit": "Crear",
+       "tags-create-no-name": "Es necesario especificar el nombre de la etiqueta.",
+       "tags-create-invalid-chars": "Los nombres de las etiquetas no deben contener comas (<code>,</code>) ni barras (<code>/</code>).",
+       "tags-create-invalid-title-chars": "Los nombres de las etiquetas no deben contener caracteres que no puedan usarse en los títulos de las páginas.",
+       "tags-create-already-exists": "La etiqueta «$1» ya existe.",
+       "tags-create-warnings-above": "Se {{PLURAL:$2|produjo el aviso siguiente|produjeron los avisos siguientes}} al intentar crear la etiqueta «$1»:",
+       "tags-create-warnings-below": "¿Continuar con la creación de la etiqueta?",
+       "tags-delete-title": "Eliminar etiqueta",
+       "tags-delete-explanation-initial": "Estás a punto de eliminar la etiqueta «$1» de la base de datos.",
+       "tags-delete-explanation-warning": "Esta acción es <strong>irreversible</strong> y ni siquiera los administradores de la base de datos podrán deshacerla. Confirma que esta es la etiqueta que se eliminará.",
+       "tags-delete-reason": "Motivo:",
+       "tags-delete-submit": "Eliminar esta etiqueta irreversiblemente",
+       "tags-delete-not-allowed": "No se pueden eliminar las etiquetas definidas por una extensión, a menos que esta lo permita expresamente.",
+       "tags-delete-not-found": "La etiqueta «$1» no existe.",
+       "tags-delete-warnings-after-delete": "La etiqueta \"$1\" se borró exitosamente, pero con {{PLURAL:$2|la siguiente advertencia|las siguientes advertencias}}:",
+       "tags-activate-title": "Activar etiqueta",
+       "tags-activate-question": "Estás a punto de activar la etiqueta «$1».",
+       "tags-activate-reason": "Motivo:",
+       "tags-activate-not-allowed": "No es posible activar la etiqueta «$1».",
+       "tags-activate-not-found": "La etiqueta «$1» no existe.",
+       "tags-activate-submit": "Activar",
+       "tags-deactivate-title": "Desactivar etiqueta",
+       "tags-deactivate-question": "Estás a punto de desactivar la etiqueta «$1».",
+       "tags-deactivate-reason": "Motivo:",
+       "tags-deactivate-not-allowed": "No es posible desactivar la etiqueta «$1».",
+       "tags-deactivate-submit": "Desactivar",
        "comparepages": "Comparar páginas",
        "compare-page1": "Página 1",
        "compare-page2": "Página 2",
        "logentry-upload-upload": "$1 {{GENDER:$2|subió}} $3",
        "logentry-upload-overwrite": "$1 {{GENDER:$2|subió}} una nueva versión de $3",
        "logentry-upload-revert": "$1 {{GENDER:$2|subió}} $3",
+       "log-name-managetags": "Registro de gestión de etiquetas",
+       "logentry-managetags-create": "$1 {{GENDER:$2|creó}} la etiqueta «$4»",
+       "logentry-managetags-delete": "$1 {{GENDER:$2|eliminó}} la etiqueta «$4» (quitada de $5 {{PLURAL:$5|revisión o entrada de registro|revisiones o entradas de registro}})",
+       "logentry-managetags-activate": "$1 {{GENDER:$2|activó}} la etiqueta «$4» para su uso por usuarios y bots",
+       "logentry-managetags-deactivate": "$1 {{GENDER:$2|desactivó}} la etiqueta «$4» para evitar su uso por usuarios y bots",
        "rightsnone": "(ninguno)",
        "revdelete-summary": "resumen de edición",
        "feedback-bugornote": "Si estás preparado para describir en detalle un problema técnico, [$1 informa de un bug] por favor.\n\nEn otro caso, puedes usar el siguiente formulario. Tu comentario será añadido a la página [$3 $2], junto con tu nombre de usuario y el navegador que usas.",
index 43a098b..4aa7182 100644 (file)
        "deletethispage": "Kustuta see lehekülg",
        "undeletethispage": "Taasta see lehekülg",
        "undelete_short": "Taasta {{PLURAL:$1|üks muudatus|$1 muudatust}}",
-       "viewdeleted_short": "Vaata {{PLURAL:$1|üht|$1}} kustutatud redaktsiooni",
+       "viewdeleted_short": "Vaata {{PLURAL:$1|üht|$1}} kustutatud muudatust",
        "protect": "Kaitse",
        "protect_change": "muuda",
        "protectthispage": "Kaitse seda lehekülge",
        "confirmable-no": "Ei",
        "thisisdeleted": "Vaata $1 või taasta?",
        "viewdeleted": "Vaata $1?",
-       "restorelink": "{{PLURAL:$1|üht|$1}} kustutatud versiooni",
+       "restorelink": "{{PLURAL:$1|üht|$1}} kustutatud muudatust",
        "feedlinks": "Voog:",
        "feed-invalid": "Vigane vootüüp.",
        "feed-unavailable": "Uudisvood ei ole saadaval.",
        "right-override-export-depth": "Eksportida lehekülgi, kaasates viidatud leheküljed kuni viienda tasemeni",
        "right-sendemail": "Saata teistele kasutajatele e-kirju",
        "right-passwordreset": "Vaadata parooli lähtestamise e-kirju",
+       "right-managechangetags": "Koostada [[Special:Tags|märgiseid]] ja kustutada neid andmebaasist",
        "newuserlogpage": "Konto loomise logi",
        "newuserlogpagetext": "Siin on logitud kasutajate registreerimine.",
        "rightslog": "Kasutajaõiguste logi",
        "action-viewmyprivateinfo": "oma eraandmeid vaadata",
        "action-editmyprivateinfo": "oma eraandmeid redigeerida",
        "action-editcontentmodel": "lehekülje sisumudelit muuta",
+       "action-managechangetags": "märgiseid koostada ege neid andmebaasist kustutada",
        "nchanges": "$1 {{PLURAL:$1|muudatus|muudatust}}",
        "enhancedrc-since-last-visit": "$1 {{PLURAL:$1|viimase vaatamise järel}}",
        "enhancedrc-history": "ajalugu",
        "unusedtemplates": "Kasutamata mallid",
        "unusedtemplatestext": "See lehekülg loetleb kõik leheküljed nimeruumis {{ns:template}}, mida teistel lehekülgedel ei kasutata.\nEnne kustutamist kontrolli ka muid malli juurde viitavaid linke.",
        "unusedtemplateswlh": "teised lingid",
-       "randompage": "Juhuslik artikkel",
+       "randompage": "Juhuslik lehekülg",
        "randompage-nopages": "{{PLURAL:$2|Järgmises nimeruumis|Järgmistes nimeruumides}} ei ole ühtegi lehekülge: $1.",
        "randomincategory": "Juhuslik lehekülg kategoorias",
        "randomincategory-invalidcategory": "\"$1\" pole sobiv kategooria nimi.",
        "movepage-moved": "'''\"$1\" teisaldatud pealkirja \"$2\" alla'''",
        "movepage-moved-redirect": "Ümbersuunamisleht loodud.",
        "movepage-moved-noredirect": "Ümbersuunamist ei loodud.",
-       "articleexists": "Selle nimega artikkel on juba olemas või pole valitud nimi lubatav. Palun valige uus nimi.",
+       "articleexists": "Sellise pealkirjaga lehekülg on juba olemas või pole valitud pealkiri lubatav.\nPalun vali teistsugune pealkiri.",
        "cantmove-titleprotected": "Lehte ei saa sinna teisaldada, sest uus pealkiri on artikli loomise eest kaitstud",
        "movetalk": "Teisalda seonduv arutelulehekülg",
        "move-subpages": "Teisalda alamleheküljed (kuni $1)",
        "tags-tag": "Märgise nimi",
        "tags-display-header": "Tähistus muudatusloendis",
        "tags-description-header": "Täiskirjeldus",
+       "tags-source-header": "Allikas",
        "tags-active-header": "Aktiivne?",
        "tags-hitcount-header": "Märgistatud muudatused",
+       "tags-actions-header": "Toimingud",
        "tags-active-yes": "Jah",
        "tags-active-no": "Ei",
+       "tags-source-extension": "Määratletud tarkvaralisas",
+       "tags-source-manual": "Kasutaja või robot rakendab käsitsi",
+       "tags-source-none": "Pole enam kasutuses",
        "tags-edit": "muuda",
+       "tags-delete": "kustuta",
+       "tags-activate": "luba",
+       "tags-deactivate": "keela",
        "tags-hitcount": "$1 {{PLURAL:$1|muudatus|muudatust}}",
+       "tags-manage-no-permission": "Sul pole õigust muudatusmärgiseid hallata.",
+       "tags-create-heading": "Uue märgise koostamine",
+       "tags-create-explanation": "Vaikimisi on vastkoostatud märgised kasutajate ja robotite jaoks kasutatavad.",
+       "tags-create-tag-name": "Märgise nimi:",
+       "tags-create-reason": "Põhjus:",
+       "tags-create-submit": "Koosta",
+       "tags-create-no-name": "Pead määrama märgise nime.",
+       "tags-create-invalid-chars": "Märgise nimi ei tohi sisaldada koma (<code>,</code>) ega kaldkriipsu (<code>/</code>).",
+       "tags-create-invalid-title-chars": "Märgise nimi ei tohi sisaldada märki, mida ei saa kasutada lehekülje pealkirjas.",
+       "tags-create-already-exists": "Märgis \"$1\" on juba olemas.",
+       "tags-create-warnings-above": "Prooviti koostada märgist \"$1\". Sellega seoses väljastati \"{{PLURAL:$2|järgmine hoiatus|järgmised hoiatused}}:",
+       "tags-create-warnings-below": "Kas soovid märgise koostamisega jätkata?",
+       "tags-delete-title": "Märgise kustutamine",
+       "tags-delete-explanation-initial": "Oled kustutamas märgist \"$1\" andmebaasist.",
+       "tags-delete-explanation-in-use": "See eemaldatakse {{PLURAL:$2|ühelt redaktsioonilt või|kõigilt $2 redaktsioonilt ja/või}} logisissekandelt, mille juures seda on praegu rakendatud.",
+       "tags-delete-explanation-warning": "Seda toimingut <strong>ei saa tagasi pöörata</strong> isegi mitte andmebaasi administraator. Veendu, et tegu on märgisega, mida kustutada tahad.",
+       "tags-delete-explanation-active": "<strong>Märgis \"$1\" on endiselt aktiivne ja seda rakendatakse edaspidi.</strong> Et nii poleks, mine kohtadesse, kust märgist rakendatakse, ja keela märgis seal.",
+       "tags-delete-reason": "Põhjus:",
+       "tags-delete-submit": "Kustuta märgis pöördumatult",
+       "tags-delete-not-allowed": "Tarkvaralisas määratletud märgiseid ei saa kustutada, kui märgis on tarkvaralisas eraldi lubatud.",
+       "tags-delete-not-found": "Märgist \"$1\" pole.",
+       "tags-delete-too-many-uses": "Märgist \"$1\" on rakendatud rohkem kui {{PLURAL:$2|ühe|$2}} redaktsiooni juures, mistõttu ei saa seda kustutada.",
+       "tags-delete-warnings-after-delete": "Märgis \"$1\" on edukalt kustutatud, kuid väljastati {{PLURAL:$2|järgmine hoiatus|järgmised hoiatused}}:",
+       "tags-activate-title": "Märgise lubamine",
+       "tags-activate-question": "Siinkohal lubad märgise \"$1\".",
+       "tags-activate-reason": "Põhjus:",
+       "tags-activate-not-allowed": "Märgist \"$1\" pole võimalik lubada.",
+       "tags-activate-not-found": "Märgist \"$1\" pole.",
+       "tags-activate-submit": "Luba",
+       "tags-deactivate-title": "Märgise keelamine",
+       "tags-deactivate-question": "Siinkohal keelad märgise \"$1\".",
+       "tags-deactivate-reason": "Põhjus:",
+       "tags-deactivate-not-allowed": "Märgist \"$1\" pole võimalik keelata.",
+       "tags-deactivate-submit": "Keela",
        "comparepages": "Lehekülgede kõrvutamine",
        "compare-page1": "Lehekülg 1",
        "compare-page2": "Lehekülg 2",
        "logentry-upload-upload": "$1 {{GENDER:$2|laadis üles}} faili $3",
        "logentry-upload-overwrite": "$1 {{GENDER:$2|laadis üles}} uue versiooni failist $3",
        "logentry-upload-revert": "$1 {{GENDER:$2|laadis üles}} faili $3",
+       "log-name-managetags": "Märgiste haldamise logi",
+       "log-description-managetags": "Sellel leheküljel on toodud [[Special:Tags|märgiste]] haldamisega seotud tegevused. Logis on ainult toimingud, mida administraatorid on teinud käsitsi. Siin puuduvad logisissekanded viki tarkvaras koostatud või sealt kustutatud märgiste kohta.",
+       "logentry-managetags-create": "$1 {{GENDER:$2|koostas}} märgise \"$4\"",
+       "logentry-managetags-delete": "$1 {{GENDER:$2|kustutas}} märgise \"$4\" (eemaldatud {{PLURAL:$5|ühe redaktsiooni või|$5 redaktsiooni ja/või}} logisissekande juurest)",
+       "logentry-managetags-activate": "$1 {{GENDER:$2|lubas}} märgise \"$4\" kasutamise kasutajate ja robotite jaoks",
+       "logentry-managetags-deactivate": "$1 {{GENDER:$2|keelas}} märgise \"$4\" kasutamise kasutajate ja robotite jaoks",
        "rightsnone": "(puudub)",
        "revdelete-summary": "resümee",
        "feedback-bugornote": "Kui arvad, et oskad tehnilist probleemi üksikasjalikult kirjeldada, [$1 teata veast].\nKui ei, kasuta allolevat lihtsat vormi. Sinu kommentaar lisatakse koos kasutajanime ja teabega kasutatava võrgulehitsejaga kohta leheküljele \"[$3 $2]\".",
index d3ce6f4..74baa82 100644 (file)
        "tags-active-no": "Ez",
        "tags-edit": "aldatu",
        "tags-hitcount": "$1 {{PLURAL:$1|aldaketa|aldaketa}}",
+       "tags-create-submit": "Sortu",
        "comparepages": "Orrialdeak alderatu",
        "compare-page1": "1. orrialdea",
        "compare-page2": "2. orrialdea",
index b3bf38c..862c6d9 100644 (file)
        "passwordremindertitle": "یادآور گذرواژهٔ {{SITENAME}}",
        "passwordremindertext": "یک نفر (احتمالاً خود شما، با نشانی آی‌پی $1) گذرواژهٔ جدیدی برای حساب کاربری شما در {{SITENAME}} درخواست کرده‌است ($4). \nیک گذرواژهٔ موقت برای کاربر «$2» ساخته شده و برابر با «$3» قرار داده شده‌است.\nاگر هدفتان همین بوده‌است، اکنون باید وارد سامانه شوید و گذرواژهٔ جدیدی برگزینید.\nگذرواژهٔ موقت شما ظرف {{PLURAL:$5|یک روز|$5 روز}} باطل می‌شود.\n\nاگر کس دیگری این درخواست را کرده‌است یا اینکه شما گذرواژهٔ پیشین خود را به یاد آورده‌اید و دیگر تمایلی به تغییر آن ندارید، می‌توانید این پیغام را نادیده بگیرید و همان گذرواژهٔ پیشین را به کار برید.",
        "noemail": "هیچ نشانی رایانامه‌ای برای کاربر «$1» ثبت نشده‌است.",
-       "noemailcreate": "باÛ\8cد Û\8cÚ© Ù\86شاÙ\86Û\8c Ø±Ø§Û\8cاÙ\86اÙ\85Ù\87 Ù\85عتبر Ù\88ارد کنید",
+       "noemailcreate": "Ø´Ù\85ا Ø¨Ø§Û\8cد Û\8cÚ© Ù\86شاÙ\86Û\8c Ù¾Ø³Øª Ø§Ù\84کترÙ\88Ù\86Û\8cÚ©Û\8c Ø¯Ø±Ø³Øª Ù\81راÙ\87Ù\85 کنید",
        "passwordsent": "گذرواژه‌ای جدید به نشانی رایانامه ثبت‌شده برای «$1» فرستاده شد.\nلطفاً پس از دریافت آن دوباره به سامانه وارد شوید.",
        "blocked-mailpassword": "نشانی آی‌پی شما از ویرایش بازداشته شده‌است و از این رو به منظور جلوگیری از سوءاستفاده اجازهٔ بهره‌گیری از قابلیت بازیابی گذرواژه را ندارد.",
        "eauthentsent": "یک نامه برای تأیید نشانی رایانامه به نشانی موردنظر ارسال شد.\nقبل از اینکه نامهٔ دیگری قابل ارسال به این نشانی باشد، باید دستورهایی که در آن نامه آمده است را جهت تأیید این مساله که این نشانی متعلق به شماست، اجرا کنید.",
        "emailconfirmlink": "تأیید نشانی رایانامه",
        "invalidemailaddress": "نشانی واردشدهٔ رایانامه قابل‌قبول نیست، چرا که دارای ساختار نامعتبری است.\nلطفاً نشانی‌ای با ساختار صحیح وارد کنید و یا بخش مربوط را خالی بگذارید.",
        "cannotchangeemail": "نشانی‌های رایانامهٔ حساب کاربری در این ویکی قابل تغییر نیست.",
-       "emaildisabled": "این وب‌گاه قادر به ارسال رایانامه نیست.",
+       "emaildisabled": "این وب سایت قادر به فرستادن پست الکترونیکی نیست.",
        "accountcreated": "حساب کاربری ایجاد شد",
        "accountcreatedtext": "حساب کاربری برای [[{{ns:User}}:$1|$1]] ([[{{ns:User talk}}:$1|بحث]]) ایجاد شده است.",
        "createaccount-title": "ایجاد حساب کاربری در {{SITENAME}}",
        "passwordreset-domain": "دامنه:",
        "passwordreset-capture": "رایانامهٔ نهایی نشان داده شود؟",
        "passwordreset-capture-help": "اگر این گزینه را علامت بزنید رایانامهٔ (حاوی گذرواژهٔ موقت) به شما نشان داده خواهد شد و برای کاربر نیز فرستاده خواهد شد.",
-       "passwordreset-email": "نشانی رایانامه:",
+       "passwordreset-email": "نشانی پست الکترونیکی:",
        "passwordreset-emailtitle": "جزئیات حساب در {{SITENAME}}",
        "passwordreset-emailtext-ip": "یک نفر (احتمالاً شما، با نشانی آی‌پی $1) درخواست بازنشانی گذرواژه‌تان در {{SITENAME}} ($4) را کرده‌است. {{PLURAL:$3|حساب|حساب‌های}} کاربری زیر با این رایانشانی مرتبط هستند:\n\n$2\n\n{{PLURAL:$3|این گذرواژهٔ موقت|این گذرواژه‌های موقت}} پس از {{PLURAL:$5|یک روز|$5 روز}} باطل خواهند شد.\nشما باید هم‌اکنون ثبت ورود کنید و گذرواژه‌ای جدید برگزینید. اگر فکر می‌کنید شخص دیگری این درخواست را داده‌است یا اگر گذرواژهٔ اصلی‌تان را به یاد آوردید و دیگر نمی‌خواهید آن را تغییر دهید، می‌توانید این پیغام را نادیده بگیرید و به استفاده از گذرواژهٔ قبلی‌تان ادامه دهید.",
        "passwordreset-emailtext-user": "کاربر $1 از {{SITENAME}} درخواست بازنشانی گذرواژهٔ شما در {{SITENAME}} ($4) را کرده است. {{PLURAL:$3|حساب|حساب‌های}} کاربری زیر با این رایانشانی مرتبط است:\n\n$2\n\n{{PLURAL:$3|این گذرواژهٔ موقت|این گذرواژه‌های موقت}} تا {{PLURAL:$5|یک روز|$5 روز}} باطل می‌شود.\nشما باید هم‌اکنون وارد شده و یک گذرواژهٔ جدید برگزینید. اگر شخص دیگری این درخواست را داده است، یا اگر گذرواژهٔ اصلی‌تان را به خاطر آوردید و دیگر نمی‌خواهید آن را تغییر دهید، می‌توانید این پیغام را نادیده بگیرید و به استفاده از گذرواژهٔ قبلی‌تان ادامه دهید.",
        "passwordreset-emailsent": "یک نامهٔ بازنشانی گذرواژه فرستاده شده‌است.",
        "passwordreset-emailsent-capture": "یک رایانامهٔ بازنشانی که در پایین نمایش داده شده، فرستاده شده است.",
        "passwordreset-emailerror-capture": "رایانامهٔ بازنشانی، که در زیر نمایش داده شده، ایجاد شد، ولی ارسال آن به {{GENDER:$2|کاربر}} موفقیت‌آمیز نبود: $1",
-       "changeemail": "تغÛ\8cÛ\8cر Ù\86شاÙ\86Û\8c Ø±Ø§Û\8cاÙ\86اÙ\85Ù\87",
+       "changeemail": "دگرش Ø¯Ø± Ù\86شاÙ\86Û\8c Ù¾Ø³Øª Ø§Ù\84کترÙ\88Ù\86Û\8cÚ©Û\8c",
        "changeemail-text": "این فرم را تکمیل کنید تا آدرس رایانامه‌تان تغییر یابد. برای این که این تغییر را تأیید کنید لازم است گذرواژهٔ خود را وارد کنید.",
        "changeemail-no-info": "برای دسترسی مستقیم به این صفحه شما باید به سامانه وارد شده باشید.",
        "changeemail-oldemail": "نشانی رایانامهٔ کنونی:",
        "search-external": "جستجوی خارجی",
        "searchdisabled": "جستجو در {{SITENAME}} فعال نیست.\nموقتاً می‌توانید از جستجوی Google استفاده کنید.\nتوجه کنید که نتایج حاصل از جستجو با آن روش ممکن است به‌روز نباشند.",
        "search-error": "خطایی هنگام جست‌وجو رخ داده است: $1",
-       "preferences": "ترجیح‌ها",
-       "mypreferences": "ترجیح‌ها",
+       "preferences": "ترجیحات",
+       "mypreferences": "ترجیحات",
        "prefs-edits": "تعداد ویرایش‌ها:",
        "prefsnologintext2": "خواهشمند است برای تغییر تنظیمات‌تان وارد شوید.",
        "prefs-skin": "پوسته",
        "prefs-watchlist-token": "رمز فهرست پی‌گیری:",
        "prefs-misc": "متفرقه",
        "prefs-resetpass": "تغییر گذرواژه",
-       "prefs-changeemail": "تغÛ\8cÛ\8cر Ø±Ø§Û\8cاÙ\86اÙ\85Ù\87",
-       "prefs-setemail": "تنظیم نشانی رایانامه",
-       "prefs-email": "گزینه‌های رایانامه",
+       "prefs-changeemail": "دگرش Ø¯Ø± Ù\86شاÙ\86Û\8c Ù¾Ø³Øª Ø§Ù\84کترÙ\88Ù\86Û\8cÚ©Û\8c",
+       "prefs-setemail": "کار گذاشتن نشانی پست الکترونیکی",
+       "prefs-email": "گزینه‌های پست الکترونیکی",
        "prefs-rendering": "نمایش صفحه",
        "saveprefs": "ذخیره",
        "restoreprefs": "برگرداندن تمام تنظیمات پیش‌فرض (در تمامی قسمت‌ها)",
        "timezoneregion-europe": "اروپا",
        "timezoneregion-indian": "اقیانوس هند",
        "timezoneregion-pacific": "اقیانوس آرام",
-       "allowemail": "اÙ\85کاÙ\86 Ø¯Ø±Û\8cاÙ\81ت Ø±Ø§Û\8cاÙ\86اÙ\85Ù\87 Ø§Ø² Ø¯Û\8cگر Ú©Ø§Ø±Ø¨Ø±Ø§Ù\86",
+       "allowemail": "بÙ\87 Ú©Ø§Ø± Ø§Ù\86داختÙ\86 Ø¯Ø±Û\8cاÙ\81ت Ù¾Ø³Øª Ø§Ù\84کترÙ\88Ù\86Û\8cÚ©Û\8c Ø§Ø² Ø¯Û\8cگر Ú©Ø§Ø±Ø¨Ø±Ù\87ا",
        "prefs-searchoptions": "جستجو",
        "prefs-namespaces": "فضاهای نام",
        "default": "پیش‌فرض",
        "prefs-common-css-js": "سی‌اس‌اس/جاوااسکریپت مشترک برای تمام پوسته‌ها:",
        "prefs-reset-intro": "شما می‌توانید از این صفحه برای بازگرداندن تنظیمات خود به پیش‌فرض تارنما استفاده کنید.\nاین کار بازگشت‌ناپذیر است.",
        "prefs-emailconfirm-label": "تأیید رایانامه:",
-       "youremail": "رایانامه:",
+       "youremail": "پست الکترونیکی:",
        "username": "{{GENDER:$1|نام کاربری}}:",
        "prefs-memberingroups": "{{GENDER:$2|عضو}} {{PLURAL:$1|گروه|گروه}}:",
        "prefs-registration": "زمان ثبت‌نام:",
        "prefs-help-realname": "نام واقعی اختیاری است.\nاگر وارد شده است هنگام ارجاع به آثارتان و انتساب آن‌ها به شما ممکن است از نام واقعی‌تان استفاده شود.",
        "prefs-help-email": "نشانی رایانامه اختیاری‌است، اما فرستادن گذرواژه‌ای جدید را اگر گذرواژهٔ خود را فراموش کنید ممکن می‌کند.",
        "prefs-help-email-others": "شما همچنین می‌توانید انتخاب کنید که کاربران بتوانند از طریق پیوندی در صفحهٔ کاربری یا صفحهٔ بحث کاربری‌تان به شما رایانامه بفرستند.\nنشانی رایانامه شما زمانی که دیگران با شما تماس بگیرند فاش نمی‌شود.",
-       "prefs-help-email-required": "نشانی رایانامه الزامی‌است.",
+       "prefs-help-email-required": "نشانی پست الکترونیکی نیاز است.",
        "prefs-info": "اطلاعات اولیه",
        "prefs-i18n": "بین‌المللی‌سازی",
        "prefs-signature": "امضا",
        "mailnologin": "نشانی‌ای از فرستنده موجود نیست",
        "mailnologintext": "برای فرستادن پست الکترونیکی به کاربران دیگر باید [[Special:UserLogin|به سیستم وارد شوید]] و نشانی پست الکترونیکی معتبری در [[Special:Preferences|ترجیح‌های]] خود داشته باشید.",
        "emailuser": "پست الکترونیکی",
-       "emailuser-title-target": "رایانامه به {{GENDER:$1|کاربر}}",
-       "emailuser-title-notarget": "رایانامه به کاربر",
-       "emailpage": "رایانامه به کاربر",
+       "emailuser-title-target": "فرستادن پست الکترونیکی به {{GENDER:$1|کاربر}}",
+       "emailuser-title-notarget": "فرستادن پست الکترونیکی به کاربر",
+       "emailpage": "فرستادن پست الکترونیکی به کاربر",
        "emailpagetext": "شما می‌توانید از فرم زیر برای ارسال یک رایانامه به این {{GENDER:$1|کاربر}} استفاده کنید.\nنشانی رایانامه‌ای که در [[Special:Preferences|ترجیحات کاربریتان]] وارد کرده‌اید در نشانی فرستنده (From) نامه خواهد آمد، تا گیرنده بتواند پاسخ دهد.",
        "defemailsubject": "پست الکترونیکی {{SITENAME}} از طرف کاربر «$1»",
        "usermaildisabled": "رایانامهٔ کاربر غیرقعال است",
        "emailsend": "بفرست",
        "emailccme": "رونوشت پیغام را برایم بفرست.",
        "emailccsubject": "رونوشت پیغام شما به $1: $2",
-       "emailsent": "رایانامه فرستاده شد",
-       "emailsenttext": "Ù¾Û\8cغاÙ\85 Ø±Ø§Û\8cاÙ\86اÙ\85Ù\87 شما فرستاده شد.",
+       "emailsent": "پست الکترونیکی فرستاده شد",
+       "emailsenttext": "Ù¾Û\8cاÙ\85 Ù¾Ø³Øª Ø§Ù\84کترÙ\88Ù\86Û\8cÚ©Û\8c شما فرستاده شد.",
        "emailuserfooter": "این پست الکترونیکی با استفاده از ویژگی «پست الکترونیکی» {{SITENAME}} توسط $1 به $2 فرستاده شد.",
        "usermessage-summary": "گذاشتن پیغام سامانه.",
        "usermessage-editor": "پیغام رسان سامانه",
        "ipbreason-dropdown": "*دلایل متداول قطع دسترسی\n**واردکردن اطلاعات نادرست\n**پاک‌کردن اطلاعات مفید از صفحات\n**هرزنگاری از طریق درج مکرر پیوند به وب‌گاه‌ها\n**درج چرندیات یا نوشته‌های بی‌معنا در صفحات\n**تهدید یا ارعاب دیگر کاربران\n**سوء استفاده از چند حساب کاربری\n**نام کاربری نامناسب",
        "ipb-hardblock": "جلوگیری از ویرایش کردن کاربران ثبت نام کرده از طریق این نشانی آی‌پی",
        "ipbcreateaccount": "جلوگیری از ایجاد حساب",
-       "ipbemailban": "جلوگیری از ارسال رایانامه",
+       "ipbemailban": "جلوگیری از فرستادن پست الکترونیکی",
        "ipbenableautoblock": "بستن  خودکار آخرین نشانی آی‌پی استفاده شده توسط کاربر و نشانی‌های دیگری که از آن‌ها برای ویرایش تلاش می‌کند",
        "ipbsubmit": "این کاربر بسته شود",
        "ipbother": "زمانی دیگر",
        "anononlyblock": "فقط کاربران گمنام",
        "noautoblockblock": "بستن خودکار غیرفعال است",
        "createaccountblock": "امکان ایجاد حساب مسدود است",
-       "emailblock": "رایانامه مسدود شد",
+       "emailblock": "پست الکترونیکی از کار انداخته شد",
        "blocklist-nousertalk": "نمی تواند صفحهٔ بحث خود را ویرایش کند",
        "ipblocklist-empty": "فهرست بسته‌شدن‌ها خالی‌است.",
        "ipblocklist-no-results": "دسترسی حساب کاربری یا نشانی آی‌پی مورد نظر قطع نیست.",
        "unblocklink": "باز شود",
        "change-blocklink": "تغییر قطع دسترسی",
        "contribslink": "مشارکت‌ها",
-       "emaillink": "ارسال رایانامه",
+       "emaillink": "فرستادن پست الکترونیکی",
        "autoblocker": "به طور خودکار بسته شد چون آی‌پی شما به تازگی توسط کاربر «[[User:$1|$1]]» استفاده شده‌است.\nدلیل قطع دسترسی $1 چنین است \"$2\"",
        "blocklogpage": "سیاههٔ بستن",
        "blocklog-showlog": "دسترسی این کاربر در گذشته بسته شده‌است.\nسیاههٔ قطع دسترسی در زیر نمایش یافته است:",
index 1a783fe..b0320db 100644 (file)
        "right-override-export-depth": "Viedä sivuja sisältäen viitatut sivut viiden syvyydellä",
        "right-sendemail": "Lähettää sähköpostia muille käyttäjille",
        "right-passwordreset": "Tarkastella salasanan alustusviestejä",
+       "right-managechangetags": "Luoda ja poistaa [[Special:Tags|merkintöjä]] tietokannasta",
        "newuserlogpage": "Uudet käyttäjät",
        "newuserlogpagetext": "Tämä on loki luoduista käyttäjätunnuksista.",
        "rightslog": "Käyttöoikeusloki",
        "action-viewmyprivateinfo": "katsoa omia yksityisiä tietojasi",
        "action-editmyprivateinfo": "muokata omia yksityisiä tietojasi",
        "action-editcontentmodel": "muokata sivun sisältömallia",
+       "action-managechangetags": "luoda ja poistaa merkintöjä tietokannasta",
        "nchanges": "$1 {{PLURAL:$1|muutos|muutosta}}",
        "enhancedrc-since-last-visit": "$1 {{PLURAL:$1|viimeisen käynnin jälkeen}}",
        "enhancedrc-history": "historia",
        "delete-confirm": "Poista ”$1”",
        "delete-legend": "Sivun poisto",
        "historywarning": "<strong>Varoitus:</strong> Sivulla, jota olet poistamassa, on muokkaushistoriaa ja sitä on muokattu $1 {{PLURAL:$1|kerran|kertaa}}:",
-       "confirmdeletetext": "Olet poistamassa sivun tai tiedoston ja kaiken sen historian. Ymmärrä teon seuraukset ja tee poisto {{GRAMMAR:genitive|{{SITENAME}}}} [[{{MediaWiki:Policy-url}}|käytäntöjen]] mukaisesti.",
+       "confirmdeletetext": "Olet poistamassa sivun ja kaiken sen historian.\nVahvista, että olet aikeissa tehdä tämän, ja että ymmärrät sen seuraukset, sekä teet poiston [[{{MediaWiki:Policy-url}}|käytäntöjen]] mukaisesti.",
        "actioncomplete": "Toiminto suoritettu",
        "actionfailed": "Toiminto epäonnistui",
        "deletedtext": "”$1” on poistettu.\nSivulla $2 on lista viimeaikaisista poistoista.",
        "tags-tag": "Merkinnän nimi",
        "tags-display-header": "Näkyvyys muutosluetteloissa",
        "tags-description-header": "Täysi kuvaus tarkoituksesta",
+       "tags-source-header": "Lähde",
        "tags-active-header": "Aktiivinen?",
        "tags-hitcount-header": "Merkityt muutokset",
+       "tags-actions-header": "Toiminnot",
        "tags-active-yes": "Kyllä",
        "tags-active-no": "Ei",
+       "tags-source-none": "Ei enää käytössä",
        "tags-edit": "muokkaa",
+       "tags-delete": "poista",
+       "tags-activate": "aktivoi",
+       "tags-deactivate": "poista käytöstä",
        "tags-hitcount": "$1 {{PLURAL:$1|muutos|muutosta}}",
+       "tags-manage-no-permission": "Sinulla ei ole oikeuksia hallinnoida merkintöjä.",
+       "tags-create-heading": "Luo uusi merkintä",
+       "tags-create-tag-name": "Merkinnän nimi:",
+       "tags-create-reason": "Syy:",
+       "tags-create-submit": "Luo",
+       "tags-create-no-name": "Sinun täytyy antaa nimi merkinnälle.",
+       "tags-delete-title": "Poista merkintä",
+       "tags-delete-reason": "Syy:",
+       "tags-delete-not-found": "Merkintää \"$1\" ei ole olemassa.",
+       "tags-activate-title": "Aktivoi merkintä",
+       "tags-activate-question": "Olet aikeissa aktivoida merkinnän \"$1\".",
+       "tags-activate-reason": "Syy:",
+       "tags-activate-not-allowed": "Ei ole mahdollista aktivoida merkintää \"$1\".",
+       "tags-activate-not-found": "Merkintää \"$1\" ei ole olemassa.",
+       "tags-activate-submit": "Aktivoi",
+       "tags-deactivate-title": "Poista merkintä käytöstä",
+       "tags-deactivate-question": "Olet aikeissa poistaa käytöstä merkinnän \"$1\".",
+       "tags-deactivate-reason": "Syy:",
+       "tags-deactivate-not-allowed": "Ei ole mahdollista poistaa käytöstä merkintää \"$1\".",
+       "tags-deactivate-submit": "Poista käytöstä",
        "comparepages": "Vertaile sivuja",
        "compare-page1": "Sivu 1",
        "compare-page2": "Sivu 2",
index 86d0d12..014f1e6 100644 (file)
@@ -35,7 +35,7 @@
        "tog-shownumberswatching": "Taal faan brükern uunwise, diar det sidj uun't uug haa",
        "tog-oldsig": "Aktuel signatuur:",
        "tog-fancysig": "Signatuur üs wikitekst uunsä (saner ferwisangen)",
-       "tog-uselivepreview": "Live-föörskau funktjuun brük (eksperimentel)",
+       "tog-uselivepreview": "Live-föörskau funktjuun brük",
        "tog-forceeditsummary": "Wäärne, wan bi't seekrin nian tuupfaadang uunden woort",
        "tog-watchlisthideown": "Aanj feranrangen bi a sidjen, diar ik uun't uug behual wal, fersteeg",
        "tog-watchlisthidebots": "Feranrangen faan bots bi a sidjen, diar ik uun't uug behual wal, fersteeg",
        "pool-queuefull": "Pool as auerläästet",
        "pool-errorunknown": "Ünbekäänd feeler",
        "pool-servererror": "Di pooltäälersiinst werket ei ($1).",
+       "poolcounter-usage-error": "Feeler bi't bewerkin: $1",
        "aboutsite": "Auer {{SITENAME}}",
        "aboutpage": "Project:Auer",
        "copyright": "Det sidj as tu fun oner $1 , wan diar niks ööders stäänt.",
        "anoneditwarning": "'''Paase üüb:''' Dü beest ei uunmeldet. Din aktuel IP-adres komt tu sen, wan dü feranrangen föörnamst. Wan dü di <strong>[$1 uunmeldest]</strong> of <strong>[$2 en konto iinrachtst]</strong>, wurd din feranrangen mä dan brükernööm ferbünjen, tuup mä ööder föördialen.",
        "anonpreviewwarning": "\"Dü beest ei uunmeldet. Bi't seekrin woort din IP-adres uun a ferluup faan werjuunen aptiakent.\"",
        "missingsummary": "'''Paase üüb:''' Dü heest det ei tuupfaadet.\nWan dü det sidj seekerst, woort det saner en kurtfaadet beskriiwang auernimen.",
+       "selfredirect": "<strong>Paase üüb:</strong> Dü feerst detheer sidj tu detsalew sidj widjer.\nDü heest was det ferkiard mual uunden, of dü bewerkest det ferkiard sidj.\nWan dü noch ans üüb „{{int:savearticle}}“ trakst, woort det widjerfeerang likes iinracht.",
        "missingcommenttext": "Faade det oner tuup.",
        "missingcommentheader": "'''Paase üüb:''' Dü heest nian auerskraft uunden.\nWan dü det sidj seekerst, woort det saner auerskraft auernimen.",
        "summary-preview": "Föörskau faan det tuupfaadang:",
        "content-model-text": "normool tekst",
        "content-model-javascript": "JavaScript",
        "content-model-css": "CSS",
+       "content-json-empty-object": "Leesag objekt",
+       "content-json-empty-array": "Leesag array",
        "duplicate-args-category": "Sidjen, diar dobelt argumenten uun föörlaagen aprep.",
        "duplicate-args-category-desc": "Detdair sidj rept föörlaagen ap, diar dobelt argumenten brük, so üs <code><nowiki>{{foo|bar=1|bar=2}}</nowiki></code> of <code><nowiki>{{foo|bar|1=baz}}</nowiki></code>.",
        "expensive-parserfunction-warning": "'''Paase üüb:''' Detdiar sidj brükt tuföl widjloftag server-funktjuunen.\n\nDiar mut ei muar üs {{PLURAL:$2|1|$2}} brükt wurd. Nü {{PLURAL:$1|woort diar 1|wurd diar $1}} brükt.",
        "revdelete-legend": "Iinstelangen, hüföl tu sen wees skal",
        "revdelete-hide-text": "Tekst faan det werjuun",
        "revdelete-hide-image": "Fersteeg, wat uun det datei stäänt",
-       "revdelete-hide-name": "Logbuk-aktjuun fersteeg",
+       "revdelete-hide-name": "Mual an parameetern fersteeg",
        "revdelete-hide-comment": "Tuupfaadet beskriiwang",
        "revdelete-hide-user": "Brükernööm/IP-adres faan di brüker",
        "revdelete-hide-restricted": "Dooten uk för administratooren an öödern fersteeg",
        "prefs-personal": "Brüker dooten",
        "prefs-rc": "Leetst feranrangen",
        "prefs-watchlist": "Uun't uug behual",
+       "prefs-editwatchlist": "List mä sidjen, diar dü uun't uug behual wel, bewerke",
+       "prefs-editwatchlist-label": "Iindracher üüb det list mä sidjen, diar dü uun't uug behual wel, bewerke:",
+       "prefs-editwatchlist-edit": "Iindracher üüb det list mä sidjen, diar dü uun't uug behual wel, uunluke an strik",
+       "prefs-editwatchlist-raw": "Uun't listenformoot bewerke",
+       "prefs-editwatchlist-clear": "Nian sidjen muar uun't uug behual",
        "prefs-watchlist-days": "So föl daar uun't uug behual:",
        "prefs-watchlist-days-max": "Ei muar üs {{PLURAL:$1|ään dai|$1 daar}}",
        "prefs-watchlist-edits": "Ei muar feranrangen üs:",
        "uploaderror": "Bi't huuchschüüren as wat skiaf gingen",
        "upload-recreate-warning": "'''Paase üüb: En datei mä didiar nööm as al ans stregen of fersköwen wurden.'''\n\nWat nü komt, as ütj det logbuk för't striken an fersküüwen faan detdiar datei.",
        "uploadtext": "Brük detdiar formulaar, am nei datein huuchtuschüüren.\n\nGung tu det [[Special:FileList|list faan huuchschüürd datein]], am datein tu schüken of uuntuwisin. Luke uk iin uun't logbuk för't [[Special:Log/upload|huuchschüüren]] of [[Special:Log/delete|striken]] faan datein.\n\nAm en '''bil''' uun en artiikel tu brüken, brük en link faan det furem:\n* '''<code><nowiki>[[</nowiki>{{ns:file}}<nowiki>:Datei.jpg]]</nowiki></code>''' – för en grat bil\n* '''<code><nowiki>[[</nowiki>{{ns:file}}<nowiki>:Datei.png|200px|thumb|left|alternatiif tekst]]</nowiki></code>''' – för en 200px briad bil uun en box, mä „alternatiif tekst“ üs beskriiwang faan det bil\n*'''<code><nowiki>[[</nowiki>{{ns:media}}<nowiki>:Datei.ogg]]</nowiki></code>''' – för en direkt ferwisang üüb det datei, saner det datei uuntuwisin",
-       "upload-permitted": "Tuläät slacher faan datein: $1.",
-       "upload-preferred": "Slacher faan datein, diar dü brük skulst: $1.",
-       "upload-prohibited": "Ei tuläät slacher faan datein: $1.",
+       "upload-permitted": "Tuläät {{Plural:$2|slach|slacher}} faan datein: $1.",
+       "upload-preferred": "{{Plural:$2|Slach|Slacher}} faan datein, diar dü brük skulst: $1.",
+       "upload-prohibited": "Ei tuläät {{Plural:$2|slach|slacher}} faan datein: $1.",
        "uploadlogpage": "Datei-logbuk",
        "uploadlogpagetext": "Detheer as det logbuk för huuchschüürd datein. Dü könst uk det [[Special:NewFiles|galerii faan nei datein]] uunluke.",
        "filename": "Dateinööm",
        "deleteprotected": "Dü könst detdiar sidj ei strik, auer det seekert wurden as.",
        "deleting-backlinks-warning": "'''Paase üüb:''' Diar ferwise noch [[Special:WhatLinksHere/{{FULLPAGENAME}}|ööder sidjen]] üüb det sidj, diar dü strik wel. Of det sidj as noch huarööders iinbünjen.",
        "rollback": "Feranrangen turagsaat",
-       "rollback_short": "Turagsaat",
        "rollbacklink": "turagsaat",
        "rollbacklinkcount": "$1 {{PLURAL:$1|feranrang|feranrangen}} turagsaat",
        "rollbacklinkcount-morethan": "Muar üs $1 {{PLURAL:$1|werjuun|werjuunen}} turagsaat",
        "namespace": "Nöömrüm:",
        "invert": "Ütjwool amkiir",
        "tooltip-invert": "Saat diar en tiaken, am feranrangen faan sidjen uun didiar nöömrüm ei uuntuwisin.",
+       "tooltip-whatlinkshere-invert": "Saat diar en tiaken, am sidjen uun didiar nöömrüm ei uuntuwisin.",
        "namespace_association": "Ferbünjen nöömrüm",
        "tooltip-namespace_association": "Saat diar en tiaken, am di ferbünjen nöömrüm of diskusjuunsnöömrüm mä iintubetjin.",
        "blanknamespace": "(Sidjen)",
        "thumbnail-temp-create": "Det datei för det tidjwiis sümnaielbil küd ei skrewen wurd",
        "thumbnail-dest-create": "Det föörskaubil küd diar ei seekert wurd.",
        "thumbnail_invalid_params": "Sümnaieldooten steme ei",
+       "thumbnail_toobigimagearea": "Datei mä en grate faan muar üs $1",
        "thumbnail_dest_directory": "Det fertiaknis koon ei skrewen wurd.",
        "thumbnail_image-type": "Sok bilen kön ei brükt wurd",
        "thumbnail_gd-library": "GD-bibleteek ei gans diar: Det funktjuun $1 waant",
        "import-logentry-interwiki": "„$1“ mä transwiki importiaret",
        "import-logentry-interwiki-detail": "$1 {{PLURAL:$1|werjuun|werjuunen}} faan $2 importiaret",
        "javascripttest": "JavaScript-test",
-       "javascripttest-title": "$1-tests wurd ütjfeerd.",
        "javascripttest-pagetext-noframework": "Detdiar sidj as för JavaScript-tests föörsen.",
        "javascripttest-pagetext-unknownframework": "Ünbekäänd test-framework „$1“.",
+       "javascripttest-pagetext-unknownaction": "Ünbekäänd aktjuun „$1“.",
        "javascripttest-pagetext-frameworks": "Schük ian faan jodiar test-frameworks ütj: $1",
        "javascripttest-pagetext-skins": "Schük en brüker-skak ütj, am di test ütjtufeeren:",
        "javascripttest-qunit-intro": "Luke efter bi [$1 test dokumentatjuun] üüb mediawiki.org",
-       "javascripttest-qunit-heading": "JavaScript-QUnit-tester faan MediaWiki",
        "tooltip-pt-userpage": "Din brükersidj",
        "tooltip-pt-anonuserpage": "Brükersidj faan det IP-adres, faan huar ütj dü werkest",
        "tooltip-pt-mytalk": "Din diskusjuunssidj",
        "version-entrypoints": "URLs faan hüsdörsidjen",
        "version-entrypoints-header-entrypoint": "Hüsdörsidj",
        "version-entrypoints-header-url": "URL",
+       "version-libraries": "Instaliaret bibleteeken",
+       "version-libraries-library": "Bibleteek",
+       "version-libraries-version": "Werjuun",
        "redirect": "Widjerfeerang faan en brüker, en sidj, en sidjenwerjuun of en datei.",
        "redirect-legend": "Widjerfeerang üüb en sidjenwerjuun of datei.",
        "redirect-summary": "Detdiar spezial-sidj feert widjer üüb en brükersidj, sidj, sidjenwerjuun of datei.\nAn det woort so brükt:  [[{{#Special:Redirect}}/user/101]], [[{{#Special:Redirect}}/page/64308]], [[{{#Special:Redirect}}/revision/328429]] of [[{{#Special:Redirect}}/file/Example.jpg]].",
        "compare-revision-not-exists": "Son werjuun as diar ei.",
        "dberr-problems": "Dää mi iarag! Det sidj hää technisk komer.",
        "dberr-again": "Teew en uugenblak an ferschük det noch ans.",
-       "dberr-info": "(Koon ei mä a dootenbeenk-server ferbinj: $1)",
-       "dberr-info-hidden": "(Ferbinjang mä a dootenbeenk-server as skiaf gingen)",
+       "dberr-info": "(Koon ei üüb det dootenbeenk tugrip: $1)",
+       "dberr-info-hidden": "(Üüb det dootenbeenk küd ei tugreben wurd)",
        "dberr-usegoogle": "Uun a teskentidj küdst dü det mä Google ferschük.",
        "dberr-outofdate": "Seenk diaram, dat Google ferlicht ual dooten uunwiset.",
        "dberr-cachederror": "Detheer komt ütj en cache an as ferlicht ei muar aktuel.",
index e82b700..8096ff6 100644 (file)
                        "לערי ריינהארט",
                        "Fitoschido",
                        "McDutchie",
-                       "Josep Maria 15."
+                       "Josep Maria 15.",
+                       "Fisterraeomar",
+                       "Breogan2008",
+                       "VaiPolaSombra"
                ]
        },
        "tog-underline": "Subliñar as ligazóns:",
@@ -27,7 +30,7 @@
        "tog-usenewrc": "Agrupar as modificacións por páxina nos cambios recentes e na lista de vixilancia",
        "tog-numberheadings": "Numerar automaticamente as cabeceiras",
        "tog-showtoolbar": "Mostrar a barra de ferramentas de edición",
-       "tog-editondblclick": "Editar as páxinas logo de facer dobre clic",
+       "tog-editondblclick": "Facer dobre clic para editar as páxinas",
        "tog-editsectiononrightclick": "Permitir a edición de seccións premendo co botón dereito nos títulos das seccións",
        "tog-watchcreations": "Engadir as páxinas que cree e os ficheiros que cargue á miña lista de vixilancia",
        "tog-watchdefault": "Engadir as páxinas e os ficheiros que edite á miña lista de vixilancia",
@@ -37,8 +40,8 @@
        "tog-minordefault": "Marcar todas as edicións como pequenas por defecto",
        "tog-previewontop": "Mostrar a vista previa antes da caixa de edición",
        "tog-previewonfirst": "Mostrar a vista previa na primeira edición",
-       "tog-enotifwatchlistpages": "Enviádeme unha mensaxe de correo electrónico cando unha páxina ou un ficheiro da miña lista de vixilancia sufra un cambio",
-       "tog-enotifusertalkpages": "Enviádeme unha mensaxe de correo electrónico cando a miña páxina de conversa cambie",
+       "tog-enotifwatchlistpages": "Desexo recibir un aviso por correo electrónico cando unha páxina ou un ficheiro da miña lista de vixilancia sufra algún cambio",
+       "tog-enotifusertalkpages": "Desexo recibir un aviso por correo electrónico cando a miña páxina de conversa cambie",
        "tog-enotifminoredits": "Enviádeme tamén unha mensaxe de correo electrónico cando se produzan edicións pequenas nas páxinas ou nos ficheiros",
        "tog-enotifrevealaddr": "Revelar o meu enderezo de correo electrónico nos correos de notificación",
        "tog-shownumberswatching": "Mostrar o número de usuarios que están a vixiar",
        "right-override-export-depth": "Exportar páxinas incluíndo as páxinas ligadas ata unha profundidade de 5",
        "right-sendemail": "Enviar correos electrónicos a outros usuarios",
        "right-passwordreset": "Ver os correos electrónicos de restablecemento de contrasinais",
+       "right-managechangetags": "Crear e borrar [[Special:Tags|tags]] da base de datos",
        "newuserlogpage": "Rexistro de creación de usuarios",
        "newuserlogpagetext": "Este é un rexistro de creación de contas de usuario.",
        "rightslog": "Rexistro de dereitos de usuario",
        "action-viewmyprivateinfo": "ver a súa información privada",
        "action-editmyprivateinfo": "editar a súa información privada",
        "action-editcontentmodel": "editar o modelo de contido dunha páxina",
+       "action-managechangetags": "crear e borrar etiquetas da base de datos",
        "nchanges": "$1 {{PLURAL:$1|modificación|modificacións}}",
        "enhancedrc-since-last-visit": "$1 {{PLURAL:$1|desde a última visita}}",
        "enhancedrc-history": "historial",
        "tags-tag": "Nome da etiqueta",
        "tags-display-header": "Aparición nas listas de cambios",
        "tags-description-header": "Descrición completa do significado",
+       "tags-source-header": "Fonte",
        "tags-active-header": "Activa?",
        "tags-hitcount-header": "Edicións etiquetadas",
+       "tags-actions-header": "Accións",
        "tags-active-yes": "Si",
        "tags-active-no": "Non",
+       "tags-source-extension": "Definida por unha extensión",
+       "tags-source-manual": "Aplicado manualmente por usuarios e bots",
+       "tags-source-none": "Xa non está en uso",
        "tags-edit": "editar",
+       "tags-delete": "Borrar",
+       "tags-activate": "activar",
+       "tags-deactivate": "Reactivar",
        "tags-hitcount": "$1 {{PLURAL:$1|modificación|modificacións}}",
+       "tags-manage-no-permission": "Non ten os permisos necesarios para modificar etiquetas.",
+       "tags-create-heading": "Crear unha nova etiqueta",
+       "tags-create-explanation": "Por defecto, as etiquetas creadas recentemente poderán ser empregadas polos usuarios e os bots.",
+       "tags-create-tag-name": "Nome da páxina:",
+       "tags-create-reason": "Motivo:",
+       "tags-create-submit": "Crear",
+       "tags-create-no-name": "Debe especificar unha páxina.",
+       "tags-create-invalid-chars": "Os nomes das etiquetas non poden conter nin comas (<code>,</code>) nin barras (<code>/</code>).",
+       "tags-create-invalid-title-chars": "As páxinas non deben conter caracteres que non se poidan usar nos títulos das páxinas.",
+       "tags-create-already-exists": "A páxina \"$1\" xa existe.",
+       "tags-create-warnings-below": "Desexa continuar creando a etiqueta?",
+       "tags-delete-title": "Borrar etiqueta",
+       "tags-delete-explanation-initial": "Está a piques de borrar a etiqueta \"$1\" da base de datos.",
+       "tags-delete-explanation-warning": "Esta acción é <strong>irreversible</strong> e nin sequera os administradores da base de datos poderán desfacela. Asegúrese de que é esta a etiqueta que desexa borrar.",
+       "tags-delete-explanation-active": "<strong>A etiqueta \"$1\" segue activa e continuará aplicándose no futuro.</strong> Para evitalo, vaia ao(s) lugar(es) onde se establece a aplicación desta etiqueta e desactívea alí.",
+       "tags-delete-reason": "Motivo:",
+       "tags-delete-submit": "Eliminar esta etiqueta irreversiblemente",
+       "tags-delete-not-allowed": "As etiquetas definidas por unha extensión non se poden borrar, agás que a extensión específica o permita.",
+       "tags-delete-not-found": "A páxina \"$1\" non existe.",
+       "tags-delete-too-many-uses": "A etiqueta \"$1\" aplícase a máis de $2 {{PLURAL:$2|revision|revisions}}, polo que non pode borrarse.",
+       "tags-activate-title": "Activar etiqueta",
+       "tags-activate-question": "Está a piques de activar a etiqueta\"$1\".",
+       "tags-activate-reason": "Motivo:",
+       "tags-activate-not-allowed": "Non é posible activar a páxina \"$1\".",
+       "tags-activate-not-found": "A páxina \"$1\" non existe.",
+       "tags-activate-submit": "Activar",
+       "tags-deactivate-title": "Desactivar etiqueta",
+       "tags-deactivate-question": "Está a piques de desactivar a etiqueta \"$1\".",
+       "tags-deactivate-reason": "Motivo:",
+       "tags-deactivate-not-allowed": "Non é posible reactivar a páxina \"$1\".",
+       "tags-deactivate-submit": "Reactivar",
        "comparepages": "Comparar páxinas",
        "compare-page1": "Páxina 1",
        "compare-page2": "Páxina 2",
        "logentry-upload-upload": "$1 {{GENDER:$2|cargou}} \"$3\"",
        "logentry-upload-overwrite": "$1 {{GENDER:$2|cargou}} unha nova versión de \"$3\"",
        "logentry-upload-revert": "$1 {{GENDER:$2|cargou}} \"$3\"",
+       "log-name-managetags": "Rexistro de xestión de etiquetas",
+       "log-description-managetags": "Esta páxina contén unha lista das tarefas de xestión relacionadas con [[Special:Tags|tags]]. No rexistro figuran só aquelas accións realizadas de forma manual por un administrador; pódense crear ou borrar etiquetas por medio do software wiki sen que se engada unha nova entrada ao rexistro.",
+       "logentry-managetags-create": "$1 {{GENDER:$2|created}} a etiqueta \"$4\"",
        "rightsnone": "(ningún)",
        "revdelete-summary": "o resumo de edición",
        "feedback-bugornote": "Se está listo para describir un problema técnico en detalle, [$1 informe do erro].\nEn caso contrario, pode empregar o formulario sinxelo inferior. O seu comentario aparecerá na páxina \"[$3 $2]\" xunto ao seu nome de usuario e o navegador que está usando.",
index 23dd9fc..22a56fc 100644 (file)
        "right-override-export-depth": "ייצוא דפים כולל דפים מקושרים עד עומק של חמישה",
        "right-sendemail": "שליחת דואר אלקטרוני למשתמשים אחרים",
        "right-passwordreset": "צפייה בדואר אלקטרוני של איפוס סיסמה",
+       "right-managechangetags": "יצירת ומחיקת [[Special:Tags|תגיות]] מבסיס הנתונים",
        "newuserlogpage": "יומן רישום משתמשים",
        "newuserlogpagetext": "זהו יומן המכיל הרשמות של משתמשים.",
        "rightslog": "יומן תפקידים",
        "action-viewmyprivateinfo": "לצפות במידע הפרטי שלך",
        "action-editmyprivateinfo": "לערוך את המידע הפרטי שלך",
        "action-editcontentmodel": "לערוך את מודל התוכן של דף",
+       "action-managechangetags": "ליצור ולמחוק תגיות מבסיס הנתונים",
        "nchanges": "{{PLURAL:$1|שינוי אחד|$1 שינויים}}",
        "enhancedrc-since-last-visit": "$1 {{PLURAL:$1|מאז ביקורך האחרון}}",
        "enhancedrc-history": "היסטוריה",
        "tags-tag": "שם התגית",
        "tags-display-header": "הופעה ברשימות השינויים",
        "tags-description-header": "תיאור מלא של המשמעות",
+       "tags-source-header": "מקור",
        "tags-active-header": "פעילה?",
        "tags-hitcount-header": "שינויים עם תגיות",
+       "tags-actions-header": "פעולות",
        "tags-active-yes": "כן",
        "tags-active-no": "לא",
+       "tags-source-extension": "הוגדר על־ידי הרחבה",
+       "tags-source-manual": "הוחל באופן ידני על־ידי משתמשים ובוטים",
+       "tags-source-none": "אינו בשימוש כעת",
        "tags-edit": "עריכה",
+       "tags-delete": "מחיקה",
+       "tags-activate": "הפעלה",
+       "tags-deactivate": "ביטול הפעלה",
        "tags-hitcount": "{{PLURAL:$1|שינוי אחד|$1 שינויים}}",
+       "tags-manage-no-permission": "אין לך הרשאה לנהל תגיות לסימון שינויים.",
+       "tags-create-heading": "יצירת תגית חדשה",
+       "tags-create-explanation": "כברירת מחדל, תגיות חדשות שנוצרות יהיו זמינות לשימושם של משתמשים ובוטים.",
+       "tags-create-tag-name": "שם התגית:",
+       "tags-create-reason": "הסבר:",
+       "tags-create-submit": "יצירה",
+       "tags-create-no-name": "יש לציין שם לתגית.",
+       "tags-create-invalid-chars": "שמות תגיות אינם יכולים לכלול תווי פסיק (<code>,</code>) או סלש ימני (<code>/</code>).",
+       "tags-create-invalid-title-chars": "שמות תגיות אינם יכולים לכלול תווים שאינם ניתנים לשימוש בכותרות דפים.",
+       "tags-create-already-exists": "התגית \"$1\" כבר קיימת.",
+       "tags-create-warnings-above": "{{PLURAL:$2|האזהרה הבאה התקבלה|האזהרות הבאות התקבלו}} בעת הניסיון ליצירת התגית \"$1\":",
+       "tags-create-warnings-below": "האם ברצונך להמשיך ביצירת התגית?",
+       "tags-delete-title": "מחיקת התגית",
+       "tags-delete-explanation-initial": "אתם עומדים למחוק את התגית \"$1\" מבסיס הנתונים.",
+       "tags-delete-explanation-in-use": "התגית תוסר {{PLURAL:$2|מגרסה אחת/פריט יומן אחד|מכל $2 הגרסאות/פריטי היומן}} עבורם היא מוחלת כרגע.",
+       "tags-delete-explanation-warning": "פעולה זו <strong>אינה הפיכה</strong> ו<strong>אינה ניתנת לביטול</strong>, אפילו לא על־ידי מנהלי בסיס הנתונים. אנא ודאו שזוהי התגית שאתם מתכוונים למחוק.",
+       "tags-delete-explanation-active": "<strong>התגית \"$1\" עדיין פעילה, והיא תמשיך להיות מוחלת בעתיד.</strong> כדי למנוע זאת, יש לעבור למקום (או למקומות) בהם התגית מוחלת, ולבטל אותה שם.",
+       "tags-delete-reason": "הסבר:",
+       "tags-delete-submit": "מחיקה בלתי הפיכה של תגית זו",
+       "tags-delete-not-allowed": "תגיות שהוגדרו על־ידי הרחבה אינן ניתנות למחיקה אלא אם כן ההרחבה מתירה זאת במיוחד.",
+       "tags-delete-not-found": "התגית \"$1\" אינה קיימת.",
+       "tags-delete-too-many-uses": "התגית \"$1\" מוחלת על יותר {{PLURAL:$2|מגרסה אחת|מ־$2 גרסאות}}, ולכן לא ניתן למחוק אותה.",
+       "tags-delete-warnings-after-delete": "התגית \"$1\" נמחקה בהצלחה, אבל {{PLURAL:$2|התקבלה האזהרה הבאה|התקבלו האזהרות הבאות}}:",
+       "tags-activate-title": "הפעלת תגית",
+       "tags-activate-question": "אתם עומדים להפעיל את התגית \"$1\".",
+       "tags-activate-reason": "הסבר:",
+       "tags-activate-not-allowed": "לא ניתן להפעיל את התגית \"$1\".",
+       "tags-activate-not-found": "התגית \"$1\" אינה קיימת.",
+       "tags-activate-submit": "הפעלה",
+       "tags-deactivate-title": "ביטול הפעלת תגית",
+       "tags-deactivate-question": "אתם עומדים לבטל את הפעלת התגית \"$1\".",
+       "tags-deactivate-reason": "הסבר:",
+       "tags-deactivate-not-allowed": "לא ניתן לבטל את הפעלת התגית \"$1\".",
+       "tags-deactivate-submit": "ביטול הפעלה",
        "comparepages": "השוואת דפים",
        "compare-page1": "דף 1",
        "compare-page2": "דף 2",
        "logentry-upload-upload": "$1 {{GENDER:$2|העלה|העלתה}} את $3",
        "logentry-upload-overwrite": "$1 {{GENDER:$2|העלה|העלתה}} גרסה חדשה של $3",
        "logentry-upload-revert": "$1 {{GENDER:$2|העלה|העלתה}} את $3",
+       "log-name-managetags": "יומן ניהול תגיות",
+       "log-description-managetags": "דף זה כולל רשימה של פעולות ניהול הקשורות ל[[Special:Tags|תגיות]]. היומן כולל רק פעולות שבוצעו ידנית על־ידי מפעיל מערכת; ייתכן שתגיות ייווצרו או יימחקו על־ידי תוכנת הוויקי ללא הוספת ערך ליומן זה.",
+       "logentry-managetags-create": "$1 {{GENDER:$2|יצר|יצרה}} את התגית \"$4\"",
+       "logentry-managetags-delete": "$1 {{GENDER:$2|מחק|מחקה}} את התגית \"4$\" (שהוסרה {{PLURAL:$5|מגרסה אחת/פריט יומן אחד|מ־$5 גרסאות ו/או פריטי יומן}})",
+       "logentry-managetags-activate": "$1 {{GENDER:$2|הפעיל|הפעילה}} את התגית \"$4\" לשימוש על־ידי משתמשים ובוטים",
+       "logentry-managetags-deactivate": "$1 {{GENDER:$2|ביטל|ביטלה}} את הפעלת התגית \"$4\" לשימוש על־ידי משתמשים ובוטים",
        "rightsnone": "(כלום)",
        "revdelete-summary": "תקציר העריכה",
        "feedback-bugornote": "אם אתם מוכנים לתאר בעיה טכנית בפרטים, אנא [$1 דווחו באג].\nאחרת, תוכלו להשתמש בטופס הפשוט שלהלן. הערתכם תתווסף לדף \"[$3 $2]\", יחד עם שם המשתמש שלכם.",
index b2a2f8a..4fd9066 100644 (file)
        "right-override-export-depth": "Panna aur jurra panna, 5 ke gahirrai talak, ke export karo",
        "right-sendemail": "Duusra sadasya ke lage e-mail bhejo",
        "right-passwordreset": "Password ke badle waala e-mail ke dekho",
+       "right-managechangetags": "Database se banao aur mitao [[Special:Tags|tags]]",
        "newuserlogpage": "Sadasya ke banae waala log",
        "newuserlogpagetext": "Ii sadasya ke banae waala log hai.",
        "rightslog": "Sadasya adhikar suchi",
        "action-viewmyprivateinfo": "Aapan private jaankari ke dekho",
        "action-editmyprivateinfo": "Aapan private jaankari ke badlo",
        "action-editcontentmodel": "ek panna ke content model ke badlo",
+       "action-managechangetags": "database se tags ke banao aur mitao",
        "nchanges": "$1 {{PLURAL:$1|badlao|badlao}}",
        "enhancedrc-since-last-visit": "$1 {{PLURAL:$1|last time dekhe ke baad}}",
        "enhancedrc-history": "itihaas",
        "version-poweredby-others": "duusra waala",
        "version-poweredby-translators": "translatewiki.net translators",
        "version-credits-summary": "Ham log ii sab jan ke [[Special:Version|MediaWiki]] me yogdaan ke khatir recognize kartaa hae.",
+       "version-license-info": "Mediawiki free software hae; jiske aap GNU General Public License as published by the Free Software Foundation; ke niche redistribute aur badle saktaa hae. Ii chaahe version 2 of the License, nai to (at your option) koi baad ke version ke apply hoe hae.\n\nMediawiki ii asha se distribute karaa jaawe hae ki ii aap ke kaam me aai, BINA KOI WARRANTY KE. Iske koi implied warranty of MERCHANTABILITY, nai to, FITNESS FOR A PARTICULAR PURPOSE bhi nai hae. Aur jaankari ke khatir GNU General Public License ke dekho.\n\nAapke ii program ke saathe {{SERVER}}{{SCRIPTPATH}}/COPYING a copy of the GNU General Public License] mila hoi. Agar nai mila tab  Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA, nai to, [//www.gnu.org/licenses/old-licenses/gpl-2.0.html read it online] ke lage likho.",
        "version-software": "Installed software",
        "version-software-product": "Product",
        "version-software-version": "Version",
        "version-libraries": "Installed libraries",
        "version-libraries-library": "Library",
        "version-libraries-version": "Version",
+       "redirect": "File, sadasya, panna, nai to, revision ID se redirect",
        "redirect-legend": "File nai to panna pe redirect karo",
+       "redirect-summary": "Ii khaas panna ek file (given the filename), panna (given a revision ID or page ID), nai to, sadasya ke panna (given a numeric user ID) pe redirect hoe hae.  Usage: [[{{#Special:Redirect}}/file/Example.jpg]], [[{{#Special:Redirect}}/page/64308]], [[{{#Special:Redirect}}/revision/328429]], or [[{{#Special:Redirect}}/user/101]].",
        "redirect-submit": "Jaao",
        "redirect-lookup": "Lookup:",
        "redirect-value": "Value:",
+       "redirect-user": "Sadasya ke ID",
        "redirect-page": "Sadasya ke ID",
        "redirect-revision": "Panna ke revision",
        "redirect-file": "Filename",
        "fileduplicatesearch-submit": "Khojo",
        "fileduplicatesearch-info": "$1 × $2 pixel<br />File size: $3<br />MIME type: $4",
        "fileduplicatesearch-result-1": "Ii file \"$1\" ke koi duplication nai hae.",
+       "fileduplicatesearch-result-n": "File \"$1\" me {{PLURAL:$2|1 identical duplication|$2 identical duplications}} hae.",
        "fileduplicatesearch-noresults": "Koi file jiske naam \"$1\" ke nai paawa gais hae.",
        "specialpages": "Khaas panna",
        "specialpages-note-top": "Legend",
        "tags-tag": "Tag ke naam",
        "tags-display-header": "Appearance on change lists",
        "tags-description-header": "Meaning ke puura description",
+       "tags-source-header": "Source",
        "tags-active-header": "Active?",
        "tags-hitcount-header": "Tagged changes",
+       "tags-actions-header": "Actions",
        "tags-active-yes": "Haan",
        "tags-active-no": "Nai",
+       "tags-source-extension": "Ek extension se define hoe hae",
+       "tags-source-manual": "Sadasya aur bot se manually apply karaa jaawe hae",
+       "tags-source-none": "Ab iske kaam me nai lawa jaae hae",
        "tags-edit": "badlo",
+       "tags-delete": "mitao",
+       "tags-activate": "activate karo",
+       "tags-deactivate": "deactivate karo",
        "tags-hitcount": "$1 {{PLURAL:$1|badlao|badlao}}",
+       "tags-manage-no-permission": "Aap ke change tags ke manage kare ke ijaajat nai hae.",
+       "tags-create-heading": "Ek nawaa tag ke banao",
+       "tags-create-explanation": "Default se, jon nawaa tag banawa gais hae ke sadasya aur bots ke kaam me laae khatir dewa jaai.",
+       "tags-create-tag-name": "Tag ke naam:",
+       "tags-create-reason": "Kaaran:",
+       "tags-create-submit": "Banao",
+       "tags-create-no-name": "Aap ke ek tag ke naam ke batae ke parri.",
+       "tags-create-invalid-chars": "Tag ke naam me saait comma (<code>,</code>) nai to forward slashes (<code>/</code>) hoi.",
+       "tags-create-invalid-title-chars": "Tag ke naam me aisan characters nai hoe ke chaahi jiske panna ke title me nai kaam me lawa jaae sake hae.",
+       "tags-create-already-exists": "Tag \"$1\" abhi hae.",
+       "tags-create-warnings-above": "Niche ke {{PLURAL:$2|chetauni|chetauni}} you time mila jab tag \"$1\" ke banae ke kosis karaa jaawat rahaa:",
+       "tags-create-warnings-below": "Ka aap tag banate rahe mantaa hae?",
+       "tags-delete-title": "Tag ke delete karo",
+       "tags-delete-explanation-initial": "Aap tag \"$1\" ke database se mitae waala hae.",
+       "tags-delete-explanation-in-use": "Iske {{PLURAL:$2|$2 revision or log entry|all $2 revisions and/or log entries}} se hatae dewa jaai jahaan pe it is currently applied.",
+       "tags-delete-reason": "Kaaran:",
        "comparepages": "Panna ke biich me antar dekho",
        "compare-page1": "Panna 1",
        "compare-page2": "Panna 2",
        "dberr-again": "Thora deri wait kar ke fir se load kare ke try karo",
        "dberr-info": "(Cannot access the database: $1)",
        "dberr-info-hidden": "(Database ke nai access kare sakaa jaawe hae)",
+       "dberr-usegoogle": "Fir haal aap Google se khoje saktaa hae",
+       "dberr-outofdate": "Note karna ki you logan jon ham logan ke contents ke index Karin hae, saait out of date hoi.",
+       "dberr-cachederror": "Ii maaga gais panna ke ek cached copy hae, aur saait up to date nai hoi.",
+       "htmlform-invalid-input": "App ke kuchh input se problem hae.",
+       "htmlform-select-badoption": "Jon value ke aap specify karaa hae, ek valid option nai hae.",
+       "htmlform-int-invalid": "Jon value ke aap specify karaa hae, ek integer nai hae.",
+       "htmlform-float-invalid": "Jon value ke aap specify karaa hae, ek number nai hae.",
+       "htmlform-int-toolow": "Jon value kae aap specify karaa hae, minimum of $1 se kamti hae.",
+       "htmlform-int-toohigh": "Jon value ke aap specify karaa hae, maximum of $1 se jaada hae.",
+       "htmlform-required": "Ii value ke jaruri hae.",
        "htmlform-submit": "Submit karo",
        "htmlform-reset": "Badlao ke pahile jaise karo",
        "htmlform-selectorother-other": "Duusra",
        "logentry-delete-revision": "$1 {{GENDER:$2|changed}} visibility of {{PLURAL:$5|a revision|$5 revisions}} panna $3: $4 pe",
        "logentry-delete-event-legacy": "$1 {{GENDER:$2|badal dewa gais hae}} visibility of log events on $3",
        "logentry-delete-revision-legacy": "$1 {{GENDER:$2|changed}} visibility of revisions on panna $3",
+       "logentry-suppress-delete": "$1 {{GENDER:$2|suppressed}} panna $3",
+       "logentry-suppress-event": "$1 secretly {{GENDER:$2|changed}} visibility of {{PLURAL:$5|a log event|$5 log events}} on $3: $4",
+       "logentry-suppress-revision": "$1 secretly {{GENDER:$2|changed}} visibility of {{PLURAL:$5|a revision|$5 revisions}} on page $3: $4",
+       "logentry-suppress-event-legacy": "$1 secretly {{GENDER:$2|changed}} visibility of log events on $3",
+       "logentry-suppress-revision-legacy": "$1 secretly {{GENDER:$2|changed}} visibility of revisions on page $3",
+       "revdelete-content-hid": "lokawa gais content",
+       "revdelete-summary-hid": "edit summary ke lukawa gais hae",
+       "revdelete-uname-hid": "username ke lukawa gais hae",
+       "revdelete-content-unhid": "content ke lukawa gais hae",
+       "revdelete-summary-unhid": "edit summary ke lukawa gais hae",
+       "revdelete-uname-unhid": "username ke lukawa gais hae",
        "revdelete-restricted": "sysops pe llabu restrictions",
        "revdelete-unrestricted": "sysops se hatawa gae rukawat",
-       "logentry-rights-rights": "$1 $3 ke group ke membership ke $4 se badal ke $5 kar dia hae",
-       "logentry-rights-rights-legacy": "$1 $3 ke group membership ke badal dia hae",
-       "logentry-rights-autopromote": "$1 ke apne se $2 se $3 ke promotion dewa gais",
+       "logentry-merge-merge": "$1 {{GENDER:$2|merged}} $3 into $4 (revisions up to $5)",
+       "logentry-move-move": "$1 {{GENDER:$2|moved}} panna $3 se $4",
+       "logentry-move-move-noredirect": "$1 {{GENDER:$2|moved}} panna $3 se $4 without leaving a redirect",
+       "logentry-move-move_redir": "$1 {{GENDER:$2|moved}} panna $3 se $4 over redirect",
+       "logentry-move-move_redir-noredirect": "$1 {{GENDER:$2|moved}} panna $3 se $4 over a redirect without leaving a redirect",
+       "logentry-patrol-patrol": "$1 {{GENDER:$2|marked}} revision $4 panna $3 ke patrol karaa gais hae",
+       "logentry-patrol-patrol-auto": "$1 automatically {{GENDER:$2|marked}} revision $4 panna $3 ke patrol karis hae",
+       "logentry-newusers-newusers": "Sadasya $1 ke account  {{GENDER:$2|created}} ke banawa gais hae",
+       "logentry-newusers-create": "Sadasya $1 ke account  {{GENDER:$2|created}} ke banawa gais hae",
+       "logentry-newusers-create2": "Sadasya $3 ke account  {{GENDER:$2|created}} ke $1 banais hae.",
+       "logentry-newusers-byemail": "Sadasya $3 ke account {{GENDER:$2|created}} ke $1 banais hae  aur password ke email se bheja gais hae",
+       "logentry-newusers-autocreate": "Sadasya $1 ke account {{GENDER:$2|created}} ke automatically banawa gais hae",
+       "logentry-rights-rights": "$1 {{GENDER:$2|changed}} group ke membership $3 ke khatir $4 se lai ke $5 talak",
+       "logentry-rights-rights-legacy": "$1 {{GENDER:$2|changed}} group ke membership $3 ke khatir",
+       "logentry-rights-autopromote": "$1 ke apne se $4 se $5 {{GENDER:$2|promoted karaa gais hae}}",
+       "logentry-upload-upload": "$1 {{GENDER:$2|upload karaa gais hae}} $3",
+       "logentry-upload-overwrite": "$1 {{GENDER:$2|uploaded}} a new version of $3",
+       "logentry-upload-revert": "$1 {{GENDER:$2|upload karaa gais hae}} $3",
        "rightsnone": "(koi nai hai)",
        "revdelete-summary": "summary ke badlo",
-       "searchsuggest-search": "Khojo"
+       "feedback-bugornote": "Agar aap ek technical problem ke detail me describe kare mangtaa hae tab meharbaani kar ke [$1 report a bug].\n\nNai to, aap niche ke sahaj form ke kaam me laae saktaa hae. Aap ke comment ke, aap ke naam ke saathe, panna \"[$3 $2]\" me jorra jaai.",
+       "feedback-subject": "Subject:",
+       "feedback-message": "Sandes:",
+       "feedback-cancel": "Cancel karo",
+       "feedback-submit": "Feedback do",
+       "feedback-adding": "Panna me subject jorra jaawe hae...",
+       "feedback-error1": "Error: Unrecognized result from API",
+       "feedback-error2": "Error: Edit fail hoi gais hae",
+       "feedback-error3": "Error: API se koi response nai mila",
+       "feedback-thanks": "Dhanyabaad! Aap ke feedback ke panna \"[$2 $1]\" me post karaa gais hae.",
+       "feedback-close": "Kar dewa gais hae",
+       "feedback-bugcheck": "Julum! Khaali ii check karna ki ii ek pahile se jaana waala bugs me se nai hae [$1 known bugs].",
+       "feedback-bugnew": "Ham karaa hae. Nawaa bug ke report karo",
+       "searchsuggest-search": "Khojo",
+       "searchsuggest-containing": "isme hae.....",
+       "api-error-badaccess-groups": "Aap ke ii wiki me file upload kare ke ijajat nai hae.",
+       "api-error-badtoken": "Internal error: Bad token.",
+       "api-error-copyuploaddisabled": "Uploading by URL ke ii server me disable kar dewa gais hae.",
+       "api-error-duplicate": "There {{PLURAL:$1|is [$2 another file]|are [$2 some other files]}} already on the site with the same content.",
+       "api-error-duplicate-archive": "There {{PLURAL:$1|was [$2 another file]|were [$2 some other files]}} already on the site with the same content, but {{PLURAL:$1|it was|they were}} deleted.",
+       "api-error-duplicate-archive-popup-title": "Duplicate {{PLURAL:$1|file that has|files that have}} already been deleted.",
+       "api-error-duplicate-popup-title": "Duplicate {{PLURAL:$1|file|files}}.",
+       "api-error-empty-file": "Jon file ke aap submit karaa rahaa, khaali hae.",
+       "api-error-emptypage": "Nawaa, khaali panna ke banae ke ijajat nai hae.",
+       "api-error-fetchfileerror": "Internal error: File khoje ke time kuch wrong hoe gais hae.",
+       "api-error-fileexists-forbidden": "Ek file, jiske naam \"$1\" hae abhi hae, aur iske overwrite nai karaa jaae sake hae.",
+       "api-error-fileexists-shared-forbidden": "Ek file, jiske naam \"$1\" hae abhi hae aur file repository me shared hae, aur iske overwrite nai karaa jaae sake hae.",
+       "api-error-file-too-large": "Jon file ke aap submit karaa hae bahut barraa hae.",
+       "api-error-filename-tooshort": "Filename bahut chhota hae.",
+       "api-error-filetype-banned": "Ii rakam ke file banned hae."
 }
index d42c4a2..4cee8ab 100644 (file)
@@ -54,6 +54,7 @@
        "tog-watchdefault": "Az általam szerkesztett lapok és fájlok felvétele a figyelőlistámra",
        "tog-watchmoves": "Az általam átnevezett lapok és fájlok felvétele a figyelőlistámra",
        "tog-watchdeletion": "Az általam törölt lapok és fájlok felvétele a figyelőlistámra",
+       "tog-watchrollback": "Az általam visszaállított lapok felvétele a figyelőlistámra",
        "tog-minordefault": "Alapértelmezetten minden szerkesztésemet jelölje aprónak",
        "tog-previewontop": "Előnézet megjelenítése a szerkesztőablak előtt",
        "tog-previewonfirst": "Előnézet mutatása az első szerkesztésnél",
        "pool-timeout": "Letelt a zárolás feloldására szánt várakozási idő",
        "pool-queuefull": "A pool sor megtelt",
        "pool-errorunknown": "Ismeretlen hiba",
+       "pool-servererror": "A pool counter szolgáltatás nem elérhető ($1).",
+       "poolcounter-usage-error": "Használati hiba: $1",
        "aboutsite": "A {{SITENAME}} wikiről",
        "aboutpage": "Project:Rólunk",
        "copyright": "A tartalom további jelölés hiányában a(z) $1 feltételei szerint használható fel.",
        "userlogin-resetpassword-link": "Elfelejtetted a jelszavad?",
        "userlogin-helplink2": "Segítség a bejelentkezéshez",
        "userlogin-loggedin": "Már be vagy jelentkezve mint {{GENDER:$1|$1}}. Ha más néven akarsz belépni, alább megteheted.",
-       "userlogin-createanother": "Felhasználói fiók létrehozása",
+       "userlogin-createanother": "Másik felhasználói fiók létrehozása",
        "createacct-emailrequired": "E-mail cím",
        "createacct-emailoptional": "E-mail cím (opcionális)",
        "createacct-email-ph": "Add meg e-mail címed",
        "changeemail-submit": "E-mail cím megváltoztatása",
        "changeemail-throttled": "Túl sok hibás bejelentkezés.\nVárj $1, mielőtt újra próbálkozol.",
        "resettokens": "Tokenek törlése",
+       "resettokens-text": "Újra generálhatod a tokeneket, amely a fiókodhoz rendelt bizonyos magánadatokhoz enged hozzáférést.\n\nEzt akkor érdemes használnod, hogy véletlenül megosztottad a tokeneket valakivel, vagy ha valaki feltörte a fiókodat.",
        "resettokens-no-tokens": "Nincs újragenerálható token.",
        "resettokens-legend": "Tokenek újragenerálása",
        "resettokens-tokens": "Tokenek:",
index 03fc60e..814ce04 100644 (file)
@@ -17,7 +17,9 @@
                        "Համլետ",
                        "לערי ריינהארט",
                        "아라",
-                       "Lilitik22"
+                       "Lilitik22",
+                       "GrigorGB",
+                       "Աշոտ1997"
                ]
        },
        "tog-underline": "ընդգծել հղումները՝",
        "tog-usenewrc": "Խմբավորել փոփոխությունները վերջին փոփոխություններում և հսկացանկում (պահանջում է JavaScript)",
        "tog-numberheadings": "Ինքնաթվագրել վերնագրերը",
        "tog-showtoolbar": "Ցույց տալ խմբագրումների գործիքների վահանակը",
-       "tog-editondblclick": "Ô½Õ´Õ¢Õ¡Õ£Ö\80Õ¥Õ¬ Õ§Õ»Õ¥Ö\80Õ¨ Õ¯Ö\80Õ¯Õ¶Õ¡Õ¯Õ« Õ´Õ¡Õ¿Õ¶Õ¡Õ°Õ¡Ö\80մամբ",
-       "tog-editsectiononrightclick": "Ô½Õ´Õ¢Õ¡Õ£Ö\80Õ¥Õ¬ Õ¢Õ¡ÕªÕ«Õ¶Õ¶Õ¥Ö\80Õ¨ Õ¾Õ¥Ö\80Õ¶Õ¡Õ£Ö\80Õ« Õ¡Õ» Õ´Õ¡Õ¿Õ¶Õ¡Õ°Õ¡Ö\80մամբ",
-       "tog-watchcreations": "Ավելացնել իմ ստեղծած էջերը և բեռնած նիշքերը հսկացանկում",
-       "tog-watchdefault": "Ավելացնել իմ խմբագրած էջերը և նիշքերը հսկացանկում",
-       "tog-watchmoves": "Ավելացնել իմ վերնավանած էջերը և նիշքերը հսկացանկում",
-       "tog-watchdeletion": "Ավելացնել իմ ջնջած էջերը և նիշքերը հսկացանկում",
-       "tog-minordefault": "Ô½Õ´Õ¢Õ¡Õ£Ö\80Õ¸Ö\82Õ´Õ¶Õ¥Ö\80Õ¨ Õ¬Õ¼Õ¥Õ¬ÕµÕ¡ÕµÕ¶ նշել որպես չնչին",
+       "tog-editondblclick": "Ô½Õ´Õ¢Õ¡Õ£Ö\80Õ¥Õ¬ Õ§Õ»Õ¥Ö\80Õ¨ Õ¯Ö\80Õ¯Õ¶Õ¡Õ¯Õ« Õ½Õ¥Õ²մամբ",
+       "tog-editsectiononrightclick": "Ô½Õ´Õ¢Õ¡Õ£Ö\80Õ¥Õ¬ Õ¢Õ¡ÕªÕ«Õ¶Õ¶Õ¥Ö\80Õ¨ Õ¾Õ¥Ö\80Õ¶Õ¡Õ£Ö\80Õ« Õ¡Õ» Õ½Õ¥Õ²մամբ",
+       "tog-watchcreations": "Ô±Õ¾Õ¥Õ¬Õ¡Ö\81Õ¶Õ¥Õ¬ Õ«Õ´ Õ½Õ¿Õ¥Õ²Õ®Õ¡Õ® Õ§Õ»Õ¥Ö\80Õ¨ Ö\87 Õ¢Õ¥Õ¼Õ¶Õ¡Õ® Õ¶Õ«Õ·Ö\84Õ¥Ö\80Õ¨ Õ«Õ´ Õ°Õ½Õ¯Õ¡Ö\81Õ¡Õ¶Õ¯Õ¸Ö\82Õ´",
+       "tog-watchdefault": "Ô±Õ¾Õ¥Õ¬Õ¡Ö\81Õ¶Õ¥Õ¬ Õ«Õ´ Õ­Õ´Õ¢Õ¡Õ£Ö\80Õ¡Õ® Õ§Õ»Õ¥Ö\80Õ¨ Ö\87 Õ¶Õ«Õ·Ö\84Õ¥Ö\80Õ¨ Õ«Õ´ Õ°Õ½Õ¯Õ¡Ö\81Õ¡Õ¶Õ¯Õ¸Ö\82Õ´",
+       "tog-watchmoves": "Ô±Õ¾Õ¥Õ¬Õ¡Ö\81Õ¶Õ¥Õ¬ Õ«Õ´ Õ¾Õ¥Ö\80Õ¶Õ¡Õ¾Õ¡Õ¶Õ¡Õ® Õ§Õ»Õ¥Ö\80Õ¨ Ö\87 Õ¶Õ«Õ·Ö\84Õ¥Ö\80Õ¨ Õ«Õ´ Õ°Õ½Õ¯Õ¡Ö\81Õ¡Õ¶Õ¯Õ¸Ö\82Õ´",
+       "tog-watchdeletion": "Ô±Õ¾Õ¥Õ¬Õ¡Ö\81Õ¶Õ¥Õ¬ Õ«Õ´ Õ»Õ¶Õ»Õ¡Õ® Õ§Õ»Õ¥Ö\80Õ¨ Ö\87 Õ¶Õ«Õ·Ö\84Õ¥Ö\80Õ¨ Õ«Õ´ Õ°Õ½Õ¯Õ¡Ö\81Õ¡Õ¶Õ¯Õ¸Ö\82Õ´",
+       "tog-minordefault": "Ô²Õ¸Õ¬Õ¸Ö\80 Õ­Õ´Õ¢Õ¡Õ£Ö\80Õ¸Ö\82Õ´Õ¶Õ¥Ö\80Õ¨ Õ¬Õ¼Õ¥Õ¬ÕµÕ¡ÕµÕ¶ Õ¯Õ¥Ö\80ÕºÕ¸Õ¾ նշել որպես չնչին",
        "tog-previewontop": "Ցույց տալ նախադիտումը խմբագրման դաշտից առաջ",
-       "tog-previewonfirst": "Õ\86Õ¡Õ­Õ¡Õ¤Õ«Õ¿Õ¥Õ¬ Õ´Õ«Õ¶Õ¹Ö\87 Õ¡Õ¼Õ¡Õ»Õ«Õ¶ Õ­Õ´Õ¢Õ¡Õ£Ö\80Õ¸Ö\82Õ©ÕµÕ¸Ö\82Õ¶ը",
+       "tog-previewonfirst": "Õ\91Õ¸Ö\82Ö\81Õ¡Õ¤Ö\80Õ¥Õ¬ Õ¶Õ¡Õ­Õ¡Õ¤Õ«Õ¿Õ¸Ö\82Õ´Õ¨ Õ´Õ«Õ¶Õ¹Ö\87 Õ¡Õ¼Õ¡Õ»Õ«Õ¶ Õ­Õ´Õ¢Õ¡Õ£Ö\80Õ¸Ö\82Õ´ը",
        "tog-enotifwatchlistpages": "էլ-փոստով տեղեկացնել հսկվող էջերում փոփոխությունների մասին",
        "tog-enotifusertalkpages": "էլ-փոստով տեղեկացնել իմ քննարկման էջի փոփոխության մասին",
-       "tog-enotifminoredits": "Õ§Õ¬-Ö\83Õ¸Õ½Õ¿Õ¸Õ¾ Õ¿Õ¥Õ²Õ¥Õ¯Õ¡Ö\81Õ¶Õ¥Õ¬ Õ§Õ»Õ¥Ö\80Õ« Õ¶Õ¡Ö\87 չնչին խմբագրումների մասին",
+       "tog-enotifminoredits": "Õ§Õ¬-Ö\83Õ¸Õ½Õ¿Õ¸Õ¾ Õ¿Õ¥Õ²Õ¥Õ¯Õ¡Ö\81Õ¶Õ¥Õ¬ Õ¶Õ¡Ö\87 Õ§Õ»Õ¥Ö\80Õ« չնչին խմբագրումների մասին",
        "tog-enotifrevealaddr": "Ցույց տալ իմ էլ-փոստի հասցեն ծանուցման նամակներում",
-       "tog-shownumberswatching": "Õ\91Õ¸Ö\82ÕµÖ\81 Õ¿Õ¡Õ¬ Õ§Õ» Õ°Õ½Õ¯Õ¸Õ² Õ´Õ¡Õ½Õ¶Õ¡Õ¯Õ«Ö\81Õ¶Õ¥Ö\80Õ« Õ©Õ«Õ¾Õ¨",
-       "tog-oldsig": "Ներկայիս ստորագրությունն է․",
+       "tog-shownumberswatching": "Ցույց տալ հսկող մասնակիցների թիվը",
+       "tog-oldsig": "Ընթացիկ ստորագրությունը՝",
        "tog-fancysig": "Ստորագրությունը վիքիտեքստի տեսքով (առանց ավտոմատ հղման)",
        "tog-uselivepreview": "Օգտագործել անմիջական նախադիտում, առանց էջը վերբեռնելու (փորձնական)",
        "tog-forceeditsummary": "Նախազգուշացնել խմբագրման ամփոփումը դատարկ թողնելու դեպքում",
-       "tog-watchlisthideown": "Թաքցնել իմ խմբագրումները հսկացանկից",
+       "tog-watchlisthideown": "Հսկացանկից թաքցնել իմ խմբագրումները",
        "tog-watchlisthidebots": "Թաքցնել բոտերի խմբագրումները հսկացանկից",
        "tog-watchlisthideminor": "Թաքցնել չնչին խմբագրումները հսկացանկից",
        "tog-watchlisthideliu": "Թաքցնել մուտք գործած մասնակիցների խմբագրումները հսկացանկից",
        "createacct-captcha": "Անվտանգության ստուգում",
        "createacct-imgcaptcha-ph": "Մուտքագրեք վերը բերված գրվածքը",
        "createacct-submit": "Ստեղծել ձեր հաշիվը",
+       "createacct-another-submit": "Ստեղծել այլ հաշիվ",
        "createacct-benefit-heading": "{{SITENAME}}՝ ստեղծվում է ձեր պես մարդկանց կողմից։",
        "createacct-benefit-body1": "{{PLURAL:$1|խմբագրում}}",
        "createacct-benefit-body2": "{{PLURAL:$1|էջ}}",
        "prefs-personal": "Անձնական",
        "prefs-rc": "Վերջին փոփոխություններ",
        "prefs-watchlist": "Հսկացանկ",
+       "prefs-editwatchlist": "Խմբագրել հսկացանկը",
        "prefs-watchlist-days": "Հսկացանկում ցուցադրվող օրերի թիվը՝",
        "prefs-watchlist-days-max": "Առավելագույնը $1 {{PLURAL:$1|օր}}",
        "prefs-watchlist-edits": "Ընդարձակված հսկացանկում ցուցադրվող օրերի թիվը՝",
        "deletereason-dropdown": "*Ջնջման տարածված պատճառներ\n** Հեղինակի խնդրանքով\n** Հեղինակային իրավունքների խախտում\n** Վանդալություն",
        "delete-edit-reasonlist": "Խմբագրել ջնջման պատճառները",
        "rollback": "Հետ գլորել խմբագրումները",
-       "rollback_short": "Հետ գլորել",
        "rollbacklink": "հետ գլորել",
        "rollbacklinkcount": "հետ գլորել $1 {{PLURAL:$1|խմբագրում}}",
        "rollbackfailed": "Հետ գլորումը ձախողվեց",
        "blankpage": "Դատարկ էջ",
        "intentionallyblankpage": "Այս էջը միտումնավոր դատարկ է թողված։",
        "tag-filter-submit": "Ֆիլտրել",
+       "tags-source-header": "Աղբյուր",
+       "tags-actions-header": "Գործողություններ",
        "tags-edit": "խմբագրել",
+       "tags-delete": "ջնջել",
+       "tags-deactivate": "Ապաակտիվացնել",
+       "tags-create-reason": "Պատճառ՝",
+       "tags-create-submit": "Ստեղծել",
+       "tags-delete-reason": "Պատճառ՝",
+       "tags-activate-reason": "Պատճառ՝",
+       "tags-activate-submit": "Ակտիվացնել",
+       "tags-deactivate-reason": "Պատճառ՝",
+       "tags-deactivate-submit": "Ապաակտիվացնել",
        "comparepages": "Համեմատել էջեր",
        "compare-page1": "Էջ 1",
        "compare-page2": "Էջ 2",
index d6dc939..4fb7f1e 100644 (file)
        "prefs-personal": "Profilo del usator",
        "prefs-rc": "Modificationes recente",
        "prefs-watchlist": "Observatorio",
+       "prefs-editwatchlist": "Modificar observatorio",
+       "prefs-editwatchlist-label": "Modificar entratas in tu observatorio:",
+       "prefs-editwatchlist-edit": "Vider e remover titulos in tu observatorio",
+       "prefs-editwatchlist-raw": "Modificar observatorio crude",
+       "prefs-editwatchlist-clear": "Rader tu observatorio",
        "prefs-watchlist-days": "Numero de dies a monstrar in le observatorio:",
        "prefs-watchlist-days-max": "Maximo $1 {{PLURAL:$1|die|dies}}",
        "prefs-watchlist-edits": "Numero maxime de modificationes a monstrar in le observatorio expandite:",
        "uploaderror": "Error de incargamento",
        "upload-recreate-warning": "'''Attention: Un file con iste nomine ha ja essite delite o renominate.'''\n\nLe registro de deletiones e renominationes pro iste pagina es fornite hic pro major commoditate:",
        "uploadtext": "Con le formulario sequente tu pote incargar un nove file in le wiki.\nPro vider o cercar files ja incargate, visita le [[Special:FileList|lista de files incargate]]. In ultra, le (re)incargamentos es registrate in le [[Special:Log/upload|registro de incargamentos]], le deletiones in le [[Special:Log/delete|registro de deletiones]].\n\nPro includer un file in un pagina, usa un ligamine in un del sequente formas:\n* '''<code><nowiki>[[</nowiki>{{ns:file}}<nowiki>:File.jpg]]</nowiki></code>''' pro usar le version complete del file\n* '''<code><nowiki>[[</nowiki>{{ns:file}}<nowiki>:File.png|200px|thumb|left|texto alternative]]</nowiki></code>''' pro usar un rendition a latitude de 200 pixel in un quadro in le margine sinistre con 'texto alternative' qua description\n* '''<code><nowiki>[[</nowiki>{{ns:media}}<nowiki>:File.ogg]]</nowiki></code>''' pro facer un ligamine directe al file sin monstrar le file",
-       "upload-permitted": "Typos de file permittite: $1.",
-       "upload-preferred": "Typos de file preferite: $1.",
-       "upload-prohibited": "Typos de file prohibite: $1.",
+       "upload-permitted": "{{PLURAL:$2|Typo|Typos}} de file permittite: $1.",
+       "upload-preferred": "{{PLURAL:$2|Typo|Typos}} de file preferite: $1.",
+       "upload-prohibited": "{{PLURAL:$2|Typo|Typos}} de file prohibite: $1.",
        "uploadlogpage": "Registro de incargamentos",
        "uploadlogpagetext": "Infra es un lista de files recentemente incargate.\nVide le [[Special:NewFiles|galeria de nove files]] pro un presentation plus visual.",
        "filename": "Nomine del file",
index 1cae38c..0bf8947 100644 (file)
        "otherlanguages": "Bahasa lain",
        "redirectedfrom": "(Dialihkan dari $1)",
        "redirectpagesub": "Halaman pengalihan",
+       "redirectto": "Mengalihkan ke:",
        "lastmodifiedat": "Halaman ini terakhir diubah pada $2, $1.",
        "viewcount": "Halaman ini telah diakses sebanyak {{PLURAL:$1|$1 kali}}.<br />",
        "protectedpage": "Halaman yang dilindungi",
        "pool-queuefull": "Kumpulan antrean penuh",
        "pool-errorunknown": "Kesalahan yang tidak diketahui",
        "pool-servererror": "Layanan penghitung pool ini tidak tersedia ($1).",
+       "poolcounter-usage-error": "Galat penggunaan: $1",
        "aboutsite": "Tentang {{SITENAME}}",
        "aboutpage": "Project:Perihal",
        "copyright": "Konten tersedia sesuai di bawah $1.",
        "hidetoc": "sembunyikan",
        "collapsible-collapse": "Ciutkan",
        "collapsible-expand": "Kembangkan",
+       "confirmable-confirm": "Apakah {{GENDER:$1|Anda}} yakin?",
+       "confirmable-yes": "Ya",
+       "confirmable-no": "Tidak",
        "thisisdeleted": "Lihat atau kembalikan $1?",
        "viewdeleted": "Lihat $1?",
        "restorelink": "{{PLURAL:$1|$1 suntingan}} yang telah dihapus",
        "filerenameerror": "Tidak dapat mengubah nama berkas \"$1\" menjadi \"$2\".",
        "filedeleteerror": "Tidak dapat menghapus berkas \"$1\".",
        "directorycreateerror": "Tidak dapat membuat direktori \"$1\".",
+       "directoryreadonlyerror": "Direktori \"$1\" hanya-baca.",
+       "directorynotreadableerror": "Direktori \"$1\" tidak bisa dibaca.",
        "filenotfound": "Tidak dapat menemukan berkas \"$1\".",
        "unexpected": "Nilai di luar jangkauan: \"$1\"=\"$2\".",
        "formerror": "Kesalahan: Tidak dapat mengirimkan formulir",
        "viewyourtext": "Anda dapat melihat atau menyalin sumber dari '''suntingan Anda''' ke halaman ini:",
        "protectedinterface": "Halaman ini memuat teks antarmuka untuk perangkat lunak pada wiki ini, dan dilindungi terhadap penyalahgunaan. Untuk menambah atau mengubah terjemahan pada semua wiki, harap gunakan [//translatewiki.net/ translatewiki.net], proyek pelokalan MediaWiki.",
        "editinginterface": "<strong>Peringatan:</strong> Anda menyunting suatu halaman yang digunakan untuk menyediakan teks antarmuka bagi perangkat lunak.\nPerubahan pada halaman ini akan memengaruhi tampilan pada antarmuka pengguna untuk pengguna lain pada wiki ini.",
+       "translateinterface": "Untuk menambah atau mengubah terjemahan semua wiki, mohon gunakan [//translatewiki.net/ translatewiki.net], Proyek pelokalan MediaWiki.",
        "cascadeprotected": "Halaman ini telah dilindungi dari penyuntingan karena disertakan di {{PLURAL:$1|halaman|halaman-halaman}} berikut yang telah dilindungi dengan opsi \"runtun\":\n$2",
        "namespaceprotected": "Anda tak memiliki hak akses untuk menyunting halaman di ruang nama '''$1'''.",
        "customcssprotected": "Anda tidak memiliki izin untuk menyunting halaman CSS ini, karena berisi pengaturan pribadi pengguna lain.",
        "createaccount-text": "Seseorang telah membuat sebuah akun untuk alamat surel Anda di {{SITENAME}} ($4) dengan nama \"$2\" dan kata sandi \"$3\". Anda dianjurkan untuk masuk log dan mengganti kata sandi Anda sekarang.\n\nAnda dapat mengabaikan pesan ini jika akun ini dibuat karena suatu kesalahan.",
        "login-throttled": "Anda sudah terlalu sering mencoba masuk log.\nSilakan menunggu $1 sebelum mencoba lagi.",
        "login-abort-generic": "Proses masuk Anda tidak berhasil - Dibatalkan",
+       "login-migrated-generic": "Akun Anda telah dimigrasi, dan nama pengguna Anda tidak lagi terdaftar di wiki ini.",
        "loginlanguagelabel": "Bahasa: $1",
        "suspicious-userlogout": "Permintaan Anda untuk keluar log ditolak karena tampaknya dikirim oleh penjelajah yang rusak atau proksi penyinggah.",
        "createacct-another-realname-tip": "Nama asli bersifat opsional.\nJika Anda memberikannya, nama asli Anda akan digunakan untuk memberi pengenalan atas hasil kerja Anda.",
        "preview": "Pratayang",
        "showpreview": "Lihat pratayang",
        "showdiff": "Lihat perubahan",
+       "blankarticle": "<strong>Peringatan:</strong> Halaman yang akan Anda buat tidak berisi apa-apa.\nJika Anda mengeklik \"{{int:savearticle}}\" sekali lagi, halaman ini akan dibuat tanpa adanya isi.",
        "anoneditwarning": "<strong>Peringatan:</strong> Anda sedang tidak masuk log. Alamat IP Anda akan terlihat oleh publik jika Anda melakukan suatu perubahan. Jika Anda <strong>[$1 masuk log]</strong> atau <strong>[$2 membuat akun]</strong>, suntingan Anda akan diatribusikan kepada nama pengguna Anda, beserta berbagai keuntungan lainnya.",
        "anonpreviewwarning": "''Anda belum masuk log. Menyimpan halaman akan menyebabkan alamat IP Anda tercatat pada riwayat suntingan laman ini.''",
        "missingsummary": "'''Peringatan:''' Anda tidak memasukkan ringkasan penyuntingan. Jika Anda kembali menekan tombol Simpan, suntingan Anda akan disimpan tanpa ringkasan penyuntingan.",
+       "selfredirect": "<strong>Peringatan:</strong> Anda akan mengalihkan halaman ini balik ke halaman ini.\nAnda bisa jadi telah menuliskan tujuan pengalihan yang salah, atau telah menyunting halaman yang salah.\nJika Anda mengeklik \"{{int:savearticle}}\" sekali lagi, halaman pengalihan akan dibuat.",
        "missingcommenttext": "Harap masukkan komentar di bawah ini.",
        "missingcommentheader": "''Peringatan:''' Anda belum memberikan subjek atau judul untuk komentar Anda. Jika Anda kembali menekan \"{{int:savearticle}}\", suntingan Anda akan disimpan tanpa komentar tersebut.",
        "summary-preview": "Pratayang ringkasan:",
        "content-model-text": "teks polos",
        "content-model-javascript": "JavaScript",
        "content-model-css": "CSS",
+       "content-json-empty-object": "Objek kosong",
+       "content-json-empty-array": "Larik kosong",
+       "duplicate-args-category": "Halaman dengan argumen ganda di pemanggilan templat",
+       "duplicate-args-category-desc": "Halaman ini berisi pemanggilan templat yang menggunakan argumen ganda, seperti <code><nowiki>{{foo|bar=1|bar=2}}</nowiki></code> atau <code><nowiki>{{foo|bar|1=baz}}</nowiki></code>.",
        "expensive-parserfunction-warning": "Peringatan: Halaman ini mengandung terlalu banyak panggilan fungsi parser.\n\nSaat ini terdapat {{PLURAL:$1|$1 panggilan|$1 panggilan}}, seharusnya kurang dari $2 {{PLURAL:$2|panggilan|panggilan}}.",
        "expensive-parserfunction-category": "Halaman dengan terlalu banyak panggilan fungsi parser",
        "post-expand-template-inclusion-warning": "Peringatan: Ukuran templat yang digunakan terlalu besar.\nBeberapa templat akan diabaikan.",
        "search-result-category-size": "{{PLURAL:$1|1 anggota|$1 anggota}} ({{PLURAL:$2|1 subkategori|$2 subkategori}}, {{PLURAL:$3|1 berkas|$3 berkas}})",
        "search-redirect": "(pengalihan $1)",
        "search-section": "(bagian $1)",
+       "search-category": "(kategori $1)",
        "search-file-match": "(cocok dengan isi berkas)",
        "search-suggest": "Mungkin maksud Anda adalah: $1",
        "search-interwiki-caption": "Proyek lain",
        "searchall": "semua",
        "showingresults": "Di bawah ini ditampilkan hingga {{PLURAL:$1|'''1''' hasil|'''$1''' hasil}}, dimulai dari #'''$2'''.",
        "showingresultsinrange": "Menampilkan sampai dengan {{PLURAL:$1|<strong>1</strong> hasil|<strong>$1</strong> hasil}} dalam jangkauan #<strong>$2</strong> sampai #<strong>$3</strong>.",
+       "search-showingresults": "{{PLURAL:$4|Hasil <strong>$1</strong> dari <strong>$3</strong>|Hasil <strong>$1 - $2</strong> dari <strong>$3</strong>}}",
        "search-nonefound": "Tidak ada hasil yang sesuai dengan kriteria.",
        "powersearch-legend": "Pencarian lanjut",
        "powersearch-ns": "Mencari di ruang nama:",
        "prefs-personal": "Profil",
        "prefs-rc": "Perubahan terbaru",
        "prefs-watchlist": "Pemantauan",
+       "prefs-editwatchlist": "Sunting daftar pantauan",
+       "prefs-editwatchlist-label": "Sunting entri di daftar pantuan:",
+       "prefs-editwatchlist-edit": "Lihat dan hapus judul di daftar pantauan Anda",
+       "prefs-editwatchlist-raw": "Sunting daftar pantauan mentah",
+       "prefs-editwatchlist-clear": "Kosongkan daftar pantauan",
        "prefs-watchlist-days": "Jumlah hari maksimum yang ditampilkan di daftar pantauan:",
        "prefs-watchlist-days-max": "Maksimum $1 {{PLURAL:$1|hari|hari}}",
        "prefs-watchlist-edits": "Jumlah suntingan maksimum yang ditampilkan di daftar pantauan yang lebih lengkap:",
        "gender-unknown": "Tak dinyatakan",
        "gender-male": "Laki-laki",
        "gender-female": "Perempuan",
-       "prefs-help-gender": "Opsional: digunakan untuk perbaikan penyebutan jender oleh perangkat lunak. \nInformasi ini akan terbuka untuk umum.",
+       "prefs-help-gender": "Opsional: digunakan untuk perbaikan penyebutan jenis kelamin oleh perangkat lunak. \nInformasi ini akan terbuka untuk umum.",
        "email": "Surel",
        "prefs-help-realname": "Nama asli bersifat opsional.\nJika disediakan, nama ini dapat digunakan untuk memberi atribusi atas karya Anda.",
        "prefs-help-email": "Alamat surel bersifat opsional, namun diperlukan untuk menyetel ulang sandi jika Anda lupa.",
        "right-browsearchive": "Mencari halaman yang telah dihapus",
        "right-undelete": "Mengembalikan halaman yang telah dihapus",
        "right-suppressrevision": "Menampilkan, menyembunyikan dan membatalkan penyembunyian revisi tertentu atas suatu halaman dari pengguna",
+       "right-viewsuppressed": "Lihat revisi yang disembunyikan dari semua pengguna",
        "right-suppressionlog": "Melihat log privat",
        "right-block": "Memblokir penyuntingan oleh pengguna lain",
        "right-blockemail": "Memblokir pengiriman surel oleh pengguna",
        "license": "Jenis lisensi:",
        "license-header": "Jenis lisensi",
        "nolicense": "Tidak ada yang dipilih",
+       "licenses-edit": "Sunting opsi lisensi",
        "license-nopreview": "(Pratayang tak tersedia)",
        "upload_source_url": " (suatu URL valid yang dapat diakses publik)",
        "upload_source_file": " (suatu berkas di komputer Anda)",
        "randomincategory": "Halaman acak dalam kategori",
        "randomincategory-invalidcategory": "\"$1\" bukanlah nama kategori yang berlaku.",
        "randomincategory-nopages": "Tidak ada halaman dalam [[:Category:$1]].",
+       "randomincategory-category": "Kategori:",
+       "randomincategory-legend": "Halaman sembarang di kategori",
        "randomredirect": "Pengalihan sembarang",
        "randomredirect-nopages": "Tak terdapat pengalihan pada ruang nama \"$1\".",
        "statistics": "Statistik",
        "pager-older-n": "{{PLURAL:$1|1 lebih lama|$1 lebih lama}}",
        "suppress": "Pengawas",
        "querypage-disabled": "Halaman istimewa ini dinonaktifkan demi alasan kinerja.",
+       "apihelp": "Bantuan API",
+       "apihelp-no-such-module": "Modul \"$1\" tidak ditemukan.",
        "booksources": "Sumber buku",
        "booksources-search-legend": "Cari di sumber buku",
        "booksources-isbn": "ISBN:",
index d54f14d..d03c816 100644 (file)
@@ -20,7 +20,7 @@
        "tog-numberheadings": "Керташкашта аланза таьрахьа хотта",
        "tog-showtoolbar": "Г|алатнийcдара г|ирсагартакх хьахьокха (JavaScript)",
        "tog-editondblclick": "Шозза д|ато|амцa oаг|ув хувца (JavaScript)",
-       "tog-editsectiononrightclick": "Ð\94екÑ\8aам Ñ\85Ñ\83вÑ\86а ÐºÐµÑ\80Ñ\82мÑ\83гÓ\80а Ð°Ñ\8cÑ\82Ñ\82а Ñ\86лиÑ\86ака Ñ\8f (JavaScript)",
+       "tog-editsectiononrightclick": "РалÑ\81декÑ\8aаÑ\80аÑ\88 Ñ\85Ñ\83вÑ\86а Ð´Ð°Ñ\85каÑ\86а Ð°Ñ\8cÑ\82Ñ\82а Ð´|аÑ\82о|амÑ\86а  ÐºÐµÑ\80Ñ\82аÑ\88ка Ñ\82|а (JavaScript)",
        "tog-watchcreations": "Tеркама хьат|аяздар т|а аз яь оаг|онаши чуяьккха паьлаши т|атоха",
        "tog-watchdefault": "Tеркама хьат|аяздар т|а аз хийца оаг|онаши паьлаша кустяздараши т|атоха",
        "tog-watchmoves": "Tеркама хьат|аяздар т|а аз ц|ихийца оагӀонаши паьлаши т|атоха",
@@ -48,8 +48,9 @@
        "tog-showhiddencats": "Къайла катагаш гойта",
        "underline-always": "Даиман",
        "underline-never": "Ц|аккха",
-       "underline-default": "МазабӀарглокхарий оттамаш хайрамбе",
+       "underline-default": "Мазаб|арглокхарa оттамаш хайраде",
        "editfont-style": "Нийсдара меттига чу йола зарба б|армат:",
+       "editfont-monospace": "Башхалон зарба",
        "sunday": "К|иранди",
        "monday": "Оршот",
        "tuesday": "Шинара",
        "oct": "Тов.",
        "nov": "Лайч.",
        "dec": "Чант.",
+       "january-date": "Нажгамсхой $1",
+       "february-date": "Саькур $1",
+       "march-date": "Муттхьол $1",
+       "april-date": "Тушоли $1",
+       "may-date": "Бекарг $1",
+       "june-date": "Аьтинг $1",
+       "july-date": "К|имарс $1",
+       "august-date": "Мангал $1",
+       "september-date": "Моажол $1",
+       "october-date": "Тов $1",
+       "november-date": "Лайчил $1",
+       "december-date": "Чантар $1",
        "pagecategories": "{{PLURAL:$1|1=Катаг|Катагаш}}",
        "category_header": "\"$1\" Катага чура оаг|онаш",
        "subcategories": "Чуракатагаш",
        "category-empty": "''Укх катага чу цхьаккха оаг|онаш е паьлаш яц.''",
        "hidden-categories": "{{PLURAL:$1|1=Къайла катаг|Къайла катагаш}}",
        "hidden-category-category": "Къайла катагаш",
-       "category-subcat-count": "{{PLURAL:$2|Ð\99ола ÐºÐ°Ñ\82аг Ñ\82Ó\80еÑ\85Ñ\8cаÑ\80а Ð±Ñ\83Ñ\85каÑ\82аг Ñ\87Ñ\83лоаÑ\86а.|{{PLURAL:$1|1=$1 Ð±Ñ\83Ñ\85каÑ\82аг Ñ\85Ñ\8cаÑ\85Ñ\8cекÑ\85а Ñ\8f|$1 Ð±Ñ\83Ñ\85каÑ\82агаÑ\88 Ñ\85Ñ\8cаÑ\85Ñ\8cекÑ\85а Ñ\8f}} $2 Ð¹Ð¾Ð»Ð°Ñ\87аÑ\80а.}}",
-       "category-subcat-count-limited": "Укх катагий {{PLURAL:$1|1=$1 кӀалкатаг|$1 кӀалкатагаш}}.",
-       "category-article-count": "{{PLURAL:$2|Ð\99ола Ñ\86аÑ\82ег Ñ\86Ñ\85Ñ\8cа Ð¾Ð°Ð³Ó\80Ñ\83в Ð¼Ð°Ñ\80а Ñ\87Ñ\83лоаÑ\86аÑ\86.|{{PLURAL:$1|1=$1 Ð¾Ð°Ð³Ó\80Ñ\83в Ñ\85Ñ\8cаÑ\85екÑ\85а Ñ\8f|$1 Ð¾Ð°Ð³Ó\80Ñ\83внаÑ\88 Ñ\85Ñ\8cаÑ\85екÑ\85а Ñ\8f}} Ñ\83кÑ\85 Ñ\86аÑ\82ега $2 Ð¹Ð¾Ð»Ð°Ñ\87аÑ\80ах.}}",
-       "category-article-count-limited": "Укх катагач {{PLURAL:$1|1=$1 оагӀув|$1 оагӀувнаш}}.",
-       "category-file-count": "{{PLURAL:$2|Укх цатего ца паьла мара чулоацац.|{{PLURAL:$1|1=$1 паьла хьахьекха я|$1 паьлаш хьахьекха я}} укх цатегий $2 долачаьрахь.}}",
-       "category-file-count-limited": "Укх катагач {{PLURAL:$1|1=$1 паьл|$1 паьлаш}}.",
+       "category-subcat-count": "{{PLURAL:$2|УкÑ\85 ÐºÐ°Ñ\82агa Ñ\82|еÑ\85Ñ\8cаÑ\80а Ð±Ñ\83Ñ\85каÑ\82аг Ñ\87Ñ\83лоаÑ\86.|{{PLURAL:$1|1=$1 Ð±Ñ\83Ñ\85каÑ\82аг Ñ\85Ñ\8cаÑ\85Ñ\8cекÑ\85а Ñ\8f|$1 Ð±Ñ\83Ñ\85каÑ\82агаÑ\88 Ñ\85Ñ\8cаÑ\85Ñ\8cекÑ\85а Ñ\8f}} $2 Ð¹Ð¾Ð»Ð°Ñ\87аÑ\80ex.}}",
+       "category-subcat-count-limited": "Укх катагa чу {{PLURAL:$1|1=$1 к|алкатаг|$1 к|алкатагаш}}.",
+       "category-article-count": "{{PLURAL:$2|УкÑ\85 ÐºÐ°Ñ\82ага Ñ\86Ñ\85Ñ\8cа Ð¾Ð°Ð³|Ñ\83в Ð¼Ð°Ñ\80а Ñ\87Ñ\83лоаÑ\86аÑ\86.|{{PLURAL:$1|1=$1 Ð¾Ð°Ð³|Ñ\83в Ñ\85Ñ\8cаÑ\85екÑ\85а Ñ\8f|$1 Ð¾Ð°Ð³|oнаÑ\88 Ñ\85Ñ\8cаÑ\85екÑ\85а Ñ\8f}} Ñ\83кÑ\85 ÐºÐ°Ñ\82ага $2 Ð¹Ð¾Ð»Ð°Ñ\87аÑ\80eх.}}",
+       "category-article-count-limited": "Укх катага чу {{PLURAL:$1|1=$1 оаг|ув|$1 оаг|oнаш}}.",
+       "category-file-count": "{{PLURAL:$2|Укх катаг чу цхьа лурдар мара дац.|{{PLURAL:$1|1=$1 лурдар хьахьекха я|$1 лурдараш хьахьекха я}} укх катагa $2 долачаьрeх.}}",
+       "category-file-count-limited": "Укх катага чу {{PLURAL:$1|1=$1 лурдар|$1 лурдараш}}.",
        "listingcontinuesabbrev": "д|ахо",
        "index-category": "Д|ахьожама оаг|онаш",
        "noindex-category": "Д|ахьожаманза оаг|онаш",
        "newwindow": "(кердача коре)",
        "cancel": "Эшац",
        "moredotdotdot": "Д|ахо",
-       "mypage": "Са оагӀув",
+       "morenotlisted": "Ер |ояздар хьалдиззанз да.",
+       "mypage": "Oаг|ув",
        "mytalk": "Дувцам",
        "anontalk": "Укх IP-меттига дувцам",
        "navigation": "Наькъатохкарг",
        "actions": "Х|амдараш",
        "namespaces": "Ц|ерий аренаш",
        "variants": "Дешкепаш",
+       "navigation-heading": "Наькъагойтара хоржаг|ирс",
        "errorpagetitle": "Г|алат",
        "returnto": "цу $1 оаг|он т|а юхаг|о",
        "tagline": "Кечал укхазара я {{SITENAME}}",
        "permalink": "Даиман латташ йола хьожадерг",
        "print": "Кепатохар",
        "view": "Б|аргтассам",
+       "view-foreign": "Мазаоаг|он чу $1 хьажа",
        "edit": "Хувца",
        "create": "Хьаде",
        "editthispage": "Ер оаг|ув хувца",
        "create-this-page": "Ep oаг|ув хьае",
        "delete": "Д|аяккха",
        "deletethispage": "Ер оаг|ув д|аяьккха",
+       "undeletethispage": "Ер оаг|ув д|аяккханз йита",
        "undelete_short": "Меттаоттае {{PLURAL:$1|1=хувцам|$1 хувцамаш}}",
-       "viewdeleted_short": "БӀаргтасса {{PLURAL:$1|1=дӀадаьккха хувцам тӀа|$1 дӀадаьккха хувцамаш тӀа}}",
+       "viewdeleted_short": "Б|аргтасса {{PLURAL:$1|1=д|адаьккха хувцам|$1 д|адаьккха хувцамаш}}",
        "protect": "Лораде",
        "protect_change": "хувца",
        "protectthispage": "Лорае ер оаг|ув",
        "otherlanguages": "Кхыча меттаех",
        "redirectedfrom": "($1 тӀера хьадейта да)",
        "redirectpagesub": "ДӀа-хьа дайта оагӀув",
+       "redirectto": "Д|ахьожаде укх т|а:",
        "lastmodifiedat": "Укх оагӀув тӀехьара  хувцам: $2, $1.",
-       "viewcount": "Укх оагӀув тӀа бӀаргтасса хиннад {{PLURAL:$1|1=цхьазза|$1 шозза}}.",
+       "viewcount": "Укх оаг|oн т|а б|аргтассаб {{PLURAL:$1|цхьааца\n|$1 times}}. {{PLURAL:$1|1=цхьазза|$1за}}.",
        "protectedpage": "Лорама оагӀув",
        "jumpto": "Укхаза дехьа гӀо:",
        "jumptonavigation": "никътохкарг",
        "pool-timeout": "ЧIегатохара сабаран ха чакхаяьннай",
        "pool-queuefull": "Хаттарий цӀа хьалдизад",
        "pool-errorunknown": "Довзаш доаца гӀалат",
+       "poolcounter-usage-error": "Лелдара г|алат: $1",
        "aboutsite": "Лоацам {{SITENAME}}",
        "aboutpage": "Project:Лоацам",
        "copyright": "$1 чулоацамаца тIакхоачаш да.",
        "hidetoc": "къайладаккха",
        "collapsible-collapse": "чудерзаде",
        "collapsible-expand": "хьадоаржаде",
+       "confirmable-yes": "X|аа",
+       "confirmable-no": "A",
        "thisisdeleted": "$1 бӀаргтасса е юхаметтаоттаде?",
        "viewdeleted": "$1 бӀаргтасса?",
-       "restorelink": "{{PLURAL:$1|1=дӀаяьккха хувцам|$1 дӀаяьккха хувцамаш}}",
+       "restorelink": "{{PLURAL:$1|1=д|адaьккха хувцам|$1 д|адaьккха хувцамаш}}",
        "feedlinks": "Цу тайпара:",
        "site-rss-feed": "$1 RSS мугӀ",
        "site-atom-feed": "$1 Atom мугӀ",
        "nosuchaction": "Цу тайпара дулархIам бац",
        "nosuchspecialpage": "Изза мо гӀон оагӀув яц",
        "error": "ГӀалат",
+       "databaseerror-query": "Дехар: $1",
+       "databaseerror-function": "Белхма|ан: $1",
+       "databaseerror-error": "Г|алат: $1",
        "missing-article": "Кораде дезаш хинна оагӀувни яздам корадаьдац «$1» $2.\n\nИз мо гӀалат нийсалуш хула, саг тишъенна Ӏинкаца, д|адаьккха дола оагӀувни хувца искара тӀа чувала гӀертача.\n\nНаггахь санна из иштта децe, шоана гӀорса Ӏалаш деча гӀалат кораяь хила мега.\nДехар да, [[Special:ListUsers/sysop|мазакулгалхочоа]] хоам бе, URL хьахьокхаш.",
        "missingarticle-rev": "(бӀаргоагӀув № $1)",
+       "missingarticle-diff": "(башх: $1, $2)",
        "internalerror": "Чура гӀалат",
        "internalerror_info": "Чура гӀалат: $1",
        "cannotdelete-title": "ОагIув дIаяккха йиш яц \"$1\"",
        "badtitletext": "Дехаш дола оагӀувни цӀи, нийса яц, яьсса я е меттаюкъара е массаюкъара цӀи харцахь я. ЦӀера юкъе мегаш доаца харакъаш нийсаденна хила мегаш да.",
        "viewsource": "БIаргтассам",
        "actionthrottled": "Сихален овзамал",
-       "protectedpagetext": "Ð¥Ñ\83вÑ\86аман Ð±ÐµÐ»Ñ\85аÑ\88 Ð´Ð¾Ð»Ð°Ñ\88 ÐµÑ\80 Ð¾Ð°Ð³IÑ\83в ÐºÑ\8aайла Ñ\8f.",
+       "protectedpagetext": "Ð\95Ñ\80 Ð¾Ð°Ð³|Ñ\83в ÐºÑ\8aайла Ñ\8f Ñ\85Ñ\83вÑ\86амаÑ\88 Ð´ÐµÑ\80гдоаÑ\86аÑ\88 Ðµ ÐºÑ\85Ñ\8b Ð´Ð¾Ð»Ð° Ñ\85|амдаÑ\80аÑ\88.",
        "virus-unknownscanner": "довзашдоаца мазаундохьалург:",
+       "welcomeuser": "Маьрша доаг|алд, $1!",
        "yourname": "Дакъалаьцархочунна цӀи:",
        "yourpassword": "КъайладIоагӀа:",
        "yourpasswordagain": "КъайладIоагӀа юха Ӏоязаде:",
        "userlogin-resetlink": "Чувала/яла цӀии дIоагӀаи дийцаденнадий?",
        "createaccountmail": "КъайладIоагIа д-хоамнец хьадайта",
        "createaccountreason": "Бахьан:",
+       "createacct-reason": "Бахьан",
        "badretype": "Оаша яьккха дIоагIий цIераш шоайл таралуш яц.",
        "loginerror": "Дакъалаьцархочун цIи нийса яц",
-       "mailmypassword": "Керда къайладIоагӀа хьаэца",
+       "mailmypassword": "Керда къайлад|оаг|а эца",
        "mailerror": "Хоам дIабохьийташ гIалат даьннад: $1",
        "emailconfirmlink": "Доаржален хоамни хьожадорг дIачIоагIаде",
        "loginlanguagelabel": "Мотт: $1",
        "rev-delundel": "хьахьокха/къайлаяьккха",
        "rev-showdeleted": "хьахьокха",
        "revdelete-show-file-submit": "XӀаа",
-       "revdelete-radio-set": "XӀаа",
-       "revdelete-radio-unset": "A",
+       "revdelete-radio-set": "Къайла",
+       "revdelete-radio-unset": "Гуш йола",
        "revdelete-log": "Бахьан",
        "revdel-restore": "Кустгойтам хувца",
        "pagehist": "ОагӀува искар",
        "search-section": " (дакъа $1)",
        "search-suggest": "Iа лохар из хила мега: $1",
        "search-interwiki-caption": "Гаргалон хьахьоадайтамаш",
-       "search-interwiki-default": "$1 Ñ\82оламÑ\87аш:",
+       "search-interwiki-default": "$1 Ñ\85Ñ\8cаÑ\85иннаÑ\80аш:",
        "search-interwiki-more": "(кха)",
        "search-relatedarticle": "шоайл дола",
        "searchrelated": "гаргара",
        "timezoneregion-europe": "Аьроп",
        "timezoneregion-indian": "ХIинда форд",
        "timezoneregion-pacific": "Тийна форд",
-       "prefs-searchoptions": "ТоÑ\85кама Ð¾Ñ\82Ñ\82амаÑ\88",
+       "prefs-searchoptions": "Ð\9bаÑ\85аÑ\80",
        "prefs-files": "Паьлаш",
        "youremail": "Д-хоамни:",
-       "username": "Дакъалаьцархочунна цIи:",
+       "username": "{{GENDER:$1|Доакъошхочун ц|и}}:",
        "yourrealname": "Шун цIи:",
        "yourlanguage": "Мотт:",
-       "gender-male": "Ма",
-       "gender-female": "Ð\9aÑ\85ал",
+       "gender-male": "Массаоаг|онаш нийсaеш ва из",
+       "gender-female": "Ð\9cаÑ\81Ñ\81аоаг|онаÑ\88 Ð½Ð¸Ð¹Ñ\81аеÑ\88 Ñ\8f Ð¸Ð·",
        "email": "Д-хоамни",
        "prefs-help-email": "Д-хоамни моттиг ала эшаш дац, амма новкъа даца, наггахь санна къайладIоагIа шоана дийцалой, цу тIа хьатIадайтаргда.",
        "prefs-help-email-others": "Кхыбола дакъалаьцархоша шоаца бувзам я йийшхургья шун оагIува тIа гIолла, д-хоамни хьаела ца езаш.",
        "whatlinkshere-hidelinks": "$1 Iинкаш",
        "whatlinkshere-hideimages": "$1 суртIинкаш",
        "whatlinkshere-filters": "ЦIенъераш",
-       "blockip": "Ð\94акÑ\8aалаÑ\8cÑ\86аÑ\80Ñ\85оÑ\87Ñ\83нна Ñ\87Iега бола",
+       "blockip": "УкÑ\85 {{GENDER:$1|доакÑ\8aоÑ\88Ñ\85оÑ\87оа}} Ñ\87|ега бола",
        "ipboptions": "2 сахьат:2 hours,1 ди:1 day,3 ди:3 days,1 кIира:1 week,2 кIира:2 weeks,1 бутт:1 month,3 бутт:3 months,6 бутт:6 months,1 шу:1 year,сиха ца луш:infinite",
        "ipblocklist": "ЧIега бела дакъалаьцархой",
        "blocklink": "чIегa тоха",
index 0696ba7..aa6e60b 100644 (file)
        "prefs-personal": "Profilo utente",
        "prefs-rc": "Ultime modifiche",
        "prefs-watchlist": "Osservati speciali",
+       "prefs-editwatchlist": "Modifica osservati speciali",
+       "prefs-editwatchlist-label": "Modifica le voci sulla tua watchlist:",
+       "prefs-editwatchlist-edit": "Visualizza e rimuovi titoli sulla tua watchlist",
+       "prefs-editwatchlist-raw": "Modifica la lista in formato testo",
+       "prefs-editwatchlist-clear": "Cancella la tua watchlist",
        "prefs-watchlist-days": "Numero di giorni da mostrare negli osservati speciali:",
        "prefs-watchlist-days-max": "Massimo $1 {{PLURAL:$1|giorno|giorni}}",
        "prefs-watchlist-edits": "Numero di modifiche da mostrare con le funzioni avanzate:",
        "right-override-export-depth": "Esporta le pagine includendo le pagine collegate fino ad una profondità di 5",
        "right-sendemail": "Invia email ad altri utenti",
        "right-passwordreset": "Vede i messaggi di reimpostazione della password",
+       "right-managechangetags": "Crea ed elimina dal database i [[Special:Tags|tag]]",
        "newuserlogpage": "Nuovi utenti",
        "newuserlogpagetext": "Di seguito sono elencate le utenze di nuova creazione.",
        "rightslog": "Diritti degli utenti",
        "action-viewmyprivateinfo": "vedere i propri dati personali",
        "action-editmyprivateinfo": "modificare i propri dati personali",
        "action-editcontentmodel": "modificare il modello di contenuto di una pagina",
+       "action-managechangetags": "crea ed elimina i tag dal database",
        "nchanges": "$1 {{PLURAL:$1|modifica|modifiche}}",
        "enhancedrc-since-last-visit": "$1 {{PLURAL:$1|dall'ultima visita}}",
        "enhancedrc-history": "cronologia",
        "tags-tag": "Nome dell'etichetta",
        "tags-display-header": "Aspetto nella lista delle modifiche",
        "tags-description-header": "Descrizione completa del significato",
+       "tags-source-header": "Sorgente",
        "tags-active-header": "Attivo?",
        "tags-hitcount-header": "Modifiche che hanno etichetta",
+       "tags-actions-header": "Azioni",
        "tags-active-yes": "Sì",
        "tags-active-no": "No",
+       "tags-source-extension": "Definito da un'estensione",
+       "tags-source-manual": "Applicato manualmente da utenti e bot",
+       "tags-source-none": "Non più in uso",
        "tags-edit": "modifica",
+       "tags-delete": "cancella",
+       "tags-activate": "attiva",
+       "tags-deactivate": "disattiva",
        "tags-hitcount": "$1 {{PLURAL:$1|modifica|modifiche}}",
+       "tags-manage-no-permission": "Non hai il permesso di gestire il cambiamento tag.",
+       "tags-create-heading": "Crea un nuovo tag",
+       "tags-create-explanation": "Per impostazione predefinita, i tag appena creati saranno disponibili per l'utilizzo di utenti e bot.",
+       "tags-create-tag-name": "Nome del tag:",
+       "tags-create-reason": "Motivo:",
+       "tags-create-submit": "Crea",
+       "tags-create-no-name": "È necessario specificare un nome di tag.",
+       "tags-create-invalid-chars": "I nomi dei tag non devono contenere virgole (<code>,</code>) o barre (<code>/</code>).",
+       "tags-create-invalid-title-chars": "I nomi dei tag non devono contenere caratteri che non possono essere utilizzati nei titoli delle pagine.",
+       "tags-create-already-exists": "Il tag \"$1\" esiste già.",
+       "tags-create-warnings-below": "Desideri continuare a creare il tag?",
+       "tags-delete-title": "Elimina tag",
+       "tags-delete-explanation-initial": "Stai per eliminare il tag \"$1\" dal database.",
+       "tags-delete-explanation-warning": "Questa azione è <strong>irreversibile</strong> e <strong>non può essere annullata</strong>, nemmeno da amministratori di database. Accertati che questo sia davvero il tag che intendi eliminare.",
+       "tags-delete-reason": "Motivo:",
+       "tags-delete-submit": "Elimina irreversibilmente questo tag",
+       "tags-delete-not-allowed": "I tag definiti da un'estensione non possono essere eliminati a meno che ciò non sia specificamente permesso dall'estensione.",
+       "tags-delete-not-found": "Il tag \"$1\" non esiste.",
+       "tags-delete-too-many-uses": "Il tag \"$1\" è applicato a più di $2 {{PLURAL:$2|revisione|revisioni}}, il che significa che non può essere eliminato.",
+       "tags-delete-warnings-after-delete": "Il tag \"$1\" è stato eliminato con successo, ma fai attenzione {{PLURAL:$2|al seguente avviso|ai seguenti avvisi}}:",
+       "tags-activate-title": "Attiva tag",
+       "tags-activate-question": "Stai per attivare il tag \"$1\".",
+       "tags-activate-reason": "Motivo:",
+       "tags-activate-not-allowed": "Non è possibile attivare il tag \"$1\".",
+       "tags-activate-not-found": "Il tag \"$1\" non esiste.",
+       "tags-activate-submit": "Attiva",
+       "tags-deactivate-title": "Disattiva il tag",
+       "tags-deactivate-question": "Stai per disattivare il tag \"$1\".",
+       "tags-deactivate-reason": "Motivo:",
+       "tags-deactivate-not-allowed": "Non è possibile disattivare il tag \"$1\".",
+       "tags-deactivate-submit": "Disattiva",
        "comparepages": "Confronta le pagine",
        "compare-page1": "Pagina 1",
        "compare-page2": "Pagina 2",
        "logentry-upload-upload": "$1 {{GENDER:$2|ha caricato}} $3",
        "logentry-upload-overwrite": "$1 {{GENDER:$2|ha caricato}} una nuova versione di $3.",
        "logentry-upload-revert": "$1 {{GENDER:$2|ha caricato}} $3",
+       "log-name-managetags": "Registro gestione tag",
+       "logentry-managetags-create": "$1 {{GENERE:$2|ha creato}} il tag \"$4\"",
        "rightsnone": "(nessuno)",
        "revdelete-summary": "oggetto della modifica",
        "feedback-bugornote": "Se si è in grado di descrivere il problema tecnico riscontrato in maniera precisa, [$1 segnalate il bug]. In alternativa, si può usare il modulo semplificato sottostante. Il commento inserito sarà aggiunto alla pagina \"[$3 $2]\", insieme al proprio nome utente e al browser in uso.",
index cb52a24..9d80263 100644 (file)
        "category-empty": "<em>このカテゴリには現在、ページやメディアが何もありません。</em>",
        "hidden-categories": "{{PLURAL:$1|隠しカテゴリ}}",
        "hidden-category-category": "隠しカテゴリ",
-       "category-subcat-count": "{{PLURAL:$2|このカテゴリには以下の下位カテゴリのみが含まれています。|このカテゴリには $2 下位カテゴリが含まれており、そのうち以下の {{PLURAL:$1|$1 下位カテゴリ}}を表示しています。}}",
-       "category-subcat-count-limited": "このカテゴリには以下の{{PLURAL:$1|下位カテゴリ|​&#32;$1 下位カテゴリ}}が含まれています。",
+       "category-subcat-count": "{{PLURAL:$2|このカテゴリには以下の下位カテゴリのみが含まれています。|このカテゴリには$2件の下位カテゴリが含まれており、そのうち以下の{{PLURAL:$1|下位カテゴリ$1件}}を表示しています。}}",
+       "category-subcat-count-limited": "このカテゴリには以下の{{PLURAL:$1|下位カテゴリ|​&#32;$1件の下位カテゴリ}}が含まれています。",
        "category-article-count": "{{PLURAL:$2|このカテゴリには以下のページのみが含まれています。|このカテゴリには $2 ページが含まれており、そのうち以下の $1 ページを表示しています。}}",
        "category-article-count-limited": "現在のカテゴリには以下の{{PLURAL:$1|ページ|​&#32;$1 ページ}}が含まれています。",
        "category-file-count": "{{PLURAL:$2|このカテゴリには以下のファイルのみが含まれています。|このカテゴリには $2 ファイルが含まれており、そのうち以下の {{PLURAL:$1|$1 ファイル}}を表示しています。}}",
        "searchprofile-everything-tooltip": "全本文ページ (トークページを含む) 内を検索",
        "searchprofile-advanced-tooltip": "特定の名前空間内を検索",
        "search-result-size": "$1 ({{PLURAL:$2|$2 語}})",
-       "search-result-category-size": "{{PLURAL:$1|$1 件}} ({{PLURAL:$2|$2 下位カテゴリ}}、{{PLURAL:$3|$3 ファイル}})",
+       "search-result-category-size": "{{PLURAL:$1|$1件}} ({{PLURAL:$2|下位カテゴリ$2件}}、{{PLURAL:$3|ファイル$3件}})",
        "search-redirect": "($1からのリダイレクト)",
        "search-section": "($1の節)",
        "search-category": "(カテゴリ $1)",
        "tags-active-yes": "はい",
        "tags-active-no": "いいえ",
        "tags-edit": "編集",
+       "tags-delete": "削除",
        "tags-hitcount": "$1 {{PLURAL:$1|回の変更}}",
+       "tags-create-reason": "理由:",
+       "tags-create-submit": "作成",
+       "tags-delete-title": "タグを削除",
+       "tags-delete-reason": "理由:",
+       "tags-activate-reason": "理由:",
+       "tags-deactivate-reason": "理由:",
        "comparepages": "ページの比較",
        "compare-page1": "ページ 1",
        "compare-page2": "ページ 2",
index ea98632..c27d17c 100644 (file)
        "tags-tag": "ტეგის სახელი",
        "tags-display-header": "რედაქტირებების სიაში ცვლილებების წარმოდგენა",
        "tags-description-header": "მნიშვნელობის სრული აღწერა",
+       "tags-source-header": "წყარო",
        "tags-active-header": "აქტიურია?",
        "tags-hitcount-header": "აღნიშნული ცვლილებები",
+       "tags-actions-header": "ქმედებები",
        "tags-active-yes": "დიახ",
        "tags-active-no": "არა",
+       "tags-source-none": "აღარ გამოიყენება",
        "tags-edit": "რედაქტირება",
+       "tags-delete": "წაშლა",
+       "tags-activate": "გააქტიურება",
+       "tags-deactivate": "დეაქტივაცია",
        "tags-hitcount": "$1 ცვლილება",
+       "tags-create-heading": "ახალი ტეგის შექმნა",
+       "tags-create-tag-name": "ტეგის სახელი:",
+       "tags-create-reason": "მიზეზი",
+       "tags-create-submit": "შექმნა",
+       "tags-delete-title": "ტეგის წაშლა",
+       "tags-delete-reason": "მიზეზი:",
+       "tags-activate-title": "ტეგის გააქტიურება",
+       "tags-activate-reason": "მიზეზი:",
+       "tags-activate-submit": "გააქტიურება",
+       "tags-deactivate-title": "ტეგის დეაქტივაცია",
+       "tags-deactivate-reason": "მიზეზი:",
+       "tags-deactivate-submit": "დეაქტივაცია",
        "comparepages": "გვერდების შედარება",
        "compare-page1": "1 გვერდი",
        "compare-page2": "2 გვერდი",
index 8c8088e..f885ba1 100644 (file)
@@ -26,6 +26,7 @@
        "tog-watchdefault": "Мен өңдеген беттерді және файлдарды бақылау тізіміне қосу",
        "tog-watchmoves": "Мен жылжытқан беттерді және файлдарды бақылау тізіміне қосу",
        "tog-watchdeletion": "Мен жойған беттерді және файлдарды бақылау тізіміне қосу",
+       "tog-watchrollback": "Мен шегіндіруін орындаған беттерді бақылау тізіміме қосу",
        "tog-minordefault": "Әдепкі бойынша барлық өңдемелерді шағын деп белгілеу",
        "tog-previewontop": "Қарап шығу аумағын өңдеу терезесінің жоғарғы жағында көрсету",
        "tog-previewonfirst": "Бірінші өңдегенде алдын-ала қарап шығу",
@@ -52,7 +53,7 @@
        "tog-prefershttps": "Кірген кезде қауіпсіз байланысуды әрқашан қолдану",
        "underline-always": "Әрқашан",
        "underline-never": "Ешқашан",
-       "underline-default": "Ó\98депкÑ\96 Ð¼Ó\99неÑ\80 Ð½Ðµ Ð±Ñ\80оÑ\83зер",
+       "underline-default": "Ó\98депкÑ\96 Ð±Ñ\80оÑ\83зеÑ\80 Ð½Ðµ Ð¼Ó\99нер",
        "editfont-style": "Өңдеу аумағындағы қаріп мәнері",
        "editfont-default": "Негізгі браузер",
        "editfont-monospace": "Бірдей енді қаріп",
        "virus-badscanner": "Дұрыс емес ішқұрылым. Белгісіз вирус скайнері: <em>$1</em>",
        "virus-scanfailed": "скайнерлеу орындалмады (коды: $1)",
        "virus-unknownscanner": "белгісіз антивирус:",
-       "logouttext": "<strong>Ð\96үйеден Ñ\88Ñ\8bÒ\9bÑ\82Ñ\8bÒ£Ñ\8bз.</strong>\n\nÐ\9aейбÑ\96Ñ\80 Ð±ÐµÑ\82Ñ\82еÑ\80 Ð±Ñ\80оузеріңіздің кэшін тазартқанша әлі де жүйеге кіріп отырғаныңыздай көрінуі мүмкіндігін ескеріңіз.",
+       "logouttext": "<strong>Ð\96үйеден Ñ\88Ñ\8bÒ\9bÑ\82Ñ\8bÒ£Ñ\8bз.</strong>\n\nÐ\9aейбÑ\96Ñ\80 Ð±ÐµÑ\82Ñ\82еÑ\80 Ð±Ñ\80аузеріңіздің кэшін тазартқанша әлі де жүйеге кіріп отырғаныңыздай көрінуі мүмкіндігін ескеріңіз.",
        "welcomeuser": "Қош келдіңіз, $1!",
        "welcomecreation-msg": "Сіз тіркелдіңіз.\n{{SITENAME}} [[Special:Preferences|баптауларыңызды]] өзіңіз қалауыңыз бойынша өзгерте аласыз.",
        "yourname": "Қатысушы аты:",
        "protectlogtext": "Төменде беттердің қорғау/қорғамау тізімі берілген.\nАғымдағы қорғау әректтер бар беттер үшін [[Special:ProtectedPages|қорғалған беттер тізімін]] қараңыз.",
        "protectedarticle": "«[[$1]]» бетін қорғады",
        "modifiedarticleprotection": "«[[$1]]» бетінің қорғалу деңгейін өзгертті",
-       "unprotectedarticle": "«[[$1]]» Ð´ÐµÐ³ÐµÐ½Ð½ÐµÐ½ Ò\9bоÑ\80Ò\93алÑ\83Ñ\8bн Ð¶Ñ\8bлжÑ\8bÑ\82Ñ\82ы",
+       "unprotectedarticle": "«[[$1]]» Ð±ÐµÑ\82Ñ\96нÑ\96Ò£ Ò\9bоÑ\80Ò\93алÑ\83Ñ\8bн Ð°Ð»Ð°Ñ\81Ñ\82ады",
        "movedarticleprotection": "қорғалу баптауларын «[[$2]]» дегеннен «[[$1]]» дегенге жылжытты",
        "protect-title": "«$1» қорғау деңгейін өзгерту",
        "protect-title-notallowed": "«$1» қорғалу деңгейін қарау",
        "fileduplicatesearch-result-n": "«$1» файлына тең $2 телнұсқасы бар.",
        "fileduplicatesearch-noresults": "\"$1\" атауымен файл табылмады.",
        "specialpages": "Арнайы беттер",
-       "specialpages-note": "* Қалпты арнайы беттер.\n* <span class==\"mw-specialpagerestricted\">Шектелген арнайы беттер.</span>",
+       "specialpages-note": "* Қалыпты арнайы беттер. \n* <span class==\"mw-specialpagerestricted\">Шектелген арнайы беттер.</span>",
        "specialpages-group-maintenance": "Техникалық талқылау есептері",
        "specialpages-group-other": "Тағы басқа арнайы беттер",
        "specialpages-group-login": "Кіру / тіркелу",
index 6f9c049..6444df3 100644 (file)
@@ -42,7 +42,9 @@
                        "Bluemersen",
                        "Revi",
                        "Namoroka",
-                       "양념파닭"
+                       "양념파닭",
+                       "콩가루",
+                       "Twotwo2019"
                ]
        },
        "tog-underline": "링크에 밑줄:",
        "pool-queuefull": "풀 대기열이 가득 찼습니다",
        "pool-errorunknown": "알 수 없는 오류",
        "pool-servererror": "풀 카운터 서비스는 사용할 수 없습니다 ($1).",
+       "poolcounter-usage-error": "어법 에러: $1",
        "aboutsite": "{{SITENAME}} 소개",
        "aboutpage": "Project:소개",
        "copyright": "내용은 별도로 명시하지 않을 경우 $1에 따라 사용할 수 있습니다.",
        "prefs-personal": "사용자 정보",
        "prefs-rc": "최근 바뀜",
        "prefs-watchlist": "주시문서 목록",
+       "prefs-editwatchlist": "주시목록 편집",
+       "prefs-editwatchlist-clear": "주시문서 목록 지우기",
        "prefs-watchlist-days": "주시문서 목록에서 볼 날짜 수:",
        "prefs-watchlist-days-max": "최대 $1{{PLURAL:$1|일}}",
        "prefs-watchlist-edits": "주시문서 목록에서 볼 편집 수:",
        "right-purge": "확인 없이 문서의 캐시를 새로 고침",
        "right-autoconfirmed": "IP 기반의 속도 제한에 영향을 받지 않음",
        "right-bot": "봇의 편집으로 취급",
-       "right-nominornewtalk": "토론 문서에 사소한 편집으로 새 메시지를 보낼 수 없음",
+       "right-nominornewtalk": "토론 문서에서 사소한 편집으로 새 메시지 알림을 보내지 않기",
        "right-apihighlimits": "API 상한 상승",
        "right-writeapi": "쓰기 API 사용",
        "right-delete": "문서 삭제",
        "right-editmyuserjs": "자신의 사용자 자바스크립트 파일 편집하기",
        "right-viewmywatchlist": "자신의 주시문서 목록 보기",
        "right-editmywatchlist": "자신의 주시문서 목록을 편집합니다. 이 권한이 없어도 문서를 추가할 수 있는 권한이 이외에도 있음을 참고하세요.",
-       "right-viewmyprivateinfo": "자신의 개인 데이터 보기 (예를 들어 이메일 주소, 실명)",
-       "right-editmyprivateinfo": "자신의 개인 데이터 편집 (예를 들어 이메일 주소, 실명)",
+       "right-viewmyprivateinfo": "자신의 개인정보 보기 (이메일 주소, 실명 등)",
+       "right-editmyprivateinfo": "자신의 개인정보 편집 (이메일 주소, 실명 등)",
        "right-editmyoptions": "자신의 환경 설정 편집",
        "right-rollback": "특정 문서를 편집한 마지막 사용자의 편집을 신속하게 되돌리기",
        "right-markbotedits": "되돌리기를 봇의 편집으로 취급 가능",
        "right-override-export-depth": "5단계로 링크된 문서를 포함하여 문서를 내보내기",
        "right-sendemail": "다른 사용자에게 이메일 보내기",
        "right-passwordreset": "비밀번호 재설정 이메일을 보기",
+       "right-managechangetags": "데이터베이스에서 [[Special:Tags|태그]]를 만들거나 지우기",
        "newuserlogpage": "사용자 만들기 기록",
        "newuserlogpagetext": "사용자가 만들어진 기록입니다.",
        "rightslog": "사용자 권한 기록",
        "action-sendemail": "이메일 보내기",
        "action-editmywatchlist": "내 주시문서 목록 편집",
        "action-viewmywatchlist": "내 주시문서 목록 보기",
-       "action-viewmyprivateinfo": "내 개인 정보 보기",
-       "action-editmyprivateinfo": "내 개인 정보 편집",
+       "action-viewmyprivateinfo": "자신의 개인정보 보기",
+       "action-editmyprivateinfo": "자신의 개인정보 편집",
        "action-editcontentmodel": "문서의 콘텐츠 모델을 편집",
+       "action-managechangetags": "데이터베이스에서 태그를 만들거나 지울",
        "nchanges": "$1개 {{PLURAL:$1|바뀜}}",
        "enhancedrc-since-last-visit": "{{PLURAL:$1|마지막 방문 이후}} $1개",
        "enhancedrc-history": "역사",
        "uploaderror": "올리기 오류",
        "upload-recreate-warning": "<strong>경고: 해당 이름으로 된 파일이 삭제되었거나 옮겨졌습니다.</strong>\n\n편의를 위해 이 문서에 대한 삭제와 옮기기 기록을 다음과 같이 제공합니다:",
        "uploadtext": "파일을 올리기 위해서는 아래의 양식을 채워주세요.\n[[Special:FileList|파일 목록]]에서 이전에 올라온 파일을 검색할 수 있습니다. [[Special:Log/upload|올리기 기록]]에는 파일이 올라온 기록이 남습니다. 삭제 기록은 [[Special:Log/delete|삭제 기록]]에서 볼 수 있습니다.\n\n문서에 파일을 넣으려면 아래 방법 중 하나를 사용하세요.\n* '''<code><nowiki>[[</nowiki>{{ns:file}}<nowiki>:File.jpg]]</nowiki></code>''' 파일의 온전한 모양을 사용하고자 할 때\n* '''<code><nowiki>[[</nowiki>{{ns:file}}<nowiki>:File.png|200픽셀|섬네일|왼쪽|설명]]</nowiki></code>''' 파일의 너비를 200픽셀로 하고 왼쪽 정렬하며 '설명' 이라는 주석을 파일 밑에 달 때\n* '''<code><nowiki>[[</nowiki>{{ns:media}}<nowiki>:File.ogg]]</nowiki></code>''' 파일을 직접 보여주지 않고 파일로 바로 링크할 때",
-       "upload-permitted": "허용하는 파일 확장자: $1",
-       "upload-preferred": "권장하는 파일 확장자: $1",
-       "upload-prohibited": "금지하는 파일 확장자: $1",
+       "upload-permitted": "허용된 파일 {{PLURAL:$2|형식}}: $1",
+       "upload-preferred": "권장 파일 {{PLURAL:$2|형식}}: $1",
+       "upload-prohibited": "금지된 파일 {{PLURAL:$2|형식}}: $1",
        "uploadlogpage": "올리기 기록",
        "uploadlogpagetext": "최근 올라온 파일 목록입니다.\n갤러리 형식으로 확인하고 싶으시다면 [[Special:NewFiles|새 파일 목록]]을 보세요.",
        "filename": "파일 이름",
        "javascripttest": "자바스크립트 테스트",
        "javascripttest-pagetext-noframework": "이 문서는 자바스크립트 테스트를 실행하기 위한 용도로 할당되어 있습니다.",
        "javascripttest-pagetext-unknownframework": "실험용 프레임워크 \"$1\"를 알 수 없습니다.",
+       "javascripttest-pagetext-unknownaction": "알 수 없는 동작 \"$1\".",
        "javascripttest-pagetext-frameworks": "다음 실험용 프레임워크 중 하나를 선택하세요: $1",
        "javascripttest-pagetext-skins": "실험할 스킨을 선택하세요:",
        "javascripttest-qunit-intro": "mediawiki.org의 [$1 테스트 설명서]를 참고하세요.",
        "version-entrypoints-header-url": "URL",
        "version-entrypoints-articlepath": "[https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:$wgArticlePath 문서 경로]",
        "version-entrypoints-scriptpath": "[https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:$wgScriptPath 스크립트 경로]",
+       "version-libraries": "설치된 라이브러리",
+       "version-libraries-library": "라이브러리",
+       "version-libraries-version": "버전",
        "redirect": "파일, 사용자, 문서나 판 ID로 넘겨주기",
        "redirect-legend": "파일이나 문서로 넘겨주기",
        "redirect-summary": "이 특수 문서는 파일(파일 이름이 주어짐), 문서(판 ID나 문서 ID가 주어짐)나 사용자 문서(숫자로 표시된 사용자 ID가 주어짐)로 넘겨줍니다. 사용법: [[{{#Special:Redirect}}/file/Example.jpg]], [[{{#Special:Redirect}}/page/64308]], [[{{#Special:Redirect}}/revision/328429]], 또는 [[{{#Special:Redirect}}/user/101]].",
        "tags-title": "태그",
        "tags-intro": "이 문서는 소프트웨어에서 편집에 대해 표시하는 태그와 그 의미를 설명하는 목록입니다.",
        "tags-tag": "태그 이름",
-       "tags-display-header": "바뀜 목록의 모양",
+       "tags-display-header": "ë°\94ë\80\9c ëª©ë¡\9dì\97\90ì\84\9cì\9d\98 ëª¨ì\96\91",
        "tags-description-header": "태그에 대한 설명",
        "tags-active-header": "활성화 여부",
        "tags-hitcount-header": "태그된 바뀜",
        "tags-active-no": "아니오",
        "tags-edit": "편집",
        "tags-hitcount": "$1개 {{PLURAL:$1|바뀜}}",
+       "tags-create-reason": "이유:",
+       "tags-create-submit": "만들기",
        "comparepages": "문서 비교",
        "compare-page1": "첫 번째 문서",
        "compare-page2": "두 번째 문서",
index 0deb773..793ac69 100644 (file)
        "prefs-personal": "Benotzerprofil",
        "prefs-rc": "Rezent Ännerungen",
        "prefs-watchlist": "Iwwerwaachungslëscht",
+       "prefs-editwatchlist": "Iwwerwaachungslëscht änneren",
+       "prefs-editwatchlist-raw": "Net-formatéiert Iwwerwaachungslëscht änneren",
+       "prefs-editwatchlist-clear": "Är Iwwerwaachungslëscht eidelmaachen",
        "prefs-watchlist-days": "Zuel vun den Deeg, déi an der Iwwerwaachungslëscht ugewise solle ginn:",
        "prefs-watchlist-days-max": "Maximal $1 {{PLURAL:$1|Dag|Deeg}}",
        "prefs-watchlist-edits": "Maximal Zuel vun den Ännerungen déi an der erweiderter Iwwerwaachungslëscht ugewise solle ginn:",
        "tags-tag": "Numm vun der Markéierung",
        "tags-display-header": "Opzielungen op den Ännerungslëschten",
        "tags-description-header": "Ganz Beschreiwung vun der Bedeitung",
+       "tags-source-header": "Quell",
        "tags-active-header": "Aktiv?",
        "tags-hitcount-header": "Markéiert Ännerungen",
+       "tags-actions-header": "Aktiounen",
        "tags-active-yes": "Jo",
        "tags-active-no": "Neen",
+       "tags-source-extension": "Duerch eng Erweiderung definéiert",
+       "tags-source-none": "Gëtt net méi gebraucht",
        "tags-edit": "änneren",
+       "tags-delete": "läschen",
+       "tags-activate": "aktivéieren",
+       "tags-deactivate": "desaktivéieren",
        "tags-hitcount": "$1 {{PLURAL:$1|Ännerung|Ännerungen}}",
+       "tags-create-reason": "Grond:",
+       "tags-create-already-exists": "D'Markéierung (tag) ''$1'' gëtt et schonn.",
+       "tags-delete-title": "Markéierung (tag) läSchen",
+       "tags-delete-reason": "Grond:",
+       "tags-delete-not-found": "D'Markéierung (tag) ''$1'' gëtt et net.",
+       "tags-activate-title": "Markéierung (tag) aktivéieren",
+       "tags-activate-reason": "Grond:",
+       "tags-activate-not-found": "D'Markéierung (tag) ''$1'' gëtt et net.",
+       "tags-activate-submit": "Aktivéieren",
+       "tags-deactivate-title": "Markéierung (tag) desaktivéieren",
+       "tags-deactivate-reason": "Grond:",
+       "tags-deactivate-submit": "Desaktivéieren",
        "comparepages": "Säite vergläichen",
        "compare-page1": "Säit 1",
        "compare-page2": "Säit 2",
index 2ad7a06..f64e51f 100644 (file)
@@ -13,7 +13,8 @@
                        "Yanteng3",
                        "아라",
                        "LNDDYL",
-                       "Jason924tw"
+                       "Jason924tw",
+                       "灰太狼Wolffy55"
                ]
        },
        "tog-underline": "鏈墊線:",
        "delete-toobig": "此頁含大誌,過$1修。刪頁限矣,防於{{SITENAME}}之亂也。",
        "delete-warning-toobig": "此頁含大誌,過$1修。刪之可亂{{SITENAME}}之事也;續時留神之。",
        "rollback": "反正",
-       "rollback_short": "正",
        "rollbacklink": "正",
        "rollbackfailed": "未能反正",
        "cantrollback": "獨一作者,無以反正。",
        "tag-filter": "[[Special:Tags|標]] 之濾:",
        "tags-title": "標",
        "tags-tag": "標名",
+       "tags-source-header": "源",
+       "tags-actions-header": "动",
        "tags-active-yes": "是",
        "tags-active-no": "否",
        "tags-edit": "纂",
+       "tags-delete": "削",
+       "tags-deactivate": "閉",
+       "tags-manage-no-permission": "無准遷檔也。",
+       "tags-create-tag-name": "標名:",
+       "tags-create-reason": "因:",
+       "tags-create-submit": "立",
+       "tags-create-no-name": "子必名此签!",
+       "tags-create-warnings-below": "子欲立此签乎?",
+       "tags-delete-title": "削签",
+       "tags-delete-reason": "因:",
+       "tags-delete-not-found": "$1之頁無存焉。",
+       "tags-activate-title": "活簽",
+       "tags-activate-reason": "因:",
+       "tags-activate-submit": "活",
+       "tags-deactivate-reason": "因:",
+       "tags-deactivate-submit": "闭",
        "comparepages": "較頁",
        "compare-page1": "頁一",
        "compare-page2": "頁二",
index b2d0dcc..7099fd6 100644 (file)
@@ -35,7 +35,7 @@
        "tog-shownumberswatching": "Asehoy ny isan'ny mpikambana manara-maso ny pejy",
        "tog-oldsig": "Topi-mason'ny sonia :",
        "tog-fancysig": "Sonia tsotra (tsy misy rohy)",
-       "tog-uselivepreview": "Hampiasa ny topi-maso malakay (andramana)",
+       "tog-uselivepreview": "Hampiasa ny topi-maso mivantana",
        "tog-forceeditsummary": "Teneno ahy ra tsy nametraka ny ambangovangony",
        "tog-watchlisthideown": "Tsy ampiseho anatin'ny pejy fanaraha-maso ny zavatra nosoratako",
        "tog-watchlisthidebots": "Asitriho amin'ny lisitro ny fanovàna nataon'ny rôbô",
        "viewsourcetext": "Azonao atao no mijery sy mandrika ny votoatin'ity pejy ity :",
        "viewyourtext": "Azonao atao ny mijery ary mandika ny fangon'ny '''fanovanao''' tamin'ity pejy ity:",
        "protectedinterface": "Ity pejy ity dia manome ny lahatsoratra ho an'ny rindrankajy eto amin'ity Wiki ity, ary narovana mba tsy hisian'ny fanararaotana. Raha tia hanampy na hanova ny dikanteny ho an'ny wiki rehetra, ampiasao [//translatewiki.net/ translatewiki.net], izay tetikasa fandikanan ny rindrankajy Mediawiki.",
-       "editinginterface": "'''Tandremo''' : Manova pejy ampiasaina amin'ny famoahana ny hafatray ny rindrankajy ianao io.\n\nHisy fiantraikany amin'ny fisehon'ny tranonkala amin'ny mpampiasa rehetra eto amin'ity wiki ity ny fanovana.\n\nRaha hanampy dikanteny izay tokony hihatra amin'ny wiki rehetra, ampiaao ny tranonkala [//translatewiki.net/ translatewiki.net translatewiki.net], ny tetikasa fandikana an'i MediaWiki.",
+       "editinginterface": "<strong> Fampitandremana: <strong> manova pejy ampiasaina amin'ny famoronan-tsoratry ny rindrankajy ianao. Hisy fiatraika amin'ny fisehon'ny interfasim-pikambana ho an'ny mpikambana hafan'ity wiki ity ny fiovana ho atao.",
        "cascadeprotected": "Ankehitriny dia voaaro ity pejy ity satria misy pejy voaaro {{PLURAL:$1||$1}}1 mampiasa ity pejy ity. Io pejy io dia mampiasa ny fiarovana \"en cascade\" :\n\n$2",
        "namespaceprotected": "Tsy manana alalàna manova ny toeran'anarana « '''$1''' » ianao.",
        "customcssprotected": "Tsy afaka manova ity pejy CSS ity ianao satria misy ny safidy manokan'ny mpikambana hafa.",
        "gender-female": "Manova pejy wiki izy (vehivavy)",
        "prefs-help-gender": "Ankifidy : ampiasaina ho an'ny fifandraisan'ny rindrankajy aminao. Ho sarababem-bahoaka ity fampahalalana ity.",
        "email": "Imailaka",
-       "prefs-help-realname": "Anarana marina (afaka tsy fenoina): raha fenoinao ity dia hampiasaina hanomezana anao tambin'ny asa izay efainao eto.",
+       "prefs-help-realname": "Tsy voatery omena ny tena anarana.\nRaha omena izany dia hanomezana dera ny fandraisan'anjaranao",
        "prefs-help-email": "Azo tsy omena ny adiresy imailaka, fa ilaina izy io raha sendra hadino ny tenimiafinao.",
        "prefs-help-email-others": "Azonareo atao ny misafidy mba hamela ny hafa hifandray aminao eo amin'ny alanana rohy iray eo amin'ny pejin-dresakao.\nTsy haseho ny adiresy imailakao rehefa manoratra any aminao ny mpikambana hafa.",
        "prefs-help-email-required": "Ilaina ny adiresy imailaka",
        "uploaderror": "Nisy tsy fetezana ny fandefasana rakitra",
        "upload-recreate-warning": "'''Tandremo : novain-toerana na nofafana ny rakitra mitondra io anarana io.'''\n\nAseho eo ambany ho fampahalalana fanampiny ny iditra ao amin'ny laogim-panisahana ary ny laogim-pamafana :",
        "uploadtext": "Ampiasao ity fisy ity handefasana rakitra. Jereo eto ny [[Special:FileList|lisitry ny rakitra]] nalefan'ny mpikambana, na koa azonao ampiasaina ny [[Special:Log/delete|tantaran'asan'ny fandefasana sy famonoana rakitra]].\n\nRaha hanisy sary ao anaty pejy, dia mampiasà rohy toy ny iray amin'ireto\n'''<nowiki>[[</nowiki>{{ns:file}}<nowiki>:file.jpg]]</nowiki>''', na\n'''<nowiki>[[</nowiki>{{ns:file}}<nowiki>:file.png|alt text]]</nowiki>''' na\n'''<nowiki>[[</nowiki>{{ns:media}}<nowiki>:file.ogg]]</nowiki>''' raha hirohy mivantana amin'ny rakitra.",
-       "upload-permitted": "Endriky ny rakitra manan-alalana : $1.",
-       "upload-preferred": "Endriky ny rakitra nampidirina : $1",
-       "upload-prohibited": "Endriky ny rakitra tsy manan-alalana : $1",
+       "upload-permitted": "Karazan-drakitra {{PLURAL:$2||}}mahazo alalana : $1",
+       "upload-preferred": "Karazan-drakitra tiana{{PLURAL:$2||}}: $1.",
+       "upload-prohibited": "Karazan-drakitra voarara{{PLURAL:$2||}}: $1.",
        "uploadlogpage": "Fampidiran-drakitra",
        "uploadlogpagetext": "Ity ny lisitr'ireo rakitra nalefa farany indrindra.",
        "filename": "Anarana",
        "delete-toobig": "Ity pejy ity dia manana tantaram-panovana lava be, izany hoe manana versiona {{PLURAL:$1}} $1.\nNoferana mba tsy hikorontana ny fandehanan'i {{SITENAME}} ny famafana ireo pejy ireo.{{PLURAL:$1|}}",
        "delete-warning-toobig": "Lava be mihitsy ny tantaram-piovan'ity pejy ity, mihoatra santiôna $1{{PLURAL:}}.\nMety hitondra fikorontanana ao amin'ny banky angon'i {{SITENAME}} ny famafana azy ;\nataovy am-pitandremana ity tao ity.",
        "rollback": "Foano indray ilay fanovana",
-       "rollback_short": "Aza ovaina indray",
        "rollbacklink": "foano",
        "rollbacklinkcount": "hamoana fanovana{{PLURAL:$1}} $1",
        "rollbackfailed": "Tsy voaverina amin'ny teo aloha",
        "import-logentry-upload": "nampiditra [[$1]] tamin'ny fampidiran-drakitra",
        "import-logentry-interwiki": "nampiditra $1 tamin'ny transwiki",
        "javascripttest": "Fanandramana JavaScript",
-       "javascripttest-title": "Mandefa fanandramana $1",
        "javascripttest-pagetext-skins": "Mifidia skin hanaovana ny fanandramana:",
        "javascripttest-qunit-intro": "Jereo ny [$1 fanoroana mikasika ny andrana] eo amin'i mediawiki.org.",
-       "javascripttest-qunit-heading": "Tohin'andrana QUnit an'i Javascript eo amin'i MediaWiki",
        "tooltip-pt-userpage": "Ny pejinao",
        "tooltip-pt-anonuserpage": "Ny pejim-bikamban'ny IP andraisanao anjara",
        "tooltip-pt-mytalk": "Pejin-dresakao",
index 6f4199c..d57efe7 100644 (file)
        "restorelink": "{{PLURAL:$1|едно избришано уредување|$1 избришани уредувања}}",
        "feedlinks": "Во вид:",
        "feed-invalid": "Погрешен начин на претплата на емитувања",
-       "feed-unavailable": "RSS/Atom емитувањата не се достапни",
+       "feed-unavailable": "RSS/Атом-емитувањата не се достапни",
        "site-rss-feed": "$1 — RSS-емитувања",
-       "site-atom-feed": "$1 — Atom-емитувања",
+       "site-atom-feed": "$1 — Атом-емитувања",
        "page-rss-feed": "„$1“ - RSS емитувања",
-       "page-atom-feed": "„$1“ — Atom-емитувања",
-       "feed-atom": "Atom",
+       "page-atom-feed": "„$1“ — Атом-емитувања",
+       "feed-atom": "Атом",
        "feed-rss": "RSS",
        "red-link-title": "$1 (страницата не постои)",
        "sort-descending": "Подреди надолно",
        "resettokens-legend": "Враќање одново на шифри",
        "resettokens-tokens": "Шифри:",
        "resettokens-token-label": "$1 (тековна вредност: $2)",
-       "resettokens-watchlist-token": "Шифра за каналот (Atom/RSS) на [[Special:Watchlist|измени во набљудуваните страници]]",
+       "resettokens-watchlist-token": "Шифра за каналот (Атом/RSS) на [[Special:Watchlist|измени во набљудуваните страници]]",
        "resettokens-done": "Шифрата е вратена одново.",
        "resettokens-resetbutton": "Врати избрани шифри",
        "bold_sample": "Задебелен текст",
        "right-override-export-depth": "Извезување на страници вклучувајќи поврзани страници со длабочина до 5",
        "right-sendemail": "Испраќање на е-пошта до други корисници",
        "right-passwordreset": "Преглед на пораки по е-пошта за промена на лозинка",
+       "right-managechangetags": "Создавање3 или бришење на [[Special:Tags|ознаки]] од базата",
        "newuserlogpage": "Дневник на регистрирања на корисници",
        "newuserlogpagetext": "Ова е дневник на регистрирани корисници.",
        "rightslog": "Дневник на корисничките права",
        "action-viewmyprivateinfo": "преглед на вашите лични податоци",
        "action-editmyprivateinfo": "уредување на вашите лични податоци",
        "action-editcontentmodel": "уредување на содржинскиот модел на страница",
+       "action-managechangetags": "создавање или бришење на ознаки од базата",
        "nchanges": "$1 {{PLURAL:$1|промена|промени}}",
        "enhancedrc-since-last-visit": "$1 {{PLURAL:$1|од последната посаета}}",
        "enhancedrc-history": "историја",
        "tooltip-t-whatlinkshere": "Список на сите вики-страници што водат овде",
        "tooltip-t-recentchangeslinked": "Скорешни промени на страници со врски на оваа страница",
        "tooltip-feed-rss": "RSS емитување за оваа страница",
-       "tooltip-feed-atom": "Atom емитување за оваа страница",
+       "tooltip-feed-atom": "Атом-емитување за оваа страница",
        "tooltip-t-contributions": "Список на придонеси на овој корисник",
        "tooltip-t-emailuser": "Испрати е-пошта на овој корисник",
        "tooltip-t-info": "Повеќе информаици за страницава",
        "tags-tag": "Име на ознака",
        "tags-display-header": "Изглед во списоците на промени",
        "tags-description-header": "Целосен опис на значењето",
+       "tags-source-header": "Извор",
        "tags-active-header": "Активно?",
        "tags-hitcount-header": "Означени промени",
+       "tags-actions-header": "Дејства",
        "tags-active-yes": "Да",
        "tags-active-no": "Не",
+       "tags-source-extension": "Одредени од додаток",
+       "tags-source-manual": "Применети рачно од корисници и ботови",
+       "tags-source-none": "Вон употреба",
        "tags-edit": "уреди",
+       "tags-delete": "избриши",
+       "tags-activate": "активирај",
+       "tags-deactivate": "деактивирај",
        "tags-hitcount": "$1 {{PLURAL:$1|промена|промени}}",
+       "tags-manage-no-permission": "Немате дозвола за раководење со ознаки за промени.",
+       "tags-create-heading": "Создај нова ознака",
+       "tags-create-explanation": "Новосоздадните ознаки по основно ќе се стават на располагање за употреба од корисници и ботови.",
+       "tags-create-tag-name": "Име на ознаката:",
+       "tags-create-reason": "Причина:",
+       "tags-create-submit": "Создај",
+       "tags-create-no-name": "Мора да укажете име на ознаката.",
+       "tags-create-invalid-chars": "Ознаката не смее да содржи запирки (<code>,</code>) и надесни коси црти (<code>/</code>).",
+       "tags-create-invalid-title-chars": "Имињата на ознаките не смеат да содржат знаци што не може да се користат во наслови на страници.",
+       "tags-create-already-exists": "Ознаката „$1“ веќе постои.",
+       "tags-create-warnings-above": "Во обидот да ја создадам ознаката „$1“ наидов на {{PLURAL:$2|следново предупредување|следниве предупредувања}}:",
+       "tags-create-warnings-below": "Дали сакате да продолжите со создавањето на ознаката?",
+       "tags-delete-title": "Избриши ознака",
+       "tags-delete-explanation-initial": "На пат сте да ја избришете ознаката „$1“ од базата.",
+       "tags-delete-explanation-in-use": "Ќе биде отстранета од {{PLURAL:$2|една преработка или дневнички запис врз која|сите $2 преработки и/или дневнички записи врз кои}} е применета.",
+       "tags-delete-explanation-warning": "Ова дејство е <strong>неповратно</strong> и <strong>не може да се отповика</strong>, дури ни од администраторите на базата. Затоа, осигурајте се дека ова навистина е ознаката што сакате да ја избришете.",
+       "tags-delete-explanation-active": "<strong>Ознаката „$1“ сè уште е активна и во иднина ќе продолжи да се применува.</strong> За да го запрете ова, одете на местото/тата на кои ѝ е зададено да се применува и оневозможете ја таму.",
+       "tags-delete-reason": "Причина:",
+       "tags-delete-submit": "Неповратно избриши ја ознакава",
+       "tags-delete-not-allowed": "Ознаките зададени од додаток не можат да се бришат освен ако тоа не е изрично дозволено од додатокот.",
+       "tags-delete-not-found": "Ознаката „$1“ не постои.",
+       "tags-delete-too-many-uses": "Ознаката „$1“ се применува во повеќе од {{PLURAL:$2|една преработка|$2 преработки}}, што значи дека не може да се избрише.",
+       "tags-delete-warnings-after-delete": "Ознаката „$1“ е успешно избришана, но наидов на {{PLURAL:$2|следново предупредување|следниве предупредувања}}:",
+       "tags-activate-title": "Активирај ознака",
+       "tags-activate-question": "На пат сте да ја активирате ознаката „$1“.",
+       "tags-activate-reason": "Причина:",
+       "tags-activate-not-allowed": "Не можам да ја активирам ознаката „$1“.",
+       "tags-activate-not-found": "Ознаката „$1“ не постои.",
+       "tags-activate-submit": "Активирај",
+       "tags-deactivate-title": "Деактивирај ознака",
+       "tags-deactivate-question": "На пат сте да ја деактивирате ознаката „$1“.",
+       "tags-deactivate-reason": "Причина:",
+       "tags-deactivate-not-allowed": "Не можам да ја деактивирам ознаката „$1“.",
+       "tags-deactivate-submit": "Декативирај",
        "comparepages": "Спореди страници",
        "compare-page1": "Страница 1",
        "compare-page2": "Страница 2",
        "logentry-upload-upload": "$1 {{GENDER:$2|ја подигна}} $3",
        "logentry-upload-overwrite": "$1 {{GENDER:$2|подигна}} нова верзија на $3",
        "logentry-upload-revert": "$1 {{GENDER:$2|ја подигна}} $3",
+       "log-name-managetags": "Дневник на раководство со ознаки",
+       "log-description-managetags": "На страницава се наведени раководните задачи што се однесуваат на [[Special:Tags|ознаки]]. Дневникот содржи само дејства извршени рачно од администратор; ознаките можат да се создаваат и бришат од википрограмот без да се заведуваат во дневников.",
+       "logentry-managetags-create": "$1 {{GENDER:$2|ја создаде}} ознаката „$4“",
+       "logentry-managetags-delete": "$1 {{GENDER:$2|ја избриша}} ознаката „$4“ (отстранета од {{PLURAL:$5|една преработка или дневнички запис|$5 преработки и/или дневнички записи}})",
+       "logentry-managetags-activate": "$1 {{GENDER:$2|ја активираше}} ознаката „$4“ за употреба од корисници и ботови",
+       "logentry-managetags-deactivate": "$1 {{GENDER:$2|ја деактивираше}} ознаката „$4“ за употреба од корисници и ботови",
        "rightsnone": "(нема)",
        "revdelete-summary": "опис на уредување",
        "feedback-bugornote": "Ако сте спремни подробно да го опишете техничкиот проблем, тогаш [$1 пријавете грешка]. \nВо спротивно, послужете се со едноставниот образец подолу. Вашиот коментар ќе стои на страницата „[$3 $2]“, заедно со корисничкото име и прелистувачот што го користите.",
index a8b0177..f3c3f3d 100644 (file)
        "prefs-personal": "എന്നെപ്പറ്റി",
        "prefs-rc": "സമീപകാല മാറ്റങ്ങൾ",
        "prefs-watchlist": "ശ്രദ്ധിക്കുന്നവ",
+       "prefs-editwatchlist": "ശ്രദ്ധിക്കുന്നവയുടെ പട്ടിക തിരുത്തുക",
+       "prefs-editwatchlist-label": "താങ്കൾ ശ്രദ്ധിക്കുന്നവയുടെ പട്ടികയിലെ ഉൾപ്പെടുത്തലുകൾ തിരുത്തുക:",
+       "prefs-editwatchlist-edit": "താങ്കൾ ശ്രദ്ധിക്കുന്നവയുടെ പട്ടികയിലെ തലക്കെട്ടുകൾ കാണുക നീക്കംചെയ്യുക",
+       "prefs-editwatchlist-raw": "ശ്രദ്ധിക്കുന്നവയുടെ പട്ടികയുടെ മൂലരൂപം തിരുത്തുക",
+       "prefs-editwatchlist-clear": "ശ്രദ്ധിക്കുന്നവയുടെ പട്ടിക ശൂന്യമാക്കുക",
        "prefs-watchlist-days": "ശ്രദ്ധിക്കുന്ന താളുകളുടെ പട്ടികയിൽ പ്രദർശിപ്പിക്കേണ്ട പരമാവധി ദിവസങ്ങൾ:",
        "prefs-watchlist-days-max": "പരമാവധി {{PLURAL:$1|ഒരു ദിവസം|$1 ദിവസങ്ങൾ}}",
        "prefs-watchlist-edits": "ശ്രദ്ധിക്കുന്ന താളുകളുടെ പട്ടികയുടെ വികസിത രൂപത്തിൽ പ്രദർശിപ്പിക്കേണ്ട പരമാവധി മാറ്റങ്ങൾ:",
        "right-override-export-depth": "കണ്ണിവത്കരിക്കപ്പെട്ട താളുകളുടെ ആഴം 5 വരെയുള്ള താളുകൾ കയറ്റുമതി ചെയ്യുക",
        "right-sendemail": "മറ്റുപയോക്താക്കൾക്ക് ഇമെയിൽ അയയ്ക്കുക",
        "right-passwordreset": "രഹസ്യവാക്ക് പുനഃക്രമീകരിക്കാനുള്ള ഇമെയിലുകൾ കാണുക",
+       "right-managechangetags": "ഡേറ്റാബേസിൽ നിന്നുള്ള [[Special:Tags|ടാഗുകൾ]] സൃഷ്ടിക്കുക അല്ലെങ്കിൽ മായ്ക്കുക",
        "newuserlogpage": "ഉപയോക്തൃ സൃഷ്ടിയുടെ രേഖ",
        "newuserlogpagetext": "പുതിയതായി അംഗത്വമെടുത്ത ഉപയോക്താക്കളുടെ പട്ടിക താഴെ കാണാം.",
        "rightslog": "ഉപയോക്തൃ അവകാശ രേഖ",
        "action-viewmyprivateinfo": "താങ്കളുടെ സ്വകാര്യവിവരങ്ങൾ കാണുക",
        "action-editmyprivateinfo": "താങ്കളുടെ സ്വകാര്യവിവരങ്ങൾ തിരുത്തുക",
        "action-editcontentmodel": "താളിന്റെ ഉള്ളടക്ക രീതി തിരുത്തുക",
+       "action-managechangetags": "ഡേറ്റാബേസിൽ നിന്നുള്ള ടാഗുകൾ സൃഷ്ടിക്കുക അല്ലെങ്കിൽ മായ്ക്കുക",
        "nchanges": "{{PLURAL:$1|ഒരു മാറ്റം|$1 മാറ്റങ്ങൾ}}",
        "enhancedrc-since-last-visit": "കഴിഞ്ഞ സന്ദർശനത്തിനു ശേഷം {{PLURAL:$1|ഒരെണ്ണം|$1 എണ്ണം}}",
        "enhancedrc-history": "നാൾവഴി",
        "tags-tag": "റ്റാഗിന്റെ പേര്‌",
        "tags-display-header": "മാറ്റങ്ങളുടെ പട്ടികകളിലെ രൂപം",
        "tags-description-header": "അർത്ഥത്തിന്റെ പൂർണ്ണ വിവരണം",
+       "tags-source-header": "സ്രോതസ്സ്",
        "tags-active-header": "സീജീവമാണോ?",
        "tags-hitcount-header": "അനുബന്ധമുള്ള മാറ്റങ്ങൾ",
+       "tags-actions-header": "പ്രവൃത്തികൾ",
        "tags-active-yes": "അതെ",
        "tags-active-no": "അല്ല",
+       "tags-source-extension": "ഒരു അനുബന്ധം നിർവ്വചിച്ചിരിക്കുന്നത് പ്രകാരം",
+       "tags-source-manual": "ഉപയോക്താക്കളോ ബോട്ടോ നേരിട്ട് ചെയ്തിട്ടുള്ളവ",
+       "tags-source-none": "ഇപ്പോൾ ഉപയോഗത്തിലില്ല",
        "tags-edit": "തിരുത്തുക",
+       "tags-delete": "മായ്ക്കുക",
+       "tags-activate": "സജ്ജമാക്കുക",
+       "tags-deactivate": "പ്രവർത്തനരഹിതമാക്കുക",
        "tags-hitcount": "{{PLURAL:$1|ഒരു മാറ്റം|$1 മാറ്റങ്ങൾ}}",
+       "tags-manage-no-permission": "മാറ്റ ടാഗുകൾ കൈകാര്യം ചെയ്യാനുള്ള അനുവാദം താങ്കൾക്കില്ല.",
+       "tags-create-heading": "പുതിയൊരു ടാഗ് സൃഷ്ടിക്കുക",
        "comparepages": "താളുകൾ താരതമ്യപ്പെടുത്തുക",
        "compare-page1": "താൾ 1",
        "compare-page2": "താൾ 2",
index 1c017ea..9872ead 100644 (file)
        "right-override-export-depth": "Esporta 'e paggene azzeccanno 'e paggene cullegate nfin'a na profondità 'e 5",
        "right-sendemail": "Manna na mail a ll'at'utente",
        "right-passwordreset": "Vide 'e mmasciate 'e rimpustazione d' 'a password",
+       "right-managechangetags": "Crìa e scancella 'e [[Special:Tags|tag]] d' 'o database",
        "newuserlogpage": "Riggistro 'e nuove utente",
        "newuserlogpagetext": "Chest'è nu riggistro 'e criazione d'utenze.",
        "rightslog": "Deritte 'e ll'utente",
        "action-viewmyprivateinfo": "vide 'e date perzunale",
        "action-editmyprivateinfo": "cagnà 'e proprie date perzunale",
        "action-editcontentmodel": "càgna 'o mudelo 'e cuntenute 'e na paggena",
+       "action-managechangetags": "crìa e scancella 'e tag d' 'o database",
        "nchanges": "$1 {{PLURAL:$1|cagnamiento|cagnamiente}}",
        "enhancedrc-since-last-visit": "$1 {{PLURAL:$1|'a ll'urdema visita}}",
        "enhancedrc-history": "cronologgia",
        "tags-tag": "Nomme 'e ll'etichetta",
        "tags-display-header": "Comme cumpàreno ncopp' 'a lista 'e cagnamiente",
        "tags-description-header": "Descrizione sana d' 'o significato",
+       "tags-source-header": "Funte",
        "tags-active-header": "Attivo?",
        "tags-hitcount-header": "Cagnamiente etichettate",
+       "tags-actions-header": "Aziune",
        "tags-active-yes": "Sì",
        "tags-active-no": "No",
+       "tags-source-extension": "Definito 'a na stensione",
+       "tags-source-manual": "Apprecato manualmente 'a ll'utente e re bot",
+       "tags-source-none": "Nun cchiù ausato",
        "tags-edit": "càgna",
+       "tags-delete": "scancèlla",
+       "tags-activate": "appiccia",
+       "tags-deactivate": "stuta",
        "tags-hitcount": "$1 {{PLURAL:$1|cagnamiento|cagnamiente}}",
+       "tags-manage-no-permission": "Nun tenite 'o permesso pe' cagnà 'e tag.",
+       "tags-create-heading": "Crìa nu tag nuovo",
+       "tags-create-explanation": "Comme predefinito, 'e tag criate nuove nuove se farranno disponibbele pe ll'ausà ll'utente e re bot",
+       "tags-create-tag-name": "Nomme 'e ll'etichetta ('o tag):",
+       "tags-create-reason": "Mutivo:",
+       "tags-create-submit": "Crìa",
+       "tags-create-no-name": "Avite 'a specificà nu nomme p' 'o tag.",
+       "tags-create-invalid-chars": "'E nomme d' 'e tag nun avesser'a cuntenè comme (<code>,</code>) o pallicche (<code>/</code>).",
+       "tags-create-invalid-title-chars": "'E nomme d' 'e tag nun avesser'a cuntenè carattere ca nun se stann'ausanno dint' 'e titule d' 'e paggene.",
+       "tags-create-already-exists": "'O tag \"$1\" esiste già.",
+       "tags-create-warnings-above": "{{PLURAL:$2|Chist'avviso s'è truvato|Chist'avvise se so' truvate}} pe' tramente ca se steva a crià 'o tag \"$1\":",
+       "tags-create-warnings-below": "Vulite cuntinuà a crià 'o tag?",
+       "tags-delete-title": "Scancella tag",
+       "tags-delete-explanation-initial": "State pe' scancellà 'o tag \"$1\" d' 'o database.",
+       "tags-delete-explanation-in-use": "Sarrà luvato d' 'o {{PLURAL:$2|$2 verziona o d' 'o riggistro|tutt' 'e verziune $2 e/o 'e nutarelle int' 'o riggistro}} ô quale fosse azzeccato mò mò.",
+       "tags-delete-explanation-warning": "St'aziona è <strong>irreversibbele</strong> e <strong>nun se pò turnà arreto</strong>, pure 'a ll'ammenistrature d' 'o database. Faciteve capace ca stu tag è chillu ca vulite scancellà.",
+       "tags-delete-explanation-active": "<strong>'O tag \"$1\" è ancora attivo, e sarrà apprecato int' 'o futuro.</strong> Pe' fernì cu st'attività, jate, a lloco addò 'o tag s'è apprecato, e stutate llànno.",
+       "tags-delete-reason": "Mutivo:",
+       "tags-delete-submit": "Scancellà 'e manera irreversibbele stu tag",
+       "tags-delete-not-allowed": "'E tag ca se so' definite 'a na stensiona nun se ponno scancellà si nun è c' 'a stensiona 'o premmettesse.",
+       "tags-delete-not-found": "'O tag $1 nun esiste.",
+       "tags-delete-too-many-uses": "'O tag \"$1\" è apprecato a cchiù 'e $2 {{PLURAL:$2|verziona|verziune}}, cosa ca vulesse dicere ca nun se ò scancellà.",
+       "tags-delete-warnings-after-delete": "'O tag \"$1\" s'è scancellato buono, ma {{PLURAL:$2|s'è ncuntrato ll'avviso|se songhe ncuntrate ll'avise}} ccà:",
+       "tags-activate-title": "Appiccia 'o tag",
+       "tags-activate-question": "Vuje state p'appiccià 'o tag \"$1\".",
+       "tags-activate-reason": "Mutivo:",
+       "tags-activate-not-allowed": "Nun se pò appiccià 'o tag \"$1\".",
+       "tags-activate-not-found": "'O tag \"$1\" nun esiste.",
+       "tags-activate-submit": "Appicia",
+       "tags-deactivate-title": "Stuta tag",
+       "tags-deactivate-question": "Vuje state pe' stutà 'o tag \"$1\".",
+       "tags-deactivate-reason": "Mutivo:",
+       "tags-deactivate-not-allowed": "Nun se pò stutà 'o tag \"$1\".",
+       "tags-deactivate-submit": "Stuta",
        "comparepages": "Miette a cunfronto 'e paggene",
        "compare-page1": "Paggena 1",
        "compare-page2": "Paggena 2",
        "logentry-upload-upload": "$1 {{GENDER:$2|ave carrecato}} $3",
        "logentry-upload-overwrite": "$1 {{GENDER:$2|ave carrecato}} na verziona nnova 'e $3",
        "logentry-upload-revert": "$1 {{GENDER:$2|ave carrecato}} $3",
+       "log-name-managetags": "Riggistro 'e ggistione d' 'e tag",
+       "log-description-managetags": "Sta paggena accucchiasse ll'aziune 'e ggistione azzeccate a [[Special:Tags|tagge]]. 'O riggistro cuntene surtanto ll'aziune ca se fanno manualmente 'a n'ammenistratore; 'e tag s'avesser'a crià o scancellà p' 'o software wiki senza na nutarella nzignata int'a stu riggistro.",
+       "logentry-managetags-create": "$1 {{GENDER:$2|criaje}} 'o tag \"$4\"",
+       "logentry-managetags-delete": "$1 {{GENDER:$2|scancellaje}} 'o tag \"$4\" (luvato 'a $5 {{PLURAL:$5|verziona o nutarella 'e riggistro|verziune o nutarelle 'e riggistro}})",
+       "logentry-managetags-activate": "$1 {{GENDER:$2|appicciaje}} 'o tag \"$4\" pe ll'uso 'a ll'utente e re bot",
+       "logentry-managetags-deactivate": "$1 {{GENDER:$2|stutaje}} 'o tag \"$4\" pe' ll'uso d'utente e re bot",
        "rightsnone": "(nisciuno)",
        "revdelete-summary": "cagna 'o riepilego",
        "feedback-bugornote": "Si site pronto/a a descrivere nu probblema tecnico ch' 'e dettaglie, pe' piacere [$1 mannate nu bug].\nSi nun site pronto/a, allora putite ausà 'o modulo semprice ca vedite ccà abbascio. 'O commento vuosto sarrà mpezzato dint' 'a paggena [$3 $2]\", seguenno 'o nomme utente vuosto e 'o navigatóre web ca state ausanno.",
index 1af498f..dc33700 100644 (file)
        "right-edit": "Ziejen bewarken",
        "right-createpage": "Ziejen anmaken",
        "right-createtalk": "Overlegziejen anmaken",
-       "right-createaccount": "Nieje gebrukers anmaken",
+       "right-createaccount": "Nieje gebrukerskonto anmaken",
        "right-minoredit": "Bewarkingen markeren as klein",
        "right-move": "Ziejen herneumen",
        "right-move-subpages": "Ziejen samen mit de ziejen die deronder hangen verplaotsen",
        "fileexists-forbidden": "n Bestaand mit disse naam besteet al, en kan niet overschreven wörden.\nVoeg t bestaand toe onder n aandere naam.\n[[File:$1|thumb|center|$1]]",
        "fileexists-shared-forbidden": "Der besteet al n bestaand mit disse naam in de gezamenlike bestaandslokasie.\nA'j t bestaand evengoed op willen sturen, gao dan weerumme en kies n aandere naam.\n[[File:$1|thumb|center|$1]]",
        "file-exists-duplicate": "Dit bestaand is liek alleens as {{PLURAL:$1|t volgende bestaand|de volgende bestaanden}}:",
-       "file-deleted-duplicate": "n Bestaand dat liek alleens is an dit bestaand ([[:$1]]) is eerder al vortedaon.\nBekiek t vortdologboek veurda'j veurdan gaon.",
+       "file-deleted-duplicate": "n Bestaand dat liek alleens is an dit bestaand ([[:$1]]) is eerder al vortedaon.\nBekiek t vortdologboek veurda'j verdan gaon.",
        "uploadwarning": "Waorschuwing",
        "uploadwarning-text": "Pas de bestaandsbeschrieving hieronder an en probeer t opniej",
        "savefile": "Bestaand opslaon",
index 19edc9e..6e349e3 100644 (file)
@@ -11,7 +11,8 @@
                        "Zylbath",
                        "לערי ריינהארט",
                        "아라",
-                       "Kolega2357"
+                       "Kolega2357",
+                       "Servien"
                ]
        },
        "tog-underline": "Verwies ünnerstrieken",
        "virus-unknownscanner": "Unbekannten Virenscanner:",
        "logouttext": "'''Du büst nu afmellt.'''\n\nDu kannst {{SITENAME}} nu anonym wiederbruken oder di ünner dissen oder en annern Brukernaam wedder <span class='plainlinks'>[$1 anmellen]</span>.\nDenk dor an, dat welk Sieden ünner Ümstänn noch jümmer so wiest warrn köönt, as wenn du anmellt weerst. Dat ännert sik, wenn du den Cache vun dien Browser leddig maakst.",
        "yourname": "Dien Brukernaam",
+       "userlogin-yourname": "Brukernaam",
        "yourpassword": "Dien Passwoort",
+       "userlogin-yourpassword": "Passwoort",
+       "userlogin-yourpassword-ph": "Passwoort ingeven",
+       "createacct-yourpassword-ph": "Passwoort ingeven",
        "yourpasswordagain": "Passwoort nochmal ingeven",
        "remembermypassword": "Mit dissen Browser duersam inloggen (för maximal $1 {{PLURAL:$1|Dag|Daag}})",
        "yourdomainname": "Diene Domään:",
        "logout": "Afmellen",
        "userlogout": "Afmellen",
        "notloggedin": "Nich anmellt",
+       "userlogin-joinproject": "Bi {{SITENAME}} anmellen",
        "nologin": "Wenn du noch keen Brukerkonto hest, denn kannst di anmellen: $1.",
        "nologinlink": "Brukerkonto inrichten",
        "createaccount": "Nieg Brukerkonto anleggen",
        "gotaccount": "Hest Du al en Brukerkonto? '''$1'''.",
        "gotaccountlink": "Anmellen",
        "userlogin-resetlink": "De Anmelldaten vergaten?",
+       "userlogin-resetpassword-link": "Passwoort vergeten?",
+       "userlogin-helplink2": "Hülp bi dat anmellen",
        "createaccountmail": "över E-Mail",
        "createaccountreason": "Grund:",
+       "createacct-submit": "Brukerkonto inrichten",
        "badretype": "De beiden Passwöör stimmt nich övereen.",
        "userexists": "Disse Brukernaam is al weg. Bitte söök di en annern ut.",
        "loginerror": "Fehler bi dat Anmellen",
        "login-abort-generic": "Dien Anmellen harr keen Spood. Dat is afbroken worrn.",
        "loginlanguagelabel": "Spraak: $1",
        "suspicious-userlogout": "Dien Anfraag, di aftomellen, worr aflehnt, wieldat se vermoodlich vun en Browser oder Cache-Proxy sennt worrn is, de nich mehr funkschoneert.",
+       "pt-login": "Anmellen",
+       "pt-login-button": "Anmellen",
+       "pt-createaccount": "Brukerkonto inrichten",
+       "pt-userlogout": "Afmellen",
        "php-mail-error-unknown": "Unbekennten Fehler in PHP sien mail()-Funkschoon",
        "user-mail-no-addy": "Versöch en E-Mail ahn E-Mail-Adress to sennen.",
        "changepassword": "Passwoort ännern",
        "timezoneregion-indian": "Indisch Ozean",
        "timezoneregion-pacific": "Pazifisch Ozean",
        "allowemail": "Nettbreven vun annere Brukers annehmen",
-       "prefs-searchoptions": "Söökopschonen",
+       "prefs-searchoptions": "Söken",
        "prefs-namespaces": "Naamrüüm",
        "default": "Standard",
        "prefs-files": "Datein",
        "prefs-reset-intro": "Du kannst disse Sied bruken, dien Instellungen al op de Standardinstellung trüchtosetten.\nDat kann nich wedder ungeschehn maakt warrn.",
        "prefs-emailconfirm-label": "E-Mail-Bestätigung:",
        "youremail": "Dien E-Mail (kene Plicht) *",
-       "username": "Brukernaam:",
+       "username": "{{GENDER:$1|Brukernaam}}:",
        "prefs-memberingroups": "Liddmaten vun de {{PLURAL:$1|Grupp|Gruppen}}:",
        "prefs-registration": "Tied vun dat Anmellen:",
        "yourrealname": "Dien echten Naam (kene Plicht)",
        "suppress": "Oversight",
        "booksources": "Bookhannel",
        "booksources-search-legend": "Na Böker bi Bookhökers söken",
+       "booksources-search": "Söken",
        "booksources-text": "Hier staht Lenken na Websteden, woneem dat Böker to köpen gifft, de mitünner ok mehr Informatschonen to dat Book anbeden doot:",
        "booksources-invalid-isbn": "Süht ut, as wenn de angeven ISBN ungüllig is. Villicht hett dat en Fehler bi’t Afschrieven oder Koperen geven.",
        "specialloguserlabel": "Bruker:",
        "delete-toobig": "Disse Siet hett en temlich lange Versionsgeschicht vun mehr as {{PLURAL:$1|ene Version|$1 Versionen}}. Dat Wegsmieten kann de Datenbank vun {{SITENAME}} för längere Tied utlasten un den Bedriev vun dat Wiki stöörn.",
        "delete-warning-toobig": "Disse Siet hett en temlich lange Versionsgeschicht vun mehr as {{PLURAL:$1|ene Version|$1 Versionen}}. Dat Wegsmieten kann de Datenbank vun {{SITENAME}} för längere Tied utlasten un den Bedriev vun dat Wiki stöörn.",
        "rollback": "Trüchnahm vun de Ännern",
-       "rollback_short": "Trüchnehmen",
        "rollbacklink": "Trüchnehmen",
        "rollbackfailed": "Trüchnahm hett kenen Spood",
        "cantrollback": "De Ännern kann nich trüchnahmen warrn; de letzte Autor is de eenzige.",
        "watchlisttools-edit": "Oppasslist ankieken un ännern",
        "watchlisttools-raw": "Oppasslist as Textlist ännern",
        "signature": "[[{{ns:user}}:$1|$2]] ([[{{ns:user_talk}}:$1|Diskusschoon]])",
-       "unknown_extension_tag": "Unbekannt Extension-Tag „$1“",
        "duplicate-defaultsort": "Wohrschau: De DEFAULTSORTKEY „$2“ överschrifft den vörher bruukten Slötel „$1“.",
        "version": "Version",
        "version-extensions": "Installeerte Extensions",
        "specialpages-group-wiki": "Systemdaten un Warktüüch",
        "specialpages-group-redirects": "Redirect-Spezialsieden",
        "specialpages-group-spam": "Spam-Warktüüch",
+       "specialpages-group-developer": "Developer-Warktüüch",
        "blankpage": "Leddige Sied",
        "intentionallyblankpage": "Disse Sied is mit Afsicht leddig.",
        "external_image_whitelist": "  #Disse Reeg nich ännern<pre>\n#Ünnen köönt Delen vun reguläre Utdrück (de Deel twischen de //) angeven warrn.\n#De warrt mit de URLs vun Biller ut externe Borns vergleken\n#En positiv Vergliek föhrt dorto, dat dat Bild wiest warrt, ans warrt dat Bild blot as Lenk wiest\n#Regen, de mit en # anfangt, warrt as Kommentar behannelt\n#De List maakt keen Ünnerscheed bi grote un lütte Bookstaven\n\n#Delen vun reguläre Utdrück na disse Reeg indragen. Disse Reeg nich ännern</pre>",
        "revdelete-unrestricted": "Inschränkungen för Administraters rutnahmen",
        "rightsnone": "(kene)",
        "revdelete-summary": "Tosamenfaten",
+       "searchsuggest-search": "Söken",
        "expandtemplates": "Vörlagen oplösen",
        "expand_templates_intro": "Mit disse Spezialsied köönt Vörlagen in ingeven Text in Wikitext ümwannelt warrn.\nOk Parserfunkschonen so as\n<nowiki>{{</nowiki>#language:…}}, un Variabeln so as\n<nowiki>{{</nowiki>CURRENTDAY}} warrt ümwannelt. Also so temlich allens, wat twischen swiefte Klammern steit.\nDorto warrt de nödigen Parser-Phasen in MediaWiki direkt opropen.",
        "expand_templates_title": "Kontexttitel, för {{FULLPAGENAME}} etc.:",
index 0b631b2..fcf23b3 100644 (file)
        "prefs-personal": "Gebruikersprofiel",
        "prefs-rc": "Recente wijzigingen",
        "prefs-watchlist": "Volglijst",
+       "prefs-editwatchlist": "Volglijst bewerken",
        "prefs-watchlist-days": "Dagen weer te geven in de volglijst:",
        "prefs-watchlist-days-max": "Maximaal $1 {{PLURAL:$1|dag|dagen}}",
        "prefs-watchlist-edits": "Maximaal aantal bewerkingen in de uitgebreide volglijst:",
index afd652b..a8606a6 100644 (file)
        "right-override-export-depth": "Eksport stron wraz z linkowanymi do głębokości 5 linków",
        "right-sendemail": "Wysyłanie e‐maili do innych użytkowników",
        "right-passwordreset": "Sprawdzanie treści e‐maila o resetowaniu hasła",
+       "right-managechangetags": "Tworzenie i usuwanie [[Special:Tags|znaczników]] z bazy danych",
        "newuserlogpage": "Nowi użytkownicy",
        "newuserlogpagetext": "To jest rejestr ostatnio utworzonych kont użytkowników",
        "rightslog": "Uprawnienia",
        "action-viewmywatchlist": "zobaczenia swojej listy obserwowanych stron",
        "action-viewmyprivateinfo": "zobaczenia swoich prywatnych danych",
        "action-editmyprivateinfo": "edycji swoich prywatnych danych",
+       "action-managechangetags": "utwórz lub usuń znaczniki z bazy danych",
        "nchanges": "$1 {{PLURAL:$1|zmiana|zmiany|zmian}}",
        "enhancedrc-since-last-visit": "$1 {{PLURAL:$1|od ostatniej wizyty}}",
        "enhancedrc-history": "historia",
        "tags-tag": "Nazwa znacznika",
        "tags-display-header": "Wystąpienia na listach zmian",
        "tags-description-header": "Pełny opis znaczenia",
+       "tags-source-header": "Źródło",
        "tags-active-header": "Aktywny?",
        "tags-hitcount-header": "Oznaczone zmiany",
+       "tags-actions-header": "Działania",
        "tags-active-yes": "Tak",
        "tags-active-no": "Nie",
        "tags-edit": "edytuj",
+       "tags-delete": "usuń",
+       "tags-activate": "aktywuj",
+       "tags-deactivate": "dezaktywuj",
        "tags-hitcount": "$1 {{PLURAL:$1|zmiana|zmiany|zmian}}",
+       "tags-manage-no-permission": "Nie masz uprawnień do zarządzaniem zmianami znaczników.",
+       "tags-create-heading": "Utwórz nowy znacznik",
+       "tags-create-tag-name": "Nazwa znacznika:",
+       "tags-create-reason": "Powód:",
+       "tags-create-submit": "Utwórz",
+       "tags-create-no-name": "Musisz podać nazwę znacznika.",
+       "tags-create-invalid-chars": "Nazwy znaczników nie mogą zawierać przecinków (<code>,</code>) ani ukośników (<code>/</code>).",
+       "tags-create-invalid-title-chars": "Nazwy znaczników nie mogą zawierać znaków, które nie mogą być używane w tytułach stron.",
+       "tags-create-already-exists": "Znacznik „$1” już istnieje.",
+       "tags-create-warnings-below": "Czy chcesz kontynuować tworzenie znacznika?",
+       "tags-delete-title": "Usuwanie znacznika",
+       "tags-delete-explanation-initial": "Zamierzasz usunąć znacznik „$1” z bazy danych.",
+       "tags-delete-reason": "Powód:",
+       "tags-delete-submit": "Nieodwracalnie usuń ten znacznik",
+       "tags-delete-not-found": "Znacznik „$1” nie istnieje.",
+       "tags-delete-too-many-uses": "Znacznik „$1” jest stosowany w więcej niż {{PLURAL:$2|jednej wersji|$2 wersjach}}, co oznacza, że nie może być usunięty.",
+       "tags-activate-title": "Aktywacja znacznika",
+       "tags-activate-question": "Zamierzasz aktywować znacznik „$1”.",
+       "tags-activate-reason": "Powód:",
+       "tags-activate-not-allowed": "Nie można aktywować znacznika „$1”.",
+       "tags-activate-not-found": "Znacznik „$1” nie istnieje.",
+       "tags-activate-submit": "Aktywuj",
+       "tags-deactivate-title": "Dezaktywacja znacznika",
+       "tags-deactivate-question": "Zamierzasz dezaktywować znacznik „$1”.",
+       "tags-deactivate-reason": "Powód:",
+       "tags-deactivate-not-allowed": "Nie można dezaktywować znacznika „$1”.",
+       "tags-deactivate-submit": "Dezaktywuj",
        "comparepages": "Porównanie stron",
        "compare-page1": "Strona 1",
        "compare-page2": "Strona 2",
        "logentry-upload-upload": "$1 {{GENDER:$2|przesłał|przesłała}} $3",
        "logentry-upload-overwrite": "$1 {{GENDER:$2|przesłał|przesłała}} nową wersję $3",
        "logentry-upload-revert": "$1 {{GENDER:$2|przesłał|przesłała}} $3",
+       "log-name-managetags": "Rejestr zarządzania znacznikami",
+       "logentry-managetags-create": "$1 {{GENDER:$2|utworzył|utworzyła}} znacznik „$4”",
        "rightsnone": "brak",
        "revdelete-summary": "opis zmian",
        "feedback-bugornote": "Jeśli jesteś w stanie szczegółowo opisać problem techniczny, proszę [$1 zgłoś błąd].\nW przeciwnym wypadku można użyć prostego formularza poniżej. Komentarz zostanie dodany do strony \"[$3  $2]\", wraz z nazwą użytkownika.",
index bce71a7..4f403a4 100644 (file)
        "prefs-personal": "Profil dl'utent",
        "prefs-rc": "Ùltime modìfiche",
        "prefs-watchlist": "Ròba che as ten sot euj",
+       "prefs-editwatchlist": "Modifiché la lista ëd lòn ch'as ten sot-euj",
+       "prefs-editwatchlist-label": "Modifiché dle vos ëd la lista ëd lòn ch'as ten sot-euj:",
+       "prefs-editwatchlist-edit": "Vëdde e gavé dle vos ëd la lista ëd lòn ch'as ten sot-euj",
+       "prefs-editwatchlist-raw": "Modìfica lesta ëd la lista ëd lòn ch'as ten sot-euj",
+       "prefs-editwatchlist-clear": "Dësvujdé la lista ëd lòn ch'as ten sot-euj",
        "prefs-watchlist-days": "Vàire dì che a veul ës-ciairé an soa lista ëd lòn che as ten sot euj:",
        "prefs-watchlist-days-max": "Al pì $1 {{PLURAL:$1|di|di}}",
        "prefs-watchlist-edits": "Vàire modìfiche che a veul ës-ciairé con le funsion avansà:",
        "right-override-export-depth": "Esporté le pàgine ancludend le pàgine colegà fin-a a na profondeur ëd 5",
        "right-sendemail": "Mandé un mëssagi an pòsta eletrònica a j'àutri utent",
        "right-passwordreset": "Vëdde ij mëssagi ëd pòsta eletrònica ëd riampostassion dle ciav",
+       "right-managechangetags": "Creé e dëscancelé dle [[Special:Tags|tichëtte]] da la base ëd dàit",
        "newuserlogpage": "Registr dla creassion dj'utent",
        "newuserlogpagetext": "Sossì a l'é un registr andova ch'as marco le creassion dj'utent.",
        "rightslog": "Argistr dij drit ëd j'utent",
        "action-viewmyprivateinfo": "vëdde soe anformassion përsonaj",
        "action-editmyprivateinfo": "modifiché soe anformassion përsonaj",
        "action-editcontentmodel": "modifiché ël model ëd contnù ëd na pàgina",
+       "action-managechangetags": "creé e dëscancelé dle tichëtte da la base ëd dàit",
        "nchanges": "$1 {{PLURAL:$1|modìfica|modìfiche}}",
        "enhancedrc-since-last-visit": "$1 {{PLURAL:$1|da l'ùltima visita}}",
        "enhancedrc-history": "stòria",
        "tags-tag": "Nòm ëd la tichëtta",
        "tags-display-header": "Aparensa ant la lista dle modìfiche",
        "tags-description-header": "Descrission completa dël significà",
+       "tags-source-header": "Sorgiss",
        "tags-active-header": "Ativ?",
        "tags-hitcount-header": "Modìfiche con tichëtta",
        "tags-active-yes": "Bò",
index c2e6c80..7aaf14b 100644 (file)
@@ -76,7 +76,8 @@
                        "Marcos dias de oliveira",
                        "He7d3r",
                        "PauloEduardo",
-                       "Webysther"
+                       "Webysther",
+                       "Fasouzafreitas"
                ]
        },
        "tog-underline": "Sublinhar links:",
        "prefs-personal": "Dados do usuário",
        "prefs-rc": "Mudanças recentes",
        "prefs-watchlist": "Lista de páginas vigiadas",
+       "prefs-editwatchlist": "Editar lista de páginas vigiadas",
+       "prefs-editwatchlist-label": "Editar entradas na sua lista de páginas vigiadas:",
+       "prefs-editwatchlist-edit": "Visualizar e remover títulos da sua lista de páginas vigiadas",
+       "prefs-editwatchlist-raw": "Edição crua da lista de páginas vigiadas",
+       "prefs-editwatchlist-clear": "Limpar sua lista de páginas vigiadas",
        "prefs-watchlist-days": "Dias a mostrar na lista de páginas vigiadas:",
        "prefs-watchlist-days-max": "Máximo $1 {{PLURAL:$1|dia|dias}}",
        "prefs-watchlist-edits": "Número de edições mostradas na lista de páginas vigiadas expandida:",
        "right-override-export-depth": "Exportar páginas incluindo páginas ligadas até uma profundidade de 5",
        "right-sendemail": "Enviar email a outros usuários",
        "right-passwordreset": "Ver todos os e-mails de reposição de senhas",
+       "right-managechangetags": "Criar e apagar [[Special:Tags|tags]] na base de dados",
        "newuserlogpage": "Registro de criação de usuários",
        "newuserlogpagetext": "Este é um registro de novas contas de usuário",
        "rightslog": "Registro de privilégios de usuário",
        "action-viewmyprivateinfo": "veja suas informações privadas",
        "action-editmyprivateinfo": "modifique suas informações privadas",
        "action-editcontentmodel": "editar o conteudo do modelo de uma pagina",
+       "action-managechangetags": "Criar e apagar etiquetas da base de dados",
        "nchanges": "$1 {{PLURAL:$1|alteração|alterações}}",
        "enhancedrc-since-last-visit": "$1 {{PLURAL:$1|desde a última visita}}",
        "enhancedrc-history": "histórico",
        "tooltip-feed-atom": "Feed Atom desta página",
        "tooltip-t-contributions": "Ver as contribuições deste usuário",
        "tooltip-t-emailuser": "Enviar um e-mail a este usuário",
+       "tooltip-t-info": "Mais informações sobre esta página",
        "tooltip-t-upload": "Enviar arquivos",
        "tooltip-t-specialpages": "Lista de páginas especiais",
        "tooltip-t-print": "Versão para impressão desta página",
        "version-entrypoints": "URLs dos pontos de entrada",
        "version-entrypoints-header-entrypoint": "Ponto de entrada",
        "version-entrypoints-header-url": "URL",
+       "version-libraries": "Bibliotecas instaladas",
+       "version-libraries-library": "Biblioteca",
+       "version-libraries-version": "Versão",
        "redirect": "Redirecionar por arquivo, usuário ou ID de revisão",
        "redirect-legend": "Redirecionar para um arquivo ou página",
        "redirect-summary": "Esta página especial redireciona a um arquivo (dado o nome do arquivo), a uma página (dado um ID de revisão ou ID da página) ou a uma página de usuário (dado o ID do usuário). Uso: [[{{#Special:Redirect}}/file/Example.jpg]], [[{{#Special:Redirect}}/page/64308]], [[{{#Special:Redirect}}/revision/328429]], or [[{{#Special:Redirect}}/user/101]].",
        "tags-tag": "Nome da etiqueta",
        "tags-display-header": "Aparência nas listas de modificações",
        "tags-description-header": "Descrição completa do significado",
+       "tags-source-header": "Fonte",
        "tags-active-header": "Ativo?",
        "tags-hitcount-header": "Modificações etiquetadas",
+       "tags-actions-header": "Ações",
        "tags-active-yes": "Sim",
        "tags-active-no": "Não",
+       "tags-source-extension": "Definida por uma extensão",
+       "tags-source-manual": "Aplicado manualmente pelos usuários e pelos robôs",
+       "tags-source-none": "Não mais em uso",
        "tags-edit": "editar",
+       "tags-delete": "Apagar",
+       "tags-activate": "Ativar",
+       "tags-deactivate": "Desativar",
        "tags-hitcount": "$1 {{PLURAL:$1|modificação|modificações}}",
+       "tags-manage-no-permission": "Você não possui permissão para gerenciar alterações de etiquetas",
+       "tags-create-heading": "Criar uma nova etiqueta",
+       "tags-create-explanation": "Por padrão, etiquetas recém-criadas serão disponibilizadas para usuários e robôs",
+       "tags-create-tag-name": "Nome de etiqueta",
+       "tags-create-reason": "Razão:",
+       "tags-create-submit": "Criar",
+       "tags-create-no-name": "Você deve especificar um nome de etiqueta",
+       "tags-create-invalid-chars": "Nomes de etiquetas não devem conter vírgulas (<code>,</code>) ou barras (<code>/</code>).",
+       "tags-create-invalid-title-chars": "Nomes de etiqueta não devem conter caracteres que não possam ser utilizados em títulos de páginas.",
+       "tags-create-already-exists": "A etiqueta \"$1\" já existe.",
+       "tags-create-warnings-below": "Você deseja continuar a criar a etiqueta?",
+       "tags-delete-title": "Apagar etiqueta",
+       "tags-delete-submit": "Apagar irreversivelmente esta etiqueta",
+       "tags-delete-not-allowed": "Etiquetas definidas por uma extensão não podem ser apagadas a menos que a extensão especificamente o permita.",
+       "tags-delete-not-found": "A etiqueta \"$1\" não existe.",
+       "tags-activate-title": "Ativar etiqueta",
+       "tags-activate-submit": "Ativar",
+       "tags-deactivate-title": "Desativar etiqueta",
+       "tags-deactivate-submit": "Desativar",
        "comparepages": "Comparar páginas",
        "compare-page1": "Página 1",
        "compare-page2": "Página 2",
        "compare-revision-not-exists": "A revisão que você especificou não existe.",
        "dberr-problems": "Desculpe! Este sítio está passando por dificuldades técnicas.",
        "dberr-again": "Experimente esperar alguns minutos e atualizar.",
-       "dberr-info": "(Não foi possível contatar o servidor de base de dados: $1)",
+       "dberr-info": "(Não pode acessar a base de dados: $1)",
        "dberr-info-hidden": "(Não foi possível contatar o banco de dados do servidor)",
        "dberr-usegoogle": "Você pode tentar pesquisar no Google entretanto.",
        "dberr-outofdate": "Note que os seus índices relativos ao nosso conteúdo podem estar desatualizados.",
        "expand_templates_generate_xml": "Mostrar árvore de análise (parse) do XML",
        "expand_templates_generate_rawhtml": "Mostrar HTML puro",
        "expand_templates_preview": "Pré-visualização",
+       "pagelanguage": "Seletor de idioma de página",
        "pagelang-name": "Página",
        "pagelang-language": "Idioma",
        "pagelang-use-default": "Idioma padrão de uso",
index 28205f1..1477393 100644 (file)
        "right-override-export-depth": "Exportar páginas incluindo páginas ligadas até uma profundidade de 5",
        "right-sendemail": "Enviar correio eletrónico a outros utilizadores",
        "right-passwordreset": "Ver mensagens de redefinição da palavra-passe",
+       "right-managechangetags": "Criar e eliminar [[Special:Tags|etiquetas]] da base de dados",
        "newuserlogpage": "Registo de criação de utilizadores",
        "newuserlogpagetext": "Este é um registo de novas contas de utilizador",
        "rightslog": "Registo de privilégios de utilizador",
        "action-viewmyprivateinfo": "ver a sua informação privada",
        "action-editmyprivateinfo": "editar a sua informação privada",
        "action-editcontentmodel": "editar o modelo de conteúdo de uma página",
+       "action-managechangetags": "criar e eliminar etiquetas da base de dados",
        "nchanges": "$1 {{PLURAL:$1|alteração|alterações}}",
        "enhancedrc-since-last-visit": "$1 {{PLURAL:$1|desde a última visita}}",
        "enhancedrc-history": "histórico",
        "listgrouprights-namespaceprotection-header": "Restrições do domínio",
        "listgrouprights-namespaceprotection-namespace": "Domínio",
        "listgrouprights-namespaceprotection-restrictedto": "Direito(s) do utilizador para editar",
-       "trackingcategories": "Categorias de monitoramento",
+       "trackingcategories": "Categorias de monitorização",
        "trackingcategories-summary": "Esta página lista as categorias monitoradas que foram geradas automaticamente pelo software MediaWiki. Os seus nomes podem ser alterados ao editar sua mensagem correspondente no domínio {{ns:8}}.",
        "trackingcategories-msg": "Categoria monitorada",
        "trackingcategories-name": "Nome da mensagem",
        "tags-tag": "Nome da etiqueta",
        "tags-display-header": "Aparência nas listas de modificações",
        "tags-description-header": "Descrição completa do significado",
+       "tags-source-header": "Origem",
        "tags-active-header": "Ativa?",
        "tags-hitcount-header": "Modificações etiquetadas",
+       "tags-actions-header": "Ações",
        "tags-active-yes": "Sim",
        "tags-active-no": "Não",
+       "tags-source-extension": "Definida por uma extensão",
+       "tags-source-manual": "Aplicada manualmente pelos utilizadores e robôs",
+       "tags-source-none": "Já não está em uso",
        "tags-edit": "editar",
+       "tags-delete": "eliminar",
+       "tags-activate": "ativar",
+       "tags-deactivate": "desativar",
        "tags-hitcount": "$1 {{PLURAL:$1|modificação|modificações}}",
+       "tags-manage-no-permission": "Não possui permissão para gerir alterações de etiquetas.",
+       "tags-create-heading": "Criar nova etiqueta",
+       "tags-create-explanation": "Por definição, etiquetas recém-criadas estarão disponíveis para utilização por utilizadores e robôs.",
+       "tags-create-tag-name": "Nome da etiqueta:",
+       "tags-create-reason": "Motivo:",
+       "tags-create-submit": "Criar",
+       "tags-create-no-name": "Deve especificar um nome para a etiqueta.",
+       "tags-create-invalid-chars": "Os nomes das etiquetas não devem conter vírgulas (<code>,</code>) ou barras (<code>/</code>).",
+       "tags-create-invalid-title-chars": "Os nomes das etiquetas não devem conter caracteres que não podem ser usados em títulos de página.",
+       "tags-create-already-exists": "A etiqueta \"$1\" já existe.",
+       "tags-create-warnings-above": "{{PLURAL:$2|O seguinte aviso foi encontrado|Os seguintes avisos foram encontrados}} ao tentar criar a etiqueta \"$1\":",
+       "tags-create-warnings-below": "Pretende continuar com a criação da etiqueta?",
+       "tags-delete-title": "Eliminar etiqueta",
+       "tags-delete-explanation-initial": "Está prestes a eliminar a etiqueta \"$1\" da base de dados.",
+       "tags-delete-explanation-in-use": "Será removida de {{PLURAL:$2|$2 edição ou entrada de registo|todas as $2 edições e/ou entradas de registo}} em que está atualmente aplicada.",
+       "tags-delete-explanation-warning": "Esta ação é <strong>irreversível</strong> e <strong>não pode ser desfeita</strong>, nem mesmo por administradores da base de dados. Tenha a certeza de que é esta etiqueta que pretende eliminar.",
+       "tags-delete-explanation-active": "<strong>A etiqueta \"$1\" ainda está ativa e continuará a ser aplicada no futuro.</strong> Para prevenir que isto aconteça, deve dirigir-se ao(s) local(is) em que a etiqueta é aplicada, e a partir daí, desativá-la.",
+       "tags-delete-reason": "Motivo:",
+       "tags-delete-submit": "Eliminar irreversivelmente esta etiqueta",
+       "tags-delete-not-allowed": "Etiquetas definidas por uma extensão não podem ser eliminadas, a menos que a extensão, especificamente, o permita.",
+       "tags-delete-not-found": "A etiqueta \"$1\" não existe.",
+       "tags-delete-too-many-uses": "A etiqueta \"$1\" está aplicada em mais que $2 {{PLURAL:$2|edição|edições}}, o que significa que não pode ser eliminada.",
+       "tags-delete-warnings-after-delete": "A etiqueta \"$1\" foi eliminada com sucesso, mas {{PLURAL:$2|o seguinte aviso foi encontrado|os seguintes avisos foram encontrados}}:",
+       "tags-activate-title": "Ativar etiqueta",
+       "tags-activate-question": "Está prestes a ativar a etiqueta \"$1\".",
+       "tags-activate-reason": "Motivo:",
+       "tags-activate-not-allowed": "Não é possível ativar a etiqueta \"$1\".",
+       "tags-activate-not-found": "A etiqueta \"$1\" não existe.",
+       "tags-activate-submit": "Ativar",
+       "tags-deactivate-title": "Desativar etiqueta",
+       "tags-deactivate-question": "Está prestes a desativar a etiqueta \"$1\".",
+       "tags-deactivate-reason": "Motivo:",
+       "tags-deactivate-not-allowed": "Não é possível desativar a etiqueta \"$1\".",
+       "tags-deactivate-submit": "Desativar",
        "comparepages": "Comparar páginas",
        "compare-page1": "Página 1",
        "compare-page2": "Página 2",
        "logentry-upload-upload": "$1 {{GENDER:$2|carregou}} $3",
        "logentry-upload-overwrite": "$1 {{GENDER:$2|carregou}} uma nova versão de $3",
        "logentry-upload-revert": "$1 {{GENDER:$2|carregou}} $3",
+       "log-name-managetags": "Registo de gestão de etiquetas",
+       "log-description-managetags": "Esta página lista as tarefas de gestão relacionadas com [[Special:Tags|etiquetas]]. O registo contém apenas ações realizadas manualmente por um administrador; etiquetas podem ser criadas ou eliminadas pelo ''software'' da wiki sem uma entrada a ser gravada neste registo.",
+       "logentry-managetags-create": "$1 {{GENDER:$2|criou}} a etiqueta \"$4\"",
+       "logentry-managetags-delete": "$1 {{GENDER:$2|eliminou}} a etiqueta \"$4\" (removida de $5 {{PLURAL:$5|edição ou entrada de registo|edições e/ou entradas de registo}})",
+       "logentry-managetags-activate": "$1 {{GENDER:$2|ativou}} a etiqueta \"$1\" para uso de utilizadores e robôs.",
+       "logentry-managetags-deactivate": "$1 {{GENDER:$2|desativou}} a etiqueta \"$1\" para uso de utilizadores e robôs.",
        "rightsnone": "(nenhum)",
        "revdelete-summary": "editar resumo",
        "feedback-bugornote": "Se está pronto para descrever um problema técnico em detalhe, por favor, [$1 comunique o defeito].\nCaso contrário, pode facilmente usar o formulário abaixo. O seu comentário será adicionado à página \"[$3 $2]\", junto com o seu nome de utilizador e o navegador que está a usar.",
index 64582cc..6470103 100644 (file)
        "right-override-export-depth": "{{doc-right|override-export-depth}}",
        "right-sendemail": "{{doc-right|sendemail}}",
        "right-passwordreset": "{{doc-right|passwordreset}}",
+       "right-managechangetags": "{{doc-right|managechangetags}}",
        "newuserlogpage": "{{doc-logpage}}\n\nPart of the \"Newuserlog\" extension. It is both the title of [[Special:Log/newusers]] and the link you can see in [[Special:RecentChanges]].",
        "newuserlogpagetext": "Part of the \"Newuserlog\" extension. It is the description you can see on [[Special:Log/newusers]].",
        "rightslog": "{{doc-logpage}}\n\nIn [[Special:Log]]",
        "action-viewmyprivateinfo": "{{doc-action|viewmyprivateinfo}}",
        "action-editmyprivateinfo": "{{doc-action|editmyprivateinfo}}",
        "action-editcontentmodel": "{{doc-action|editcontentmodel}}",
+       "action-managechangetags": "{{doc-action|managechangetags}}",
        "nchanges": "Appears on enhanced watchlist and recent changes when page has more than one change on given date, linking to a diff of the changes.\n\nParameters:\n* $1 - the number of changes on that day (2 or more)\nThree messages are shown side-by-side: ({{msg-mw|Nchanges}} | {{msg-mw|Enhancedrc-since-last-visit}} | {{msg-mw|Enhancedrc-history}}).",
        "enhancedrc-since-last-visit": "Appears on enhanced watchlist and recent changes when page has more than one change on given date and at least one that the user hasn't seen yet, linking to a diff of the unviewed changes.\n\nParameters:\n* $1 - the number of unviewed changes (1 or more)\nThree messages are shown side-by-side: ({{msg-mw|nchanges}} | {{msg-mw|enhancedrc-since-last-visit}} | {{msg-mw|enhancedrc-history}}).",
        "enhancedrc-history": "Appears on enhanced watchlist and recent changes when page has more than one change on given date, linking to its history.\n\nThis is the same as {{msg-mw|hist}}, but not abbreviated.\n\nThree messages are shown side-by-side: ({{msg-mw|nchanges}} | {{msg-mw|enhancedrc-since-last-visit}} | {{msg-mw|enhancedrc-history}}).\n{{Identical|History}}",
        "tags-tag": "Caption of a column in [[Special:Tags]]. For more information on tags see [[mw:Manual:Tags|MediaWiki]].",
        "tags-display-header": "Caption of a column in [[Special:Tags]]. For more information on tags see [[mw:Manual:Tags|MediaWiki]].",
        "tags-description-header": "Caption of a column in [[Special:Tags]]. For more information on tags see [[mw:Manual:Tags|MediaWiki]].",
+       "tags-source-header": "Caption of a column in [[Special:Tags]]. For more information on tags see [[mw:Manual:Tags|MediaWiki]].\n{{Identical|Source}}",
        "tags-active-header": "Caption of a column in [[Special:Tags]]. Values are \"Yes\" or \"No\" to indicate if a tag that was ever used is current still registered.\n\nSee example: [[mw:Special:Tags]].\n\nFor more information on tags see [[mw:Manual:Tags|MediaWiki]].\n{{Identical|Active}}",
        "tags-hitcount-header": "Caption of a column in [[Special:Tags]]. For more information on tags see [[mw:Manual:Tags|MediaWiki]].",
+       "tags-actions-header": "Caption of a column in [[Special:Tags]]. The column contains action links like \"delete\". For more information on tags see [[mw:Manual:Tags|MediaWiki]].\n{{Identical|Action}}",
        "tags-active-yes": "Table cell contents if given tag is \"active\".\n\nSee also:\n* {{msg-mw|Tags-active-no}}\n{{Identical|Yes}}",
        "tags-active-no": "Table cell contents if given tag is not \"active\".\n\nSee also:\n* {{msg-mw|Tags-active-yes}}\n{{Identical|No}}",
+       "tags-source-extension": "Table cell contents if given tag can be applied automatically by a software [[mw:Manual:Extensions|extension]].\n\nSee also:\n* {{msg-mw|Tags-source-manual}}\n* {{msg-mw|Tags-source-none}}",
+       "tags-source-manual": "Table cell contents if given tag can be applied by users or bots.\n\nSee also:\n* {{msg-mw|Tags-source-extension}}\n* {{msg-mw|Tags-source-none}}",
+       "tags-source-none": "Table cell contents if given tag is no longer in use. (It was applied in the past, but it is currently not applied.)\n\nSee also:\n* {{msg-mw|Tags-source-extension}}\n* {{msg-mw|Tags-source-manual}}",
        "tags-edit": "Used on [[Special:Tags]]. Verb. Used as display text on a link to create/edit a description.\n{{Identical|Edit}}",
+       "tags-delete": "Used on [[Special:Tags]]. Verb. Used as display text on a link to delete a tag.\n{{Identical|Delete}}",
+       "tags-activate": "Used on [[Special:Tags]]. Verb. Used as display text on a link to activate a tag.\n{{Identical|Activate}}",
+       "tags-deactivate": "Used on [[Special:Tags]]. Verb. Used as display text on a link to deactivate a tag.\n{{Identical|Delete}}",
        "tags-hitcount": "Shown in the \"{{msg-mw|Tags-hitcount-header}}\" column in [[Special:Tags]]. For more information on tags see [[mw:Manual:Tags|MediaWiki]].\n\nParameters:\n* $1 - the number of changes marked with the tag",
+       "tags-manage-no-permission": "Error message on [[Special:Tags]]",
+       "tags-create-heading": "The title of a fieldset, beneath which lies a form used to create a tag. For more information on tags see [[mw:Manual:Tags|MediaWiki]].",
+       "tags-create-explanation": "The first paragraph of an explanation to tell users what they are about to do.",
+       "tags-create-tag-name": "Form field label for the name of the tag to be created.",
+       "tags-create-reason": "{{Identical|Reason}}",
+       "tags-create-submit": "The label of the form \"submit\" button when the user is about to create a tag.\n{{Identical|Create}}",
+       "tags-create-no-name": "Error message on [[Special:Tags]]",
+       "tags-create-invalid-chars": "Error message on [[Special:Tags]]",
+       "tags-create-invalid-title-chars": "Error message on [[Special:Tags]]",
+       "tags-create-already-exists": "Error message on [[Special:Tags]]",
+       "tags-create-warnings-above": "Explanation placed before warning messages upon creating a tag.\n\nParameters:\n* $1 - the code name of the tag that the user is attempting to create\n* $2 - the number of warnings",
+       "tags-create-warnings-below": "Question placed after warning messages upon creating a tag.",
+       "tags-delete-title": "The title of a page used to delete a tag. For more information on tags see [[mw:Manual:Tags|MediaWiki]].",
+       "tags-delete-explanation-initial": "The first paragraph of an explanation to tell users what they are about to do.\n\nParameters:\n* $1 - the code name of the tag that is about to be deleted",
+       "tags-delete-explanation-in-use": "The second paragraph (not always shown) of an explanation to tell users what they are about to do.\n\nParameters:\n* $1 - the code name of the tag that is about to be deleted\n*$2 - the number of places the tag is used. The value is the sum of (revisions + log entries) where the tag is used.",
+       "tags-delete-explanation-warning": "The third paragraph of an explanation to tell users what they are about to do.\n\nParameters:\n* $1 - the code name of the tag that is about to be deleted",
+       "tags-delete-explanation-active": "The fourth paragraph (not always shown) of an explanation to tell users what they are about to do.\n\nParameters:\n* $1 - the code name of the tag that is about to be deleted\n*$2 - the number of places the tag is used. The value is the sum of (rev",
+       "tags-delete-reason": "{{Identical|Reason}}",
+       "tags-delete-submit": "The label of the form \"submit\" button when the user is about to delete a tag. The word \"irreversibly\" is used to emphasise that the action destroys some data and is impossible to undo, even by server administrators.",
+       "tags-delete-not-allowed": "Error message on [[Special:Tags]]",
+       "tags-delete-not-found": "Error message on [[Special:Tags]]",
+       "tags-delete-too-many-uses": "Error message on [[Special:Tags]]",
+       "tags-delete-warnings-after-delete": "Warning shown after deleting a tag.\n\nParameters:\n* $1 - the code name of the tag that was deleted\n* $2 - the number of warnings",
+       "tags-activate-title": "The title of a page used to activate a tag. For more information on tags see [[mw:Manual:Tags|MediaWiki]].",
+       "tags-activate-question": "An explanation to tell users what they are about to do.\n\nParameters:\n* $1 - the code name of the tag that is about to be activated",
+       "tags-activate-reason": "{{Identical|Reason}}",
+       "tags-activate-not-allowed": "Error message on [[Special:Tags]]",
+       "tags-activate-not-found": "Error message on [[Special:Tags]]",
+       "tags-activate-submit": "The label of the form \"submit\" button when the user is about to activate a tag.\n{{Identical|Activate}}",
+       "tags-deactivate-title": "The title of a page used to deactivate a tag. For more information on tags see [[mw:Manual:Tags|MediaWiki]].",
+       "tags-deactivate-question": "An explanation to tell users what they are about to do.\n\nParameters:\n* $1 - the code name of the tag that is about to be deactivated",
+       "tags-deactivate-reason": "{{Identical|Reason}}",
+       "tags-deactivate-not-allowed": "Error message on [[Special:Tags]]",
+       "tags-deactivate-submit": "The label of the form \"submit\" button when the user is about to deactivate a tag.\n{{Identical|Deactivate}}",
        "comparepages": "The title of [[Special:ComparePages]]",
        "comparepages-summary": "{{doc-specialpagesummary|comparepages}}",
        "compare-page1": "Label for the field of the 1st page in the comparison for [[Special:ComparePages]]\n{{Identical|Page}}",
        "logentry-upload-upload": "{{Logentry|[[Special:Log/upload]]}}",
        "logentry-upload-overwrite": "{{Logentry|[[Special:Log/upload]]}}",
        "logentry-upload-revert": "{{Logentry|[[Special:Log/upload]]}}",
+       "log-name-managetags": "The title of a log which contains entries related to the management of change tags. \"Tag\" here refers to the same thing as {{msg-mw|tags-tag}}.",
+       "log-description-managetags": "The description of the tag management log. \"Tag\" here refers to the same thing as {{msg-mw|tags-tag}}.",
+       "logentry-managetags-create": "{{Logentry|[[Special:Log/managetags]]}}\n*$4 - tag name",
+       "logentry-managetags-delete": "{{Logentry|[[Special:Log/managetags]]}}\n*$4 - tag name\n* $5 - number of revisions + log entries that were tagged with the tag",
+       "logentry-managetags-activate": "{{Logentry|[[Special:Log/managetags]]}}\n*$4 - tag name",
+       "logentry-managetags-deactivate": "{{Logentry|[[Special:Log/managetags]]}}\n*$4 - tag name",
        "rightsnone": "Default rights for registered users.\n\n{{Identical|None}}",
        "revdelete-logentry": "{{RevisionDelete}}\nThis is the message for the log entry in [[Special:Log/delete]] when changing visibility restrictions for page revisions.\n\nFollowed by the message {{msg-mw|revdelete-log-message}} in brackets.\n\nPreceded by the name of the user doing this task.\n\nParameters:\n* $1 - the page name\nSee also:\n* {{msg-mw|Logdelete-logentry}}",
        "logdelete-logentry": "{{RevisionDelete}}\nThis is the message for the log entry in [[Special:Log/delete]] when changing visibility restrictions for log events.\n\nFollowed by the message {{msg-mw|logdelete-log-message}} in brackets.\n\nPreceded by the name of the user who did this task.\n\nParameters:\n* $1 - the log name in brackets\nSee also:\n* {{msg-mw|Revdelete-logentry}}",
index 753d0c0..983b819 100644 (file)
        "loginlanguagelabel": "Lingua: $1",
        "suspicious-userlogout": "Tia dumonda per partir è vegnida refusada perquai ch'i para ch'ella è vegnida tramessa d'in navigatur che funcziuna betg correctamain u d'in proxy da cache.",
        "createacct-another-realname-tip": "Il num real è opziunal.\nSche ti l'inditgeschas, vegn el duvrà per attribuir las contribuziuns.",
+       "pt-login": "T'annunziar",
+       "pt-login-button": "T'annunziar",
+       "pt-createaccount": "Crear in conto d'utilisader",
        "php-mail-error-unknown": "Errur nunenconuschenta en la funcziun mail() da PHP",
        "user-mail-no-addy": "Empruvà da trametter in e-mail senza ina adressa dad e-mail.",
        "changepassword": "Midar pled-clav",
        "delete-toobig": "Questa pagina ha in grond dumber da midadas (passa $1 {{PLURAL:$1|versiun|versiuns}}).\nLa funcziun da stizzar è vegnida restrenschida per talas paginas per evitar ch'il server da {{SITENAME}} vegni surchargià.",
        "delete-warning-toobig": "Questa pagina ha in grond dumber da midadas (passa $1 {{PLURAL:$1|versiun|versiuns}}).\nStizzar ina tala pagina pudess surchargiar las operaziuns da la banca da datas da {{SITENAME}}.\nCuntinuescha cun precauziun.",
        "rollback": "Revocar modificaziuns",
-       "rollback_short": "Revocar",
        "rollbacklink": "revocar",
        "rollbacklinkcount": "revocar $1 {{PLURAL:$1|midada|midadas}}",
        "rollbacklinkcount-morethan": "revocar dapli che $1 {{PLURAL:$1|midada|midadas}}",
        "import-logentry-interwiki": "ha importà $1 (transwiki)",
        "import-logentry-interwiki-detail": "{{PLURAL:$1|Ina versiun|$1 versiuns}} da $2",
        "javascripttest": "Test da JavaScript",
-       "javascripttest-title": "Exequir tests da $1",
        "javascripttest-pagetext-noframework": "Questa pagina è reservada per exequir tests da JavaScript.",
        "javascripttest-pagetext-unknownframework": "Framework da test nunenconuschent \"$1\".",
        "javascripttest-pagetext-frameworks": "Tscherna per plaschair in dals suandantas frameworks da test: $1",
        "javascripttest-pagetext-skins": "Tscherna in skin che duai vegnir utilisà per ils tests:",
        "javascripttest-qunit-intro": "Legia la [$1 documentaziun da tests] sin mediawiki.org.",
-       "javascripttest-qunit-heading": "Collecziun da test da QUnit per JavaScript en MediaWiki",
        "tooltip-pt-userpage": "Mussar tia pagina d'utilisader",
        "tooltip-pt-anonuserpage": "La pagina d'utilisader per l'adressa IP cun la quala che ti fas modificaziuns",
        "tooltip-pt-mytalk": "Mussar tia pagina da discussiun",
        "watchlisttools-edit": "Mussar e modifitgar la glista d'observaziun",
        "watchlisttools-raw": "Modifitgar il format da la glista (import/export)",
        "signature": "[[{{ns:user}}:$1|$2]] ([[{{ns:user_talk}}:$1|talk]])",
-       "unknown_extension_tag": "Tag d'extensiun nunenconuschent \"$1\"",
        "duplicate-defaultsort": "'''Attenziun:''' La clav da zavrar da standard \"$2\" remplazza la clav da zavrar da standard veglia \"$1\".",
        "version": "Versiun",
        "version-extensions": "Extensiuns installadas",
index 433b14a..24fcf46 100644 (file)
        "right-override-export-depth": "Exportă inclusiv paginile legate până la o adâncime de 5",
        "right-sendemail": "Trimite e-mail altor utilizatori",
        "right-passwordreset": "Vizualizează e-mailurile de reinițializare a parolelor",
+       "right-managechangetags": "Creează și șterge [[Special:Tags|etichete]] din baza de date",
        "newuserlogpage": "Jurnal utilizatori noi",
        "newuserlogpagetext": "Acesta este jurnalul creărilor conturilor de utilizator.",
        "rightslog": "Jurnal permisiuni de utilizator",
        "action-viewmyprivateinfo": "vă vizualizați informațiile personale",
        "action-editmyprivateinfo": "să vă modificați informațiile personale",
        "action-editcontentmodel": "modificați modelul de conținut al unei pagini",
+       "action-managechangetags": "creați și să ștergeți etichete din baza de date",
        "nchanges": "$1 {{PLURAL:$1|modificare|modificări|de modificări}}",
        "enhancedrc-since-last-visit": "$1 {{PLURAL:$1|de la ultima vizită}}",
        "enhancedrc-history": "istoric",
        "tags-tag": "Numele etichetei",
        "tags-display-header": "Apariția în listele cu schimbări",
        "tags-description-header": "Descrierea completă a sensului",
+       "tags-source-header": "Sursă",
        "tags-active-header": "Activă?",
        "tags-hitcount-header": "Modificări etichetate",
+       "tags-actions-header": "Acțiuni",
        "tags-active-yes": "Da",
        "tags-active-no": "Nu",
+       "tags-source-extension": "Definită de o extensie",
+       "tags-source-manual": "Aplicată manual de utilizatori și roboți",
+       "tags-source-none": "Nu mai este în uz",
        "tags-edit": "modificare",
+       "tags-delete": "șterge",
+       "tags-activate": "activează",
+       "tags-deactivate": "dezactivează",
        "tags-hitcount": "$1 {{PLURAL:$1|modificare|modificări}}",
+       "tags-manage-no-permission": "Nu aveți permisiunea de a gestiona schimbarea etichetelor.",
+       "tags-create-heading": "Creare etichetă nouă",
+       "tags-create-explanation": "În mod implicit, etichetele nou create vor fi disponibile spre utilizarea de către utilizatori și roboți.",
+       "tags-create-tag-name": "Numele etichetei:",
+       "tags-create-reason": "Motiv:",
+       "tags-create-submit": "Creează",
+       "tags-create-no-name": "Trebuie să specificați un nume de etichetă.",
+       "tags-create-invalid-chars": "Numele etichetelor nu trebuie să conțină virgule (<code>,</code>) sau bare oblice (<code>/</code>).",
+       "tags-create-invalid-title-chars": "Numele etichetelor nu trebuie să conțină caractere ce nu pot fi utilizate în titlurile paginilor.",
+       "tags-create-already-exists": "Eticheta „$1” există deja.",
+       "tags-create-warnings-above": "{{PLURAL:$2|Următorul avertisment a|Următoarele avertismente au}} fost {{PLURAL:$2|întâlnit|întâlnite}} în încercarea de a crea eticheta „$1”:",
+       "tags-create-warnings-below": "Doriți să continuați crearea etichetei?",
+       "tags-delete-title": "Ștergere etichetă",
+       "tags-delete-explanation-initial": "Sunteți pe cale să ștergeți eticheta „$1” din baza de date.",
+       "tags-delete-explanation-in-use": "Va fi eliminată {{PLURAL:$2|din cadrul unei versiuni sau intrări din jurnal căreia îi|din toate cele $2 versiuni și/sau intrări din jurnal cărora le|din toate cele $2 de versiuni și/sau intrări din jurnal cărora le}} este aplicată în acest moment.",
+       "tags-delete-explanation-warning": "Această acțiune este <strong>ireversibilă</strong> și <strong>nu poate fi anulată</strong>, nici chiar de către administratorii bazei de date. Asigurați-vă încă o dată că aceasta este eticheta pe care doriți să o ștergeți.",
+       "tags-delete-explanation-active": "<strong>Eticheta „$1” este încă activă și va continua să fie aplicată și pe viitor.</strong> Pentru a opri aplicarea ei, mergeți în locul(rile) în care este setată aplicarea acesteia și dezactivați-o de acolo.",
+       "tags-delete-reason": "Motiv:",
+       "tags-delete-submit": "Șterge ireversibil această etichetă",
+       "tags-delete-not-allowed": "Etichetele definite printr-o extensie pot fi șterse doar dacă extensia permite acest lucru în mod expres.",
+       "tags-delete-not-found": "Eticheta „$1” nu există.",
+       "tags-delete-too-many-uses": "Eticheta „$1” este aplicată pentru mai mult de $2 {{PLURAL:$2|versiune|versiuni|de versiuni}}, ceea ce înseamnă că nu poate fi ștearsă.",
+       "tags-delete-warnings-after-delete": "Eticheta „$1” a fost ștearsă cu succes, deși {{PLURAL:$2|s-a întâlnit următorul avertisment|s-au întâlnit următoarele avertismente}}:",
+       "tags-activate-title": "Activare etichetă",
+       "tags-activate-question": "Sunteți pe cale să activați eticheta „$1”.",
+       "tags-activate-reason": "Motiv:",
+       "tags-activate-not-allowed": "Nu este posibilă activarea etichetei „$1”.",
+       "tags-activate-not-found": "Eticheta „$1” nu există.",
+       "tags-activate-submit": "Activează",
+       "tags-deactivate-title": "Dezactivare etichetă",
+       "tags-deactivate-question": "Sunteți pe cale să dezactivați eticheta „$1”.",
+       "tags-deactivate-reason": "Motiv:",
+       "tags-deactivate-not-allowed": "Nu este posibilă dezactivarea etichetei „$1”.",
+       "tags-deactivate-submit": "Dezactivează",
        "comparepages": "Comparație între pagini",
        "compare-page1": "Pagina 1",
        "compare-page2": "Pagina 2",
        "logentry-upload-upload": "$1 {{GENDER:$2|a încărcat}} $3",
        "logentry-upload-overwrite": "$1 {{GENDER:$2|a încărcat}} o nouă versiune pentru $3",
        "logentry-upload-revert": "$1 {{GENDER:$2|a încărcat}} $3",
+       "log-name-managetags": "Jurnal gestionare etichete",
+       "log-description-managetags": "Această pagină listează activitățile de gestionare în ceea ce privește [[Special:Tags|etichetele]]. Jurnalul conține numai acțiunile efectuate manual de către un administrator; etichetele pot fi create sau șterse de software-ul wiki fără ca vreo intrare să fie înregistrată în acest jurnal.",
+       "logentry-managetags-create": "$1 {{GENDER:$2|a creat}} eticheta „$4”",
+       "logentry-managetags-delete": "$1 {{GENDER:$2|a șters}} eticheta „$4” (eliminată din cadrul {{PLURAL:$5|unei versiuni sau intrări din jurnal|a $5 versiuni și/sau intrări din jurnal|a $5 de versiuni și/sau intrări din jurnal}})",
+       "logentry-managetags-activate": "$1 {{GENDER:$2|a activat}} eticheta „$4” pentru utilizarea de către utilizatori și roboți",
+       "logentry-managetags-deactivate": "$1 {{GENDER:$2|a dezactivat}} eticheta „$4” de la utilizarea de către utilizatori și roboți",
        "rightsnone": "(niciunul)",
        "revdelete-summary": "descrierea modificărilor",
        "feedback-bugornote": "Dacă sunteți pregătit să descrieți o problemă tehnică în detaliu vă rugăm să [$1 raportați un bug].\nÎn caz contrar, puteți utiliza formularul de mai jos. Comentariul dumneavoastră va fi adăugat pe pagina „[$3 $2]”, împreună cu numele de utilizator și numele navigatorului pe care îl folosiți.",
index 82044e2..31fff42 100644 (file)
        "prefs-personal": "Личные данные",
        "prefs-rc": "Свежие правки",
        "prefs-watchlist": "Список наблюдения",
+       "prefs-editwatchlist": "Изменение списка наблюдения",
+       "prefs-editwatchlist-label": "Изменение записей вашего списка наблюдения:",
+       "prefs-editwatchlist-edit": "Просмотр и удаление названий из вашего списка наблюдения",
+       "prefs-editwatchlist-raw": "Редактирование списка наблюдения как текста",
+       "prefs-editwatchlist-clear": "Очистить список наблюдения",
        "prefs-watchlist-days": "Количество дней:",
        "prefs-watchlist-days-max": "Не более $1 {{PLURAL:$1|дня|дней}}",
        "prefs-watchlist-edits": "Максимальное количество правок, отображаемых в расширенном списке наблюдения:",
        "right-override-export-depth": "экспортирование страниц, включая связанные страницы с глубиной до 5",
        "right-sendemail": "отправка электронной почты другим участникам",
        "right-passwordreset": "просмотр электронных писем с изменением пароля",
+       "right-managechangetags": "Создавать и удалять [[Special:Tags|метки]] из базы данных",
        "newuserlogpage": "Журнал регистрации участников",
        "newuserlogpagetext": "Список недавно зарегистрировавшихся участников",
        "rightslog": "Журнал прав участника",
        "action-viewmyprivateinfo": "просмотр вашей частной информации",
        "action-editmyprivateinfo": "редактирование вашей частной информации",
        "action-editcontentmodel": "редактирование контентной модели страницы",
+       "action-managechangetags": "создание и удаление меток из базы данных",
        "nchanges": "$1 {{PLURAL:$1|изменение|изменения|изменений}}",
        "enhancedrc-since-last-visit": "$1 {{PLURAL:$1|с последнего посещения}}",
        "enhancedrc-history": "история",
        "watchlistedit-raw-done": "Ваш список наблюдения сохранён.",
        "watchlistedit-raw-added": "{{PLURAL:$1|Была добавлена|Были добавлены|Было добавлено}} $1 {{PLURAL:$1|запись|записи|записей}}:",
        "watchlistedit-raw-removed": "{{PLURAL:$1|Была удалена|Были удалены|Было удалено}} $1 {{PLURAL:$1|запись|записи|записей}}:",
-       "watchlistedit-clear-title": "Ð\9eÑ\87иÑ\89ение списка наблюдения",
+       "watchlistedit-clear-title": "Ð\9eÑ\87иÑ\81Ñ\82ка списка наблюдения",
        "watchlistedit-clear-legend": "Очистить список наблюдения",
        "watchlistedit-clear-explain": "Все записи будут удалены из вашего списка наблюдения",
        "watchlistedit-clear-titles": "Заголовки:",
        "tags-tag": "Имя метки",
        "tags-display-header": "Отображение в списках изменений",
        "tags-description-header": "Полное описание значения",
+       "tags-source-header": "Источник",
        "tags-active-header": "Активна?",
        "tags-hitcount-header": "Отмеченные правки",
+       "tags-actions-header": "Действия",
        "tags-active-yes": "Да",
        "tags-active-no": "Нет",
+       "tags-source-extension": "Определяется расширением",
+       "tags-source-none": "Больше не используется",
        "tags-edit": "править",
+       "tags-delete": "удалить",
+       "tags-activate": "активировать",
+       "tags-deactivate": "отключить",
        "tags-hitcount": "$1 {{PLURAL:$1|изменение|изменения|изменений}}",
+       "tags-create-heading": "Создать новую метку",
+       "tags-create-tag-name": "Название метки:",
+       "tags-create-reason": "Причина:",
+       "tags-create-submit": "Создать",
+       "tags-create-no-name": "Вы должны указать имя метки.",
+       "tags-create-already-exists": "Метка «$1» уже существует.",
+       "tags-create-warnings-below": "Вы хотите продолжить создание метки?",
+       "tags-delete-title": "Удалить метку",
+       "tags-delete-explanation-initial": "Вы собираетесь удалить метку «$1» из базы данных.",
+       "tags-delete-reason": "Причина:",
+       "tags-activate-title": "Активировать метку",
+       "tags-activate-question": "Вы собираетесь активировать метку «$1».",
+       "tags-activate-reason": "Причина:",
+       "tags-activate-not-allowed": "Невозможно активировать метку «$1».",
+       "tags-activate-not-found": "Метка «$1» не существует.",
+       "tags-activate-submit": "Активировать",
+       "tags-deactivate-title": "Отключить метку",
+       "tags-deactivate-reason": "Причина:",
+       "tags-deactivate-submit": "Отключить",
        "comparepages": "Сравнение страниц",
        "compare-page1": "Первая страница",
        "compare-page2": "Вторая страница",
        "logentry-upload-upload": "$1 загрузил{{GENDER:$2||а}} $3",
        "logentry-upload-overwrite": "$1 загрузил{{GENDER:$2||а}} новую версию $3",
        "logentry-upload-revert": "$1 загрузил{{GENDER:$2||а}} $3",
+       "log-name-managetags": "Журнал управления метками",
+       "logentry-managetags-create": "$1 создал{{GENDER:$2||а}} метку «$4»",
        "rightsnone": "(нет)",
        "revdelete-summary": "описание изменений",
        "feedback-bugornote": "Если вы готовы подробно описать техническую проблему, пожалуйста, [$1 сообщите об ошибке].\nВ противном случае вы можете использовать данную простую форму. Ваш комментарий будет добавлен на страницу «[$3 $2]» вместе с вашим именем участника и используемым браузером.",
index e2566eb..8401963 100644 (file)
        "last": "pric",
        "page_first": "prima",
        "page_last": "ùrtima",
-       "histlegend": "Pû cunfrontu tra virsioni: scègghîri li caseddi currispunnenti ê virsioni di cunfruntari e carcari Invio o lu buttuni ô funnu.<br />\nLegenda: <strong>({{int:cur}})</strong> = cunfruntari cu la virsioni currenti, <strong>({{int:last}})</strong> = cunfruntari cu la virsioni avanti d'idda, <strong>{{int:minoreditletter}}</strong> = canciamentu nicu",
+       "histlegend": "Pû cunfruntu tra virsioni: scègghîri li caseddi currispunnenti ê virsioni di cunfruntari e carcari Invio o lu buttuni ô funnu.<br />\nLegenda: <strong>({{int:cur}})</strong> = cunfruntari cu la virsioni currenti, <strong>({{int:last}})</strong> = cunfruntari cu la virsioni avanti d'idda, <strong>{{int:minoreditletter}}</strong> = canciamentu nicu",
        "history-fieldset-title": "Scurri ntâ crunuluggìa",
        "history-show-deleted": "Sulu chiddi cancillati",
        "histfirst": "i cchiu' vecchî",
        "rev-suppressed-text-unhide": "Sta virsioni dâ pàggina fu' <strong>supprimuta</strong>.\nSi ponnu a' vìdiri i dittagghî ntô [{{fullurl:{{#Special:Log}}/suppress|page={{FULLPAGENAMEE}}}} riggistru dî supprissioni].\nAncora poi [$1 talïari sta virsioni] si' voi prucèdiri.",
        "rev-deleted-text-view": "Sta virsioni dâ pàggina fu' <strong>cancillata</strong>.\nTu ancora a poi talïari; si ponnu a' vìdiri i dittagghî ntô [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} riggistru dî cancillazzioni].",
        "rev-suppressed-text-view": "Sta virsioni dâ pàggina fu' <strong>supprimuta</strong>.\nTu ancora a poi talïari; si ponnu a' vìdiri i dittagghî ntô [{{fullurl:{{#Special:Log}}/suppress|page={{FULLPAGENAMEE}}}} riggistru dî supprissioni].",
-       "rev-deleted-no-diff": "Nun è possibili taliari stu cunfrontu tra virsioni pirchì na revisioni fu '''scancillata'''.\nCunzurtari lu [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} log di cancillazzioni] pi ultiriuri dittagghi.",
+       "rev-deleted-no-diff": "Nun si po' talïari stu cunfruntu tra virsioni pirchì na revisioni fu <strong>cancillata</strong>.\nSi ponnu a' vìdiri li dittagghî ntô [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} riggistru dî cancillazzioni].",
        "rev-suppressed-no-diff": "Non poi talïari sta diffirenza picchì una dî virsioni fu' <strong>cancillata</strong>.",
        "rev-deleted-unhide-diff": "Una dî virsioni di sta diffirenza fu' <strong>cancillata</strong>.\nSi ponnu a' vìdiri i dittagghî ntô [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} riggistru dî cancillazzioni].\nAncora poi [$1 talïari sta diffirenza] si' voi prucèdiri.",
        "rev-suppressed-unhide-diff": "Una dî virsioni di sta diffirenza fu' <strong>supprimuta</strong>.\nSi ponnu a' vìdiri i dittagghî ntô [{{fullurl:{{#Special:Log}}/suppress|page={{FULLPAGENAMEE}}}} riggistru dî supprissioni].\nAncora poi [$1 talïari sta diffirenza] si' voi prucèdiri.",
        "difference-title-multipage": "Cunfruntu tra dî pàggini \"$1\" e \"$2\"",
        "difference-multipage": "(Diffirenza tra dî pàggini)",
        "lineno": "Riga $1:",
-       "compareselectedversions": "Cunfronta li virsioni scigghiuti",
+       "compareselectedversions": "Cunfrunta li virsioni scigghiuti",
        "showhideselectedversions": "Cancia la visibbilità dî virsioni scigghiuti",
        "editundo": "annulla",
        "diff-empty": "(Nudda diffirenza)",
        "backend-fail-stream": "Nun fu' pussìbbili trasmèttiri lu file \"$1\".",
        "backend-fail-backup": "Nun fu' pussìbbili fari na copia di riserva dû file \"$1\".",
        "backend-fail-notexists": "Lu file $1 nun esisti.",
-       "backend-fail-hashes": "Nun fu' pussìbbili ottèniri l'hash dî file pi' fari lu cunfrontu.",
+       "backend-fail-hashes": "Nun fu' pussìbbili ottèniri l'hash dî file pi' fari lu cunfruntu.",
        "backend-fail-notsame": "Già esisti un file nun idènticu a' \"$1\".",
        "backend-fail-invalidpath": "\"$1\" nun è un caminu d'archiviazzioni vàlidu.",
        "backend-fail-delete": "Nun fu' pussìbbili cancillari lu file \"$1\".",
        "tags-active-no": "No",
        "tags-edit": "cancia",
        "tags-hitcount": "$1 {{PLURAL:$1|canciamentu|canciamenti}}",
-       "comparepages": "Cunfronta pàggini",
+       "comparepages": "Cunfrunta pàggini",
        "compare-page1": "Pàggina 1",
        "compare-page2": "Pàggina 2",
        "compare-rev1": "Virsioni 1",
        "compare-rev2": "Virsioni 2",
-       "compare-submit": "Cunfronta",
+       "compare-submit": "Cunfrunta",
        "compare-invalid-title": "U tìtulu ca spicificasti nun è vàlidu.",
        "compare-title-not-exists": "U tìtulu ca spicificasti nun esisti.",
        "compare-revision-not-exists": "A virsioni ca spicificasti nun esisti.",
index 1e645cc..8750d56 100644 (file)
@@ -25,7 +25,8 @@
                        "Михајло Анђелковић",
                        "לערי ריינהארט",
                        "아라",
-                       "Nemo bis"
+                       "Nemo bis",
+                       "Aktron"
                ]
        },
        "tog-underline": "Подвлачење веза:",
        "content-model-text": "чист текст",
        "content-model-javascript": "јаваскрипт",
        "content-model-css": "CSS",
+       "content-json-empty-object": "Празан објекат",
        "expensive-parserfunction-warning": "'''Упозорење:''' ова страница садржи превише позива за рашчлањивање.\n\nТребало би да има мање од $2 {{PLURAL:$2|позив|позива|позива}}, а сада има $1.",
        "expensive-parserfunction-category": "Странице с превише позива за рашчлањивање",
        "post-expand-template-inclusion-warning": "'''Упозорење:''' величина укљученог шаблона је превелика.\nНеки шаблони неће бити укључени.",
        "prefs-personal": "Профил",
        "prefs-rc": "Скорашње измене",
        "prefs-watchlist": "Списак надгледања",
+       "prefs-editwatchlist": "Уређивање списка надгледања",
+       "prefs-editwatchlist-label": "Уређивање списка:",
+       "prefs-editwatchlist-edit": "Уреди списак",
+       "prefs-editwatchlist-raw": "Уреди сиров списак",
+       "prefs-editwatchlist-clear": "Испразни списак",
        "prefs-watchlist-days": "Број дана у списку надгледања:",
        "prefs-watchlist-days-max": "Највише $1 {{PLURAL:$1|дан|дана|дана}}",
        "prefs-watchlist-edits": "Највећи број измена у проширеном списку надгледања:",
        "import": "Увоз страница",
        "importinterwiki": "Међувики увоз",
        "import-interwiki-text": "Изаберите вики и наслов странице за увоз.\nДатуми и имена уредника ће бити сачувани.\nСве радње при увозу с других викија су забележене у [[Special:Log/import|дневнику увоза]].",
+       "import-interwiki-sourcewiki": "Изворна вики:",
+       "import-interwiki-sourcepage": "Изворна страница:",
        "import-interwiki-history": "Копирај све верзије историје за ову страницу",
        "import-interwiki-templates": "Укључи све шаблоне",
        "import-interwiki-submit": "Увези",
        "javascripttest": "Јаваскрипт тест",
        "javascripttest-pagetext-noframework": "Ова страница је резервисана за извршавање јаваскрипт тестова.",
        "javascripttest-pagetext-unknownframework": "Непознати радни оквир „$1“.",
+       "javascripttest-pagetext-unknownaction": "Непозната радња „$1“.",
        "javascripttest-pagetext-frameworks": "Изаберите један од следећих радних оквира: $1",
        "javascripttest-pagetext-skins": "Изаберите с којом темом желите да покренете пробу:",
        "javascripttest-qunit-intro": "Погледајте [$1 документацију за тестирање] на mediawiki.org.",
        "watchlistedit-clear-legend": "Испразни списак надгледања",
        "watchlistedit-clear-explain": "Сви наслови ће бити уклоњени из вашег списка надгледања.",
        "watchlistedit-clear-titles": "Наслови:",
-       "watchlistedit-clear-submit": "Испразни списак надгледања (Ово је трајно!)",
+       "watchlistedit-clear-submit": "Испразни списак надгледања (Ово је неповратно!)",
        "watchlistedit-clear-done": "Ваш списак надгледања је испражњен.",
        "watchlistedit-clear-removed": "{{PLURAL:$1|1 наслов је уклоњен|$1 наслова су уклоњена|$1 наслова је уклоњено}}:",
        "watchlistedit-too-many": "Има превише страница за приказ овде.",
        "version-ext-colheader-description": "Опис",
        "version-ext-colheader-credits": "Аутори",
        "version-license-title": "Лиценца за $1",
+       "version-license-not-found": "За ову екстензију није нађена информација о лиценци.",
        "version-poweredby-credits": "Овај вики покреће '''[https://www.mediawiki.org/ Медијавики]''', ауторска права © 2001-$1 $2.",
        "version-poweredby-others": "остали",
        "version-poweredby-translators": "translatewiki.net преводиоци",
        "duration-millennia": "$1 {{PLURAL:$1|миленијум|миленијума|миленијума}}",
        "rotate-comment": "Слика је ротирана за $1° у смеру казаљке на сату",
        "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|бајт|бајта|бајтова}}",
index 2747efe..d0342f1 100644 (file)
        "watchlistedit-clear-legend": "Isprazni spisak nadgledanja",
        "watchlistedit-clear-explain": "Svi naslovi će biti uklonjeni iz vašeg spiska nadgledanja.",
        "watchlistedit-clear-titles": "Naslovi:",
-       "watchlistedit-clear-submit": "Isprazni spisak nadgledanja (Ovo je trajno!)",
+       "watchlistedit-clear-submit": "Isprazni spisak nadgledanja (Ovo je nepovratno!)",
        "watchlistedit-clear-done": "Vaš spisak nadgledanja je ispražnjen.",
        "watchlistedit-clear-removed": "{{PLURAL:$1|1 naslov je uklonjen|$1 naslova su uklonjena|$1 naslova je uklonjeno}}:",
        "watchlistedit-too-many": "Ima previše stranica za prikaz ovde.",
index 741f5ca..3863e93 100644 (file)
        "prefsnologintext2": "Var god logga in för att ändra dina inställningar.",
        "prefs-skin": "Utseende",
        "skin-preview": "Förhandsvisning",
-       "datedefault": "Ovidkommande",
+       "datedefault": "Ingen preferens",
        "prefs-labs": "Testfunktioner",
        "prefs-user-pages": "Användarsidor",
        "prefs-personal": "Mitt konto",
        "right-suppressionlog": "Se privata loggar",
        "right-block": "Blockera andra användare från att redigera",
        "right-blockemail": "Blockera användare från att skicka e-post",
-       "right-hideuser": "Blockera ett användarnamn och dölja det från allmänheten",
+       "right-hideuser": "Blockera ett användarnamn och dölj det från allmänheten",
        "right-ipblock-exempt": "Kan redigera från blockerade IP-adresser",
        "right-proxyunbannable": "Kan redigera från blockerade proxyer",
        "right-unblockself": "Avblockera sig själv",
        "right-override-export-depth": "Exportera sidor inklusive länkade sidor till ett djup på 5",
        "right-sendemail": "Skicka e-post till andra användare",
        "right-passwordreset": "Visa e-postmeddelanden med lösenordsåterställning",
+       "right-managechangetags": "Skapa och radera [[Special:Tags|taggar]] från databasen",
        "newuserlogpage": "Logg över nya användare",
        "newuserlogpagetext": "Detta är en logg över nya användarkonton.",
        "rightslog": "Användarrättighetslogg",
        "rightslogtext": "Detta är en logg över ändringar av användares rättigheter.",
-       "action-read": "läsa denna sida",
+       "action-read": "läs denna sida",
        "action-edit": "redigera denna sida",
        "action-createpage": "skapa sidor",
        "action-createtalk": "skapa diskussionssidor",
        "action-viewmyprivateinfo": "visa din privata information",
        "action-editmyprivateinfo": "redigera din privata information",
        "action-editcontentmodel": "ändra innehållsmodellen för en sida",
+       "action-managechangetags": "skapa och radera taggar från databasen",
        "nchanges": "$1 {{PLURAL:$1|ändring|ändringar}}",
        "enhancedrc-since-last-visit": "$1 {{PLURAL:$1|sedan senaste besöket}}",
        "enhancedrc-history": "historik",
        "tags-tag": "Märkesnamn",
        "tags-display-header": "Utseende på listor över ändringar",
        "tags-description-header": "Full beskrivning av betydelse",
+       "tags-source-header": "Källa",
        "tags-active-header": "Aktiv?",
        "tags-hitcount-header": "Märkta ändringar",
+       "tags-actions-header": "Handlingar",
        "tags-active-yes": "Ja",
        "tags-active-no": "Nej",
+       "tags-source-extension": "Definieras av en förlängning",
+       "tags-source-none": "Används inte längre",
        "tags-edit": "redigera",
+       "tags-delete": "radera",
+       "tags-activate": "aktivera",
+       "tags-deactivate": "inaktivera",
        "tags-hitcount": "$1 {{PLURAL:$1|ändring|ändringar}}",
+       "tags-manage-no-permission": "Du har inte behörighet att hantera förändringstaggar.",
+       "tags-create-heading": "Skapa en ny tag",
+       "tags-create-explanation": "Som standard, kommer nyskapade taggar att bli tillgängliga för användning av användare och botar.",
+       "tags-create-tag-name": "Taggnamn:",
+       "tags-create-reason": "Anledning:",
+       "tags-create-submit": "Skapa",
+       "tags-create-no-name": "Du måste ange ett taggnamn.",
+       "tags-create-invalid-chars": "Taggnamn får inte innehålla kommatecken (<code>,</code>) eller snedstreck (<code>/</code>).",
+       "tags-create-invalid-title-chars": "Taggnamn får inte innehålla tecken som inte kan användas i sidtitlar.",
+       "tags-create-already-exists": "Taggen \"$1\" finns redan.",
+       "tags-create-warnings-above": "Följande {{PLURAL:$2|varning |varningar}} stöttes på när du försöker skapa etiketten \" $1 \":",
+       "tags-create-warnings-below": "Vill du fortsätta att skapa taggen?",
+       "tags-delete-title": "Radera tagg",
+       "tags-delete-explanation-initial": "Du är på väg att ta bort taggen \"$1\" från databasen.",
+       "tags-delete-explanation-warning": "Denna åtgärd är <strong>oåterkallelig</strong> och <strong>kan inte ångras</strong>, inte ens av databasadministratörer. Var säker på att detta är den tagg du vill radera.",
+       "tags-delete-explanation-active": "<strong>Taggen\" $1 \" är fortfarande aktiv, och kommer att fortsätta att appliceras i framtiden.</strong> För att hindra detta, gå till den eller de platser där taggen är inställd att användas, och inaktivera den där.",
+       "tags-delete-reason": "Anledning:",
+       "tags-delete-submit": "Radera denna tagg oåterkalleligen",
+       "tags-delete-not-found": "Taggen \"$1\" finns inte.",
+       "tags-delete-too-many-uses": "Taggen \"$1\" appliceras på mer än $2 {{PLURAL:$2|version|versioner}}, vilket innebär att den inte kan raderas.",
+       "tags-delete-warnings-after-delete": "Taggen \"$1\" raderades, men följande {{PLURAL:$2|varning|varningar}} inträffade:",
+       "tags-activate-title": "Aktivera tagg",
+       "tags-activate-question": "Du är på väg att aktivera taggen \"$1\".",
+       "tags-activate-reason": "Anledning:",
+       "tags-activate-not-allowed": "Det är inte möjligt att aktivera taggen \"$1\".",
+       "tags-activate-not-found": "Taggen \"$1\" finns inte.",
+       "tags-activate-submit": "Aktivera",
+       "tags-deactivate-title": "Inaktivera tagg",
+       "tags-deactivate-question": "Du är på väg att inaktivera taggen \"$1\".",
+       "tags-deactivate-reason": "Anledning:",
+       "tags-deactivate-not-allowed": "Det är inte möjligt att inaktivera taggen \"$1\".",
+       "tags-deactivate-submit": "Inaktivera",
        "comparepages": "Jämför sidor",
        "compare-page1": "Sida 1",
        "compare-page2": "Sida 2",
        "logentry-upload-upload": "$1 {{GENDER:$2|laddade upp}} $3",
        "logentry-upload-overwrite": "$1 {{GENDER:$2|laddade upp}} en ny version av $3",
        "logentry-upload-revert": "$1 {{GENDER:$2|laddade upp}} $3",
+       "log-name-managetags": "Tagghanterings logg",
+       "logentry-managetags-create": "$1 {{GENDER:$2|skapade}} taggen \"$4\"",
+       "logentry-managetags-delete": "$1 {{GENDER:$2|raderade}} taggen \"$4\" (borttagen från $5 {{PLURAL:$5|version eller loggpost|versioner och/eller loggposter}})",
+       "logentry-managetags-activate": "$1 {{GENDER:$2|aktiverade}} taggen \"$4\" för användning av användare och botar.",
+       "logentry-managetags-deactivate": "$1 {{GENDER:$2|inaktiverade}} taggen \"$4\" för användning av användare och botar.",
        "rightsnone": "(inga)",
        "revdelete-summary": "sammanfattning",
        "feedback-bugornote": "Om du har möjlighet att ge en detaljerad teknisk beskrivning av felet kan du lämna en [$1 buggrapport]. \nAnvänd annars formuläret nedan. Din kommentar kommer att läggas till på sidan \"[$3 $2]\", tillsammans med ditt användarnamn.",
index 00766b7..7edb633 100644 (file)
        "suppressionlog": "Log schrůńyńć",
        "suppressionlogtext": "Půńiżyj je lista nojnowszych wyćepań a zawarć s uwzglyndńyńym treśći schrůńůnej lo admińistratorůw. Coby przejrzeć lista teroźnych banůw a zawarć, uobezdrzij [[Special:BlockList|IP block list]].",
        "mergehistory": "Połůncz historyjo půmjyńań zajtůw",
-       "mergehistory-header": "Ta zajta dozwolo pouůnčyć historyje půmjyńań jydnyj zajty s inkšům, nowšům zajtům. Dej pozůr, coby sprawjyńy douo ćůnguo historyjo půmjyńań zajty w jeji historyji.",
-       "mergehistory-box": "Pouůnč historyjo sprowjyń dwůch zajtůw:",
-       "mergehistory-from": "Zajta zdřůduowo:",
+       "mergehistory-header": "Ta zajta moze skuplować gyszichta půmjan jednyj zajty ze gyszichtům inkszyj, nowszyj zajty.\nDej pozůr, co půmjany dali bydům mjoły historyczno ćůngłość edycyji zajty.",
+       "mergehistory-box": "Skupluj gyszichta sprowjyń dwůch zajtůw:",
+       "mergehistory-from": "Zdrzůdłowo zajta:",
        "mergehistory-into": "Zajta docelowo:",
-       "mergehistory-list": "Historyjo půmjyńań idźe pouůnčyć",
-       "mergehistory-merge": "Nastympujůnce půmjyńyńo zajty [[:$1]] idźe scalić s [[:$2]]. Uoznač w kolůmńy kropkům kero zmjana, uůnčńy s wčeśńijšymi, mo być scalůno. Užyće cajchůndzkůw uod nawigacyji kasuje wybůr we kolůmńy.",
-       "mergehistory-go": "Pokož půmjyńańo kere idźe scalić",
+       "mergehistory-list": "Gyszichta půmjyńań do śe skuplować",
+       "mergehistory-merge": "Nastympujůnce půmjyńyńo zajty [[:$1]] idźe scalić s [[:$2]]. Uoznocz we kolůmńy kropkům kero zmjana, wroz ze wcześńijszymi, mo być scalůno. Użyće linkůw uod nawigacyji kasuje wybůr we kolůmńy.",
+       "mergehistory-go": "Pokoż půmjyńańo kere idźe scalić",
        "mergehistory-submit": "Scal historyjo půmjyńań",
-       "mergehistory-empty": "Ńy mo historyje zmjan do scalyńa.",
-       "mergehistory-success": "$3 {{PLURAL:$3|pomjyńańe|pomjyńańa|pomjyńań}} w [[:$1]] ze sukcesym zostouo scalonych ze [[:$2]].",
-       "mergehistory-fail": "Ńy idźe scalić historyje půmjyńań. Zmjyń štalowańo parametrůw tyj uoperacyji.",
-       "mergehistory-no-source": "Ńy mo sam zajty zdřůduowyj $1.",
+       "mergehistory-empty": "Ńy mo historyje zmjan do scalyńo.",
+       "mergehistory-success": "$3 {{PLURAL:$3|pomjyńańe|pomjyńańa|pomjyńań}} we [[:$1]] ze sukcesym uostało scalonych ze [[:$2]].",
+       "mergehistory-fail": "Ńy idźe scalić historyje půmjyńań. Zmjyń sztalowańo parametrůw tyj uoperacyji.",
+       "mergehistory-no-source": "Ńy ma sam zajty zdrzůdłowyj $1.",
        "mergehistory-no-destination": "Ńy ma sam zajty docelowyj $1.",
-       "mergehistory-invalid-source": "Zajta zdřůduowo muśi mjeć poprowne mjano.",
-       "mergehistory-invalid-destination": "Zajta docelowo muśi mjeć poprowne mjano.",
-       "mergehistory-autocomment": "Historyjo [[:$1]] scalono ze [[:$2]]",
-       "mergehistory-comment": "Historyjo [[:$1]] pouůnčůno ze [[:$2]]: $3",
-       "mergehistory-same-destination": "Zajta zdřuduowo a docelowo ńy mogům być te same.",
+       "mergehistory-invalid-source": "Zajta zdrzůdłowo muśi mjeć poprawne mjano.",
+       "mergehistory-invalid-destination": "Zajta docelowo muśi mjeć poprawne mjano.",
+       "mergehistory-autocomment": "Historyjo [[:$1]] skuplowano ze [[:$2]]",
+       "mergehistory-comment": "Historyjo [[:$1]] skuplowano ze [[:$2]]: $3",
+       "mergehistory-same-destination": "Zajta zdrzůdłowo a docelowo ńy mogům być te same.",
        "mergehistory-reason": "Kůmyntorz:",
-       "mergelog": "Pouůnčůne",
+       "mergelog": "Skuplowane",
        "revertmerge": "Uodkupluj",
-       "mergelogpagetext": "PůÅ\84¾ej znojduje Å\9be lista uostatÅ\84ich pouůnÄ\8dyń historyji půmjyńań zajtůw.",
+       "mergelogpagetext": "PůÅ\84¼yj je lista uostatÅ\84ich kuplowań historyji půmjyńań zajtůw.",
        "history-title": "Gyszichta sprowjyń \"$1\"",
-       "difference-multipage": "(Porůwnańje zajt)",
+       "difference-multipage": "(Porůwnańy zajt)",
        "lineno": "Lińijo $1:",
        "compareselectedversions": "zrůwnej uobrane wersyje",
        "showhideselectedversions": "Ukoż/ukryj uobrane wersyje",
        "difference-missing-revision": "{{PLURAL:$2|Wersyjo|$2 wersyje|$2 wersyji}} #$1 zajty \"{{PAGENAME}}\" ńy {{PLURAL:$2|uostoła znaleźůno|uostoły znaleźůne|uostoło znaleźůnych}}. Zauobycz je to skiż starygo linky do wyćępanyj zajty. Powůd wyćepańa nojdźesz we [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} rejerze].",
        "searchresults": "Wyńiki sznupańo",
        "searchresults-title": "Wyniki sznupańo za „$1”",
-       "titlematches": "Znejdźono we titlach:",
+       "titlematches": "Znolyźono we titlach:",
        "textmatches": "Znejdźono na zajtach:",
        "notextmatches": "Ńy znejdźono we tekście zajtůw",
        "prevn": "poprzedńe {{PLURAL:$1|$1}}",
-       "nextn": "nastympne {{PLURAL:$1|$1}}",
+       "nextn": "nostympne {{PLURAL:$1|$1}}",
        "prevn-title": "{{PLURAL:$1|Poprzedńi|Poprzedńe}} $1 {{PLURAL:$1|wyńik|wyńiki|wyńikůw}}",
-       "nextn-title": "{{PLURAL:$1|Dolszy|Dolsze|Dolszych}} $1 {{PLURAL:$1|wyńik|wyńiki|wyńikůw}}",
+       "nextn-title": "{{PLURAL:$1|Dalszy|Dalsze|Dalszych}} $1 {{PLURAL:$1|wyńik|wyńiki|wyńikůw}}",
        "shown-title": "Ukoż $1 {{PLURAL:$1|wynik|wyniki|wynikůw}} lo zajta",
        "viewprevnext": "Uobźyrej ($1 {{int:pipe-separator}} $2) ($3)",
        "searchmenu-exists": "'''Ńy ma zajty uo mjańy \"[[:$1]]\" na tyj wiki'''",
        "search-redirect": "(půnkńyńćy $1)",
        "search-section": "(tajla $1)",
        "search-suggest": "Myśloł żeś: $1 ?",
-       "search-interwiki-caption": "Śostřane projekty",
+       "search-interwiki-caption": "Śostrzane projekty",
        "search-interwiki-default": "$1 wyńiki:",
        "search-interwiki-more": "(wjyncyj)",
        "search-relatedarticle": "Podane",
        "searchrelated": "podane",
        "searchall": "wszyjske",
-       "showingresults": "To lista na keryj je {{PLURAL:$1|'''1''' wyńik|'''$1''' wyńikůw}}, počynojůnc uod nůmeru '''$2'''.",
+       "showingresults": "To lista na keryj je {{PLURAL:$1|'''1''' wyńik|'''$1''' wyńikůw}}, sztartujůnc uod nůmery '''$2'''.",
        "search-nonefound": "Ńy mo wynikůw, kere uodpadajům kryterjům zapytańo.",
        "powersearch-legend": "Sznupańy zaawansowane",
        "powersearch-ns": "Sznupej we przestrzyńach mjan:",
        "powersearch-toggleall": "Wszyjsko",
        "powersearch-togglenone": "żodno",
        "search-external": "Zewnyntrzne sznupańy",
-       "searchdisabled": "Šnupańy we {{GRAMMAR:MS.lp|{{SITENAME}}}} zostouo zawarte. Zańim go zouůnčům, možeš sprůbować šnupańo bez Google. Ino zauwaž, co informacyje uo treśći {{GRAMMAR:MS.lp|{{SITENAME}}}} můgům być we Google ńyakuratne.",
+       "searchdisabled": "Sznupańy we {{GRAMMAR:MS.lp|{{SITENAME}}}} uostoło zawarte. Ńim go uotworzům nazod, moges sprůbować sznupańo bez Google. Ino zauważ, co informacyje uo treśći {{GRAMMAR:MS.lp|{{SITENAME}}}} můgům być we Google ńyaktuelne.",
        "search-error": "Wystůmpjůł feler przi sznupańu: $1",
        "preferences": "Preferyncyje",
        "mypreferences": "Preferyncyje",
        "datedefault": "Důmyślny",
        "prefs-labs": "Funkcyje \"labs\"",
        "prefs-user-pages": "Zajty używaczy",
-       "prefs-personal": "Dane užytkowÅ\84ika",
+       "prefs-personal": "Dane używocza",
        "prefs-rc": "Ńydowno pomjyńane",
        "prefs-watchlist": "Pozůrlista",
-       "prefs-watchlist-days": "Ličba dńi widočnych na liśće artikli, na kere dowoš pozůr:",
+       "prefs-watchlist-days": "Liczba dńůw widocznych na liśće artikli, na kere dowosz pozůr:",
        "prefs-watchlist-days-max": "Max $1 {{PLURAL:$1|dźyń|dńi}}",
-       "prefs-watchlist-edits": "Ličba půmjyńań pokazywanych we rozšyřůnyj liśće artiklůw, na kere dowoš pozůr:",
+       "prefs-watchlist-edits": "Liczba půmjyńań pokozywanych we rozszyrzůnyj liśće artiklůw, na kere dowosz pozůr:",
        "prefs-watchlist-edits-max": "Maksymalno liczba: 1000",
        "prefs-watchlist-token": "ID pozůrlisty:",
        "prefs-misc": "Roztůmajte",
        "rows": "Wjyrsze:",
        "columns": "Kolůmny:",
        "searchresultshead": "Sznupańy",
-       "stub-threshold": "Maksymalny rozmjar artikla uoznačanygo kej <a href=\"#\" class=\"stub\">stub (kůnsek)</a>",
+       "stub-threshold": "Maksymalny rozmjar artikla uoznaczanygo kej <a href=\"#\" class=\"stub\">stub (kůnsek)</a>",
        "stub-threshold-disabled": "Uodymkńynte",
-       "recentchangesdays": "Ličba dńi do pokazańo we půmjyńanych na uostatku:",
+       "recentchangesdays": "Liczba dńůw do pokazańo we půmjyńanych na uostatku:",
        "recentchangesdays-max": "(maksymalńy $1 {{PLURAL:$1|dźyń|dńi}})",
        "recentchangescount": "Liczba pozycyji na liśće půmjyńanych na uostatku, we historyje zajtůw a zajtach rejerůw:",
        "prefs-help-recentchangescount": "Ze listům ńydawnych pomjyńan, gyszichta zajt a rejer.",
-       "savedprefs": "Twoje štalowańo we preferyncyjach zostouy naškryflane.",
+       "savedprefs": "Twoje sztalowańo we preferyncyjach zostoły naszkryflane.",
        "timezonelegend": "Czasowo sztrefa",
        "localtime": "Lokalny czas:",
        "timezoneuseserverdefault": "Użyj domyślnygo czasu serwera ($1)",
        "userrights-nodatabase": "Baza danych $1 ńy istńije abo ńy je lokalno.",
        "userrights-nologin": "Muśisz [[Special:UserLogin|zalůgować śe]] na kůnto admińistratora, coby nadować uprawńyńo użytkowńikům.",
        "userrights-notallowed": "Ńy mosz dostympu do nadawańo uprawńyń używaczom.",
-       "userrights-changeable-col": "Grupy, kere možeš wybrać",
-       "userrights-unchangeable-col": "Grupy, kerych ńy možeš wybrać",
+       "userrights-changeable-col": "Grupy, kere moges wybrać",
+       "userrights-unchangeable-col": "Grupy, kerych ńy moges wybrać",
        "group": "Grupa:",
        "group-user": "Używacze",
        "group-autoconfirmed": "Autůmatyczńy zatwjerdzůne używacze",
        "right-edit": "Sprowjej zajty",
        "right-createpage": "Utworzůne zajty (kere ńy sům zajtůma godki)",
        "right-createtalk": "Utworzůne zajty godki",
-       "right-createaccount": "Utwořůne nowe kůnta užytkowńikůw",
+       "right-createaccount": "Utworzůne nowe kůnta użytkowńikůw",
        "right-minoredit": "Uoznocz půmjyńańo kej drobne",
        "right-move": "Przećepane zajty",
        "right-move-subpages": "Przećep zajty wroz ze jejich podzajtůma",
        "right-move-rootuserpages": "Przekludzańy zajtůw uod użytkowńikůw",
-       "right-movefile": "Przećepańe plikůw",
+       "right-movefile": "Przećepowańy plikůw",
        "right-suppressredirect": "Ńy twůrz przekerowańo ze starygo mjana jak przećepujesz zajta",
        "right-upload": "Wćepane pliki",
-       "right-reupload": "Nadpisuj pliki kere sam juž sům wćepane",
-       "right-reupload-own": "Nadpisuj plik wćepany sam bez tygo somygo užytkowńika",
-       "right-reupload-shared": "Nadpisuj pliki ůmješčůne w repozytorjům dźelůnych plikůw na lokalnyj kopje",
+       "right-reupload": "Nadpisuj pliki kere sam już sům wćepane",
+       "right-reupload-own": "Nadpisuj plik wćepany sam bez tygo samygo użytkowńika",
+       "right-reupload-shared": "Nadpisuj pliki umjeszczůne we repozytorjům dźelůnych plikůw na lokalnyj kopje",
        "right-upload_by_url": "Wćepńij sam plik ze adresa URL",
-       "right-purge": "Wyčyść pamjyńć podrynčno do zajty za wyjůntkym zajty potwjerdzyńo",
+       "right-purge": "Wyczyść pamjyńć podrynczno do zajty za wyjůntkym zajty potwjerdzyńo",
        "right-autoconfirmed": "Sprowjej zajty zawarte lo ńyzalůgowanych",
-       "right-bot": "Traktuj kej proces autůmatyčny",
-       "right-nominornewtalk": "Wyuůnčyńy uopcyje powjadamjańo uo drobnych půmjyńańach na zajće godki",
-       "right-apihighlimits": "Užywej uograÅ\84\8dyń wjelgości we zapytańach do API",
+       "right-bot": "Traktuj kej proces autůmatyczny",
+       "right-nominornewtalk": "Wyłůnczyńy uopcyje powjadamjańo uo drobnych půmjyńańach na zajće godki",
+       "right-apihighlimits": "Używej uograÅ\84iczyń wjelgości we zapytańach do API",
        "right-writeapi": "Zapisuj bez interfejs API",
        "right-delete": "Wyćep zajty",
        "right-bigdelete": "Wyćep zajty s dugům historyjům půmjyńań",
        "right-browsearchive": "Sznupej za wyćepanymi zajtůma",
        "right-undelete": "Wćepej nazod wyćepano zajta",
        "right-suppressrevision": "Přyglůndańy i uodtwařańy sprowjyń schrůńůnych před admińistratorami",
-       "right-suppressionlog": "Pokož prywatne lůgi",
-       "right-block": "Zawjyrańy sprowjorzům możebnośći edytowańo",
-       "right-blockemail": "Zablokuj užytkowÅ\84ikowi wysyuańy e-brifůw",
+       "right-suppressionlog": "Pokoż prywatne lůgi",
+       "right-block": "Zawjyrańy sprowjorzům mogebnośći edytowańo",
+       "right-blockemail": "Zablokuj użytkowÅ\84ikowi posyÅ\82ańy e-brifůw",
        "right-hideuser": "Zablokuj mjano użytkowńika i schrůń to przed publicznym dostympym",
        "right-ipblock-exempt": "Uobejdź zawarća uod sprowjyń do IP, autozawarća i zawarća zakresůw",
-       "right-proxyunbannable": "Uobejdź autůmatyčne zawarća uod sprowjyń do proxy",
+       "right-proxyunbannable": "Uobejdź autůmatyczne zawarća uod sprowjyń do proxy",
        "right-protect": "Zmjyń poźůmy zawarć i sprowjej zawarte zajty",
        "right-editprotected": "Sprowjej zawarte zajty (ze zawarćym kaskadowym)",
-       "right-editinterface": "Sprowjej interfejs užytkowńika",
-       "right-editusercssjs": "Sprowjej pliki CSS i JS inkšych užytkowńikůw",
-       "right-editusercss": "Sprowjej pliki CSS inkšych užytkowńikůw",
+       "right-editinterface": "Sprowjej interfejs użytkowńika",
+       "right-editusercssjs": "Sprowjej pliki CSS i JS inkszych użytkowńikůw",
+       "right-editusercss": "Sprowjej pliki CSS inkszych użytkowńikůw",
        "right-edituserjs": "Sprowjej pliki JS inkšych užytkowńikůw",
-       "right-rollback": "Rewert drap sprawjyÅ\84o uostatÅ\84ygo užytkowÅ\84ika kery sprawjou dano zajta",
-       "right-markbotedits": "Uoznoč rewertowane sprawjyńo kej sprawjyńo botůw",
+       "right-rollback": "Rewert drap sprawjyÅ\84o uostatÅ\84ygo użytkowÅ\84ika kery sprowjoÅ\82 dano zajta",
+       "right-markbotedits": "Uoznocz rewertowane sprawjyńo kej sprawjyńo botůw",
        "right-noratelimit": "Ńy mo uograńičyń přepustowośći",
        "right-import": "Import zajtůw s inkšych Wiki",
        "right-importupload": "Import zajtůw ze wćepanygo plika",
-       "right-patrol": "Uoznoč sprowjyńo kej přezdřane",
+       "right-patrol": "Uoznocz sprowjyńo kej przezdrzane",
        "right-autopatrol": "Naštaluj na autůmatyčne uoznačańy sprowjyń kej přezdřane",
        "right-patrolmarks": "Podglůnd značnikůw patrolowańo pomjeńanych na uostatku – uoznačańo kej „sprawdzůne”",
        "right-unwatchedpages": "Pokož lista zajtůw na kere žodyn ńy dowo pozoru",
        "action-autopatrol": "uoznačyńo wuasnygo sprowjyńo kej „sprawdzonygo”",
        "action-unwatchedpages": "podglůndu listy zajtůw na kere ńikt ńy dowo pozoru",
        "action-mergehistory": "skuplowańo historyje sprowjyń tyj zajty",
-       "action-userrights": "sprowjańo uprowńyń wšyjstkich sprowjořy",
+       "action-userrights": "sprowjańo uprowńyń wszyjstkich sprowjorzy",
        "action-userrights-interwiki": "sprowjańo uprowńyń sprowjořy na inkšych witrynach wiki",
        "action-siteadmin": "zawarćo a uodymkńyńćo bazy danych",
        "nchanges": "$1 {{PLURAL:$1|pomjyńańe|pomjyńańa|pomjyńań}}",
        "upload-preferred": "Zalecane formaty plikůw: $1.",
        "upload-prohibited": "Zakozane formaty plikůw: $1.",
        "uploadlogpage": "Wćepane sam",
-       "uploadlogpagetext": "PůÅ\84¾ej znojdowo Å\9be lista plikůw wÄ\87epanych na uostatku.\nPÅ\99elyź na zajta [[Special:NewFiles|galeryje nowych plikůw]], coby uobejzdÅ\99\87 pliki kej miÅ\84jatůrki.",
+       "uploadlogpagetext": "PůÅ\84¼yj jee lista plikůw wÄ\87epanych na uostatku.\nPrzelyź na zajta [[Special:NewFiles|galeryje nowych plikůw]], coby uobejzdrzeÄ\87 pliki kej miÅ\84atůrki.",
        "filename": "Mjano pliku",
        "filedesc": "Popis",
        "fileuploadsummary": "Uopis:",
        "upload-maxfilesize": "Maksymalny rozmior plika: $1",
        "watchthisupload": "Dowej pozůr na ta zajta",
        "filewasdeleted": "Plik uo takym mjańy juž bůu sam wćepany, ale zostou wyćepńjynty. Ńim wćepńeš go zaś, sprowdź $1.",
-       "filename-bad-prefix": "Mjano plika, kery wćepuješ, začyno śe uod '''\"$1\"''' &ndash; je to mjano nojčynśćy připisywane autůmatyčńy bez cyfrowe fotoaparaty, uůno ńy dowo žodnych informacyji uo zawartośći plika. Prošymy cobyś nadou plikowi inkše, lepij zrozůmjaue mjano.",
+       "filename-bad-prefix": "Mjano plika, kery wćepujesz, zaczyno śe uod '''\"$1\"''' &ndash; je to mjano nojczynśćy przipisywane autůmatyczńy bez cyfrowe fotoaparaty, a  ńy dowo uůno żodnych informacyji uo zawartośći plika. Proszymy cobyś nadoł plikowi inksze, lepij zrozůmjałe mjano.",
        "upload-success-subj": "Wćepańe plika udouo śe",
        "upload-proto-error": "Ńyprowidłowy protokůł",
        "upload-proto-error-text": "Zdalne přesůuańy plikůw wymago podańo adresu URL kery začyno śe na <code>http://</code> abo <code>ftp://</code>.",
        "filehist-comment": "Komyntorz",
        "imagelinks": "Używańy pliku",
        "linkstoimage": "{{PLURAL:$1|Tako zajta linkuje|Take zajty linkujům}} do tygo plika:",
-       "linkstoimage-more": "Wjyncyj jak $1 {{PLURAL:$1|zajta je adresowano|zajty sům adresowane|zajtůw je adresowanych}} do tygo plika.\nPůÅ\84¾Å¡o lista pokozuje yno {{PLURAL:$1|pjyrÅ¡y link|pjyrÅ¡e $1 linki|pjyrÅ¡ych $1 linkůw}} do tygo plika.\nDostympno je tyž [[Special:WhatLinksHere/$2|pouno lista]].",
+       "linkstoimage-more": "Wjyncyj jak $1 {{PLURAL:$1|zajta je adresowano|zajty sům adresowane|zajtůw je adresowanych}} do tygo plika.\nPůÅ\84¼szo lista pokozuje ino {{PLURAL:$1|pjyrszy link|pjyrsze $1 linki|pjyrszych $1 linkůw}} do tygo plika.\nDostympno je tyż [[Special:WhatLinksHere/$2|poÅ\82no lista]].",
        "nolinkstoimage": "Žodno zajta ńy je adrésowano do tygo plika.",
        "morelinkstoimage": "Pokož [[Special:WhatLinksHere/$1|wjyncy uodnośnikůw]] do tygo plika.",
        "duplicatesoffile": "{{PLURAL:$1|Nastympujůncy plik je kopjům|Nastympujůnce pliki sům kopjůma}} tygo plika:",
        "allinnamespace": "Wszyjstke zajty (we przestrzyńi mjan $1)",
        "allpagessubmit": "Ukoż",
        "allpagesprefix": "Ukoż artikle s prefiksym:",
-       "allpagesbadtitle": "Podane mjano je felerne, zawjera prefiks mjyndzyprojektowy abo mjyndzyjynzykowy. Może uůne tyż zawjerać jako buchsztaba abo inksze znaki, kerych ńy wolno używać we mjanach.",
+       "allpagesbadtitle": "Podane mjano je felerne, zawjyro prefiks mjyndzyprojektowy abo mjyndzygodkow. Może uůne tyż zawjerać jako buchsztaba abo inksze znaki, kerych ńy wolno używać we mjanach.",
        "allpages-bad-ns": "{{GRAMMAR:MS.lp|{{SITENAME}}}} ńy mo przestrzyńi mjan „$1”.",
        "allpages-hide-redirects": "Ukoż pukńyńća",
        "categories": "Kategoryje",
        "delete-toobig": "Ta zajta mo fest dugo historyja sprowjyń, wjyncyj jak $1 {{PLURAL:$1|půmjyńańy|půmjyńańo|půmjyńań}}.\nJeij wyćepańy mogło by spowodować zakłucyńo we dźołańu {{GRAMMAR:D.lp|{{SITENAME}}}} a bez tůż zostało uograńiczůne.",
        "delete-warning-toobig": "Ta zajta mo fest dugo historia sprowjyń, wjyncy kej $1 {{PLURAL:$1|půmjyńeńe|půmjyńańo|půmjyńań}}.\nDej pozůr, bo jei wyćepańe może spowodować zakłůcyńo w pracy {{GRAMMAR:D.lp|{{SITENAME}}}}.",
        "rollback": "Wycofej sprowjyńe",
-       "rollback_short": "Cofej",
        "rollbacklink": "cofej",
        "rollbackfailed": "Ńy idźe wycofać sprowjyńo",
-       "cantrollback": "Ńy idże cofnůńć pomjyńeńo, sam je ino jedna wersyja tyi zajty.",
+       "cantrollback": "Ńy idże cofnůńć pomjyńyńo, sam je ino jedna wersyja tyi zajty.",
        "alreadyrolled": "Ńy idźe lů zajty [[:$1|$1]] cofnůńć uostatńygo pomjyńeńa, kere wykonoł [[User:$2|$2]] ([[User talk:$2|godka]]{{int:pipe-separator}}[[Special:Contributions/$2|{{int:contribslink}}]]).\nKto inkszy zdůnżůł już to zrobić abo wprowadźił własne poprowki do treśći zajty.\n\nAutorym ostatńygo pomjyńyńo je terozki [[User:$3|$3]] ([[User talk:$3|godka]]{{int:pipe-separator}}[[Special:Contributions/$3|{{int:contribslink}}]]).",
        "editcomment": "Sprowjyńe uopisano: „''$1''”.",
        "revertpage": "Wycofano sprowjyńe użytkowńika [[Special:Contributions/$2|$2]] ([[User talk:$2|godka]]). Autor prziwrůcůnej wersyji to [[User:$1|$1]].",
        "import-logentry-interwiki": "zaimportowou $1 užywajůnc transwiki",
        "import-logentry-interwiki-detail": "$1 {{PLURAL:$1|wersyja|wersyje|wersyji}} ze $2",
        "tooltip-pt-userpage": "Mojo perzůnalno zajta",
-       "tooltip-pt-anonuserpage": "Zajta užytkowÅ\84ika do adresu IP spod kerygo sprowjoÅ¡",
+       "tooltip-pt-anonuserpage": "Zajta użytkowÅ\84ika do adresu IP spod kerygo sprowjosz",
        "tooltip-pt-mytalk": "Mojo zajta dyskusyje",
-       "tooltip-pt-anontalk": "Godka užytkowÅ\84ika do adresu IP spod kerygo sprowjoÅ¡",
+       "tooltip-pt-anontalk": "Godka użytkowÅ\84ika do adresu IP spod kerygo sprowjosz",
        "tooltip-pt-preferences": "Moje preferyncyje",
        "tooltip-pt-watchlist": "Lista artiklůw, na kere dowosz pozůr",
        "tooltip-pt-mycontris": "Lista uody mje sprowjonych",
        "tooltip-ca-history": "Storsze wersyje tyj zajty",
        "tooltip-ca-protect": "Zawřij ta zajta",
        "tooltip-ca-delete": "Wyćep ta zajta",
-       "tooltip-ca-undelete": "Přiwrůć wersyja tyi zajty spřed wyćepańo",
+       "tooltip-ca-undelete": "Prziwrůć wersyjo tyj zajty sprzed wyćepańo",
        "tooltip-ca-move": "Przećep ta zajta kaj indzij.",
        "tooltip-ca-watch": "Przidej artikel na pozůrlista",
        "tooltip-ca-unwatch": "Wyciep tyn artikel ze pozůrlisty",
        "tooltip-ca-nstab-main": "Uobźyrej zajta artikla",
        "tooltip-ca-nstab-user": "Ukoż perzůnalno zajta używocza",
        "tooltip-ca-nstab-media": "Uobejřij zajta artikla",
-       "tooltip-ca-nstab-special": "To je ekstra zajta. Ńy možeš jei sprowjać.",
+       "tooltip-ca-nstab-special": "To je ekstra zajta. Ńy moges jej sprowjać.",
        "tooltip-ca-nstab-project": "Uobejřij zajta projektu",
        "tooltip-ca-nstab-image": "Ukoż zajta grafiki",
        "tooltip-ca-nstab-mediawiki": "Zoboč komunikat systymowy",
        "tooltip-ca-nstab-template": "Uobźyrej muster",
        "tooltip-ca-nstab-help": "Pokož zajte s půmocą",
        "tooltip-ca-nstab-category": "Ukoż zajta kategoryje",
-       "tooltip-minoredit": "Uoznač ta zmjana za drobno",
+       "tooltip-minoredit": "Uoznacz ta zmjana za drobno",
        "tooltip-save": "Naszkryflej půmjyńańa",
        "tooltip-preview": "Ńiż naszkryflosz, uobźyrej efekt twojigo sprowjyńo.",
        "tooltip-diff": "Ukozuje twoje půmjyńańa we tekśće",
        "scarytranscludedisabled": "[Douůnčańy bez interwiki je wůuůnčůne]",
        "scarytranscludefailed": "[Ńy powjoduo śe pobrańy szablůna lů $1]",
        "scarytranscludetoolong": "[za dugo adresa URL]",
-       "deletedwhileediting": "'''Pozůr''': Ta zajta zostoła wyćepano po tym, jak żeś rozpoczůł jei sprowjańy!",
+       "deletedwhileediting": "'''Pozůr''': Ta zajta zostoła wyćepano po tym, jak żeś rozpoczůł jej sprowjańy!",
        "confirmrecreate": "Užytkowńik [[User:$1|$1]] ([[User talk:$1|godka]]) wyćepnůu tyn artikel po tym jak žeś rozpočůu(eua) jygo sprowjańe, podajůnc kej powůd wyćepańo:\n: ''$2''\nPotwjerdź chęć wćepańo nazod tygo artikla.",
        "recreate": "Wćepej nazod",
        "confirm_purge_button": "OK",
        "watchlistedit-normal-explain": "Půńiżyj mosz lista artikli na kere dowosz pozůr.\nCoby wyćepać z ńij jako zajta, zaznocz pole przi ńij i naćiś knefel „{{int:Watchlistedit-normal-submit}}”.\nMożesz tyż skorzistać ze [[Special:EditWatchlist/raw|tekstowygo sprowjorza listy artikli na kere dowosz pozůr]].",
        "watchlistedit-normal-submit": "Wyćep s listy",
        "watchlistedit-normal-done": "Z Twoi listy artikli na kere dowoš pozůr {{PLURAL:$1|zostoua wyćepano 1 zajta|zostouy wyćepane $1 zajty|zostouo wyćepanych $1 zajtůw}}:",
-       "watchlistedit-raw-title": "Tekstowy edytor listy artikli na kere dowoš pozůr",
+       "watchlistedit-raw-title": "Tekstowy edytor listy artikli na kere dowosz pozůr",
        "watchlistedit-raw-legend": "Tekstowy edytor listy artikli na kere dowoš pozůr",
        "watchlistedit-raw-explain": "Půńižy moš lista artikli na kere dowoš pozůr. W koždej lińii znojdowo śe titel jydnygo artikla. Lista možeš sprowjać dodajůnc nowe zajty i wyćepujůnc te kere na ńij sům. Jak skůńčyš, naćiś knefel „Uaktualńij lista zajtůw na kere dowům pozůr”.\nMožeš tyž [[Special:EditWatchlist|užyć standardowygo edytora]].",
        "watchlistedit-raw-titles": "Title:",
        "watchlisttools-view": "Pokož wažńijše pomjyńańo",
        "watchlisttools-edit": "Pokož i zmjyńoj pozorliste",
        "watchlisttools-raw": "Zmjyńoj surowo pozorlista",
-       "unknown_extension_tag": "Ńyznany značńik rozšeřyńo „$1”",
        "duplicate-defaultsort": "Pozůr: Zmjarkowanym kluczym sortowańo bydźe \"$2\" a zastůmpi uůn zawczasu używany klucz \"$1\".",
        "version": "Wersjo",
        "version-extensions": "Zainstalowane rozšeřyńa",
index 152435f..c4e7449 100644 (file)
        "prefs-personal": "โพรไฟล์ผู้ใช้",
        "prefs-rc": "ปรับปรุงล่าสุด",
        "prefs-watchlist": "รายการเฝ้าดู",
+       "prefs-editwatchlist": "แก้ไขรายการเฝ้าดู",
+       "prefs-editwatchlist-label": "แก้ไขรายการในรายการเฝ้าดูของคุณ:",
+       "prefs-editwatchlist-edit": "ดูและลบชื่อเรื่องในรายการเฝ้าดูของคุณ",
+       "prefs-editwatchlist-raw": "แก้ไขรายการเฝ้าดูดิบ",
+       "prefs-editwatchlist-clear": "ลบล้างรายการเฝ้าดูของคุณ",
        "prefs-watchlist-days": "จำนวนวันที่แสดงในรายการเฝ้าดู:",
        "prefs-watchlist-days-max": "มากสุด $1 วัน",
        "prefs-watchlist-edits": "จำนวนการแก้ไขมากสุดที่แสดงในรายการเฝ้าดูขยาย:",
        "right-protect": "เปลี่ยนระดับการล็อกและแก้ไขหน้าที่ถูกล็อกแบบถ่ายทอด",
        "right-editprotected": "แก้ไขหน้าที่ถูกล็อกในฐานะ \"{{int:protect-level-sysop}}\"",
        "right-editsemiprotected": "แก้ไขหน้าที่ถูกล็อกในฐานะ \"{{int:protect-level-autoconfirmed}}\"",
+       "right-editcontentmodel": "แก้ไขตัวแบบเนื้อหาของหน้า",
        "right-editinterface": "แก้ไขอินเตอร์เฟซผู้ใช้",
        "right-editusercssjs": "แก้ไขไฟล์ CSS และจาวาสคริปต์ของผู้ใช้อื่น",
        "right-editusercss": "แก้ไขไฟล์ CSS ของผู้ใช้อื่น",
        "action-viewmywatchlist": "ดูรายการเฝ้าดูของคุณ",
        "action-viewmyprivateinfo": "ดูสารสนเทศส่วนตัวของคุณ",
        "action-editmyprivateinfo": "แก้ไขสารสนเทศส่วนตัวของคุณ",
+       "action-editcontentmodel": "แก้ไขตัวแบบเนื้อหาของหน้า",
        "nchanges": "$1 การเปลี่ยนแปลง",
        "enhancedrc-since-last-visit": "$1 {{PLURAL:$1|ตั้งแต่การเยี่ยมชมครั้งสุดท้าย}}",
        "enhancedrc-history": "ประวัติ",
        "pager-older-n": "เก่ากว่า $1",
        "suppress": "ผู้ดูแลประวัติ",
        "querypage-disabled": "หน้าพิเศษนี้ถูกปิดใช้งานด้วยเหตุผลด้านสมรรถภาพ",
+       "apihelp-no-such-module": "ไม่พบมอดูล \"$1\"",
        "booksources": "แหล่งหนังสือ",
        "booksources-search-legend": "ค้นหาแหล่งหนังสือ",
        "booksources-search": "ค้นหา",
        "deleteprotected": "คุณไม่สามารถลบหน้านี้เพราะถูกล็อก",
        "deleting-backlinks-warning": "'''คำเตือน:''' [[Special:WhatLinksHere/{{FULLPAGENAME}}|หน้าอื่น]]เชื่อมโยงมายังหรือดึงข้อมูลจากหน้าที่คุณกำลังจะลบ",
        "rollback": "ย้อนการแก้ไขกลับฉุกเฉิน",
-       "rollback_short": "ย้อนกลับฉุกเฉิน",
        "rollbacklink": "ย้อนกลับฉุกเฉิน",
        "rollbacklinkcount": "ย้อนกลับฉุกเฉิน $1 การแก้ไข",
        "rollbacklinkcount-morethan": "ย้อนกลับฉุกเฉินกว่า $1 การแก้ไข",
        "import-logentry-interwiki": "นำเข้าข้ามวิกิ $1 แล้ว",
        "import-logentry-interwiki-detail": "นำเข้า $1 {{PLURAL:$1|รุ่นการแก้ไข|รุ่นการแก้ไข}}จาก $2",
        "javascripttest": "การทดสอบจาวาสคริปต์",
-       "javascripttest-title": "กำลังดำเนินงานทดสอบ $1",
        "javascripttest-pagetext-noframework": "หน้านี้สงวนไว้สำหรับดำเนินงานการทดสอบจาวาสคริปต์",
        "javascripttest-pagetext-skins": "เลือกสกินที่จะดำเนินงานการทดสอบ:",
        "javascripttest-qunit-intro": "ดู[$1 เอกสารกำกับการทดสอบ]บน mediawiki.org",
        "specialpages-group-wiki": "ข้อมูลและเครื่องมือ",
        "specialpages-group-redirects": "เปลี่ยนทางหน้าพิเศษ",
        "specialpages-group-spam": "เครื่องมือสแปม",
+       "specialpages-group-developer": "เครื่องมือผู้พัฒนา",
        "blankpage": "หน้าว่าง",
        "intentionallyblankpage": "หน้านี้ถูกทิ้งว่างโดยเจตนา",
        "external_image_whitelist": "  #เว้นบรรทัดนี้ไว้จากการแก้ไข<pre>\n#ใส่คำอธิบายปกติ (เฉพาะในส่วนที่อยู่ระหว่างสัญลักษณ์ //) ด้านล่างนี้\n#ซึ่งคำอธิบายดังกล่าวจะถูกจับคู่กับ URL ของรูปถ่ายภายนอก\n#ถ้าตรงกันจะปรากฏเป็นภาพออกมา หรือมิเช่นนั้นจะปรากฏเป็นลิงก์ไปยังรูปภาพนั้น\n#บรรทัดที่ขึ้นต้นด้วย # จะถูกกำหนดเป็นหมายเหตุเพิ่มเติม\n#กรุณาพิมพ์ตัวพิมพ์เล็ก-ใหญ่ตามชื่อไฟล์ให้ตรงกัน\n\n#ใส่ส่วนของคำอธิบายด้านบนของบรรทัดนี้และเว้นบรรทัดนี้จากการแก้ไข</pre>",
        "compare-revision-not-exists": "รุ่นที่คุณระบุไม่มีอยู่",
        "dberr-problems": "ขออภัย เว็บไซต์นี้กำลังพบกับข้อผิดพลาดทางเทคนิค",
        "dberr-again": "กรุณารอสักครู่แล้วจึงโหลดใหม่",
-       "dberr-info": "(à¹\84มà¹\88สามารà¸\96à¸\95ิà¸\94à¸\95à¹\88อà¹\80à¸\8bิรà¹\8cà¸\9fà¹\80วอรà¹\8cà¸\90าà¸\99à¸\82à¹\89อมูลà¹\84à¸\94à¹\89: $1)",
-       "dberr-info-hidden": "(à¹\84มà¹\88สามารà¸\96à¸\95ิà¸\94à¸\95à¹\88อà¹\80à¸\8bิรà¹\8cà¸\9fà¹\80วอรà¹\8cฐานข้อมูล)",
+       "dberr-info": "(à¹\84มà¹\88สามารà¸\96à¹\80à¸\82à¹\89าà¸\96ึà¸\87à¸\90าà¸\99à¸\82à¹\89อมูล: $1)",
+       "dberr-info-hidden": "(à¹\84มà¹\88สามารà¸\96à¹\80à¸\82à¹\89าà¸\96ึà¸\87ฐานข้อมูล)",
        "dberr-usegoogle": "คุณสามารถลองสืบค้นผ่านกูเกิลในระหว่างนี้",
        "dberr-outofdate": "โปรดทราบว่าดัชนีเนื้อหาของเราในกูเกิลอาจล้าสมัยแล้ว",
        "dberr-cachederror": "นี่คือข้อมูลคัดลอกชั่วคราวของหน้าที่ร้องขอ และอาจไม่เป็นปัจจุบัน",
        "revdelete-uname-unhid": "ชื่อผู้ใช้ถูกแสดง",
        "revdelete-restricted": "เพิ่มการจำกัดกับผู้ดูแลระบบ",
        "revdelete-unrestricted": "ยกเลิกการจำกัดแก่ผู้ดูแลระบบ",
+       "logentry-merge-merge": "$1 {{GENDER:$2|รวม}} $3 เข้ากับ $4 (รุ่นถึง $5)",
        "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-patrol-patrol": "$1 ทำเครื่องหมายว่ารุ่น $4 ของหน้า $3 ได้รับการตรวจสอบแล้ว",
        "logentry-patrol-patrol-auto": "$1 ทำเครื่องหมายโดยอัตโนมัติว่ารุ่น $4 ของหน้า $3 ได้รับการตรวจสอบแล้ว",
-       "logentry-newusers-newusers": "บัญชีผู้ใช้ $1 ถูกสร้างขึ้น",
+       "logentry-newusers-newusers": "บัญชีผู้ใช้ $1 ถูกสร้าง",
        "logentry-newusers-create": "บัญชีผู้ใช้ $1 ถูกสร้างขึ้น",
        "logentry-newusers-create2": "บัญชีผู้ใช้ $3 ถูกสร้างขึ้นโดย $1",
        "logentry-newusers-byemail": "บัญชีผู้ใช้ $3 ถูกสร้างขึ้นโดย $1 และส่งรหัสผ่านไปทางอีเมลแล้ว",
        "duration-decades": "$1 ทศวรรษ",
        "duration-centuries": "$1 ศตวรรษ",
        "duration-millennia": "$1 สหัสวรรษ",
+       "expandtemplates": "ขยายแม่แบบ",
        "expand_templates_output": "ผลลัพธ์",
        "expand_templates_ok": "ตกลง",
        "expand_templates_remove_comments": "นำส่วนความเห็นออก",
        "log-description-pagelang": "นี่คือปูมการเปลี่ยนภาษาหน้า",
        "logentry-pagelang-pagelang": "$1 เปลี่ยนภาษาของ $3 จาก $4 เป็น $5",
        "default-skin-not-found-row-enabled": "* <code>$1</code> / $2 (เปิดใช้งาน)",
-       "default-skin-not-found-row-disabled": "* <code>$1</code> / $2 ('''ปิดใช้งาน''')"
+       "default-skin-not-found-row-disabled": "* <code>$1</code> / $2 ('''ปิดใช้งาน''')",
+       "mediastatistics": "สถิติสื่อ",
+       "mediastatistics-summary": "สถิติเกี่ยวกับประเภทไฟล์ที่อัปโหลด ซึ่งรวมเฉพาะรุ่นล่าสุดของไฟล์นั้น \nไม่รวมไฟล์รุ่นเก่าหรือที่ถูกลบแล้ว",
+       "mediastatistics-nbytes": "{{PLURAL:$1|$1 ไบต์}} ($2; $3%)",
+       "mediastatistics-table-count": "จำนวนไฟล์",
+       "mediastatistics-table-totalbytes": "ขนาดรวม",
+       "mediastatistics-header-unknown": "ไม่ทราบ",
+       "mediastatistics-header-drawing": "ภาพวาดเส้น (ภาพเวกเตอร์)",
+       "mediastatistics-header-audio": "เสียง",
+       "mediastatistics-header-video": "วิดีทัศน์"
 }
index 346bf8d..98dc382 100644 (file)
        "tog-hidepatrolled": "Тикшерелгән үзгәртүләр яңа үзгәртүләр исемлегеннән яшерелсен.",
        "tog-newpageshidepatrolled": "Тикшерелгән битләр яңа битләр исемлегеннән яшерелсен",
        "tog-extendwatchlist": "Соңгыларын гына түгел, ә барлык үзгәртүләрне эченә алган, киңәйтелгән күзәтү исемлеге",
-       "tog-usenewrc": "Соңгы үзгәртүләрдә һәм күзәтү исемлегендә үзгәрешләрне төркемләргә(JavaScript кирәк)",
+       "tog-usenewrc": "Соңгы үзгәртүләрдә һәм күзәтү исемлегендә үзгәрешләрне төркемләргә",
        "tog-numberheadings": "Атамалар автомат рәвештә номерлансын",
-       "tog-showtoolbar": "Үзгәртү вакытында коралларның өске панеле күрсәтелсен (JavaScript кирәк)",
-       "tog-editondblclick": "Битләргә ике чирттерү белән үзгәртү бите ачылсын (JavaScript кирәк)",
-       "tog-editsectiononrightclick": "Бүлек исеменә тычканның уң чирттермәсе белән төрткәч үзгәртү бите ачылсын (JavaScript кирәк)",
+       "tog-showtoolbar": "Үзгәртү вакытында коралларның өске панеле күрсәтелсен",
+       "tog-editondblclick": "Битләргә ике чирттерү белән үзгәртү бите ачылсын",
+       "tog-editsectiononrightclick": "Бүлек исеменә тычканның уң чирттермәсе белән төрткәч үзгәртү",
        "tog-watchcreations": "Мин төзегән битләр һәм йөкләгән файллар күзәтү исемлегемә өстәлсен",
        "tog-watchdefault": "Мин үзгәрткән битләр һәм файллар күзәтү исемлегемә өстәлсен",
        "tog-watchmoves": "Мин күчергән битләр һәм файллар күзәтү исемлегемә өстәлсен",
@@ -48,7 +48,7 @@
        "tog-shownumberswatching": "Битне күзәтү исемлекләренә өстәгән кулланучылар санын күрсәтелсен",
        "tog-oldsig": "Хәзерге имза:",
        "tog-fancysig": "Имзаның шәхси вики-билгеләмәсе (автоматик сылтамасыз)",
-       "tog-uselivepreview": "Тиз карап алу кулланылсын (JavaScript, эксперименталь)",
+       "tog-uselivepreview": "Тиз карап алуны куллану",
        "tog-forceeditsummary": "Үзгәртүләрне тасвирлау юлы тутырылмаган булса, кисәтү",
        "tog-watchlisthideown": "Минем үзгәртүләрем күзәтү исемлегеннән яшерелсен",
        "tog-watchlisthidebots": "Бот үзгәртүләре күзәтү исемлегеннән яшерелсен",
        "actions": "Хәрәкәт",
        "namespaces": "Исемнәр мәйданы",
        "variants": "Төрләр",
+       "navigation-heading": "Навигация",
        "errorpagetitle": "Хата",
        "returnto": "$1 битенә кайту.",
        "tagline": "{{SITENAME}} проектыннан",
        "permalink": "Даими сылтама",
        "print": "Бастыру",
        "view": "Карау",
+       "view-foreign": "$1 сәхифәсендә карау",
        "edit": "Үзгәртү",
        "edit-local": "Локаль тасвирламаны үзгәртергә",
        "create": "Төзү",
        "jumptonavigation": "навигация",
        "jumptosearch": "эзләү",
        "view-pool-error": "Гафу итегез, хәзерге вакытта серверлар буш түгел.\nБу битне карарга теләүчеләр артык күп.\nБу биткә соңрак керүегез сорала.\n\n$1",
+       "generic-pool-error": "Гафу итегез, хәзерге вакытта серверлар буш түгел.\nБу битне карарга теләүчеләр артык күп.\nБу биткә соңрак керүегез сорала.",
        "pool-timeout": "Кысылуның  вакыты узды",
        "pool-queuefull": "Сорауларны саклау  бите тулы",
        "pool-errorunknown": "Билгесез  хата",
        "hidetoc": "яшерү",
        "collapsible-collapse": "Төрү",
        "collapsible-expand": "Ачу",
+       "confirmable-yes": "Әйе",
+       "confirmable-no": "Юк",
        "thisisdeleted": "$1 карарга яки торгызырга телисезме?",
        "viewdeleted": "$1 карарга телисезме?",
        "restorelink": "{{PLURAL:$1|1=1 бетерелгән үзгәртүне|$1 бетерелгән үзгәртүне}}",
        "mycustomjsprotected": "Сезнең биттә JavaScript үзгәртергә хокукларыгыз юк.",
        "ns-specialprotected": "Махсус битләрне үзгәртеп булмый.",
        "titleprotected": "Бу исем белән бит ясау [[User:$1|$1]] тарафыннан тыелган.\nУл күрсәткән сәбәп: ''$2''.",
+       "exception-nologin": "Сез хисап язмагызга кермәгәнсез",
        "virus-badscanner": "Көйләү хатасы. Билгесез вируслар сканеры: ''$1''",
        "virus-scanfailed": "сканерлау хатасы ($1 коды)",
        "virus-unknownscanner": "билгесез антивирус:",
        "gotaccount": "Сез инде теркәлдегезме? '''$1'''.",
        "gotaccountlink": "Керү",
        "userlogin-resetlink": "Серсүзегезне оныттыгызмы?",
+       "userlogin-resetpassword-link": "Серсүзне алыштырыргамы?",
+       "userlogin-helplink2": "Керү буенча ярдәм",
+       "userlogin-createanother": "Башка хисап язмасы төзү",
+       "createacct-emailrequired": "Электрон почта юлламагыз",
+       "createacct-emailoptional": "Электрон почта юлламагыз (мәҗбүри түгел)",
+       "createacct-email-ph": "Электрон почта юлламагызны языгыз",
        "createaccountmail": "электрон почта аша",
        "createaccountreason": "Сәбәп:",
        "badretype": "Кертелгән серсүзләр бер үк түгел.",
        "revdelete-hide-user": "Үзгәртүченең исемен/IP адресын яшер",
        "revdelete-hide-restricted": "Мәгълүматлар идарәчеләрдән дә яшерелсен",
        "revdelete-radio-same": "(үзгәртмәү)",
-       "revdelete-radio-set": "Әйе",
-       "revdelete-radio-unset": "Юк",
+       "revdelete-radio-set": "Яшеренлек",
+       "revdelete-radio-unset": "Ð\9aÒ¯Ñ\80енүÑ\87Ó\99нлек",
        "revdelete-suppress": "Мәгълүматлар идарәчеләрдән дә яшерелсен",
        "revdelete-log": "Сәбәп:",
        "revdelete-submit": "{{PLURAL:$1|сайланылган версиягә}} кулланырга",
        "deletereasonotherlist": "Башка сәбәп",
        "deletereason-dropdown": "* Бетерүнең сәбәпләре\n** вандаллык\n** автор соравы буенча\n** автор хокукларын бозу",
        "delete-edit-reasonlist": "Сәбәпләр исемлеген үзгәртү",
-       "rollback_short": "Кире кайтару",
        "rollbacklink": "кире кайтару",
        "editcomment": "Үзгәртү өчен тасвир: \"''$1''\".",
        "revertpage": "[[Special:Contributions/$2|$2]] үзгәртүләре ([[User talk:$2|бәхәс]])  [[User:$1|$1]] юрамасына кадәр кире кайтарылды",
index 0c02aaf..54f5e0b 100644 (file)
        "view-foreign": "$1da koʻrish",
        "edit": "Tahrirlash",
        "create": "Yaratish",
+       "create-local": "Mahalliy tavsifini qoʻshish",
        "editthispage": "Ushbu sahifani tahrirlash",
        "create-this-page": "Ushbu sahifani yaratish",
        "delete": "O‘chirish",
        "pool-timeout": "Toʻsishni kutish vaqti tugadi",
        "pool-queuefull": "Soʻrovlar jamlanmasi toʻldi",
        "pool-errorunknown": "Nomaʼlum xato",
+       "poolcounter-usage-error": "Foydalanish xatosi: $1",
        "aboutsite": "{{SITENAME}} haqida",
        "aboutpage": "Project:Haqida",
        "copyright": "Keltirilgan maʼlumotlar $1 orqali tarqatilmoqda (agar aksinchasi koʻrsatilmagan boʻlsa).",
        "hidetoc": "yashirish",
        "collapsible-collapse": "Yigʻish",
        "collapsible-expand": "Yoyish",
+       "confirmable-confirm": "Aminmisiz?",
        "confirmable-yes": "Ha",
        "confirmable-no": "Yoʻq",
        "thisisdeleted": "$1ni koʻrib chiqasizmi yoki tiklaysizmi?",
        "filerenameerror": "Fayl nomini «$1»dan «$2»ga o‘zgartirish imkoni yoʻq.",
        "filedeleteerror": "\"$1\" faylini oʻchirib boʻlmadi.",
        "directorycreateerror": "\"$1\" papkasini yaratish imkoni yoʻq.",
+       "directoryreadonlyerror": "\"$1\" katalogi faqat oʻqish uchun moʻljallangan.",
        "filenotfound": "\"$1\" faylini topib boʻlmadi.",
        "unexpected": "Kutilmagan qiymat: \"$1\"=\"$2\".",
+       "formerror": "Xatolik: Formani jo‘natib bo‘lmadi.",
+       "badarticleerror": "Bu harakatni ushbu sahifada bajarib bo‘lmadi.",
        "cannotdelete-title": "\"$1\" sahifasini oʻchirib boʻlmadi.",
        "badtitle": "Notoʻgʻri sarlavha",
        "viewsource": "Manbasini koʻrish",
        "namespaceprotected": "Sizda '''$1''' nomfazosi sahifalarini tahrirlash huquqi yoʻq",
        "customcssprotected": "Sizda uchbu CSS sahifani tahrirlash huquqi yoʻq, chunki bu yerda boshqa foydalanuvchining shaxsiy moslamalari saqlanadi.",
        "customjsprotected": "Sizda uchbu JavaScript sahifani tahrirlash huquqi yoʻq, chunki bu yerda boshqa foydalanuvchining shaxsiy moslamalari saqlanadi.",
+       "mycustomjsprotected": "Sizda ushbu JavaScript sahifani tahrirlashga ruxsat mavjud emas.",
+       "myprivateinfoprotected": "Sizda shaxsiy maʻlumotlaringizni tahrirlashga ruxsat mavjud emas.",
+       "mypreferencesprotected": "Sizda afzalliklarni tahrirlashga ruxsat mavjud emas.",
        "ns-specialprotected": "\"{{ns:special}}\" nomfazosi sahifalari tahrirlanishi mumkin emas.",
        "exception-nologin": "Siz tizimda o'zingizni tanishtirmadingiz",
        "exception-nologin-text": "Bu sahifani koʻrish yoki soʻralgan amalni bajarish uchun tizimga kirishingiz lozim.",
        "createacct-email-ph": "Elektron pochta manzilingizni kiriting",
        "createacct-another-email-ph": "Elektron pochta manzilini kiriting",
        "createaccountmail": "Tasodifan tanlab beriladigan vaqtinchalik maxfiy soʻzdan foydalanish (elektron pochta manzilingizga joʻnatiladi)",
+       "createacct-realname": "Haqiqiy ismi (ixtiyoriy)",
        "createaccountreason": "Sabab:",
        "createacct-reason": "Sabab",
        "createacct-reason-ph": "Nimaga yana boshqa hisob yaratyapsiz",
        "createacct-benefit-body2": "sahifalar soni",
        "createacct-benefit-body3": "soʻnggi paytdagi ishtirokchilar soni",
        "badretype": "Siz tomondan kiritilgan maxfiy so'zlar mos kelmayapti.",
+       "userexists": "Bunday foydalanuvchi nomi avvalroq yaratilgan. Iltimos, boshqa nom tanlang.",
        "loginerror": "Foydalanuvchini aniqlashda xatolik",
        "createacct-error": "Hisob yaratishda xatolik",
        "createaccounterror": "Hisob yozuvi yaratishning iloji yoʻq: $1",
        "wrongpasswordempty": "Maxfiy soʻz koʻrsatilmagan. Qaytadan urinib koʻring.",
        "mailmypassword": "Maxfiy soʻzni yangilash",
        "passwordremindertitle": "{{SITENAME}} uchun vaqtinchalik yangi maxfiy so'z",
+       "noemailcreate": "Siz haqiqiy elektron pochta manzilingizni taqdim qilishingiz kerak.",
        "mailerror": "$1 manziliga xat yuborishda xatolik",
        "emailauthenticated": "Elektron pochta manzilingiz $2, $3 da tasdiqlangan.",
        "emailconfirmlink": "Elektron pochta manzilingizni tasdiqlash",
        "pt-login-button": "Kirish",
        "pt-createaccount": "Hisob yaratish",
        "pt-userlogout": "Chiqish",
+       "php-mail-error-unknown": "PHPning mail() funksiyasida nomaʻlum xatolik.",
        "changepassword": "Maxfiy soʻzni oʻzgartirish",
        "resetpass_header": "Maxfiy soʻzni oʻzgartirish",
        "oldpassword": "Eski mahfiy so'z:",
        "resetpass_submit": "Maxfiy so'zni o'rnatish va kirish",
        "changepassword-success": "Maxfiy soʻzni oʻzgartirish muvaffaqiyatli oʻtdi!",
        "resetpass_forbidden": "Maxfiy so'z o'zgartirilishi mumkin emas",
+       "resetpass-no-info": "Siz ushbu sahifaga toʻgʻridan toʻgʻri kirishingiz uchun tizimga kirgan boʻlishingiz kerak.",
        "resetpass-submit-loggedin": "Maxfiy soʻzni oʻzgartirish",
        "resetpass-submit-cancel": "Bekor",
        "resetpass-temp-password": "Vaqtinchalik maxfiy soʻz",
        "passwordreset-text-one": "Mahfiy soʻzni tashlash uchun ushbu oynalarni toʻltiring.",
        "passwordreset-text-many": "{{PLURAL:$1|Quyidagi oynalardan birini toʻldirsangiz, elektron pochtangizga vaqtinchalik maxfiy soʻz joʻnatiladi.}}",
        "passwordreset-legend": "Maxfiy soʻzni yangilash",
+       "passwordreset-emaildisabled": "Email xususiyatlari ushbu vikida oʻchirib qoʻyilgan.",
        "passwordreset-username": "Foydalanuvchi nomi:",
        "passwordreset-domain": "Domen:",
        "passwordreset-capture": "Xatni koʻrmoqchimisiz?",
        "changeemail-none": "(yoʻq)",
        "changeemail-password": "Sizning {{SITENAME}}dagi maxfiy so‘zingiz:",
        "changeemail-submit": "Manzilni o'zgartirish",
-       "resettokens": "So‘nggi paytdagi kalitlaringiz",
-       "resettokens-legend": "Kalitlaringizni tiklash",
+       "resettokens": "Kalitlaringizni yangilash",
+       "resettokens-legend": "Kalitlaringizni yangilash",
        "resettokens-tokens": "Kalitlar:",
-       "resettokens-token-label": "$1 (joriy qiymat: $2)",
-       "resettokens-done": "Kalitlar tiklandi.",
-       "resettokens-resetbutton": "Belgilangan kalitlarni tiklash",
+       "resettokens-token-label": "$1 (joriy koʻrsatkich: $2)",
+       "resettokens-done": "Kalitlar yangilandi.",
+       "resettokens-resetbutton": "Belgilangan kalitlarni yangilash",
        "bold_sample": "Qalin matn",
        "bold_tip": "Qalin matn",
        "italic_sample": "Yotiq matn",
        "editconflict": "Tahrirlash toʻqnashuvi: $1",
        "explainconflict": "Sahifani tahrirlayotgan mahalingizda boshqa birov unga oʻzgarish kiritib ulgurdi.\nYuqoridagi tahrir oynasida sahifaning joriy matnini koʻrishingiz mumkin.\nPastdagida esa siz kiritgan oʻzgarishlar koʻrsatilgan.\nKiritmoqchi boʻlgan oʻzgarishlaringizni pastdagi oynadan yuqoridagiga oʻtkazing.\n«{{int:savearticle}}» tugmasini bossangiz <strong>faqat</strong> yuqoridagi matn saqlanadi.",
        "yourtext": "Sizning matningiz",
-       "editingold": "<strong>Ogohlantirish: Siz sahifaning eski nusxasini tahrirlayapsiz.</strong>\nUni shunday holicha saqlasangiz, keyingi nusxalardagi oʻzgarishlar yoʻqotiladi.",
+       "editingold": "<strong>Ogohlantirish: Siz sahifaning eski nusxasini tahrirlayapsiz.</strong> Uni shunday holicha saqlasangiz, keyingi nusxalardagi oʻzgarishlar yoʻqotiladi.",
        "yourdiff": "Farqlar",
        "copyrightwarning": "Iltimos, {{SITENAME}}ga yuklangan har qanday axborot $2 ostida tarqatilishiga diqqat qiling (batafsil ma'lumot uchun $1ni ko'ring).\nAgar yozganlaringiz keyinchalik tahrir qilinishi va qayta tarqatilishiga rozi bo'lmasangiz, u holda bu yerga yozmang.<br />\nSiz shuningdek bu yozganlaringiz sizniki yoki erkin litsenziya ostida ekanligini va'da qilmoqdasiz.\n'''MUALLIFLIK HUQUQLARI BILAN HIMOYALANGAN ISHLARNI ZINHOR BERUXSAT YUBORMANG!'''",
        "copyrightwarning2": "Iltimos, shuni esda tutingki, {{SITENAME}} sahifalaridagi barcha matnlar boshqa foydalanuvchilar tomonidan tahrirlanishi, almashtirilishi yoki o'chirilishi mumkin. Agar siz yozgan ma'lumotlaringizni bunday tartibda tahrirlanishiga rozi bo'lmasangiz, unda uni bu yerga joylashtirmang.<br />\nBundan tashqari, siz ushbu ma'lumotlarni o'zingiz yozgan bo'lishingiz yoki ruxsat berilgan internet manzilidan yoki shu kabi erkin resursdan nusxa olgan bo'lishingiz lozim (Qo'shimcha ma'lumotlar uchun $1 sahifasiga murojaat qiling).\n'''MUALLIFLIK HUQUQI QO'YILGAN ISHLARNI RUXSATSIZ BU YERGA JOYLASHTIRMANG!'''",
        "sectioneditnotsupported-text": "Ushbu sahifada boʻlimlarni tahrirlash imkoniyati yoʻq.",
        "permissionserrors": "Ruxsat huquqida xato",
        "permissionserrorstext-withaction": "Sizda quyidagi {{PLURAL:$1|sabab|sabablar}}ga koʻra '''$2'''ga ruxsat mavjud emas:",
-       "recreate-moveddeleted-warn": "'''Diqqat: Siz avval yoʻqotilgan sahifani yana yaratmoqchisiz.'''\n\nBu sahifani yaratishda davom etishdan avval uning nega avval yoʻqotilgani bilan qiziqib koʻring.\nQulaylik uchun quyida yoʻqotilish qaydlari keltirilgan:",
+       "recreate-moveddeleted-warn": "<strong>Diqqat: Siz avval yoʻqotilgan sahifani qaytadan yaratmoqchisiz.</strong>\n\nU avval nega yoʻqotilgani bilan qiziqib koʻring.\nQuyida ushbu sahifaga oid yoʻqotish va koʻchirish qaydlari keltirilgan:",
        "moveddeleted-notice": "Bu sahifa oʻchirilgan.\nMaʼlumot uchun quyida oʻchirish va qayta nomlash jurnallaridan mos yozuvlar keltirilgan.",
        "log-fulllog": "Qaydlarni toʻliq koʻrish",
        "edit-conflict": "Tahrirlash toʻqnashuvi.",
        "post-expand-template-argument-category": "Andozalarning to'ldirilmagan o'zgaruvchilariga ega sahifalar",
        "undo-success": "Tahrirni bekor qilish imkoniyati bor. Iltimos, solishtirish oynasini koʻrib chiqib, aynan shu oʻzgarishlarni bekor qilmoqchiligingizga ishonch hosil qiling va undan keyin «Saqla» tugmasini bosing.",
        "undo-summary": "[[Special:Contributions/$2|$2]] ([[User talk:$2|mun.]]) tomonidan qilingan $1-sonli tahrir qaytarildi",
+       "cantcreateaccounttitle": "Ro‘yxatdan o‘tib bo‘lmadi",
+       "cantcreateaccount-text": "[[User:$3|$3]] ushbu IP manzil (<strong>$1</strong>) orqali ro‘yxatdan o‘tishni bloklab qo‘ygan.\n\n$3 <em>$2</em>ni sabab qilib ko‘rsatdi",
+       "cantcreateaccount-range-text": "[[User:$3|$3]] '''$1''' sohaga tegishli IP manzillar, shu jumladan sizning IP manzilingiz ('''$4'''), orqali ro‘yxatdan o‘tishni bloklab qo‘ygan.\n\n$3 ''$2''ni sabab qilib ko‘rsatdi",
        "viewpagelogs": "Ushbu sahifaga doir qaydlarni koʻrsat",
        "nohistory": "Ushbu sahifa uchun oʻzgarishlar tarixi mavjud emas.",
        "currentrev": "Hozirgi koʻrinishi",
        "histlegend": "Farqlarni tanlash: solishtirish uchun kerakli radiobokslarni belgilang va '''{{int:compare-submit}}''' tugmasini bosing.<br />\nBu yerda: '''({{int:cur}})''' = hozirgi koʻrinish bilan farqi, '''({{int:last}})''' = avvalgi koʻrinish bilan farqi, '''{{int:minoreditletter}}''' = kichkina tahrir.",
        "history-fieldset-title": "Tarixni koʻrish",
        "history-show-deleted": "Faqat yoʻqotilganlari",
-       "histfirst": "Eng avvalgi",
-       "histlast": "Eng soʻnggi",
+       "histfirst": "eng eski",
+       "histlast": "eng yangi",
        "historysize": "({{PLURAL:$1|1 bayt|$1 bayt}})",
        "historyempty": "(boʻsh)",
        "history-feed-title": "Oʻzgarishlar tarixi",
        "history-feed-item-nocomment": "$1 $2 da",
        "rev-deleted-comment": "(tahrir izohi o'chirildi)",
        "rev-deleted-user": "(muallif nomi oʻchirilgan)",
-       "rev-deleted-event": "(qayd yozuvi o‘chirildi)",
+       "rev-deleted-event": "(jurnal tafsilotlari o‘chirildi)",
        "rev-delundel": "koʻrsatish/yashirish",
        "rev-showdeleted": "koʻrsatish",
        "revdelete-show-file-submit": "Ha",
        "preferences": "Moslamalar",
        "mypreferences": "Moslamalarim",
        "prefs-edits": "Tahrirlar soni:",
+       "prefsnologintext2": "Iltimos, moslamalarni oʻzgartirish uchun tizimga kiring.",
        "prefs-skin": "Tashqi ko‘rinishi",
        "skin-preview": "Ko‘rib chiqish",
        "datedefault": "Farqi yoʻq",
        "shared-repo": "umumiy fayllar saqlanadigan joy",
        "shared-repo-name-wikimediacommons": "Vikiombor",
        "filerevert-comment": "Sabab:",
+       "filedelete": "$1 — oʻchirish",
+       "filedelete-intro": "Siz ushbu faylni — <strong>[[Media:$1|$1]]</strong> va uning tarixini butunlay oʻchirib tashlamoqchi boʻlyapsiz.",
        "filedelete-comment": "Sabab:",
        "filedelete-submit": "O‘chirish",
+       "filedelete-reason-dropdown": "* Umumiy sabablar\n** mualliflik huquqlari buzilyapti\n** mavjud faylning nusxasi",
        "mimetype": "MIME-tur:",
        "download": "yuklash",
        "unusedtemplates": "Ishlatilinmagan andozalar",
        "statistics-pages": "Sahifalar",
        "statistics-pages-desc": "Ushbu vikidagi barcha sahifalar, jumladan munozara, yoʻnaltirish va hk.",
        "statistics-files": "Yuklangan fayllar",
-       "statistics-edits": "{{SITENAME}} qurilganidan beri qilingan tahrirlar",
-       "statistics-edits-average": "Sahifa boshiga tahrirlar",
+       "statistics-edits": "{{SITENAME}}dagi tahrirlarning umumiy soni",
+       "statistics-edits-average": "Oʻrtacha tahrirlar soni (sahifa boshiga)",
        "statistics-users": "Qayd etilgan [[Special:ListUsers|foydalanuvchilar]]",
        "statistics-users-active": "Faol foydalanuvchilar",
        "statistics-users-active-desc": "Oxirgi $1 kun ichida kamida bitta amal qilgan foydalanuvchilar",
        "delete-confirm": "$1 — oʻchirish",
        "delete-legend": "O‘chirish",
        "historywarning": "<strong>Diqqat:</strong> Siz oʻchirmoqchi boʻlayotgan sahifaning tarixida $1 ta {{PLURAL:$1|versiyasi}} bor:",
-       "confirmdeletetext": "Siz ushbu sahifani (yoki faylni) va uning tarixini butunlay oʻchirib tashlashni talab qilyapsiz. Iltimos, haqiqatdan ham shu harakatni amalga oshirmoqchiligingizni, uning oqibatlarini tushunib turganingizni va harakatingiz [[{{MediaWiki:Policy-url}}|qoidalarga]] asosanlanganini tasdiqlang.",
+       "confirmdeletetext": "Siz ushbu sahifani va uning tarixini butunlay oʻchirib tashlamoqchi boʻlyapsiz. Iltimos, [[Special:Whatlinkshere/{{FULLPAGENAMEE}}|bogʻlangan sahifalar]] bilan tanishib chiqishni unutmang.",
        "actioncomplete": "Bajarildi",
        "actionfailed": "Jarayon amalga oshmadi",
        "deletedtext": "\"$1\" yoʻqotildi.\nYaqinda sodir etilgan yoʻqotishlar uchun $2ni koʻring.",
index 3042aec..76b05b3 100644 (file)
        "prefs-personal": "Thông tin cá nhân",
        "prefs-rc": "Thay đổi gần đây",
        "prefs-watchlist": "Theo dõi",
+       "prefs-editwatchlist": "Sửa các trang tôi theo dõi",
+       "prefs-editwatchlist-label": "Chỉnh sửa các mục trong danh sách theo dõi của bạn:",
+       "prefs-editwatchlist-edit": "Xem và xoá các tiêu đề trong danh sách theo dõi của bạn",
+       "prefs-editwatchlist-raw": "Sửa danh sách theo dõi dạng thô",
+       "prefs-editwatchlist-clear": "Xóa sạch danh sách theo dõi của bạn",
        "prefs-watchlist-days": "Số ngày hiển thị trong danh sách theo dõi:",
        "prefs-watchlist-days-max": "Tối đa $1 ngày",
        "prefs-watchlist-edits": "Số lần sửa đổi tối đa trong danh sách theo dõi mở rộng:",
        "right-override-export-depth": "Xuất trang kèm theo các trang được liên kết đến với độ sâu tối đa là 5",
        "right-sendemail": "Gửi thư điện tử cho thành viên khác",
        "right-passwordreset": "Xem các thư điện tử đặt lại mật khẩu",
+       "right-managechangetags": "Tạo và xóa [[Special:Tags|thẻ]] từ cơ sở dữ liệu",
        "newuserlogpage": "Nhật trình mở tài khoản",
        "newuserlogpagetext": "Đây là danh sách những tài khoản thành viên mở lên gần đây.",
        "rightslog": "Nhật trình cấp quyền thành viên",
        "action-viewmyprivateinfo": "xem thông tin cá nhân của bạn",
        "action-editmyprivateinfo": "sửa đổi thông tin cá nhân của bạn",
        "action-editcontentmodel": "sửa mô hình nội dung của trang",
+       "action-managechangetags": "tạo và xóa các thẻ từ cơ sở dữ liệu",
        "nchanges": "$1 {{PLURAL:$1|thay đổi|thay đổi}}",
        "enhancedrc-since-last-visit": "$1 {{PLURAL:$1|sau lần truy cập vừa rồi}}",
        "enhancedrc-history": "lịch sử",
        "tags-tag": "Tên thẻ",
        "tags-display-header": "Hiển thị trên danh sách thay đổi",
        "tags-description-header": "Mô tả ý nghĩa đầy đủ",
+       "tags-source-header": "Nguồn gốc",
        "tags-active-header": "Có kích hoạt?",
        "tags-hitcount-header": "Các thay đổi được ghi thẻ",
+       "tags-actions-header": "Tác vụ",
        "tags-active-yes": "Kích hoạt",
        "tags-active-no": "Vô hiệu",
+       "tags-source-extension": "Xác định bởi một mở rộng",
+       "tags-source-manual": "Áp dụng thủ công bởi người dùng và bot",
+       "tags-source-none": "Không còn sử dụng",
        "tags-edit": "sửa",
+       "tags-delete": "xóa",
+       "tags-activate": "Kích hoạt",
+       "tags-deactivate": "vô hiệu",
        "tags-hitcount": "$1 {{PLURAL:$1|thay đổi|thay đổi}}",
+       "tags-manage-no-permission": "Bạn không có quyền hạn để quản lý các thẻ thay đổi.",
+       "tags-create-heading": "Tạo một thẻ mới",
+       "tags-create-explanation": "Theo mặc định, các thẻ mới được tạo ra sẽ được hợp lệ hóa để người dùng và các bot sử dụng.",
+       "tags-create-tag-name": "Tên thẻ:",
+       "tags-create-reason": "Lý do:",
+       "tags-create-submit": "Tạo mới",
+       "tags-create-no-name": "Bạn phải chỉ định một tên thẻ.",
+       "tags-create-invalid-chars": "Tên thẻ không được chứa dấu phẩy (<code>,</code>) hoặc dấu gạch chéo lên (<code>/</code>).",
+       "tags-create-invalid-title-chars": "Tên thẻ không được chứa các ký tự mà không thể được sử dụng trong tiêu đề của trang .",
+       "tags-create-already-exists": "Các từ khóa \"$1\" đã tồn tại.",
+       "tags-create-warnings-above": "{{PLURAL:$2| Cảnh báo}} sau gặp phải khi cố gắng để tạo ra các thẻ \"$1\":",
+       "tags-create-warnings-below": "Bạn có muốn tiếp tục tạo thẻ này?",
+       "tags-delete-title": "Xóa thẻ",
+       "tags-delete-explanation-initial": "Bạn muốn xóa thẻ \"$1\" từ cơ sở dữ liệu.",
+       "tags-delete-explanation-in-use": "Nó sẽ được gỡ bỏ từ {{PLURAL:$2|$2 mục sửa đổi hoặc mục đăng nhập|tất cả $2 bản sửa đổi và/hoặc đăng nhập các mục}} mà nó hiện đang áp dụng.",
+       "tags-delete-explanation-warning": "Hành động này là <strong>không thể đảo ngược</strong> và <strong>không thể hoàn tác</strong>, ngay cả bởi người quản trị cơ sở dữ liệu. Hãy chắc chắn đây là thẻ mà bạn muốn xóa.",
+       "tags-delete-reason": "Lý do:",
+       "tags-delete-submit": "Không thể phục hồi xóa thẻ này",
+       "tags-delete-not-allowed": "Thẻ được định nghĩa bởi một mở rộng không thể bị xóa trừ khi mở rộng đặc biệt cho phép điều đó xảy ra.",
+       "tags-delete-not-found": "Thẻ \"$1\" không tồn tại.",
+       "tags-delete-too-many-uses": "Từ khóa \"$1\" được áp dụng cho hơn $2 {{PLURAL:$2|phiên bản}}, có nghĩa là nó không thể bị xóa.",
+       "tags-activate-title": "Kích hoạt thẻ",
+       "tags-activate-question": "Bạn sắp sửa kích hoạt thẻ \"$1\".",
+       "tags-activate-reason": "Lý do:",
+       "tags-activate-not-allowed": "Không thể kích hoạt thẻ \"$1\".",
+       "tags-activate-not-found": "Thẻ \"$1\" không tồn tại.",
+       "tags-activate-submit": "Kích hoạt",
+       "tags-deactivate-title": "Vô hiệu thẻ",
+       "tags-deactivate-question": "Bạn sắp sửa vô hiệu thẻ \"$1\".",
+       "tags-deactivate-reason": "Lý do:",
+       "tags-deactivate-not-allowed": "Không thể vô hiệu hóa thẻ \"$1\".",
+       "tags-deactivate-submit": "Vô hiệu",
        "comparepages": "So sánh trang",
        "compare-page1": "Trang 1",
        "compare-page2": "Trang 2",
        "logentry-upload-upload": "$1 {{GENDER:$2}}đã tải lên $3",
        "logentry-upload-overwrite": "$1 {{GENDER:$2}}đã tải lên một phiên bản mới của $3",
        "logentry-upload-revert": "$1 {{GENDER:$2}}đã tải lên $3",
+       "log-name-managetags": "Danh sách quản lý thẻ",
+       "logentry-managetags-create": "$1 {{GENDER:$2| đã tạo}} thẻ \"$4\"",
+       "logentry-managetags-activate": "$1 {{GENDER:$2|đã kích hoạt}} tag \"$4\" để sử dụng bởi người dùng và các bot",
+       "logentry-managetags-deactivate": "$1 {{GENDER:$2|đã vô hiệu}} thẻ \"$4\" để sử dụng bởi người dùng và các bot",
        "rightsnone": "(không có)",
        "revdelete-summary": "tóm lược sửa đổi",
        "feedback-bugornote": "Nếu bạn đã sẵn sàng để miêu tả các chi tiết của một vấn đề kỹ thuật, xin vui lòng [$1 báo cáo lỗi].\nNếu không thì bạn có thể điền biểu mẫu đơn giản ở dưới. Lời ghi của bạn sẽ được đăng lên trang “[$3 $2]”, cùng với tên người dùng và trình duyệt của bạn.",
index b68fe15..f23dfee 100644 (file)
@@ -7,57 +7,57 @@
                        "아라"
                ]
        },
-       "tog-underline": "Заалһиг татас татх:",
-       "tog-hideminor": "ШидÑ\80Ó\99 Ñ\81олÑ\8cлһна Ñ\81еÑ\82күлд Ð±Ð°Ò» Ñ\85үвÑ\80лһиг Ð±Ñ\83лÑ\82Ñ\83лх",
-       "tog-hidepatrolled": "Шидрә сольлһна сеткүлд шүүсн хүврлһиг бултулх",
-       "tog-newpageshidepatrolled": "Шин халхна сеткүләс шүүсн хүврлһиг бултулх",
-       "tog-extendwatchlist": "Хар шидрә сольлһн биш, цуг сольлһн үзүлдг, өргдүлсн шинҗллһнә сеткүл",
+       "tog-underline": "Заалһиг татасллһн:",
+       "tog-hideminor": "Ð\91аһ Ñ\8fÑ\81вÑ\80 Ð¾Ñ\82Ñ\85н Ñ\8fÑ\81вÑ\80 Ñ\81едкүлÓ\99Ñ\81 Ð½Ñ\83Ñ\83х",
+       "tog-hidepatrolled": "Шүүсн ясвр отхн ясвр седкүләс нуух",
+       "tog-newpageshidepatrolled": "Шүүсн халхс отхн ясвр седкүләс нуух",
+       "tog-extendwatchlist": "Һанц отхн биш хамг ясврта өргн оврхин седкүл",
        "tog-usenewrc": "Ясрулсн шидрә сольлһна сеткүл олзлх (JavaScript кергтә)",
-       "tog-numberheadings": "То-диг Ñ\87икÓ\99н Ð´Ð°Ð°х",
-       "tog-showtoolbar": "Ð\9eÑ\80а Ð·ÐµÑ\80-зев Ò¯Ð·Ð»Ñ\85 (JavaScript ÐºÐµÑ\80гÑ\82Ó\99)",
-       "tog-editondblclick": "Давхр индстлһар чиклх (JavaScript кергтә)",
-       "tog-editsectiononrightclick": "ҺаÑ\80Ñ\87ига Ð±Ð°Ñ\80Ñ\83н Ð¸Ð½Ð´Ñ\81Ñ\82лһаÑ\80 Ñ\85үвиг Ñ\87иклÑ\85 (JavaScript ÐºÐµÑ\80гÑ\82Ó\99)",
-       "tog-watchcreations": "Ð\91и Ñ\8dвÑ\80Ó\99ннÑ\8c Ð½ÐµÐ¼Ð³Ð´Ñ\81н Ñ\85алÑ\85Ñ\81 Ñ\88инÒ\97ллһнÓ\99 Ñ\81еÑ\82күлд немх",
-       "tog-watchdefault": "Ð\91и Ñ\8dвÑ\80Ó\99ннÑ\8c Ñ\87иклÑ\81н Ñ\85алÑ\85Ñ\81 Ñ\88инÒ\97ллһнÓ\99 Ñ\81еÑ\82күлд немх",
-       "tog-watchmoves": "Ð\91и Ñ\8dвÑ\80Ó\99ннÑ\8c ÐºÓ©Ð½Ð´Ñ\81н Ñ\85алÑ\85Ñ\81 Ñ\88инÒ\97ллһнÓ\99 Ñ\81еÑ\82күлд немх",
-       "tog-watchdeletion": "Ð\91и Ñ\8dвÑ\80Ó\99ннÑ\8c Ò»Ð°Ñ\80Ò»Ñ\81н Ñ\85алÑ\85Ñ\81 Ñ\88инÒ\97ллһнÓ\99 Ñ\81еÑ\82күлд немх",
-       "tog-minordefault": "ЦÑ\83г Ñ\81олÑ\8cлһн Ð±Ð°Ò» Ñ\87инÑ\80Ñ\82Ó\99 Ñ\82ааÑ\81н Ð±Ð¾Ð»Ñ\83лх",
-       "tog-previewontop": "СолÑ\8cлһна Ñ\82еегин өмн хәләвр үзүлх",
-       "tog-previewonfirst": "СолÑ\8cÑ\85ла, Ñ\85Ó\99лÓ\99вÑ\80 Ò¯Ð·Ò¯Ð»Ñ\85.",
-       "tog-enotifwatchlistpages": "ШинÒ\97лÑ\81н Ñ\85алÑ\85 Ñ\81олÑ\8cÑ\85ла, Ð½Ð°Ð½Ð´ e-mail Ð±Ð¸Ñ\87г Ð¹Ð¾Ð²Ñ\83лх",
-       "tog-enotifusertalkpages": "Мини ухалвр халх сольхла, нанд e-mail бичг йовулх",
-       "tog-enotifminoredits": "Ð\91аһ Ñ\81олÑ\8cлһн Ð±Ð¾Ð»Ð² Ñ\87игн Ð±Ð¾Ð»Ñ\85ла, Ð½Ð°Ð½Ð´ e-mail Ð±Ð¸Ñ\87г Ð¹Ð¾Ð²Ñ\83лх",
-       "tog-enotifrevealaddr": "Ð\9cини e-mail Ñ\85айг Ð·Ó\99ңгллһнÓ\99 бичгт үзүлх",
-       "tog-shownumberswatching": "ТеÑ\80 Ñ\85алÑ\85 Ñ\88инÒ\97лдг Ð´ÐµÐ¼Ð½Ñ\87нÑ\80ин то үзүлх",
-       "tog-oldsig": "Ð\91Ó\99Ó\99дг Ñ\82Ó\99вÑ\81н Ò»Ð°Ñ\80на Ñ\85Ó\99лÓ\99вр:",
-       "tog-fancysig": "ЭвÑ\80Ó\99н Ñ\82Ó\99вÑ\81н Ò»Ð°Ñ\80на Ð±Ð¸ÐºÐ¸ Ñ\82емдлһн (авÑ\82о Ð·Ð°Ð°Ð»Ò»Ñ\82а Ñ\83га)",
-       "tog-uselivepreview": "Шамдһа Ñ\85Ó\99лÓ\99вÑ\80 Ð¾Ð»Ð·Ð»Ñ\85 (JavaScript ÐºÐµÑ\80гÑ\82Ó\99, Ð°Ð¼Ñ\81лһн)",
-       "tog-forceeditsummary": "УÑ\87Ñ\80\83Ñ\82Ñ\85 Ñ\85ооÑ\81н Ð±Ó\99Ó\99Ñ\85лÓ\99 медүлх",
-       "tog-watchlisthideown": "ШинÒ\97ллһнÓ\99 Ñ\81еÑ\82күлд Ð¼Ð¸Ð½Ð¸ Ñ\81олÑ\8cлһиг Ð±Ñ\83лÑ\82Ñ\83лх",
-       "tog-watchlisthidebots": "ШинÒ\97ллһнÓ\99 Ñ\81еÑ\82күлд ÐºÓ©Ð´Ð»Ð²Ñ\80ин Ñ\81олÑ\8cлһиг Ð±Ñ\83лÑ\82Ñ\83лх",
-       "tog-watchlisthideminor": "ШинÒ\97ллһнÓ\99 Ñ\81еÑ\82күлд Ð±Ð°Ò» Ñ\81олÑ\8cлһиг Ð±Ñ\83лÑ\82Ñ\83лх",
-       "tog-watchlisthideliu": "ШинÒ\97ллһнÓ\99 Ñ\81еÑ\82күлд Ð´ÐµÐ¼Ð½Ñ\87нÑ\80ин Ñ\81олÑ\8cлһиг Ð±Ñ\83лÑ\82Ñ\83лх",
-       "tog-watchlisthideanons": "ШинÒ\97ллһнÓ\99 Ñ\81еÑ\82күлд Ð´Ð°Ð»Ð´Ñ\83Ñ\80ин Ñ\81олÑ\8cлһиг Ð±Ñ\83лÑ\82Ñ\83лх",
-       "tog-watchlisthidepatrolled": "Шинҗллһнә сеткүлд шүүсн сольлһиг бултулх",
-       "tog-ccmeonemails": "Миниһәр талдан демнчнрт йовулсн бичглә әдл буулһавр нанд йовулх",
-       "tog-diffonly": "Йилһәнә хөөн халхиг бичә үзүлх",
-       "tog-showhiddencats": "Ð\91Ñ\83лÑ\82Ñ\83лсн әәшлүд үзүлх",
-       "tog-norollbackdiff": "Ð¥Ó\99Ñ\80Ò¯ ÐºÐµÑ\85лÓ\99 Ð¹Ð¸Ð»Ò»Ó\99н Ð±Ð¸Ñ\87Ó\99 үзүлх",
-       "underline-always": "Даңгин болх",
+       "tog-numberheadings": "ЭвÑ\80Ó\99Ñ\80 Ò»Ð°Ñ\80Ñ\86г Ñ\82ойглх",
+       "tog-showtoolbar": "ЯÑ\81вÑ\80ин Ð·ÐµÐ²Ñ\81г Ò¯Ð·Ò¯Ð»Ñ\85",
+       "tog-editondblclick": "Давхр шавдлһар халх ясх",
+       "tog-editsectiononrightclick": "ҺаÑ\80Ñ\86г Ð±Ð°Ñ\80Ñ\83н Ñ\88авдÑ\81аÑ\80 Ñ\81алвÑ\80 Ñ\87иклÑ\85",
+       "tog-watchcreations": "Ð\9cини Ð±Ò¯Ñ\82Ó\99Ñ\81н Ñ\85алÑ\85Ñ\81 Ð±Ð¾Ð»Ð½ Ð¾Ñ\80Ñ\83лÑ\81н Ð±Ð¾Ð¾Ð¼Ð³Ñ\83д Ð¾Ð²Ñ\80Ñ\85ин Ñ\81едкүлд немх",
+       "tog-watchdefault": "Ð\9cини Ñ\8fÑ\81Ñ\81н Ñ\85алÑ\85Ñ\81 Ð±Ð¾Ð»Ð½ Ð±Ð¾Ð¾Ð¼Ð³Ñ\83д Ð¾Ð²Ñ\80Ñ\85ин Ñ\81едкүлд немх",
+       "tog-watchmoves": "Ð\9cини Ð·Ó©Ó©Ñ\81н Ñ\85алÑ\85Ñ\81 Ð±Ð¾Ð»Ð½ Ð±Ð¾Ð¾Ð¼Ð³Ñ\83д Ð¾Ð²Ñ\80Ñ\85ин Ñ\81едкүлд немх",
+       "tog-watchdeletion": "Ð\9cини Ó\99Ñ\80лһÑ\81н Ñ\85алÑ\85Ñ\81 Ð±Ð¾Ð»Ð½ Ð±Ð¾Ð¾Ð¼Ð³Ñ\83д Ð¾Ð²Ñ\80Ñ\85ин Ñ\81едкүлд немх",
+       "tog-minordefault": "Хамг Ñ\8fÑ\81вÑ\80 Ð±Ð°Ò» Ñ\88иг Ñ\82ааÑ\80Ñ\81аÑ\80 Ñ\82емдглх",
+       "tog-previewontop": "ЯÑ\81вÑ\80ин Ñ\85Ó\99Ó\99Ñ\80Ñ\86г өмн хәләвр үзүлх",
+       "tog-previewonfirst": "ЯÑ\81вÑ\80Ñ\82 Ð¾Ð´Ñ\85ла, Ñ\85Ó\99лÓ\99вÑ\80 Ò¯Ð·Ò¯Ð»Ñ\85",
+       "tog-enotifwatchlistpages": "Ð\9eвÑ\80Ñ\81н Ñ\85алÑ\85 Ð°Ð»Ñ\8c Ð±Ð¾Ð¾Ð¼Ð³ Ñ\8fÑ\81гдÑ\85ла, e-mail Ð±Ð¸Ñ\87гÓ\99Ñ\80 Ð¼ÐµÐ´Ò¯лх",
+       "tog-enotifusertalkpages": "Мини меткән халх ясгдхла, e-mail бичгәр медүлх",
+       "tog-enotifminoredits": "ХалÑ\85 Ð±Ð¾Ð»Ð½ Ð±Ð¾Ð¾Ð¼Ð³ Ð±Ð°Ò»Ð°Ñ\80 Ñ\87игн Ñ\8fÑ\81гдÑ\85ла, e-mail Ð±Ð¸Ñ\87гÓ\99Ñ\80 Ð¼ÐµÐ´Ò¯лх",
+       "tog-enotifrevealaddr": "Ð\9cини e-mail Ñ\85айг Ð¼ÐµÐ´Ò¯Ð»Ð²Ñ\80 бичгт үзүлх",
+       "tog-shownumberswatching": "Ð\9eвÑ\80дг Ð´ÐµÐ¼Ð½Ó\99Ñ\87ин то үзүлх",
+       "tog-oldsig": "Ð\91Ó\99Ó\99гÑ\87 Ñ\82Ó\99вÑ\81н Ò»Ð°р:",
+       "tog-fancysig": "Ð\9eнÑ\86 Ñ\82Ó\99вÑ\81н Ò»Ð°Ñ\80ин Ð²Ð¸ÐºÐ¸ Ñ\8dÑ\80Ó\99 (Ñ\8dвÑ\80Ó\99н Ð·Ð°Ð°Ð»Ò»Ð³Ð¾)",
+       "tog-uselivepreview": "Ð\9eÑ\80Ñ\87н Ñ\85Ó\99лÓ\99вÑ\80 ÐºÐµÑ\80глÑ\85",
+       "tog-forceeditsummary": "ЯÑ\81вÑ\80ин Ò¯Ð½Ð´Ñ\81н Ñ\85ооÑ\81на Ñ\82Ñ\83Ñ\81к медүлх",
+       "tog-watchlisthideown": "Ð\9cини Ñ\8fÑ\81вÑ\80 Ð¾Ð²Ñ\80Ñ\85ин Ñ\81едкүлÓ\99Ñ\81 Ð½Ñ\83Ñ\83х",
+       "tog-watchlisthidebots": "Ð\9aөдлгÑ\87ин Ñ\8fÑ\81вÑ\80 Ð¾Ð²Ñ\80Ñ\85ин Ñ\81едкүлÓ\99Ñ\81 Ð½Ñ\83Ñ\83х",
+       "tog-watchlisthideminor": "Ð\91аһ Ñ\8fÑ\81вÑ\80 Ð¾Ð²Ñ\80Ñ\85ин Ñ\81едкүлÓ\99Ñ\81 Ð½Ñ\83Ñ\83х",
+       "tog-watchlisthideliu": "Ð\91Ò¯Ñ\80Ñ\82кгдÑ\81н Ð´ÐµÐ¼Ð½Ó\99Ñ\87нÑ\80ин Ñ\8fÑ\81вÑ\80 Ð¾Ð²Ñ\80Ñ\85ин Ñ\81едкүлÓ\99Ñ\81 Ð½Ñ\83Ñ\83х",
+       "tog-watchlisthideanons": "Ð\9dеÑ\80го Ð´ÐµÐ¼Ð½Ó\99Ñ\87нÑ\80ин Ñ\8fÑ\81вÑ\80 Ð¾Ð²Ñ\80Ñ\85ин Ñ\81едкүлÓ\99Ñ\81 Ð½Ñ\83Ñ\83х",
+       "tog-watchlisthidepatrolled": "Шүүгдсн ясвр оврхин седкүләс нуух",
+       "tog-ccmeonemails": "Мини бус демнәчт йовулсн бичгин дүрлвр нанд йовулх",
+       "tog-diffonly": "Йилһәнә дор халхин дотр эс үзүлх",
+       "tog-showhiddencats": "Ð\9dÑ\83Ñ\83сн әәшлүд үзүлх",
+       "tog-norollbackdiff": "Ð\91Ñ\83Ñ\86аÑ\81на Ñ\85өөн Ð¹Ð¸Ð»Ò»Ó\99н Ñ\8dÑ\81 үзүлх",
+       "underline-always": "Даң",
        "underline-never": "Кезәчн болшго",
-       "underline-default": "Хәләгчин таасн",
-       "editfont-style": "ЧикллһнÓ\99 Ñ\86ааÑ\81на Ò¯Ð·Ð³-кевин Ñ\8fнз:",
-       "editfont-default": "Хәләлгчин көгәс",
-       "editfont-monospace": "Ð\94аңгин Ñ\83Ñ\83дмÑ\82а Ò¯Ð·Ð³-кев",
-       "editfont-sansserif": "Онь уга үзг-кев",
-       "editfont-serif": "Оньта үзг-кев",
-       "sunday": "Нарн",
-       "monday": "Сарң",
-       "tuesday": "Мигмр",
-       "wednesday": "Үлмҗ",
-       "thursday": "Пүрвә",
-       "friday": "Басң",
-       "saturday": "Бембә",
+       "underline-default": "Харагчин көг керглх",
+       "editfont-style": "ЯÑ\81вÑ\80ин Ñ\82еегк Ð±Ð°Ñ\80 Ò¯Ð·Ð³Ð¸Ð½ Ñ\82Ó©Ñ\80л:",
+       "editfont-default": "Харагчин көгәс",
+       "editfont-monospace": "Ð\9dегдмл Ñ\8dÒ£Ñ\82Ó\99 Ð±Ð°Ñ\80 Ò¯Ð·Ð³",
+       "editfont-sansserif": "Онь уга бар үзг",
+       "editfont-serif": "Оньта бар үзг",
+       "sunday": "Нарн өдр",
+       "monday": "Сарң өдр",
+       "tuesday": "Мигмр өдр",
+       "wednesday": "Үлмҗ өдр",
+       "thursday": "Пүрвә өдр",
+       "friday": "Басң өдр",
+       "saturday": "Бембә өдр",
        "sun": "Нрн",
        "mon": "Срң",
        "tue": "Мгр",
        "nov": "Үкр",
        "dec": "Бар",
        "pagecategories": "{{PLURAL:$1|1=Әәшл|Әәшлүд}}",
-       "category_header": "«$1» Ó\99Ó\99Ñ\88лд Ð±Ó\99Ó\99дг халхс",
-       "subcategories": "Ð\91аһаÑ\80 әәшлүд",
-       "category-media-header": "«$1» Ó\99Ó\99Ñ\88лд Ð±Ó\99Ó\99дг боомгуд",
-       "category-empty": "''Тер әәшл хоосн болҗана.''",
-       "hidden-categories": "{{PLURAL:$1|1=Ð\91Ñ\83лÑ\82Ñ\83лÑ\81н Ó\99Ó\99Ñ\88л|Ð\91Ñ\83лÑ\82Ñ\83лсн әәшлүд}}",
-       "hidden-category-category": "Ð\91Ñ\83лÑ\82Ñ\83лсн әәшлүд",
-       "category-subcat-count": "{{PLURAL:$2|ТеÑ\80 Ó\99Ó\99Ñ\88л Ñ\8dн Ò»Ð°Ð½Ñ\86Ñ\85н Ð±Ð°Ò»Ð°Ñ\80 Ó\99Ó\99Ñ\88лÑ\82Ó\99.|{{PLURAL:$1|$1 Ð±Ð°Ò»Ð°Ñ\80 Ó\99Ó\99Ñ\88л Ò¯Ð·Ò¯Ð»Ð²|$1 Ð±Ð°Ò»Ð°Ñ\80 Ó\99Ó\99Ñ\88лүд|$1 Ð±Ð°Ò»Ð°Ñ\80 Ó\99Ó\99Ñ\88лүд Ò¯Ð·Ò¯Ð»Ð²}} $2 Ñ\83Ñ\82 Ñ\82Ñ\83Ñ\80Ñ\88дан Ò¯Ð·Ò¯Ð»Ð².}}",
-       "category-subcat-count-limited": "ТеÑ\80 Ó\99Ó\99Ñ\88лд {{PLURAL:$1|1=нег Ð±Ð°Ò»Ð°Ñ\80 Ó\99Ó\99Ñ\88л|$1 Ð±Ð°Ò»Ð°Ñ\80 Ó\99Ó\99Ñ\88лүд}} Ð±Ð¾Ð»Ò\97ана.",
-       "category-article-count": "{{PLURAL:$2|ТеÑ\80 Ó\99Ó\99Ñ\88л Ò»Ð°Ð½Ñ\86Ñ\85н Ñ\85алÑ\85Ñ\82а.|{{PLURAL:$1|$1 Ñ\85алÑ\85Ñ\81иг Ò¯Ð·Ò¯Ð»Ð²|$1 Ñ\85алÑ\85иг Ò¯Ð·Ò¯Ð»Ð²|$1 Ñ\85алÑ\85Ñ\81иг Ò¯Ð·Ò¯Ð»Ð²}}, $2 Ñ\83Ñ\82 Ñ\82Ñ\83Ñ\80Ñ\88дан.}}",
-       "category-article-count-limited": "ТеÑ\80 Ó\99Ó\99Ñ\88лд {{PLURAL:$1|1=нег Ñ\85алÑ\85|$1 Ñ\85алÑ\85Ñ\81}} Ð±Ð¾Ð»Ò\97ана.",
-       "category-file-count": "{{PLURAL:$2|ТеÑ\80 Ó\99Ó\99Ñ\88лд Ò»Ð°Ð½Ñ\86Ñ\85н Ñ\85алÑ\85 Ð±Ð¾Ð»Ò\97ана.|ТеÑ\80үнÓ\99Ñ\81 {{PLURAL:$1|1=нег Ð±Ð¾Ð¾Ð¼Ð³ Ò¯Ð·Ò¯Ð»Ñ\81н|$1 Ð±Ð¾Ð¾Ð¼Ð³Ñ\83д Ò¯Ð·Ò¯Ð»Ñ\81н}} $2 Ñ\83Ñ\82 Ñ\82Ñ\83Ñ\80Ñ\88дан.}}",
-       "category-file-count-limited": "Эн {{PLURAL:$1|1=боомг|$1 Ð±Ð¾Ð¾Ð¼Ð³Ñ\83д}} Ñ\82еÑ\80 Ó\99Ó\99Ñ\88лд Ð±Ð¾Ð»Ò\97ана.",
-       "listingcontinuesabbrev": "(цааранднь)",
-       "index-category": "Ð\98ндекÑ\81Ñ\81н халхс",
-       "noindex-category": "Ð\98ндекÑ\81Ñ\81н Ð±Ð¸Ñ\88 халхс",
-       "about": "ТодлÒ\97 Ð±ичлһн",
+       "category_header": "«$1» Ó\99Ó\99Ñ\88лк халхс",
+       "subcategories": "Ð\9aүүкн әәшлүд",
+       "category-media-header": "«$1» Ó\99Ó\99Ñ\88лк боомгуд",
+       "category-empty": "<em>Эн әәшлд одахн халх аль боомг уга.</em>",
+       "hidden-categories": "{{PLURAL:$1|1=Ð\9dÑ\83Ñ\83Ñ\81н Ó\99Ó\99Ñ\88л|Ð\9dÑ\83Ñ\83сн әәшлүд}}",
+       "hidden-category-category": "Ð\9dÑ\83Ñ\83сн әәшлүд",
+       "category-subcat-count": "{{PLURAL:$2|Эн Ó\99Ó\99Ñ\88лд Ò»Ð°Ð½Ñ\86Ñ\85н ÐºÒ¯Ò¯ÐºÐ½ Ó\99Ó\99Ñ\88л.|Эн Ó\99Ó\99Ñ\88лд {{PLURAL:$1|$1 ÐºÒ¯Ò¯ÐºÐ½ Ó\99Ó\99Ñ\88л|$1 ÐºÒ¯Ò¯ÐºÐ½ Ó\99Ó\99Ñ\88л|$1 ÐºÒ¯Ò¯ÐºÐ½ Ó\99Ó\99Ñ\88л}} $2 Ñ\82ооһаÑ\81.}}",
+       "category-subcat-count-limited": "Эн Ó\99Ó\99Ñ\88лд {{PLURAL:$1|$1 ÐºÒ¯Ò¯ÐºÐ½ Ó\99Ó\99Ñ\88л|$1 ÐºÒ¯Ò¯ÐºÐ½ Ó\99Ó\99Ñ\88л}} Ð±Ó\99Ó\99нÓ\99.",
+       "category-article-count": "{{PLURAL:$2|Эн Ó\99Ó\99Ñ\88лд Ò»Ð°Ð½Ñ\86Ñ\85н Ñ\85алÑ\85Ñ\82а.|Эн {{PLURAL:$1|$1 Ñ\85алÑ\85 Ñ\8dн Ó\99Ó\99Ñ\88лд|$1 Ñ\85алÑ\85 Ñ\8dн Ó\99Ó\99Ñ\88лд|$1 Ñ\85алÑ\85 Ñ\8dн Ó\99Ó\99Ñ\88лд}}, $2 Ñ\82ооһаÑ\81.}}",
+       "category-article-count-limited": "Ð\9eÑ\80Ñ\87н Ó\99Ó\99Ñ\88лд {{PLURAL:$1|1=нег Ñ\85алÑ\85|$1 Ñ\85алÑ\85}} Ð±Ó\99Ó\99нÓ\99.",
+       "category-file-count": "{{PLURAL:$2|Эн Ó\99Ó\99Ñ\88лд Ò»Ð°Ð½Ñ\86Ñ\85н Ñ\85алÑ\85 Ð±Ó\99Ó\99нÓ\99.|Эн Ó\99Ó\99Ñ\88лд {{PLURAL:$1|1=нег Ð±Ð¾Ð¾Ð¼Ð³|$1 Ð±Ð¾Ð¾Ð¼Ð³Ñ\83д}} $2 Ñ\82ооһаÑ\81.}}",
+       "category-file-count-limited": "Ð\9eÑ\80Ñ\87н Ó\99Ó\99Ñ\88лд Ñ\8dн {{PLURAL:$1|боомг|$1 Ð±Ð¾Ð¾Ð¼Ð³Ñ\83д}} Ð±Ó\99Ó\99нÓ\99.",
+       "listingcontinuesabbrev": "(залһан)",
+       "index-category": "Ð\9aелкгдм халхс",
+       "noindex-category": "Ð\9aелкгдÑ\88го халхс",
+       "about": "Ð\91ичлһн",
        "article": "Зүүл",
-       "newwindow": "(Ñ\88ин Ñ\82еÑ\80зд)",
-       "cancel": "Уга ÐºÐµх",
-       "moredotdotdot": "ЦааÑ\80анднь...",
-       "mypage": "Ð\9cини Ñ\8dвÑ\80Ó\99 Ñ\85алх",
-       "mytalk": "Ð\9aүүндлһн Ð±Ó\99Ó\99Ñ\80м",
-       "anontalk": "IP хайгна күндллһн",
-       "navigation": "Ð\9eÑ\80м Ð¼ÐµÐ´Ð»Ò»Ð½",
+       "newwindow": "(Ñ\88ин Ñ\86оңÑ\85Ñ\82)",
+       "cancel": "Ð\91Ñ\83Ñ\86х",
+       "moredotdotdot": "Ð\9dань...",
+       "mypage": "Ð¥алх",
+       "mytalk": "Ð\9cеÑ\82кÓ\99н",
+       "anontalk": "Эн IP хайгин меткән",
+       "navigation": "Ð\90йлл",
        "and": "&#32;болн",
-       "qbfind": "Ð¥Ó\99Ó\99лһн",
-       "qbbrowse": "Ð\93Ò¯Ò¯Ò»Ó\99д Ñ\85әләх",
-       "qbedit": "Чиклх",
-       "qbpageoptions": "ТеÑ\80 халх",
-       "qbmyoptions": "Тана халхс",
-       "faq": "Юм Ð±Ð¸",
-       "faqpage": "Project:Юм Ð±Ð¸",
-       "actions": "Үүлд",
-       "namespaces": "Ð\9dеÑ\80нÓ\99 Ñ\83Ñ\81",
-       "variants": "СÑ\83ңһлÑ\82Ñ\81",
+       "qbfind": "Ð¥Ó\99Ó\99вÑ\80",
+       "qbbrowse": "Ð¥әләх",
+       "qbedit": "ЯÑ\81х",
+       "qbpageoptions": "Эн халх",
+       "qbmyoptions": "Ð\9cини халхс",
+       "faq": "СÑ\83Ñ\80мһа Ñ\81Ñ\83Ñ\80вÑ\80",
+       "faqpage": "Project:СÑ\83Ñ\80мһа Ñ\81Ñ\83Ñ\80вÑ\80",
+       "actions": "Үүлдвр",
+       "namespaces": "Ð\9dеÑ\80нÓ\99 Ñ\82Ó©Ñ\80л",
+       "variants": "ХүвлвÑ\80",
        "errorpagetitle": "Эндү",
-       "returnto": "«$1» Ñ\82ал Ñ\85Ó\99Ñ\80Ò¯ Ð¸Ñ\80х.",
-       "tagline": "{{grammar:genitive|{{SITENAME}}}} гидг һазрас өггцн",
-       "help": "ЦÓ\99Ó\99лһлһн",
-       "search": "Ð¥Ó\99Ó\99лһн",
-       "searchbutton": "Хәәлһн",
-       "go": "Ор",
-       "searcharticle": "Ор",
-       "history": "тууҗ",
+       "returnto": "«$1» Ñ\82ал Ñ\85Ó\99Ñ\80Ò¯ Ð¾Ð´х.",
+       "tagline": "{{SITENAME}} талас",
+       "help": "Ð\94Ó©Ò£",
+       "search": "Ð¥Ó\99Ó\99вÑ\80",
+       "searchbutton": "Хәәх",
+       "go": "Одх",
+       "searcharticle": "Одх",
+       "history": "Халхин тууҗ",
        "history_short": "Тууҗ",
-       "updatedmarker": "мини шидрә орлһна хөөн шинрүлсн",
+       "updatedmarker": "мини отхн орсна хөөн шинрүлсн",
        "printableversion": "Барин бәәдл",
        "permalink": "Даңгин заалһ",
        "print": "Барлх",
-       "edit": "Чиклх",
+       "edit": "ЯÑ\81х",
        "create": "Бүтәх",
-       "editthispage": "Эн халхиг чиклх",
-       "create-this-page": "Эн халхиг бүтәх",
-       "delete": "Һарһх",
-       "deletethispage": "Эн халхиг һарһх",
-       "undelete_short": "$1 {{PLURAL:$1|сольлһиг|сольлһиг|сольлһиг}} босхҗ тохрар",
+       "editthispage": "Эн халх ясх",
+       "create-this-page": "Эн халх бүтәх",
+       "delete": "Әрлһх",
+       "deletethispage": "Эн халх әрлһх",
+       "undelete_short": "{{PLURAL:$1|Нег ясвр|$1 ясвр|ясвр}} босхх",
        "protect": "Харсх",
        "protect_change": "сольх",
-       "protectthispage": "Эн халхиг харсх",
-       "unprotect": "Харсх уга",
-       "unprotectthispage": "ТеÑ\80 Ñ\85алÑ\85иг Ñ\85аÑ\80Ñ\81Ñ\85 Ñ\83га",
+       "protectthispage": "Эн халх харсх",
+       "unprotect": "Харслт сольх",
+       "unprotectthispage": "Эн Ñ\85алÑ\85ин Ñ\85аÑ\80Ñ\81лÑ\82 Ñ\81олÑ\8cÑ\85",
        "newpage": "Шин халх",
-       "talkpage": "ТеÑ\80 Ñ\85алÑ\85ин Ñ\82Ñ\83Ñ\81к ÐºÐµÐ»х",
+       "talkpage": "Эн Ñ\85алÑ\85 Ð¼ÐµÑ\82клдх",
        "talkpagelinktext": "Меткән",
-       "specialpage": "Ð\9aөдлÑ\85нÓ\99 халх",
-       "personaltools": "ЭвÑ\80Ó\99н Ð·ÐµÑ\80-зев",
-       "articlepage": "Зүүл үзх",
+       "specialpage": "ШиÑ\88лң халх",
+       "personaltools": "ТÑ\83Ñ\81лң Ð·ÐµÐ²Ñ\81г",
+       "articlepage": "Зүүл хәләх",
        "talk": "Меткән",
        "views": "Хәләврүд",
-       "toolbox": "Зер-зев",
-       "userpage": "Демнчна халх үзх",
-       "projectpage": "Төсвин халх үзх",
-       "imagepage": "Боомгин халх үзх",
-       "mediawikipage": "Зәңгин халх үзх",
-       "templatepage": "Кевләр халх үзх",
-       "viewhelppage": "ЦÓ\99Ó\99лһлһиг Ñ\83зх",
-       "categorypage": "Әәшлин халх үзх",
+       "toolbox": "Зевсг",
+       "userpage": "Демнәчнә халх хәләх",
+       "projectpage": "Төсвин халх хәләх",
+       "imagepage": "Боомгин халх хәләх",
+       "mediawikipage": "Зәңгин халх хәләх",
+       "templatepage": "Кевләрин халх хәләх",
+       "viewhelppage": "Ð\94өңгин Ñ\85алÑ\85 Ñ\85Ó\99лÓ\99х",
+       "categorypage": "Әәшлин халх хәләх",
        "viewtalkpage": "Меткән халх узх",
-       "otherlanguages": "Талдан келәр",
-       "redirectedfrom": "($1 гидг һазрас авч одсмн)",
-       "redirectpagesub": "Ð\90вÑ\87 Ð¾Ð´дг халх",
-       "lastmodifiedat": "ТеÑ\80 Ñ\85алÑ\85 Ñ\8dн Ñ\86агÑ\82 Ñ\81үл Ñ\87иклÓ\99д Ð±Ð¾Ð»Ò\97: $2, $1.",
-       "viewcount": "ТеÑ\80 Ñ\85алÑ\85д $1 {{PLURAL:$1|дÓ\99кÒ\97|дÓ\99кÒ\97|дÓ\99кÒ\97}} Ð¾Ñ\80Ò\97.",
+       "otherlanguages": "Ð\91Ñ\83Ñ\81 келәр",
+       "redirectedfrom": "($1 талас туусн)",
+       "redirectpagesub": "ТÑ\83Ñ\83дг халх",
+       "lastmodifiedat": "Эн Ñ\85алÑ\85ин Ð¾Ñ\82Ñ\85н Ñ\81олÑ\8cÑ\81н: $2, $1.",
+       "viewcount": "Эн Ñ\85алÑ\85Ñ\82 {{PLURAL:$1|нег Ð´Ó\99кÒ\97|$1 Ð´Ó\99кÒ\97}} Ñ\85андла.",
        "protectedpage": "Харссн халх",
-       "jumpto": "Ð\98Ñ\80х тал:",
-       "jumptonavigation": "Һазр медлһн",
-       "jumptosearch": "Ñ\85Ó\99Ó\99лһн",
-       "view-pool-error": "Гемим тәвтн, ода серверүд хар-хату көдлмштә.\nДегд дала күн тер халх үзхәр бәәнә.\nБуйн болтха, бәәҗәһәд дәкәд арһ хәәтн.\n\n$1",
-       "aboutsite": "{{SITENAME}} тускар",
-       "aboutpage": "Project:ТодлÒ\97 Ð±ичлһн",
-       "copyright": "Өггцн $1 йоста орҗ болм",
-       "copyrightpage": "{{ns:project}}:Ð\91иÑ\87Ñ\81н ÐºÒ¯Ò¯Ð½Ó\99 зөв",
-       "currentevents": "Ода болсн йовдл",
-       "currentevents-url": "Project:Ода болсн йовдл",
-       "disclaimers": "Дааврас эс зөвшәрлһн",
-       "disclaimerpage": "Project:Даарас эс зөвшәрлһн",
-       "edithelp": "ЧикллһнÓ\99 дөң",
+       "jumpto": "Ð\9eдх тал:",
+       "jumptonavigation": "айлл",
+       "jumptosearch": "Ñ\85Ó\99Ó\99вÑ\80",
+       "view-pool-error": "Гем тәвтн, ода серверуд күндрҗәнә.\nДегд олн халх хәләх сурлт орв.\nБуйн болтха, күләһәд халхт хандх седвәр бәән давттн.\n\n$1",
+       "aboutsite": "{{SITENAME}} туск",
+       "aboutpage": "Project:Ð\91ичлһн",
+       "copyright": "Бус эс гихлә, дотр $1 зөвшәрләр орлһта.",
+       "copyrightpage": "{{ns:project}}:Ð\97окÑ\8aÑ\8fÑ\87ин зөв",
+       "currentevents": "Өдгәк йовдл",
+       "currentevents-url": "Project:Өдгәк йовдл",
+       "disclaimers": "Даавран буцлт",
+       "disclaimerpage": "Project:Даавран буцлт",
+       "edithelp": "ЯÑ\81вÑ\80ин дөң",
        "mainpage": "Нүр халх",
        "mainpage-description": "Нүр халх",
        "policy-url": "Project:Бодлһн",
-       "portal": "Ð\91Ò¯Ñ\80дÓ\99Ñ\86ин хург",
-       "portal-url": "Project:Ð\91Ò¯Ñ\80дÓ\99Ñ\86ин хург",
-       "privacy": "Нууцин бодлһн",
-       "privacypage": "Project:Нууцин бодлһн",
-       "badaccess": "Зөвәнә эндү",
-       "badaccess-group0": "Та сурсн үүл кеҗ болшго.",
-       "badaccess-groups": "Эн Ò¯Ò¯Ð» Ò»Ð°Ð½Ñ\86Ñ\85н {{PLURAL:$2|1=багаÑ\81|багÑ\83даÑ\81}} $1 ÐºÐµÒ\97 Ñ\87адна.",
+       "portal": "Ð\9dииÑ\86Ó\99нÓ\99 хург",
+       "portal-url": "Project:Ð\9dииÑ\86Ó\99нÓ\99 хург",
+       "privacy": "Нуултын бодлһн",
+       "privacypage": "Project:Нуултын бодлһн",
+       "badaccess": "Зөвшәлин эндү",
+       "badaccess-group0": "Та сурсн үүлдврән күцәҗ болшгот.",
+       "badaccess-groups": "СанÑ\81н Ò¯Ò¯Ð»Ð´Ð²Ñ\80 Ò»Ð°Ð½Ñ\86 Ñ\8dн {{PLURAL:$2|багин|багмÑ\83дÑ\8bн}} Ð´ÐµÐ¼Ð½Ó\99Ñ\87нÑ\80 ÐºÒ¯Ñ\86Ó\99Ò\97 Ñ\87адна: $1",
        "versionrequired": "MediaWiki'н $1 һарц кергтә",
-       "versionrequiredtext": "Тер халх олзхар, MediaWiki'н $1 һарц кергтә.\n[[Special:Version|Һарца халх]] хәләтн.",
-       "ok": "Тиим",
-       "retrievedfrom": "\"$1\" гидг халхас йовулсн",
-       "youhavenewmessages": "Та $1та бәәнәт ($2).",
-       "youhavenewmessagesmulti": "Таньд $1 деер шин зәңг ирсн бәәнә.",
-       "editsection": "чиклх",
-       "editold": "чиклх",
-       "viewsourceold": "ишиг үзх",
-       "editlink": "чиклх",
-       "viewsourcelink": "ишиг хәләх",
-       "editsectionhint": "«$1» гидг хүвиг чиклх",
+       "versionrequiredtext": "Эн халх керглхәр, MediaWiki'н $1 һарц кергтә.\n[[Special:Version|Һарцин халх]] хәләтн.",
+       "ok": "Не",
+       "retrievedfrom": "\"$1\" халхас авсн",
+       "youhavenewmessages": "Танд $1 бәәнә ($2).",
+       "newmessageslinkplural": "шин зәңг",
+       "youhavenewmessagesmulti": "Танд $1 деер шин зәңг бәәнә.",
+       "editsection": "ясх",
+       "editold": "ясх",
+       "viewsourceold": "иш код хәләх",
+       "editlink": "ясх",
+       "viewsourcelink": "иш код хәләх",
+       "editsectionhint": "«$1» салвр ясх",
        "toc": "Һарг",
        "showtoc": "үзүлх",
-       "hidetoc": "бÑ\83лÑ\82Ñ\83лх",
-       "thisisdeleted": "$1 гүүһәд хәләхү аль хәрүлхү?",
-       "viewdeleted": "$1 үзүлхү?",
-       "restorelink": "{{PLURAL:$1|1=$1 һарһсн сольлһн|$1 һарһсн сольлһн}}",
-       "feedlinks": "ТеÑ\80 Ð±Ó\99Ó\99длÑ\82Ó\99",
-       "feed-invalid": "Ð\91Ñ\83Ñ\80Ñ\83 Ð±Ð¸Ñ\87гдлһнÓ\99 Ñ\82өлÓ\99 Ñ\81үвин Ñ\8fнз.",
-       "feed-unavailable": "СиндикаÑ\86ин Ñ\81үв Ð¾Ñ\80лһÑ\82а Ð±Ð¸Ñ\88",
-       "site-rss-feed": "$1 — RSS-зәңг",
-       "site-atom-feed": "$1 — Atom-зәңг",
-       "page-rss-feed": "«$1» — RSS-зәнгллһн",
-       "page-atom-feed": "«$1» â\80\94 Atom Ð·Ó\99нгллһн",
-       "red-link-title": "$1 (халх бәәшго)",
+       "hidetoc": "нÑ\83Ñ\83х",
+       "thisisdeleted": "$1 хәләхий аль босххий?",
+       "viewdeleted": "$1 хәләхий?",
+       "restorelink": "{{PLURAL:$1|нег әрлһсн ясвр|$1 әрлһсн ясвр}}",
+       "feedlinks": "Ð\9aÒ¯Ñ\81м:",
+       "feed-invalid": "Ð\91Ñ\83Ñ\80Ñ\83 Ð·Ð°ÐºÑ\8aÑ\8fлһÑ\85 Ñ\86Ñ\83вгин Ñ\82Ó©Ñ\80л.",
+       "feed-unavailable": "Ð\9dегдÑ\81н ÐºÒ¯Ñ\81м Ð¾Ñ\80лһго",
+       "site-rss-feed": "$1 — RSS күсм",
+       "site-atom-feed": "$1 — Atom күсм",
+       "page-rss-feed": "«$1» — RSS күсм",
+       "page-atom-feed": "«$1» â\80\94 Atom ÐºÒ¯Ñ\81м",
+       "red-link-title": "$1 (халх уга)",
        "nstab-main": "Зүүл",
-       "nstab-user": "Демнч",
-       "nstab-media": "Ð\90һаÑ\80ин халх",
-       "nstab-special": "Ð\9aөдлÑ\85нÓ\99 халх",
+       "nstab-user": "Демнәч",
+       "nstab-media": "Ð\91оомгин халх",
+       "nstab-special": "ШиÑ\88лң халх",
        "nstab-project": "Төслин халх",
        "nstab-image": "Боомг",
        "nstab-mediawiki": "Зәңг",
        "nstab-template": "Кевләр",
-       "nstab-help": "ЦÓ\99Ó\99лһлһн",
+       "nstab-help": "Ð\94Ó©Ò£",
        "nstab-category": "Әәшл",
-       "nosuchaction": "Иим үүл бәәшго",
-       "nosuchactiontext": "URL'д Ð±Ð¸Ñ\87Ñ\81н Ò¯Ò¯Ð» Ð±Ñ\83Ñ\80Ñ\83 Ð±Ð¾Ð»Ò\97ана.\nТа URL Ð±Ð¸Ñ\87Ó\99д Ñ\8dндү ÐºÐµÒ\97 Ð±Ð¾Ð»Ð²Ð·Ð° Ð°Ð»Ñ\8c Ð±Ñ\83Ñ\80Ñ\83 Ð·Ð°Ð°Ð»Ò»Ð°Ñ\81 Ð´Ð°Ñ\85Ò\97.\nÐ\94Ó\99кÓ\99д, Ñ\82еÑ\80 Ð¹Ð¾Ð²Ð´Ð» {{SITENAME}} Ñ\82Ó©Ñ\81лин Ñ\8dндү Ð±Ð¾Ð»Ð²Ð·Ð°.",
-       "nosuchspecialpage": "Иим көдлхнә халх бәәшго",
-       "nospecialpagetext": "<strong>Та сурсн көдлхнә халх бәәшго.</strong>\n\nЧик көдлхнә халхин буулһавр: [[Special:SpecialPages|{{int:specialpages}}]].",
+       "nosuchaction": "Иим үүлдвр уга",
+       "nosuchactiontext": "URL'д Ð·Ð°Ð°Ñ\81н Ò¯Ò¯Ð»Ð´Ð²Ñ\80 Ð±Ñ\83Ñ\80Ñ\83.\nТа URL Ð¾Ñ\80Ñ\83лад Ñ\8dндүÑ\80Ñ\81н Ð°Ð»Ñ\8c Ð±Ñ\83Ñ\80Ñ\83 Ð·Ð°Ð°Ð»Ò»Ð°Ñ\80 Ð¾Ð´Ñ\81н Ð¼Ð°Ò»Ð´.\nÐ\94Ó\99кÓ\99д, Ñ\8dн {{SITENAME}} Ñ\82Ó©Ñ\81лин Ñ\8dндү Ð¼Ð°Ò»Ð´.",
+       "nosuchspecialpage": "Иим шишлң халх уга",
+       "nospecialpagetext": "<strong>Тана сурсн шишлң халх уга.</strong>\n\nБәәдг шишлң халхин бүрткл: [[Special:SpecialPages|{{int:specialpages}}]].",
        "error": "Эндү",
-       "databaseerror": "Өггцнә базин эндү",
-       "missing-article": "Өггцнә халһлд сурсн халхин бичг олв уга. Эн халх олх йоста: \"$1\" нертә $2.\n\nТер йовдл һарһсн халхна тууҗин өңгрсн заалһиг дахлһна арһ болад бәәнә.\n\nЭс гиҗ, тиим болх зөвтә, та заклһна теткүлин эндүһиг олв.\nБуйн болтха, URL заалһ бичәд, тер йовдлин туск [[Special:ListUsers/sysop|закрачд]] келтн.",
-       "missingarticle-rev": "($1 тойгта халхна янз)",
-       "missingarticle-diff": "(йилһән: $1, $2)",
-       "internalerror": "Ð\94оÑ\82Ñ\80нÑ\8c эндү",
-       "internalerror_info": "Ð\94оÑ\82Ñ\80нÑ\8c эндү: $1",
-       "filerenameerror": "Боомгин нериг «$1»-с «$2» болһн сольҗ чаддго",
-       "filedeleteerror": "«$1» боомг һарһҗ чаддго.",
-       "unexpected": "Таалһта уга кемҗә: «$1» = «$2».",
-       "badtitle": "Буру нернь",
-       "badtitletext": "Сурсн нерн буру, хоосн, аль му бичсн келн хоорнд нертә. Тиим чигн биз, нерн зөв уга үзгтә.",
-       "viewsource": "Ишиг хәләх",
+       "databaseerror": "То-дигин саңгин эндү",
+       "missing-article": "То-дигин саңт сурсн «$1» халхин $2 олх йоста бичг олсн уга.\n\nТиим заңта йовдл әрлһсн халхна тууҗин хуучрсн заалһар одх седвәрәр һардг авъяста.\n\nКемр эн учр биш, та көтлврин теткүлин эндү олсн бәәдлтәт.\nБуйн болтха, эн URL зааҗ, эн йовдлын туск [[Special:ListUsers/sysop|закрачт]] келтн.",
+       "missingarticle-rev": "(№ $1 һарц)",
+       "missingarticle-diff": "(Ð\99илһән: $1, $2)",
+       "internalerror": "Ð\94оÑ\82Ñ\80к эндү",
+       "internalerror_info": "Ð\94оÑ\82Ñ\80к эндү: $1",
+       "filerenameerror": "Боомгин нер «$1» талас «$2» болһҗ болмҗго",
+       "filedeleteerror": "«$1» боомг әрлһҗ болмҗго.",
+       "unexpected": "Таарго кемҗән: «$1» = «$2».",
+       "badtitle": "Болшго нернь",
+       "badtitletext": "Сурсн халхин нерн буру, хоосн, аль буру бичсн келн хоорндк аль вики хоорндк нерн. Нернд болшго темдгүд керглсн маһд.",
+       "viewsource": "Иш код хәләх",
        "actionthrottled": "Хурдна заг",
-       "ns-specialprotected": "ШиÑ\88лң Ñ\85алÑ\85 Ñ\87иклÑ\81н Ð±Ó\99Ó\99Ñ\85 болшго.",
-       "virus-unknownscanner": "медгдго антивирус:",
+       "ns-specialprotected": "ШиÑ\88лң Ñ\85алÑ\85 Ñ\8fÑ\81Ñ\87 болшго.",
+       "virus-unknownscanner": "медснго антивирус:",
        "logouttext": "'''Та һарад бәәнәт.'''\n\nТа {{SITENAME}} гидг ормиг нертә уга олзлҗ чаднат, аль та <span class='plainlinks'>[$1 дәкәд орҗ]</span> цацу аль талдан нертә чаднат.\nЗәрм халхс цааранднь та ода чигн орсн мет үзүлҗ чаддг тускар темдглтн (та хәләчин санлиг цеврлтл).",
-       "yourname": "Демнчна нернь:",
+       "yourname": "Демнәчнә нерн:",
        "yourpassword": "Нууц үг:",
-       "yourpasswordagain": "Нууц үгиг давтн:",
+       "yourpasswordagain": "Нууц үг давтн:",
        "remembermypassword": "Намаг эн тоолдврд тодлх ($1 {{PLURAL:$1|1=өдрт|өдрмүдт}} икәр биш)",
        "yourdomainname": "Тана домен:",
        "login": "Орлһн",
-       "nav-login-createaccount": "ХаÑ\80Ò»Ñ\85 / Ð±Ð¸Ñ\87гдлһн ÐºÐµх",
-       "userlogin": "Орх аль бичгдлһиг бүтәх",
-       "userloginnocreate": "ХаÑ\80Ò»х",
+       "nav-login-createaccount": "Ð\9eÑ\80Ñ\85/бүÑ\80Ñ\82кгдх",
+       "userlogin": "Орх/бүрткгдх",
+       "userloginnocreate": "Ð\9eÑ\80х",
        "logout": "Һарх",
        "userlogout": "Һарх",
-       "notloggedin": "Та орв биш",
-       "nologin": "Бичгдлһта уга? '''$1'''.",
-       "nologinlink": "Ð\91иÑ\87гдлһиг бүтәх",
-       "createaccount": "Ð\91иÑ\87гдлһиг бүтәх",
-       "gotaccount": "Бичгдлһтә? '''$1'''.",
-       "gotaccountlink": "ХаÑ\80Ò»тн",
+       "notloggedin": "Та орсн уга",
+       "nologin": "Бичгдлһгот? '''$1'''.",
+       "nologinlink": "Ð\91иÑ\87гдлһн бүтәх",
+       "createaccount": "Ð\91иÑ\87гдлһн бүтәх",
+       "gotaccount": "Бичгдлһтәт? '''$1'''.",
+       "gotaccountlink": "Ð\9eÑ\80тн",
        "createaccountmail": "электрона улаһар",
        "userexists": "Эн нер олзлдг юмн.\nБуйн болтха, талдан нернь автн.",
        "loginerror": "Орлһна эндү",
-       "createaccounterror": "Ð\91иÑ\87гдлһиг Ð±Ò¯Ñ\82Ó\99Ñ\85 Ð±Ð¾Ð»Ñ\88го: $1",
-       "noname": "Та Ð·Ó©Ð²Ñ\82Ó\99 Ð´ÐµÐ¼Ð½Ñ\87на Ð½ÐµÑ\80нÑ\8c Ð±Ð¸Ñ\87в уга.",
+       "createaccounterror": "Ð\91иÑ\87гдлһн Ð±Ò¯Ñ\82Ó\99Ò\97 Ð±Ð¾Ð»Ð¼Ò\97го: $1",
+       "noname": "Та Ð·Ó©Ð²Ñ\88Ó\99Ñ\81н Ð´ÐµÐ¼Ð½Ó\99Ñ\87нÓ\99 Ð½ÐµÑ\80 Ð·Ð°Ð°Ñ\81н уга.",
        "loginsuccesstitle": "Йовудта орлһн",
-       "loginsuccess": "''' Тадн ода «$1» нертә {{SITENAME}} гидг нерәдлһтә төсвд бәәнәт.'''",
-       "nosuchuser": "«$1» Ð³Ð¸Ð´Ð³ Ð½ÐµÑ\80Ó\99длһÑ\82Ó\99 Ð´ÐµÐ¼Ð½Ñ\87 Ð±Ó\99Ó\99Ñ\88го.\nÐ\94емнÑ\87на Ð½ÐµÑ\80Ñ\82 Ð±Ð°Ò» Ð±Ð¾Ð»Ð½ Ð¸Ðº Ò¯Ð·Ð³Ò¯Ð´ Ó\99дл Ð±Ð¸Ñ\88 Ð±Ð¾Ð»Ð½Ð°.\n«<nowiki>$1</nowiki>» Ð³Ð¸Ð´Ð³ Ð½ÐµÑ\80Ó\99длһÑ\82Ó\99 Ð´ÐµÐ¼Ð½Ñ\87 Ð±Ó\99Ó\99Ñ\88го.\nÐ\91иÑ\87лһиг Ñ\88Ò¯Ò¯Ñ\82н Ð°Ð»Ñ\8c [[Special:UserLogin/signup|бигÑ\87длһиг бүтәтн]].",
-       "nosuchusershort": "«$1» Ð³Ð¸Ð´Ð³ Ð½ÐµÑ\80Ó\99длһÑ\82Ó\99 Ð´ÐµÐ¼Ð½Ñ\87 Ð±Ó\99Ó\99Ñ\88го.\nÐ\91иÑ\87лһиг шүүтн.",
-       "nouserspecified": "Та демнчна нернь бичх йостав.",
-       "login-userblocked": "ТеÑ\80 Ð´ÐµÐ¼Ð½Ñ\87 Ð±Ò¯Ñ\81лÑ\81н, Ñ\85аÑ\80һад Ð¾Ñ\80Ò\97 Ð±Ð¾Ð»Ñ\88го Ð±Ó\99Ó\99нÓ\99.",
-       "wrongpassword": "Та буру нууц үг бичв.\nДәкәд арһ хәәтн.",
-       "wrongpasswordempty": "Та хоосн нууц үгиг бичв.\nДәкәд арһ хәәтн.",
+       "loginsuccess": "<strong>Та ода «$1» нертә {{SITENAME}} төсвд бәәнәт.</strong>",
+       "nosuchuser": "«$1» Ð½ÐµÑ\80Ñ\82Ó\99 Ð´ÐµÐ¼Ð½Ó\99Ñ\87 Ñ\83га.\nÐ\94емнÓ\99Ñ\87нÓ\99 Ð½ÐµÑ\80нд Ð±Ð°Ò» Ð±Ð¾Ð»Ð½ Ñ\82ом Ò¯Ð·Ð³Ò¯Ð´ Ó\99дл Ð±Ð¸Ñ\88.\nЧик Ð±Ð¸Ñ\87Ñ\81н Ñ\88Ò¯Ò¯Ñ\82н Ð°Ð»Ñ\8c [[Special:UserLogin/signup|бигÑ\87длһн бүтәтн]].",
+       "nosuchusershort": "«$1» Ð½ÐµÑ\80Ñ\82Ó\99 Ð´ÐµÐ¼Ð½Ó\99Ñ\87 Ñ\83га.\nЧик Ð±Ð¸Ñ\87Ñ\81н шүүтн.",
+       "nouserspecified": "Та демнәчнә нер заах йоста.",
+       "login-userblocked": "Эн Ð´ÐµÐ¼Ð½Ó\99Ñ\87 Ð±Ò¯Ñ\81лÑ\81н, Ð¾Ñ\80Ò\97 Ð±Ð¾Ð»Ñ\88го.",
+       "wrongpassword": "Та буру нууц үг бичвт.\nДәкәд сөртн.",
+       "wrongpasswordempty": "Та хоосн нууц үг бичвт.\nДәкәд сөртн.",
        "passwordtooshort": "Нууц үг баһар биш $1 {{PLURAL:$1|үзгтә|үзгүдта|үзгүдта}} бәәх йоста.",
-       "password-name-match": "Нууц үг денмнчна нертә әдл биш бәәх йоста.",
+       "password-name-match": "Нууц үг денмнәчнә нерәс бус бәәх йоста.",
        "mailmypassword": "Шин нууц үгиг E-mail бичгәр йовулҗ",
        "emailauthenticated": "Тана e-mail хайг $2 өдрт, $3 цагт батлсн.",
-       "accountcreated": "Бичгдллһн бүтәв.",
+       "accountcreated": "Бичгдлһн бүтәв.",
        "loginlanguagelabel": "Келн: $1",
-       "changepassword": "Нууц үгиг сольҗ",
-       "resetpass_header": "Бичгдллһнә нууц үгиг сольх",
+       "changepassword": "Нууц үг сольлһн",
+       "resetpass_header": "Бичгдлһнә нууц үг сольх",
        "oldpassword": "Көгшн нууц үг:",
        "newpassword": "Шин нууц үг:",
-       "retypenew": "Шин нууц үгиг дәкәд бичтн:",
+       "retypenew": "Шин нууц үг дәкәд бичтн:",
        "changepassword-success": "Тана нууц үгиг йовудта сольв! Та ода орнат...",
-       "resetpass-submit-loggedin": "Нууц үгиг сольх",
-       "resetpass-submit-cancel": "Уга ÐºÐµх",
+       "resetpass-submit-loggedin": "Нууц үг сольх",
+       "resetpass-submit-cancel": "Ð\91Ñ\83Ñ\86х",
        "bold_sample": "Тарһн бичг",
        "bold_tip": "Тарһн бичг",
        "italic_sample": "Өкәсн бичг",
        "italic_tip": "Өкәсн бичг",
-       "link_sample": "Ð\97аалһна нерн",
-       "link_tip": "Өвр заалһ",
-       "extlink_sample": "http://www.example.com Ð·Ð°Ð°Ð»Ò»Ð½Ð° Ð½ÐµÑ\80нÑ\8c",
-       "extlink_tip": "Һаза заалһ (http:// гидг эклц бичә мартн)",
-       "headline_sample": "Толһа нерн",
-       "headline_tip": "Дү толһа нерн",
-       "nowiki_sample": "Энд темдглһтә уга бичгиг бичтн",
-       "nowiki_tip": "Ð\91ики Ñ\82емдглһиг басх",
-       "image_tip": "Ð\9eÑ\80Ñ\86Ñ\83лсн боомг",
-       "media_tip": "Боомгин заалһ",
-       "sig_tip": "Тана тәвсн һар цагин темдгтә",
-       "hr_tip": "Кевтдг татасн (дундин бәәдлтә олзлтн)",
-       "summary": "Учр-утх:",
-       "subject": "Төр/нерәдлһн:",
-       "minoredit": "Ð\91аһ Ñ\87икллһн",
-       "watchthis": "ШинÒ\97лх",
-       "savearticle": "Хадһлх",
+       "link_sample": "Ð\97аалһин нерн",
+       "link_tip": "Дотрк заалһ",
+       "extlink_sample": "http://www.example.com Ð·Ð°Ð°Ð»Ò»Ð¸Ð½ Ò»Ð°Ñ\80Ñ\86г",
+       "extlink_tip": "Һазак заалһ (http:// эклвр бичә мартн)",
+       "headline_sample": "Һарцгин бичәсн",
+       "headline_tip": "Дү һарцг",
+       "nowiki_sample": "Энд кевлүлх кергго бичәсн орултн",
+       "nowiki_tip": "Ð\92ики ÐºÐµÐ²Ð»Ò¯Ð»Ð»Ñ\82 басх",
+       "image_tip": "Углсн боомг",
+       "media_tip": "Боомгур заалһ",
+       "sig_tip": "Тана тәвсн һар цаг хойр",
+       "hr_tip": "Кевтә татасн (нигтәр биш керглтн)",
+       "summary": "Үндсн:",
+       "subject": "Төр/һарцг:",
+       "minoredit": "Ð\91аһ Ñ\8fÑ\81вÑ\80",
+       "watchthis": "Эн Ñ\85алÑ\85 Ð¾Ð²Ñ\80х",
+       "savearticle": "ХалÑ\85 Ñ\85адһлÑ\85",
        "preview": "Хәләвр",
        "showpreview": "Хәләвр",
-       "showdiff": "Ð\99илһән",
+       "showdiff": "Ð\9aеÑ\81н Ð¹илһән",
        "anoneditwarning": "'''Урдаснь зәңг:''' та орв биш.\nТадна IP хайг эн халхна чикллһнә сеткүлд бичҗ авх.",
-       "summary-preview": "Эн учр-утхта болх:",
-       "subject-preview": "ТеÑ\80 Ò»Ð°Ñ\80Ñ\87иг болх:",
-       "blockedtitle": "Демнч бүслгдәд бәәнә.",
-       "loginreqlink": "харһх",
-       "accmailtitle": "Ð\9dÑ\83Ñ\83Ñ\86 Ò¯Ð³Ñ\82Ó\99 Ð±Ð¸Ñ\87г Ð¹Ð¾Ð²Ñ\83лла.",
+       "summary-preview": "Эн үндсн болх:",
+       "subject-preview": "Эн Ò»Ð°Ñ\80Ñ\86г болх:",
+       "blockedtitle": "Демнәч бүслгдсн",
+       "loginreqlink": "орх",
+       "accmailtitle": "Ð\9dÑ\83Ñ\83Ñ\86 Ò¯Ð³Ñ\82Ó\99 Ð±Ð¸Ñ\87г Ð¹Ð¾Ð²Ñ\83лгдв",
        "newarticle": "(Шин)",
-       "newarticletext": "Та Ð·Ð°Ð°Ð»Ò»Ð¸Ð³ Ð´Ð°Ñ\85ад Ð±Ó\99Ó\99дг Ñ\83га Ñ\85алÑ\85д Ð¸Ñ\80в.\nТеÑ\80үг Ð±Ò¯Ñ\82Ó\99Ò\97 Ð±Ð¾Ð»Ñ\85ла, Ð´Ð¾Ñ\80аһаÑ\80 Ñ\82еÑ\80зд Ð±Ð¸Ñ\87Ñ\82н (дÓ\99кÓ\99д Ó©Ð³Ð³Ñ\86нÓ\99 Ñ\82өлÓ\99 [$1 Ñ\82Ó\99Ó\99лвÑ\80] Ñ\85Ó\99лÓ\99Ñ\82н).\nТа Ñ\8dн Ò»Ð°Ð·Ñ\80Ñ\82 Ñ\8dндүһÓ\99Ñ\80 Ð±Ó\99Ó\99Ñ\85лÓ\99, '''Ð¥Ó\99Ñ\80Ò¯''' Ð´Ð°Ñ\80Ñ\86иг дартн.",
-       "noarticletext": "Эн халх хоосн. Та [[Special:Search/{{PAGENAME}}|эн нернә сананд орулһна хәәх]] , <span class=\"plainlinks\">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} бүртклин бичгт хәәх], аль '''[{{fullurl:{{FULLPAGENAME}}|action=edit}} бүтәх]'''</span>.",
+       "newarticletext": "Та Ð·Ð°Ð°Ð»Ò»Ð°Ñ\80 Ð¾Ð´Ð°Ñ\85н Ñ\83га Ñ\85алÑ\85Ñ\82 Ð¾Ð´Ð².\nҮүниг Ð±Ò¯Ñ\82Ó\99Ñ\85Ó\99Ñ\80, Ð´Ð¾Ñ\80к Ñ\86оңÑ\85Ñ\82 Ð±Ð¸Ñ\87Ó\99Ñ\81н Ð¾Ñ\80Ñ\83лÑ\82н (Ñ\82одÑ\80Ñ\85а [$1 Ð´Ó©Ò£Ð³Ð¸Ð½ Ñ\85алÑ\85] Ñ\85Ó\99лÓ\99Ñ\82н).\nТа Ñ\8dнд Ñ\8dндүһÓ\99Ñ\80 Ð¾Ð´Ð»Ñ\85лаÑ\82, Ñ\85аÑ\80агÑ\87ин '''Ð¥Ó\99Ñ\80Ò¯''' Ñ\82овÑ\80Ñ\83н дартн.",
+       "noarticletext": "Эн халх одахн хоосн. Та [[Special:Search/{{PAGENAME}}|эн нернә дурдлһн хәәҗ]] , <span class=\"plainlinks\">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} ирлцәтә седкүлин бичгдл хәәҗ], аль '''[{{fullurl:{{FULLPAGENAME}}|action=edit}} иим нертә халх бүтәҗ]''' чаднат</span>.",
        "clearyourcache": "'''Оньган өгтн:''' Кесн сольлһн үзхәр, тана хәләлгчин кеш цеврүлтн: '''Mozilla / Firefox''': ''Ctrl+Shift+R'', '''IE:''' ''Ctrl+F5'', '''Safari''': ''Cmd+Shift+R'', '''Konqueror''': ''F5'', '''Opera''': ''Tools→Preferences'' менүһәс.",
        "usercssyoucanpreview": "'''Селвг:''' тана шин CSS боомг шүүҗ хадһлар, «{{int:showpreview}}» товч олзлтн.",
        "userjsyoucanpreview": "'''Селвг:''' тана шин JS боомг шүүҗ хадһлар, «{{int:showpreview}}» товч олзлтн.",
        "previewnote": "'''Эн мел хәләвр бәәдг тускар тодлтн.'''\nТана сольлһн ода чигн хадһлсн уга!",
        "previewconflict": "Тер хәләвр деегүрк чикллһнә теегт бәәдг бичг хадлһҗ бичсн мет үзүлнә.",
        "session_fail_preview": "'''Гемим тәвтн, сервер тана сольлһта даңдад болв. Юнгад гихлә, тана харһлһна медүллһн геев.\nБуйн болтха, дәкәд арһ хәәтн.\nТер эндү давтхла, [[Special:UserLogout|һартн]] тегәд бас харһтн.'''",
-       "editing": "Чикллһн: $1",
-       "editingsection": "«$1» гидг халхна чикллһн (хүв)",
-       "editconflict": "ЧикллһнÓ\99 керүл: $1",
-       "yourtext": "Тана бичсн",
+       "editing": "ЯÑ\81вÑ\80: $1",
+       "editingsection": "«$1» ясвр (салвр)",
+       "editconflict": "ЯÑ\81вÑ\80ин керүл: $1",
+       "yourtext": "Тана бичәсн",
        "yourdiff": "Йилһән",
        "copyrightwarning": "Буйн болтха, цуг өгүллһн {{SITENAME}} төлә $2 гидг закаһар кесн, тоолсн бәәдг тускар тодлтн (Дәкәд өггцд төлә $1 хәләтн).  Та тана бичсн чилклсн аль делгрңсн бәәҗ седхлә биш, эн ормд бичә бичтн.<br /> Дәкәд та маднд эн эврәнь бичсн, күмн әмтнә хазас аль цацу сул медснәс бәәдг үгән өгнәт. '''Зөвән авхла уга, харссн бичсн күүнә көдлмш бичә тәвтн!'''",
        "copyrightwarning2": "Буйн болтха, цуг өгүллһн {{SITENAME}} төлә чиклсн аль һарһсн бәәдг чадта тускар тодлтн.  Та тана бичсн чилклсн аль делгрңсн бәәҗ седхлә биш, эн ормд бичә бичтн.<br /> Дәкәд та маднд эн эврәнь бичсн, күмн әмтнә хазас аль цацу сул медснәс бәәдг үгән өгнәт ($1 хәләтн). '''Зөвән авхла уга, харссн бичсн күүнә көдлмш бичә тәвтн!'''",
        "template-semiprotected": "(зәрм харссн)",
        "hiddencategories": "Эн халх тер $1 {{PLURAL:$1|бултулсн әәшләс|бултулсн әәшлүдәс|бултулсн әәшлүдәс}}:",
        "permissionserrorstext-withaction": "Та $2 кеҗ болшго. Юнгад гихлә, эн {{PLURAL:$1|1=учрар|учрар}}:",
-       "edit-conflict": "ЧикллһнÓ\99 керүл.",
+       "edit-conflict": "ЯÑ\81вÑ\80ин керүл.",
        "parser-template-loop-warning": "Зуран бүтү нүдлв: [[$1]]",
-       "viewpagelogs": "ТеÑ\80 Ñ\85алÑ\85на Ñ\81еÑ\82күлдүд Ò¯Ð·Ò¯Ð»х",
-       "currentrev-asof": "Ода болсн янз ($1)",
-       "revisionasof": "Тер цагин янз: $1",
-       "previousrevision": "← Урдк янз",
-       "nextrevision": "Дарук янз →",
-       "currentrevisionlink": "Ð\9eда Ð±Ð¾Ð»Ñ\81н Ñ\8fнз",
+       "viewpagelogs": "Эн Ñ\85алÑ\85ин Ñ\81едкүлүд Ñ\85Ó\99лÓ\99х",
+       "currentrev-asof": "$1 һарц",
+       "revisionasof": "$1 һарц",
+       "previousrevision": "← Урдк һарц",
+       "nextrevision": "Дарук һарц →",
+       "currentrevisionlink": "Ð\91Ó\99Ó\99гÑ\87 Ò»Ð°Ñ\80Ñ\86",
        "cur": "ода",
        "next": "дарук",
        "last": "урдк",
        "page_first": "түрүн",
-       "page_last": "кенз",
-       "histlegend": "Тәәлвр: (ода) — одачн янзас йилһән; (урдк) — урдк янзас йилһән; '''б''' — баһ сольлһн",
-       "history-fieldset-title": "Тууҗиг хәләх",
-       "histfirst": "ЭÑ\80Ñ\82",
-       "histlast": "ШидÑ\80Ó\99",
+       "page_last": "оÑ\82Ñ\85н",
+       "histlegend": "Һарцин суңһвр: дүңнх сансн халхин һарцс суңһад, Enter аль дорк товрун дартн.<br />\nТәәлвр: <strong>({{int:cur}})</strong> — отхн һарцас йилһән, <strong>({{int:last}})</strong> — урдк һарцас йилһән, <strong>{{int:minoreditletter}}</strong> — баһ ясвр.",
+       "history-fieldset-title": "Тууҗ хәләх",
+       "histfirst": "маÑ\88 Ñ\85Ñ\83Ñ\83Ñ\87н",
+       "histlast": "маÑ\88 Ñ\88ин",
        "historyempty": "(хоосн)",
-       "rev-delundel": "үзүлÑ\85±Ñ\83лÑ\82Ñ\83лх",
+       "rev-delundel": "үзүлÑ\85½Ñ\83Ñ\83х",
        "rev-showdeleted": "үзүлх",
        "revdelete-show-file-submit": "Тиим",
-       "revdelete-radio-set": "ЭÑ\8d",
-       "revdelete-radio-unset": "Уга",
-       "revdel-restore": "Үзгдллһиг сольх",
-       "pagehist": "ХалÑ\85на тууҗ",
-       "revdelete-otherreason": "Талдан/дÓ\99кÓ\99д учр:",
+       "revdelete-radio-set": "Ð\9dÑ\83Ñ\83гдÑ\81н",
+       "revdelete-radio-unset": "Үзгдмл",
+       "revdel-restore": "үзгдмл сольх",
+       "pagehist": "ХалÑ\85ин тууҗ",
+       "revdelete-otherreason": "Ð\91Ñ\83Ñ\81/немгÑ\87 учр:",
        "mergehistory-reason": "Учр:",
        "revertmerge": "Хувах",
-       "history-title": "$1 — сольлһна тууҗ",
+       "history-title": "«$1» ясврин тууҗ",
        "lineno": "$1 мөр:",
        "compareselectedversions": "Суңһсн янзс әдлцүлх",
-       "editundo": "уга кех",
-       "searchresults": "Ð¥Ó\99Ó\99лһнÓ\99 Ð°Ñ\88Ñ\83д",
-       "searchresults-title": "Хәәлһнә ашуд \"$1\" төлә",
-       "notextmatches": "Әдл бичг халхд уга",
+       "editundo": "буцх",
+       "searchresults": "Ð¥Ó\99Ó\99вÑ\80ин Ð°Ñ\88",
+       "searchresults-title": "«$1» хәәврин аш",
+       "notextmatches": "Халхсин бичәснд ирлцән уга",
        "prevn": "урдк {{PLURAL:$1|$1}}",
        "nextn": "дарук {{PLURAL:$1|$1}}",
-       "viewprevnext": "Ð\93Ò¯Ò¯Ò»Ó\99д Ñ\85әләх ($1 {{int:pipe-separator}} $2) ($3)",
+       "viewprevnext": "Ð¥әләх ($1 {{int:pipe-separator}} $2) ($3)",
        "searchprofile-articles": "Зүүлс",
        "searchprofile-images": "Үзгдл-соңсвр",
-       "searchprofile-everything": "ЦÑ\83һаÑ\80",
-       "searchprofile-articles-tooltip": "$1 Ð³Ð¸Ð´Ð³ Ð·Ò¯Ò¯Ð»Ð´ хәәх",
+       "searchprofile-everything": "Хамг",
+       "searchprofile-articles-tooltip": "$1 Ð´Ð¾Ñ\82Ñ\80 хәәх",
        "searchprofile-images-tooltip": "Боомг хәәх",
-       "search-result-size": "$1 ({{PLURAL:$2|$2 үг|$2 үгмүд|$2 үгмүд}})",
-       "search-redirect": "(авч одлһн $1)",
-       "search-section": "($1 хүв)",
-       "search-suggest": "Та эниг таанат: $1 ?",
-       "search-interwiki-caption": "Садта проектмуд",
-       "search-interwiki-default": "$1 ашуд:",
-       "search-interwiki-more": "(дÓ\99кÓ\99д)",
-       "searchall": "Ñ\86Ñ\83г",
-       "powersearch-legend": "Ð\9aÒ¯Ñ\87н Ñ\85Ó\99Ó\99лһн",
-       "powersearch-ns": "Эн Ð½ÐµÑ\80нÓ\99 Ñ\83 Ð´Ð¾Ñ\82Ñ\80ан хәәх:",
+       "search-result-size": "$1 ({{PLURAL:$2|$2 үг|$2 үг|$2 үг}})",
+       "search-redirect": "(туудг $1)",
+       "search-section": "(«$1» салвр)",
+       "search-suggest": "Тана таасн маһд: $1",
+       "search-interwiki-caption": "Садта төслүд",
+       "search-interwiki-default": "$1 талас аш:",
+       "search-interwiki-more": "(нанÑ\8c)",
+       "searchall": "Ñ\85амг",
+       "powersearch-legend": "Ð\9dÓ\99Ñ\80н Ñ\85Ó\99Ó\99вÑ\80",
+       "powersearch-ns": "Эн Ð½ÐµÑ\80нÓ\99 Ñ\82Ó©Ñ\80лд хәәх:",
        "powersearch-togglenone": "Уга",
-       "preferences": "Ð\94Ñ\83Ñ\80ллһн",
-       "mypreferences": "Көгүд",
-       "prefs-edits": "ЧикллһнÓ\99 то:",
-       "prefs-skin": "Ð¥Ñ\83вÑ\86нÑ\8c",
+       "preferences": "Ð\9aөгмүд",
+       "mypreferences": "Көгмүд",
+       "prefs-edits": "ЯÑ\81вÑ\80ин то:",
+       "prefs-skin": "Ð\91Ó\99Ó\99дл",
        "skin-preview": "Хәләвр",
-       "datedefault": "Келхлә уга",
-       "prefs-personal": "Демнчна көгүд",
-       "prefs-rc": "ШидÑ\80Ó\99 Ñ\81олÑ\8cлһн",
-       "prefs-watchlist": "ШинÒ\97ллһнÓ\99 Ñ\81еÑ\82күл",
+       "datedefault": "Көг уга",
+       "prefs-personal": "Демнәчна то-диг",
+       "prefs-rc": "Ð\9eÑ\82Ñ\85н Ñ\8fÑ\81вÑ\80",
+       "prefs-watchlist": "Ð\9eвÑ\80Ñ\85ин Ñ\81едкүл",
        "prefs-watchlist-days": "Шинҗллһнә седкүлд үзүлсн ик гисн өдрин то:",
-       "prefs-watchlist-days-max": "Maximum $1 {{PLURAL:$1|1=day|days}}",
-       "prefs-misc": "Талдан",
-       "prefs-resetpass": "Нууц угиг сольҗ",
-       "prefs-email": "E-mail'ын көгүд",
+       "prefs-watchlist-days-max": "$1 {{PLURAL:$1|өдрәс|өдрәс}} удан биш",
+       "prefs-misc": "Ð\91Ñ\83Ñ\81",
+       "prefs-resetpass": "Нууц үг сольх",
+       "prefs-email": "E-mail'ин көгмүд",
        "prefs-rendering": "Һазад бәәдл",
        "saveprefs": "Хадһлх",
-       "restoreprefs": "ЦÑ\83г Ñ\8dклÑ\86ин ÐºÓ©Ð³Ò¯Ð´Ð¸Ð³ Ð±Ð¾Ñ\81Ñ\85Ò\97 Ñ\82оÑ\85Ñ\80аÑ\80",
-       "prefs-editing": "Чикллһн",
+       "restoreprefs": "Хамг Ñ\82ааÑ\80Ñ\81н ÐºÓ©Ð³ Ð±Ð¾Ñ\81Ñ\85Ñ\85 (Ñ\86Ñ\83г Ñ\81алвÑ\80)",
+       "prefs-editing": "ЯÑ\81вÑ\80",
        "rows": "Мөрд:",
        "columns": "Бахд:",
        "savedprefs": "Тана көгүдиг хадһлв.",
-       "timezonelegend": "ЧаÑ\81ин бүс:",
-       "localtime": "Бәәрн һазра цаг:",
-       "timezoneuseserverdefault": "Серверинь олзлх",
-       "timezoneuseoffset": "Талдан (көндллһн заатн)",
+       "timezonelegend": "Цагин бүс:",
+       "localtime": "Бәәрн цаг:",
+       "timezoneuseserverdefault": "Серверин көг керглх",
+       "timezoneuseoffset": "Ð\91Ñ\83Ñ\81 (көндллһн заатн)",
        "servertime": "Серверин цаг:",
-       "guesstimezone": "Хәләлгчәс авх",
-       "timezoneregion-africa": "Априк",
+       "guesstimezone": "Харагчасавх",
+       "timezoneregion-africa": "Африк",
        "timezoneregion-america": "Америк",
        "timezoneregion-antarctica": "Антарктик",
        "timezoneregion-arctic": "Арктик",
        "timezoneregion-atlantic": "Атлантин дала",
        "timezoneregion-australia": "Австрал",
        "timezoneregion-europe": "Европ",
-       "timezoneregion-indian": "ЭнеÑ\82екгин дала",
+       "timezoneregion-indian": "Эндкг дала",
        "timezoneregion-pacific": "Номһн дала",
        "allowemail": "Талдан демнчнрәс ирсн e-mail бичг зөвшәрх",
-       "prefs-searchoptions": "Ð¥Ó\99Ó\99лһнÓ\99 ÐºÓ©Ð³",
+       "prefs-searchoptions": "Ð¥Ó\99Ó\99вÑ\80",
        "prefs-namespaces": "Нернә ус",
        "prefs-custom-css": "Онц CSS",
        "prefs-custom-js": "Онц JS",
-       "prefs-emailconfirm-label": "E-mail Ð±Ð°Ñ\82лһн:",
+       "prefs-emailconfirm-label": "E-mail Ð»Ð°Ð²Ð»Ð»Ñ\82:",
        "youremail": "E-mail хайг:",
-       "username": "Демнчна нер:",
-       "prefs-memberingroups": "{{PLURAL:$1|1=Багин|Багдудин}} хүв:",
+       "username": "Демнәчнә нерн:",
+       "prefs-memberingroups": "{{PLURAL:$1|Багин|Багмудын}} гешүн:",
        "prefs-registration": "Темдглҗ  бүртклһнә цаг:",
        "yourrealname": "Үнн нерн:",
        "yourlanguage": "Бәәдлин келн:",
        "yournick": "Тәвсн һар:",
        "prefs-help-signature": "Меткән халхна бичсн бичгт «<nowiki>~~~~</nowiki>» немәд һаран тәвх кергтә. Тер үзгүд тана тәвсн һарт болн цагин бичлгт болулх.",
-       "yourgender": "Ð\9aииÑ\81н:",
-       "gender-unknown": "Бичсн уга",
-       "gender-male": "Эр",
-       "gender-female": "Эм",
+       "yourgender": "ЯмÑ\80 Ð±Ð¸Ñ\87лһн Ð´ÐµÐµÑ\80Ñ\88Ó\99нÓ\99Ñ\82?",
+       "gender-unknown": "Би эс заахар деершәнәв",
+       "gender-male": "Эн вики халхс ясна (эр)",
+       "gender-female": "Эн Ð²Ð¸ÐºÐ¸ Ñ\85алÑ\85Ñ\81 Ñ\8fÑ\81на (Ñ\8dм)",
        "prefs-help-gender": "Эн дәкәд бәәдг: чик күндллһн тоолвртар төлә. Эн өггцн цуг әмтнә болх.",
        "email": "E-mail хайг",
        "prefs-help-realname": "Үнн нернь та эврә дурар бичнәт. Бичлхлә, эн тәвсн һарт элзлдг бәәх.",
        "prefs-help-email": "E-mail хайг та эврә дурар бичнәт. Бичхлә, тадн шин түлкүр үгиг бичгәр йовулсн өгҗ чаднат (мартхла).",
        "prefs-info": "Һол медә",
        "prefs-i18n": "Олн орни бәәлһн",
-       "prefs-signature": "Тәвсн һаран",
-       "prefs-advancedediting": "Ð\94Ó\99кÓ\99д ÐºÓ©Ð³Ò¯Ð´",
-       "prefs-advancedrc": "Ð\94Ó\99кÓ\99д ÐºÓ©Ð³Ò¯Ð´",
-       "prefs-advancedrendering": "Ð\94Ó\99кÓ\99д ÐºÓ©Ð³Ò¯Ð´",
-       "prefs-advancedsearchoptions": "Ð\94Ó\99кÓ\99д ÐºÓ©Ð³Ò¯Ð´",
-       "prefs-advancedwatchlist": "Ð\94Ó\99кÓ\99д ÐºÓ©Ð³Ò¯Ð´",
+       "prefs-signature": "Тәвсн һар",
+       "prefs-advancedediting": "Ð\99иÑ\80ңкÓ\99 ÐºÓ©Ð³",
+       "prefs-advancedrc": "Ð\9dÓ\99Ñ\80н ÐºÓ©Ð³",
+       "prefs-advancedrendering": "Ð\9dÓ\99Ñ\80н ÐºÓ©Ð³",
+       "prefs-advancedsearchoptions": "Ð\9dÓ\99Ñ\80н ÐºÓ©Ð³",
+       "prefs-advancedwatchlist": "Ð\9dÓ\99Ñ\80н ÐºÓ©Ð³",
        "prefs-diffs": "Йилһәс",
        "userrights-reason": "Учр:",
        "group": "Баг:",
-       "group-user": "Демнчнр",
+       "group-user": "Демнәчнр",
        "group-autoconfirmed": "Эврә батлсн демнчнр",
        "group-bot": "Көдлврүд",
        "group-sysop": "Закрачуд",
        "group-bureaucrat": "Нойнчуд",
        "group-all": "(цуг)",
-       "group-user-member": "Ð\94емнч",
-       "group-autoconfirmed-member": "Эврә батлсн демнчнр",
-       "group-bot-member": "Ð\9aөдлвÑ\80",
-       "group-sysop-member": "Ð\97акрач",
-       "group-bureaucrat-member": "Ð\9dойнч",
+       "group-user-member": "демнÓ\99ч",
+       "group-autoconfirmed-member": "эврә лавлсн демнәч",
+       "group-bot-member": "көдлгÑ\87",
+       "group-sysop-member": "закрач",
+       "group-bureaucrat-member": "нойнч",
        "grouppage-user": "{{ns:project}}:Демнч",
-       "grouppage-autoconfirmed": "{{ns:project}}:ЭвÑ\80Ó\99 Ð±Ð°Ñ\82лсн демнчнр",
-       "grouppage-bot": "{{ns:project}}:Ð\9aөдлвÑ\80үд",
+       "grouppage-autoconfirmed": "{{ns:project}}:ЭвÑ\80Ó\99 Ð»Ð°Ð²лсн демнчнр",
+       "grouppage-bot": "{{ns:project}}:Ð\9aөдлгÑ\87үд",
        "grouppage-sysop": "{{ns:project}}:Закрачуд",
        "grouppage-bureaucrat": "{{ns:project}}:Нойнчуд",
-       "newuserlogpage": "Бичгдлһнә сеткүл",
-       "rightslog": "Демнчна зөвәнә сеткүл",
-       "action-edit": "эн халхиг чиклх",
-       "nchanges": "$1 {{PLURAL:$1|1=сольлһн|сольлһн}}",
-       "recentchanges": "ШидÑ\80Ó\99 Ñ\81олÑ\8cлһн",
-       "recentchanges-legend": "ШидÑ\80Ó\99 Ñ\81олÑ\8cлһна ÐºÓ©Ð³Ò¯Ð´",
-       "recentchanges-summary": "Эн цагин дараһар бичсн шидрә сольлһн",
-       "recentchanges-feed-description": "Эн Ð·Ó\99ңгллһд Ñ\88идÑ\80Ó\99 Ñ\85үвÑ\80һд Ñ\88инÒ\97лх.",
-       "recentchanges-label-newpage": "ТеÑ\80 Ò¯Ò¯Ð»Ó\99р шин халх бүтәв",
-       "recentchanges-label-minor": "Эн Ð±Ð°Ò» Ñ\87инÑ\80Ñ\82Ó\99 Ñ\81олÑ\8cлһн",
-       "recentchanges-label-bot": "Эн Ñ\81олÑ\8cлһн ÐºÓ©Ð´Ð»Ð²Ñ\80 (Ñ\80обоÑ\82) ÐºÐµÑ\85в",
-       "recentchanges-legend-newpage": "$1 — шин халх",
-       "rclistfrom": "ТеÑ\80 Ñ\86агаÑ\81 Ð°Ð²Ð½ Ñ\81олÑ\8cлһн үзүлх: $3 $2.",
-       "rcshowhideminor": "баһ Ñ\87икллһиг $1",
-       "rcshowhidebots": "көдлвÑ\80үдиг $1",
-       "rcshowhideliu": "демнчнриг $1",
-       "rcshowhideanons": "нер уга демнчнриг $1",
-       "rcshowhidemine": "мини Ñ\87икллһиг $1",
-       "rclinks": "Ð\9aенз $1 Ñ\81олÑ\8cлһн, ÐºÐµÐ½Ð· $2 өдрмүдт үзүлх<br />$3",
+       "newuserlogpage": "Бичгдлһнә седкүл",
+       "rightslog": "Демнәчна зөвин седкүл",
+       "action-edit": "эн халх ясх",
+       "nchanges": "$1 ясвр",
+       "recentchanges": "Ð\9eÑ\82Ñ\85н Ñ\8fÑ\81вÑ\80",
+       "recentchanges-legend": "Ð\9eÑ\82Ñ\85н Ñ\8fÑ\81вÑ\80ин ÐºÓ©Ð³",
+       "recentchanges-summary": "Энд цагин дараһар бичсн отхн ясвр.",
+       "recentchanges-feed-description": "Эн ÐºÒ¯Ñ\81мд Ð²Ð¸ÐºÐ¸Ð½ Ð¾Ñ\82Ñ\85н Ñ\8fÑ\81вÑ\80 Ð¾Ð²Ñ\80х.",
+       "recentchanges-label-newpage": "Эн Ñ\8fÑ\81вÑ\80ар шин халх бүтәв",
+       "recentchanges-label-minor": "Эн Ð±Ð°Ò» Ñ\87инÑ\80Ñ\82Ó\99 Ñ\8fÑ\81вÑ\80",
+       "recentchanges-label-bot": "Эн Ñ\8fÑ\81вÑ\80 ÐºÓ©Ð´Ð»Ð³Ñ\87 (боÑ\82) ÐºÐµв",
+       "recentchanges-legend-newpage": "{{int:recentchanges-label-newpage}} ([[Special:NewPages|list of new pages]] чигн хәләтн)",
+       "rclistfrom": "Эн Ñ\86агаÑ\81 Ð°Ð²Ð½ Ñ\8fÑ\81вÑ\80 үзүлх: $3 $2.",
+       "rcshowhideminor": "баһ Ñ\8fÑ\81вÑ\80 $1",
+       "rcshowhidebots": "көдлгÑ\87үд $1",
+       "rcshowhideliu": "$1 бүрткгдсн демнәч",
+       "rcshowhideanons": "нерго демнәчнр $1",
+       "rcshowhidemine": "мини Ñ\8fÑ\81вÑ\80 $1",
+       "rclinks": "Ð\9eÑ\82Ñ\85н $1 Ñ\8fÑ\81вÑ\80, Ñ\81үл $2 өдрмүдт үзүлх<br />$3",
        "diff": "йилһ",
        "hist": "тууҗ",
-       "hide": "бÑ\83лÑ\82Ñ\83лх",
-       "show": "Ò¯зүлх",
+       "hide": "Ð\9dÑ\83Ñ\83х",
+       "show": "Ò®зүлх",
        "minoreditletter": "б",
        "newpageletter": "Ш",
        "boteditletter": "к",
-       "newsectionsummary": "/* $1 */ Ð¨Ð¸Ð½ Ñ\85үв",
-       "rc-enhanced-expand": "ТодÑ\80Ñ\85аÑ\81иг Ò¯Ð·Ò¯Ð»Ñ\85 (JavaScript ÐºÐµÑ\80гÑ\82Ó\99)",
-       "rc-enhanced-hide": "Тодрхасиг бултулх",
-       "recentchangeslinked": "Садн Ñ\87икллһн",
-       "recentchangeslinked-feed": "Садта чикллһн",
-       "recentchangeslinked-toolbox": "Садта чикллһн",
-       "recentchangeslinked-title": "$1 садта сольлһн",
+       "newsectionsummary": "/* $1 */ Ð¨Ð¸Ð½ Ñ\81алвÑ\80",
+       "rc-enhanced-expand": "Ð\9dÓ\99Ñ\80н Ñ\83Ñ\87Ñ\80 Ò¯Ð·Ò¯Ð»Ñ\85",
+       "rc-enhanced-hide": "Тодрха нуух",
+       "recentchangeslinked": "Садн Ñ\8fÑ\81вÑ\80",
+       "recentchangeslinked-feed": "Садн ясвр",
+       "recentchangeslinked-toolbox": "Садн ясвр",
+       "recentchangeslinked-title": "$1 садн ясвр",
        "recentchangeslinked-summary": "Эн тер халх заалдг халхсин (аль тер янзин халхсин) шидрә сольлһн.\nТана [[Special:Watchlist|шинҗллһнә сеткүлин]] халхс '''тарһн''' бичәтә.",
-       "recentchangeslinked-page": "ХалÑ\85на Ð½ÐµÑ\80нÑ\8c:",
-       "recentchangeslinked-to": "Зөрүһәр, эн халхд заалдг халхсин хүврлһиг үзүлх",
-       "upload": "Боомгиг тәвх",
-       "uploadbtn": "Боомгиг тәвх",
-       "uploadnologintext": "Та [[Special:UserLogin|Ñ\85аÑ\80Ò»Ñ\85]] кергтә.",
+       "recentchangeslinked-page": "ХалÑ\85ин Ð½ÐµÑ\80н:",
+       "recentchangeslinked-to": "Зөрүһәр, эн халхт заалдг халхсин ясвр үзүлх",
+       "upload": "Боомг тәвх",
+       "uploadbtn": "Боомг тәвх",
+       "uploadnologintext": "Ð\91оомг Ð¾Ñ\80Ñ\83лÑ\85аÑ\80 $1 кергтә.",
        "uploaderror": "Тәвллһнә эндү",
        "uploadlogpage": "Тәвллһнә сеткүл",
-       "filename": "Ð\91оомгна нернь",
+       "filename": "Ð\91оомгин нернь",
        "filedesc": "Учр-утх",
        "fileuploadsummary": "Учр-утх:",
        "savefile": "Хадһлх",
        "filehist-datetime": "Өдр/цаг",
        "filehist-thumb": "Зураллһн",
        "filehist-thumbtext": "$1 янзин зураллһн",
-       "filehist-user": "Демнч",
+       "filehist-user": "Демнәч",
        "filehist-dimensions": "Юмна кир",
        "filehist-comment": "Аҗгллһн",
-       "imagelinks": "Боомгд заалһуд",
-       "linkstoimage": "{{PLURAL:$1|Эн $1 халх|Эн $1 халхс|Эн $1 халхс}} тер боомгд заалдг бәәнә:",
+       "imagelinks": "Боомг керглән",
+       "linkstoimage": "Эн $1 халх эн боомгур заана:",
        "sharedupload": "Эн боомг $1 ормас. Териг талдан төсвд олзлҗ болх.",
        "uploadnewversion-linktext": "Тер боомгин шин һарц тәвх",
        "randompage": "Уршг зүүл",
        "statistics-edits-average": "Халхарн сольлһна то",
        "statistics-users": "Бичгдлһтә [[Special:ListUsers|демнчнр]]",
        "statistics-users-active": "Үүлтә демнчнр",
-       "statistics-users-active-desc": "{{PLURAL:$1|$1 өдрт|$1 өдрмүдт|$1 өдрмүдт}} болв чигн үүл кесн демнчнр",
-       "brokenredirects-edit": "Ñ\87иклх",
+       "statistics-users-active-desc": "Сүл $1 өдрт үүлдвр кесн демнчәнр",
+       "brokenredirects-edit": "Ñ\8fÑ\81х",
        "brokenredirects-delete": "һарһх",
-       "nbytes": "$1 {{PLURAL:$1|байд|байдуд|байдуд}}",
-       "nmembers": "$1 {{PLURAL:$1|мөч|мөчин|мөчүд}}",
+       "nbytes": "$1 байт",
+       "nmembers": "$1 гешүн",
        "prefixindex": "Цуг халхс эн эклцтә",
        "newpages": "Шин халхс",
        "move": "Көндәх",
        "movethispage": "Эн халхд шин нер аль шин орм өгх",
-       "pager-newer-n": "{{PLURAL:$1|1=шинәр 1|шинәр $1}}",
-       "pager-older-n": "{{PLURAL:$1|1=көгшәр 1|көгшәр $1}}",
+       "pager-newer-n": "$1 нань шин",
+       "pager-older-n": "$1 нань хуучн",
        "booksources": "Дегтрин делгүрс",
        "booksources-search-legend": "Дегтр туск хәәх",
        "log": "Сеткүлс",
        "allpagesto": "Энд асрлһиг зогсх:",
        "allarticles": "Цуг халхс",
        "allpagessubmit": "Орх",
-       "linksearch": "Һаза заалһуд",
+       "linksearch": "Һазад заалһ хәәвр",
        "listgrouprights-members": "(мөчүдин сеткүл)",
        "emailuser": "Энд E-mail йовулх",
-       "watchlist": "ШинÒ\97ллһнÓ\99 Ñ\81еÑ\82күл",
-       "mywatchlist": "ШинÒ\97ллһнÓ\99 Ñ\81еÑ\82күл",
-       "addedwatchtext": "«[[:$1]]» гидг нерәдлһтә халх тана [[Special:Watchlist|шинҗллһнә сеткүлд]] немв.\nТегәд тер халхна болн терүнә ухалврин сольлһн энд шиҗлсн болх. Эн халх '''тарһн'' үзгәр [[Special:RecentChanges|шидрә сольлһна]] халхд бичсн (амр умшхар) болх.",
+       "watchlist": "Ð\9eвÑ\80Ñ\85ин Ñ\81едкүл",
+       "mywatchlist": "Ð\9eвÑ\80Ñ\85ин Ñ\81едкүл",
+       "addedwatchtext": "«[[:$1]]» халх тана [[Special:Watchlist|оврхин седкүлд]] немв.\nЭн халхин болн үүнә меткән халхин ирх сольлһн энд бүрктх.",
        "removedwatchtext": "«[[:$1]]» халх тана [[Special:Watchlist|шинҗллһнә сеткүләс]] һарһв.",
        "watch": "Шинҗлх",
        "watchthispage": "Эн халхиг шинҗлх",
        "unwatch": "Шинҗлх биш",
-       "watchlist-details": "$1 {{PLURAL:$1|халх|халхс|халхс}} ухалвр угаһар тана шиҗллһнә сеткүлд.",
-       "wlshowlast": "Ð\9aенз $1 Ñ\87аÑ\81д $2 Ó©Ð´Ñ\80Ñ\82  үзүлх",
+       "watchlist-details": "Тана оврхин седкүлд меткәнә халхас бус $1 халх.",
+       "wlshowlast": "Сүл $1 Ñ\86агин $2 Ó©Ð´Ñ\80ин Ñ\82Ñ\83Ñ\80Ñ\88к үзүлх",
        "watchlist-options": "Шинҗллһнә сеткүлин көгүд",
        "watching": "Шинҗллһнә бүтлклд немлһн...",
        "unwatching": "Шинҗлһнә бүрткләс һарһлһн...",
        "deletecomment": "Учр:",
        "deleteotherreason": "Талдан аль дәкәд учр:",
        "deletereasonotherlist": "Талдан учр",
-       "rollback_short": "Хәрүллһн",
        "rollbacklink": "хәрүлх",
        "protectlogpage": "Харсллһна сеткүл",
        "protectedarticle": "«[[$1]]» халхиг харсв",
        "protect-default": "Цуг демнчнрд зөвән өгҗ",
        "protect-fallback": "$1 зөв кергтә",
        "protect-level-autoconfirmed": "Шин болн нер уга демнчнрас харсх",
-       "protect-level-sysop": "Дарһас һанцхн",
+       "protect-level-sysop": "Һанц закрачт зөвшәл",
        "protect-summary-cascade": "каскад",
        "protect-expiring": "$1 (UTC) гидг цагт өңгрнә",
        "protect-cascade": "Халхсиг эн халхд дотр харсх (каскад)",
        "namespace": "Нернә у:",
        "invert": "Зөрү суңһлт",
        "blanknamespace": "(Һол)",
-       "contributions": "Демнчна өгүллһн",
+       "contributions": "Демнәчнә тәвц",
        "contributions-title": "$1 демнчна тус",
-       "mycontris": "Ð\9cини Ð´ÐµÐ¼Ð½Ð»Ò»Ð½",
-       "contribsub2": "$1 төлә ($2)",
+       "mycontris": "ТÓ\99вÑ\86",
+       "contribsub2": "{{GENDER:$3|$1}} тәвц ($2)",
        "uctop": "(отхн)",
        "month": "Эн сарас (болн эртәр):",
        "year": "Эн җиләс (болн эртәр):",
index b8f9930..584d3d5 100644 (file)
        "content-model-javascript": "JavaScript",
        "content-model-css": "CSS",
        "content-json-empty-object": "ליידיגער אביעקט",
+       "content-json-empty-array": "ליידיגער אריי",
        "duplicate-args-category": "בלעטער וואס ניצן געטאפלטע ארגומענטן אין מוסטער רופן",
+       "duplicate-args-category-desc": "דער בלאט אנטהאלט מוסטער־אויפרופן וואס ניצן דופליקאטן פון ארגומענטן, ווי למשל <code><nowiki>{{foo|bar=1|bar=2}}</nowiki></code> or <code><nowiki>{{foo|bar|1=baz}}</nowiki></code>.",
        "expensive-parserfunction-warning": "'''אזהרה:''' דער בלאט אנטהאלט צופיל טייערע פארזירער רופן.\n\nער דארף האבן ווינציגער פון  $2 {{PLURAL:$2|רוף|רופן}}, אבער אצינד {{PLURAL:$1|איז דא $1 רוף|זענען דא $1 רופן}}.",
        "expensive-parserfunction-category": "בלעטער מיט צופֿיל טייערע פאַרזער פֿונקציאן רופֿן",
        "post-expand-template-inclusion-warning": "'''אכטונג:''' איינגעשלאסענע מוסטערן אין דעם בלאט זענען צו גרויס.\nטייל מוסטערן וועלן נישט ווערן איינגעשלאסן.",
        "prefs-personal": "באַניצער פראָפֿיל",
        "prefs-rc": "לעצטע ענדערונגען",
        "prefs-watchlist": "אויפפאסונג ליסטע",
+       "prefs-editwatchlist": "רעדאַקטירן די אויפֿפאַסונג ליסטע",
+       "prefs-editwatchlist-label": "רעדאקטירן ארטיקלען אויף אײַער אויפפאסונג־ליסטע:",
+       "prefs-editwatchlist-raw": "רעדאַקטירן די רויע אויפֿפאַסונג ליסטע",
+       "prefs-editwatchlist-clear": "ליידיגן אייער אויפפאסונג ליסטע",
        "prefs-watchlist-days": "טעג צו ווייזן אין דער אויפפאסונג ליסטע:",
        "prefs-watchlist-days-max": "העכסטן $1 {{PLURAL:$1|טאג|טעג}}",
        "prefs-watchlist-edits": "מאַקסימום נומער פון נײַע ענדערונגען צו ווייַזן אין פֿאַרברייטערטער אויפֿפאַסונג ליסטע:",
        "undelete-show-file-submit": "יא",
        "namespace": "נאמענטייל:",
        "invert": "ווײַז אַלע אויסער די",
+       "tooltip-whatlinkshere-invert": "מארקירט דאס קעסטל צו באהאלטן לינקען פון בלעטער אינעם אויסגעקליבענעם נאמענטייל.",
        "namespace_association": "אָנגעבונדענער נאָמענטייל",
        "tooltip-namespace_association": "צייכנט דאס קעסטל כדי איינשליסן דעם שמועס אדער סוביעקט נאמענטייל וואס געהערט צום אויסגעקליבענעם נאמענטייל",
        "blanknamespace": "(הויפט)",
        "ipbexpiry": "אויסגיין:",
        "ipbreason": "אורזאַך:",
        "ipbreason-dropdown": "* פֿארשפרייטע בלאקירן סיבות\n** ארײַנלייגן פֿאלשע אינפֿארמאציע\n** אויסמעקן אינהאַלט פֿון בלעטער\n** פֿארפֿלייצן לינקען צו דרויסנדיקע ערטער\n** ארײַנלייגן שטותים/טאָטעריש אין בלעטער\n** סטראשעט און שטערט\n** קרומבאניצן מערערע קאנטעס\n** באַניצער נאָמען פראבלעמאַטיש",
+       "ipb-hardblock": "פארמיידן אריינלאגירטע באניצער פון רעדאקטירן פון דעם IP־אדרעס",
        "ipbcreateaccount": "פֿאַרמײַדן שאַפֿן קאנטעס",
        "ipbemailban": "פֿארמײַדן באַניצער פון שיקן ע־פאסט",
        "ipbenableautoblock": "אויטאמאַטיש בלאקירן דעם לעצטן IP אַדרעס פֿ\nפֿון דעם באַניצער, און אַבי וועלכן IP אַדרעס ער פרובירט צו ניצן",
        "unblocked": "[[User:$1|$1]] איז געווארן באַפֿרייט פון זײַן בלאק",
        "unblocked-range": "$1 איז באפרייט פון בלאקירן",
        "unblocked-id": "בלאק $1 איז געווארן אַראָפגענומען.",
+       "unblocked-ip": "[[Special:Contributions/$1|$1]] איז געווארן אויפבלאקירט.",
        "blocklist": "בלאקירטע באַניצער",
        "ipblocklist": "בלאקירטע באַניצער",
        "ipblocklist-legend": "געפֿינען א בלאקירטן באניצער",
        "thumbnail-temp-create": "מ'קען נישט שאפן א פראוויזארישע פארקלענערטע טעקע",
        "thumbnail-dest-create": "מ'קען נישט שפייכלערן פארקלענערונג צום ציל",
        "thumbnail_invalid_params": "אומגילטיגע קליינבילד פאראמעטערס",
+       "thumbnail_toobigimagearea": "טעקע מיט דימענסיעס גרעסער פון $1",
        "thumbnail_dest_directory": "מ'קען נישט שאפֿן דעם ציל קארטאטעק",
        "thumbnail_image-type": "בילד טיפ נישט געשטיצט",
        "thumbnail_gd-library": "אומפולשטענדיקע קאנפיגוראציע פאר דער GD-ביבליאטעק: פונקציע $1 פעלט",
        "javascripttest": "JavaScript טעסט",
        "javascripttest-pagetext-noframework": " דער בלאט איז רעזערווירט פאר JavaScript. פרואוון.",
        "javascripttest-pagetext-unknownframework": "אומבאקאנטער טעסטן גערעם \"$1\".",
+       "javascripttest-pagetext-unknownaction": "אומבאַקאַנטע אַקציע '$1'",
        "javascripttest-pagetext-frameworks": "ביטע קלויבט איינעם פון די פאלגנדע טעסטן־גערעם: $1",
        "javascripttest-pagetext-skins": "קלויבט א באניצער־אייבערפלאך מיט וואס דורכצופירן די בדיקות:",
        "javascripttest-qunit-intro": "זעט [$1 דאקומענטאציע פאר טעסטן] בײַ mediawiki.org.",
index 01fccfc..9b1f21e 100644 (file)
        "mainpage": "首页",
        "mainpage-description": "首页",
        "policy-url": "Project:方针",
-       "portal": "社区门户",
+       "portal": "社区主页",
        "portal-url": "Project:社区门户",
        "privacy": "隐私政策",
        "privacypage": "Project:隐私政策",
        "copyrightwarning": "请注意您对{{SITENAME}}的所有贡献都被认为是在$2下发布,请查看在$1的细节。\n如果您不希望您的文字被任意修改和再散布,请不要提交。<br />\n您同时也要向我们保证您所提交的内容是您自己所作,或得自一个不受版权保护或相似自由的来源。\n'''不要在未获授权的情况下发表!'''<br />",
        "copyrightwarning2": "请注意,您对{{SITENAME}}的所有贡献都可能被其他贡献者编辑,修改或删除。如果您不希望您的文字被任意修改和再散布,请不要提交。<br />\n您同时也要向我们保证您所提交的内容是您自己所作,或得自一个不受版权保护或相似自由的来源(参阅$1的细节)。'''不要在未获授权的情况下发表!'''",
        "longpageerror": "'''错误:您所提交的文本长度有{{PLURAL:$1|1|$1}}KB,这大于{{PLURAL:$2|1|$2}}KB的最大值。'''\n因此,该文本无法保存。",
-       "readonlywarning": "警告:数据库被锁定以进行维护,所以您目前将无法保存您的修改。'''您或许希望将本段文字先剪贴并保存到文本文件,并在稍后进行修改。\n\n锁定数据库的管理员有如下解释:$1",
+       "readonlywarning": "<strong>警告:数据库被锁定以进行维护,所以您目前将无法保存您的编辑。</strong>您可能希望将您的文本复制粘贴到一个文本文档并保存它,以便稍后更改。\n\n锁定数据库的管理员有如下解释:$1",
        "protectedpagewarning": "'''警告:本页面已被保护,只有拥有管理员权限的用户可以编辑。'''下面提供最后的日志条目以供参考:",
        "semiprotectedpagewarning": "'''注意:'''本页面已被保护,只有注册用户可以编辑。下面提供最后的日志条目以供参考:",
        "cascadeprotectedwarning": "<strong>警告:</strong>本页面已经被保护,只有拥有管理员权限的用户可以编辑,因为它包含于以下启用连锁保护的{{PLURAL:$1|页面}}中:",
        "right-override-export-depth": "导出页面,包括最多5层链接",
        "right-sendemail": "发送电子邮件给其他用户",
        "right-passwordreset": "查看密码重置电子邮件",
+       "right-managechangetags": "从数据库创建和删除[[Special:Tags|标签]]",
        "newuserlogpage": "用户创建日志",
        "newuserlogpagetext": "这是用户创建的日志。",
        "rightslog": "用户权限日志",
        "action-viewmyprivateinfo": "查看您的私人信息",
        "action-editmyprivateinfo": "编辑你的私人信息",
        "action-editcontentmodel": "编辑页面的内容模型",
+       "action-managechangetags": "创建和从数据库中删除标签",
        "nchanges": "$1次更改",
        "enhancedrc-since-last-visit": "{{PLURAL:$1|上次访问后}}$1个",
        "enhancedrc-history": "历史",
        "tags-tag": "标签名称",
        "tags-display-header": "更改列表中的表现形式",
        "tags-description-header": "完整含义说明",
+       "tags-source-header": "来源",
        "tags-active-header": "是否活跃?",
        "tags-hitcount-header": "标记的更改数",
+       "tags-actions-header": "操作",
        "tags-active-yes": "是",
        "tags-active-no": "否",
+       "tags-source-extension": "由一个扩展定义",
+       "tags-source-manual": "可被用户和机器人手动应用",
+       "tags-source-none": "不再被使用",
        "tags-edit": "编辑",
+       "tags-delete": "删除",
+       "tags-activate": "激活",
+       "tags-deactivate": "取消激活",
        "tags-hitcount": "$1个更改",
+       "tags-manage-no-permission": "您没有权限管理更改标签。",
+       "tags-create-heading": "创建一个新标签",
+       "tags-create-explanation": "默认情况下,新创建的标签将可供用户和机器人使用。",
+       "tags-create-tag-name": "标签名称:",
+       "tags-create-reason": "原因:",
+       "tags-create-submit": "创建",
+       "tags-create-no-name": "您必须指定一个标签名称。",
+       "tags-create-invalid-chars": "标签名称必须不包含逗号(<code>,</code>)或正斜线(<code>/</code>)。",
+       "tags-create-invalid-title-chars": "标签名称不得含有无法在网页标题中使用的字符。",
+       "tags-create-already-exists": "“$1”标签已存在。",
+       "tags-create-warnings-above": "下列{{PLURAL:$2|警告}}是尝试创建“$1”标签时遇到的:",
+       "tags-create-warnings-below": "您希望继续创建此标签吗?",
+       "tags-delete-title": "删除标签",
+       "tags-delete-explanation-initial": "您即将从数据库中删除“$1”标签。",
+       "tags-delete-explanation-in-use": "它将从{{PLURAL:$2|所有$2个修订版本和/或日志记录}}移除至当前应用它的地方。",
+       "tags-delete-explanation-warning": "此操作是<strong>不可逆转</strong>且<strong>不可撤销</strong>的,即使是数据库管理员。请确定这是您希望删除的标签。",
+       "tags-delete-explanation-active": "<strong>“$1”标签仍处于激活状态,且在今后将被继续应用。</strong>要停止此情况继续发生,前往添加此标签的位置,并在那里将它停用。",
+       "tags-delete-reason": "原因:",
+       "tags-delete-submit": "不可逆转地删除此标签",
+       "tags-delete-not-allowed": "扩展定义的标签不能被删除,除非该扩展明确允许。",
+       "tags-delete-not-found": "标签“$1”不存在。",
+       "tags-delete-too-many-uses": "“$1”标签已应用到超过$2个修订版本,这意味着它不能被删除。",
+       "tags-delete-warnings-after-delete": "标签“$1”已成功删除,但遇到了以下{{PLURAL:$2|警告}}:",
+       "tags-activate-title": "激活标签",
+       "tags-activate-question": "您将要激活标签“$1”。",
+       "tags-activate-reason": "原因:",
+       "tags-activate-not-allowed": "不可能激活“$1”标签。",
+       "tags-activate-not-found": "标签“$1”不存在。",
+       "tags-activate-submit": "激活",
+       "tags-deactivate-title": "取消激活标签",
+       "tags-deactivate-question": "您将要取消激活标签“$1”。",
+       "tags-deactivate-reason": "原因:",
+       "tags-deactivate-not-allowed": "无法取消激活标签“$1”。",
+       "tags-deactivate-submit": "取消激活",
        "comparepages": "对比页面",
        "compare-page1": "页面1",
        "compare-page2": "页面2",
        "logentry-upload-upload": "$1{{GENDER:$2|上传}}$3",
        "logentry-upload-overwrite": "$1{{GENDER:$2|上传}}$3的新版本",
        "logentry-upload-revert": "$1{{GENDER:$2|上传}}$3",
+       "log-name-managetags": "标签管理日志",
+       "log-description-managetags": "此页面列出有关[[Special:Tags|标签]]的管理任务。该日志仅包含管理员手工进行的操作;wiki软件可能创建或删除标签而未在此日志中留下记录。",
+       "logentry-managetags-create": "$1{{GENDER:$2|创建了}}标签“$4”",
+       "logentry-managetags-delete": "$1 {{GENDER:$2|删除了}}“$4”标签(已从$5个{{PLURAL:$5|修订版本和/或日志条目}}中移除)",
+       "logentry-managetags-activate": "$1 {{GENDER:$2|激活了}}“$4”标签供用户和机器人使用",
+       "logentry-managetags-deactivate": "$1 {{GENDER:$2|停用了}}“$4”标签供用户和机器人使用",
        "rightsnone": "(无)",
        "revdelete-summary": "编辑摘要",
        "feedback-bugornote": "如果你准备好详细描述一个技术问题,请[$1 报告bug]。或者你可以使用下面的简单表格。你的评论将被添加至页面“[$3 $2]”,附有你的用户名。",
index 3b1fa48..aaf0d36 100644 (file)
@@ -58,7 +58,8 @@
                        "LNDDYL",
                        "Cathypilot0117",
                        "NigelSoft",
-                       "EagerLin"
+                       "EagerLin",
+                       "Cbliu"
                ]
        },
        "tog-underline": "底線標示連結:",
        "mytalk": "對話",
        "anontalk": "此 IP 位址的對話頁面",
        "navigation": "導覽",
-       "and": "&#32;å\8f\8a&#32;",
+       "and": "&#32;å\92\8c",
        "qbfind": "尋找",
        "qbbrowse": "瀏覽",
        "qbedit": "編輯",
        "qbpageoptions": "此頁面",
        "qbmyoptions": "我的頁面",
        "faq": "常見問題",
-       "faqpage": "Project:FAQ",
+       "faqpage": "Project:常見問題",
        "actions": "動作",
        "namespaces": "命名空間",
        "variants": "變體",
        "disclaimerpage": "Project:General disclaimer",
        "edithelp": "編輯説明",
        "mainpage": "主頁",
-       "mainpage-description": "頁",
+       "mainpage-description": "頁",
        "policy-url": "Project:Policy",
        "portal": "社群入口",
        "portal-url": "Project:Community portal",
        "prefs-personal": "使用者基本資料",
        "prefs-rc": "近期變更",
        "prefs-watchlist": "監視清單",
+       "prefs-editwatchlist": "編輯監視清單",
+       "prefs-editwatchlist-label": "編輯在您監視清單上的項目:",
+       "prefs-editwatchlist-edit": "檢視並移除在您監視清單上的標題",
+       "prefs-editwatchlist-raw": "編輯原始監視清單",
+       "prefs-editwatchlist-clear": "清除您的監視清單",
        "prefs-watchlist-days": "監視清單中顯示的天數:",
        "prefs-watchlist-days-max": "最多 $1 {{PLURAL:$1|天}}",
        "prefs-watchlist-edits": "展開監視清單中顯示的變更數量上限:",
        "right-override-export-depth": "匯出頁面包含連結內容,深度上限為 5 層",
        "right-sendemail": "傳送電子郵件給其他使用者",
        "right-passwordreset": "檢視重設密碼電子郵件",
+       "right-managechangetags": "建立並自資料庫移除[[Special:Tags|標籤]]",
        "newuserlogpage": "建立使用者日誌",
        "newuserlogpagetext": "此為建立使用者的日誌。",
        "rightslog": "使用者權限日誌",
        "action-viewmyprivateinfo": "檢視您的個人資訊",
        "action-editmyprivateinfo": "編輯您的個人資訊",
        "action-editcontentmodel": "編輯頁面的內容模型",
+       "action-managechangetags": "建立並自資料庫移除標籤",
        "nchanges": "$1 次變更",
        "enhancedrc-since-last-visit": "自上次訪問已有 $1",
        "enhancedrc-history": "歷史",
        "tooltip-search-fulltext": "搜尋使用此文字的頁面",
        "tooltip-p-logo": "前往主頁",
        "tooltip-n-mainpage": "前往主頁",
-       "tooltip-n-mainpage-description": "前往頁",
+       "tooltip-n-mainpage-description": "前往頁",
        "tooltip-n-portal": "關於本專案、您可以做什麼、哪裡可以找到您需要的事物",
        "tooltip-n-currentevents": "於最新動態中尋找背景資訊",
        "tooltip-n-recentchanges": "列出此 Wiki 中的近期變更清單",
        "tags-tag": "標籤名稱",
        "tags-display-header": "在變更日誌中顯示的方式",
        "tags-description-header": "意義完整的說明",
+       "tags-source-header": "來源",
        "tags-active-header": "開啟?",
        "tags-hitcount-header": "已標記的變更",
+       "tags-actions-header": "操作",
        "tags-active-yes": "是",
        "tags-active-no": "否",
+       "tags-source-extension": "由擴充套件定義",
+       "tags-source-manual": "由使用者與機器人手動套用",
+       "tags-source-none": "不再使用",
        "tags-edit": "編輯",
+       "tags-delete": "刪除",
+       "tags-activate": "啟動",
+       "tags-deactivate": "停用",
        "tags-hitcount": "$1 次變更",
+       "tags-manage-no-permission": "您沒有權限管理變更標籤。",
+       "tags-create-heading": "建立新標籤",
+       "tags-create-explanation": "在預設情況下,新建立的標籤可被使用者及機器人使用。",
+       "tags-create-tag-name": "標籤名稱:",
+       "tags-create-reason": "原因:",
+       "tags-create-submit": "建立",
+       "tags-create-no-name": "您必須指定一個標籤名稱。",
+       "tags-create-invalid-chars": "標籤名稱不可包含逗號 (<code>,</code>) 或斜線 (<code>/</code>)。",
+       "tags-create-already-exists": "標籤 \"$1\" 已存在。",
+       "tags-create-warnings-below": "您是否要繼續建立標籤?",
+       "tags-delete-title": "刪除標籤",
+       "tags-delete-explanation-initial": "您正要從資料庫刪除標籤 \"$1\"。",
+       "tags-delete-reason": "原因:",
+       "tags-delete-submit": "無法取消刪除此標籤",
+       "tags-delete-not-found": "標籤 \"$1\" 不存在。",
+       "tags-activate-title": "啟動標籤",
+       "tags-activate-question": "您正要啟動標籤 \"$1\"。",
+       "tags-activate-reason": "原因:",
+       "tags-activate-not-allowed": "無法啟動標籤 \"$1\"。",
+       "tags-activate-not-found": "標籤 \"$1\" 不存在。",
+       "tags-activate-submit": "啟動",
+       "tags-deactivate-title": "停用標籤",
+       "tags-deactivate-question": "您正要停用標籤 \"$1\"。",
+       "tags-deactivate-reason": "原因:",
+       "tags-deactivate-not-allowed": "無法停用標籤 \"$1\"。",
+       "tags-deactivate-submit": "停用",
        "comparepages": "比較頁面",
        "compare-page1": "第 1 頁",
        "compare-page2": "第 2 頁",
        "logentry-upload-upload": "$1 {{GENDER:$2|已上傳}} $3",
        "logentry-upload-overwrite": "$1 {{GENDER:$2|上傳了}}新版本的 $3",
        "logentry-upload-revert": "$1 {{GENDER:$2|已上傳}} $3",
+       "log-name-managetags": "標籤管理日誌",
+       "log-description-managetags": "此頁面列出與[[Special:Tags|標籤]]相關的管理工作項目。 在日誌中僅包含由管理員手動所做的操作;被 Wiki 軟體所建立或刪除的標籤項目,不會記錄在此日誌中",
        "rightsnone": "(無)",
        "revdelete-summary": "編輯摘要",
        "feedback-bugornote": "如果您準備要詳細描述一個技術問題,請至 [$1 回報問題]。\n或您可以使用以下的簡易表單回報問題,您的使用者名稱與評論將被新增到頁面 \"[$3 $2]\"。",
index 9b98b20..af14bb3 100644 (file)
@@ -1207,7 +1207,13 @@ abstract class Maintenance {
                }
 
                if ( $isatty && function_exists( 'readline' ) ) {
-                       return readline( $prompt );
+                       $resp = readline( $prompt );
+                       if ( $resp === null ) {
+                               // Workaround for https://github.com/facebook/hhvm/issues/4776
+                               return false;
+                       } else {
+                               return $resp;
+                       }
                } else {
                        if ( $isatty ) {
                                $st = self::readlineEmulation( $prompt );
index a0dee3c..76bc982 100644 (file)
@@ -155,12 +155,36 @@ class ConvertExtensionToRegistration extends Maintenance {
        }
 
        protected function handleResourceModules( $realName, $value ) {
+               $defaults = array();
+               $remote = $this->hasOption( 'skin' ) ? 'remoteSkinPath' : 'remoteExtPath';
                foreach ( $value as $name => $data ) {
                        if ( isset( $data['localBasePath'] ) ) {
                                $data['localBasePath'] = $this->stripPath( $data['localBasePath'], $this->dir );
+                               if ( !$defaults ) {
+                                       $defaults['localBasePath'] = $data['localBasePath'];
+                                       unset( $data['localBasePath'] );
+                                       if ( isset( $data[$remote] ) ) {
+                                               $defaults[$remote] = $data[$remote];
+                                               unset( $data[$remote] );
+                                       }
+                               } else {
+                                       if ( $data['localBasePath'] === $defaults['localBasePath'] ) {
+                                               unset( $data['localBasePath'] );
+                                       }
+                                       if ( isset( $data[$remote] ) && isset( $defaults[$remote] )
+                                               && $data[$remote] === $defaults[$remote]
+                                       ) {
+                                               unset( $data[$remote] );
+                                       }
+                               }
                        }
+
+
                        $this->json[$realName][$name] = $data;
                }
+               if ( $defaults ) {
+                       $this->json['ResourceFileModulePaths'] = $defaults;
+               }
        }
 }
 
index c93a971..cc2167e 100644 (file)
@@ -98,23 +98,18 @@ $maintenance->finalSetup();
 require_once "$IP/includes/Setup.php";
 
 // Do the work
-try {
-       $maintenance->execute();
+$maintenance->execute();
 
-       // Potentially debug globals
-       $maintenance->globals();
+// Potentially debug globals
+$maintenance->globals();
 
-       // Perform deferred updates.
-       DeferredUpdates::doUpdates( 'commit' );
+// Perform deferred updates.
+DeferredUpdates::doUpdates( 'commit' );
 
-       // log profiling info
-       wfLogProfilingData();
+// log profiling info
+wfLogProfilingData();
 
-       // Commit and close up!
-       $factory = wfGetLBFactory();
-       $factory->commitMasterChanges();
-       $factory->shutdown();
-} catch ( Exception $mwe ) {
-       echo $mwe->getText();
-       exit( 1 );
-}
+// Commit and close up!
+$factory = wfGetLBFactory();
+$factory->commitMasterChanges();
+$factory->shutdown();
index e20c477..3f10a33 100644 (file)
@@ -60,6 +60,11 @@ if ( $__useReadline ) {
        readline_read_history( $__historyFile );
 }
 
+$__phpPath = preg_match( '/Zend Engine|HipHop VM/', wfShellExecWithStderr( 'php --version' ) )
+       ? 'php' //standard system path name
+       : ''; // not accessible somehow
+
+$__multiLine = '';
 $__e = null; // PHP exception
 while ( ( $__line = Maintenance::readconsole() ) !== false ) {
        if ( $__e && !preg_match( '/^(exit|die);?$/', $__line ) ) {
@@ -74,8 +79,18 @@ while ( ( $__line = Maintenance::readconsole() ) !== false ) {
                readline_add_history( $__line );
                readline_write_history( $__historyFile );
        }
+       // Try to only run PHP once a valid chunk is formed (deals with newlines)
+       if ( $__phpPath ) {
+               $res = wfShellExecWithStderr(
+                       "echo " . wfEscapeShellArg( "<?php\n{$__multiLine}{$__line}" ) . " | php -l" );
+               if ( strpos( $res, 'No syntax errors' ) !== 0 && substr( $__multiLine, -2 ) !== "\n\n" ) {
+                       $__multiLine .= "$__line\n";
+                       continue;
+               }
+       }
        try {
-               $__val = eval( $__line . ";" );
+               $__val = eval( $__multiLine . $__line . ";" );
+               $__multiLine = '';
        } catch ( Exception $__e ) {
                echo "Caught exception " . get_class( $__e ) .
                        ": {$__e->getMessage()}\n" . $__e->getTraceAsString() . "\n";
index 40605ce..6abfb66 100644 (file)
@@ -68,7 +68,7 @@ class RunJobs extends Maintenance {
 
                $json = ( $this->getOption( 'result' ) === 'json' );
 
-               $runner = new JobRunner();
+               $runner = new JobRunner( MWLoggerFactory::getInstance( 'runJobs' ) );
                if ( !$json ) {
                        $runner->setDebugHandler( array( $this, 'debugInternal' ) );
                }
index cfffbbc..3cb4a2b 100644 (file)
@@ -50,9 +50,15 @@ require_once __DIR__ . '/../Maintenance.php';
  */
 class CompressOld extends Maintenance {
        /**
-        * @todo document
+        * Option to load each revision individually.
+        *
         */
        const LS_INDIVIDUAL = 0;
+
+       /**
+        * Option to load revisions in chunks.
+        *
+        */
        const LS_CHUNKED = 1;
 
        public function __construct() {
@@ -137,7 +143,8 @@ class CompressOld extends Maintenance {
        }
 
        /**
-        * @todo document
+        * Fetch the text row-by-row to 'compressPage' function for compression.
+        *
         * @param int $start
         * @param string $extdb
         */
@@ -172,7 +179,8 @@ class CompressOld extends Maintenance {
        }
 
        /**
-        * @todo document
+        * Compress the text in gzip format.
+        *
         * @param stdClass $row
         * @param string $extdb
         * @return bool
@@ -214,6 +222,8 @@ class CompressOld extends Maintenance {
        }
 
        /**
+        * Compress the text in chunks after concatenating the revisions.
+        *
         * @param int $startId
         * @param int $maxChunkSize
         * @param string $beginDate
index 348fb77..ab59cb8 100644 (file)
@@ -25,7 +25,6 @@ define( 'REPORTING_INTERVAL', 1 );
 
 if ( !defined( 'MEDIAWIKI' ) ) {
        require_once __DIR__ . '/../commandLine.inc';
-       require_once __DIR__ . '/../../includes/externalstore/ExternalStoreDB.php';
        require_once 'resolveStubs.php';
 
        $fname = 'moveToExternal';
index 290f164..36741cb 100644 (file)
@@ -22,8 +22,6 @@
  * @ingroup Maintenance ExternalStorage
  */
 
-define( 'REPORTING_INTERVAL', 100 );
-
 if ( !defined( 'MEDIAWIKI' ) ) {
        $optionsWithArgs = array( 'm' );
 
index 6bbcf39..4ef12ba 100644 (file)
@@ -5,17 +5,17 @@
     "test": "grunt test"
   },
   "devDependencies": {
-    "grunt": "0.4.2",
+    "grunt": "0.4.5",
     "grunt-banana-checker": "0.2.0",
-    "grunt-contrib-jshint": "0.10.0",
+    "grunt-contrib-jshint": "0.11.0",
     "grunt-contrib-watch": "0.6.1",
-    "grunt-jscs": "0.8.1",
+    "grunt-jscs": "1.5.0",
     "grunt-jsonlint": "1.0.4",
-    "grunt-karma": "0.9.0",
+    "grunt-karma": "0.10.1",
     "karma": "0.12.31",
     "karma-chrome-launcher": "0.1.7",
-    "karma-firefox-launcher": "0.1.3",
+    "karma-firefox-launcher": "0.1.4",
     "karma-qunit": "0.1.4",
-    "qunitjs": "1.15.0"
+    "qunitjs": "1.17.1"
   }
 }
index 4e3fb5a..f172cfb 100644 (file)
@@ -36,7 +36,7 @@ header( 'Content-Type: text/html; charset=utf-8' );
 <!DOCTYPE html>
 <html>
 <head>
-       <meta charset="UTF-8">
+       <meta charset="UTF-8" />
        <title>Profiling data</title>
        <style>
                /* noc.wikimedia.org/base.css */
@@ -422,7 +422,7 @@ if ( isset( $_REQUEST['filter'] ) ) {
        ?>
        </tbody>
 </table>
-<hr>
+<hr />
 <p>Total time: <code><?php printf( '%5.02f', profile_point::$totaltime ); ?></code></p>
 
 <p>Total memory: <code><?php printf( '%5.02f', profile_point::$totalmemory / 1024 ); ?></code></p>
index 6e8cd99..233485c 100644 (file)
@@ -266,8 +266,8 @@ return array(
                'targets' => array( 'desktop', 'mobile' ),
        ),
        'jquery.qunit' => array(
-               'scripts' => 'resources/lib/jquery/jquery.qunit.js',
-               'styles' => 'resources/lib/jquery/jquery.qunit.css',
+               'scripts' => 'resources/lib/qunitjs/qunit.js',
+               'styles' => 'resources/lib/qunitjs/qunit.css',
                'position' => 'top',
                'targets' => array( 'desktop', 'mobile' ),
        ),
@@ -765,7 +765,10 @@ return array(
        /* MediaWiki */
 
        'mediawiki' => array(
-               'scripts' => 'resources/src/mediawiki/mediawiki.js',
+               'scripts' => array(
+                       'resources/src/mediawiki/mediawiki.js',
+                       'resources/src/mediawiki/mediawiki.startUp.js',
+               ),
                'debugScripts' => 'resources/src/mediawiki/mediawiki.log.js',
                'raw' => true,
                'targets' => array( 'desktop', 'mobile' ),
@@ -1073,7 +1076,9 @@ return array(
        'mediawiki.action.history.diff' => array(
                'styles' => array(
                        'resources/src/mediawiki.action/mediawiki.action.history.diff.css',
-                       'resources/src/mediawiki.action/mediawiki.action.history.diff.print.css' => array( 'media' => 'print' ),
+                       'resources/src/mediawiki.action/mediawiki.action.history.diff.print.css' => array(
+                               'media' => 'print'
+                       ),
                ),
                'group' => 'mediawiki.action.history',
                'targets' => array( 'desktop', 'mobile' ),
diff --git a/resources/lib/jquery/jquery.qunit.css b/resources/lib/jquery/jquery.qunit.css
deleted file mode 100644 (file)
index 385a1ce..0000000
+++ /dev/null
@@ -1,264 +0,0 @@
-/*!
- * QUnit 1.16.0
- * http://qunitjs.com/
- *
- * Copyright 2006, 2014 jQuery Foundation and other contributors
- * Released under the MIT license
- * http://jquery.org/license
- *
- * Date: 2014-12-03T16:32Z
- */
-
-/** Font Family and Sizes */
-
-#qunit-tests, #qunit-header, #qunit-banner, #qunit-testrunner-toolbar, #qunit-userAgent, #qunit-testresult {
-       font-family: "Helvetica Neue Light", "HelveticaNeue-Light", "Helvetica Neue", Calibri, Helvetica, Arial, sans-serif;
-}
-
-#qunit-testrunner-toolbar, #qunit-userAgent, #qunit-testresult, #qunit-tests li { font-size: small; }
-#qunit-tests { font-size: smaller; }
-
-
-/** Resets */
-
-#qunit-tests, #qunit-header, #qunit-banner, #qunit-userAgent, #qunit-testresult, #qunit-modulefilter {
-       margin: 0;
-       padding: 0;
-}
-
-
-/** Header */
-
-#qunit-header {
-       padding: 0.5em 0 0.5em 1em;
-
-       color: #8699A4;
-       background-color: #0D3349;
-
-       font-size: 1.5em;
-       line-height: 1em;
-       font-weight: 400;
-
-       border-radius: 5px 5px 0 0;
-}
-
-#qunit-header a {
-       text-decoration: none;
-       color: #C2CCD1;
-}
-
-#qunit-header a:hover,
-#qunit-header a:focus {
-       color: #FFF;
-}
-
-#qunit-testrunner-toolbar label {
-       display: inline-block;
-       padding: 0 0.5em 0 0.1em;
-}
-
-#qunit-banner {
-       height: 5px;
-}
-
-#qunit-testrunner-toolbar {
-       padding: 0.5em 1em 0.5em 1em;
-       color: #5E740B;
-       background-color: #EEE;
-       overflow: hidden;
-}
-
-#qunit-userAgent {
-       padding: 0.5em 1em 0.5em 1em;
-       background-color: #2B81AF;
-       color: #FFF;
-       text-shadow: rgba(0, 0, 0, 0.5) 2px 2px 1px;
-}
-
-#qunit-modulefilter-container {
-       float: right;
-}
-
-/** Tests: Pass/Fail */
-
-#qunit-tests {
-       list-style-position: inside;
-}
-
-#qunit-tests li {
-       padding: 0.4em 1em 0.4em 1em;
-       border-bottom: 1px solid #FFF;
-       list-style-position: inside;
-}
-
-#qunit-tests > li {
-       display: none;
-}
-
-#qunit-tests li.pass, #qunit-tests li.running, #qunit-tests li.fail {
-       display: list-item;
-}
-
-#qunit-tests.hidepass li.pass, #qunit-tests.hidepass li.running  {
-       display: none;
-}
-
-#qunit-tests li strong {
-       cursor: pointer;
-}
-
-#qunit-tests li.skipped strong {
-       cursor: default;
-}
-
-#qunit-tests li a {
-       padding: 0.5em;
-       color: #C2CCD1;
-       text-decoration: none;
-}
-#qunit-tests li a:hover,
-#qunit-tests li a:focus {
-       color: #000;
-}
-
-#qunit-tests li .runtime {
-       float: right;
-       font-size: smaller;
-}
-
-.qunit-assert-list {
-       margin-top: 0.5em;
-       padding: 0.5em;
-
-       background-color: #FFF;
-
-       border-radius: 5px;
-}
-
-.qunit-collapsed {
-       display: none;
-}
-
-#qunit-tests table {
-       border-collapse: collapse;
-       margin-top: 0.2em;
-}
-
-#qunit-tests th {
-       text-align: right;
-       vertical-align: top;
-       padding: 0 0.5em 0 0;
-}
-
-#qunit-tests td {
-       vertical-align: top;
-}
-
-#qunit-tests pre {
-       margin: 0;
-       white-space: pre-wrap;
-       word-wrap: break-word;
-}
-
-#qunit-tests del {
-       background-color: #E0F2BE;
-       color: #374E0C;
-       text-decoration: none;
-}
-
-#qunit-tests ins {
-       background-color: #FFCACA;
-       color: #500;
-       text-decoration: none;
-}
-
-/*** Test Counts */
-
-#qunit-tests b.counts                       { color: #000; }
-#qunit-tests b.passed                       { color: #5E740B; }
-#qunit-tests b.failed                       { color: #710909; }
-
-#qunit-tests li li {
-       padding: 5px;
-       background-color: #FFF;
-       border-bottom: none;
-       list-style-position: inside;
-}
-
-/*** Passing Styles */
-
-#qunit-tests li li.pass {
-       color: #3C510C;
-       background-color: #FFF;
-       border-left: 10px solid #C6E746;
-}
-
-#qunit-tests .pass                          { color: #528CE0; background-color: #D2E0E6; }
-#qunit-tests .pass .test-name               { color: #366097; }
-
-#qunit-tests .pass .test-actual,
-#qunit-tests .pass .test-expected           { color: #999; }
-
-#qunit-banner.qunit-pass                    { background-color: #C6E746; }
-
-/*** Failing Styles */
-
-#qunit-tests li li.fail {
-       color: #710909;
-       background-color: #FFF;
-       border-left: 10px solid #EE5757;
-       white-space: pre;
-}
-
-#qunit-tests > li:last-child {
-       border-radius: 0 0 5px 5px;
-}
-
-#qunit-tests .fail                          { color: #000; background-color: #EE5757; }
-#qunit-tests .fail .test-name,
-#qunit-tests .fail .module-name             { color: #000; }
-
-#qunit-tests .fail .test-actual             { color: #EE5757; }
-#qunit-tests .fail .test-expected           { color: #008000; }
-
-#qunit-banner.qunit-fail                    { background-color: #EE5757; }
-
-/*** Skipped tests */
-
-#qunit-tests .skipped {
-       background-color: #EBECE9;
-}
-
-#qunit-tests .qunit-skipped-label {
-       background-color: #F4FF77;
-       display: inline-block;
-       font-style: normal;
-       color: #366097;
-       line-height: 1.8em;
-       padding: 0 0.5em;
-       margin: -0.4em 0.4em -0.4em 0;
-}
-
-/** Result */
-
-#qunit-testresult {
-       padding: 0.5em 1em 0.5em 1em;
-
-       color: #2B81AF;
-       background-color: #D2E0E6;
-
-       border-bottom: 1px solid #FFF;
-}
-#qunit-testresult .module-name {
-       font-weight: 700;
-}
-
-/** Fixture */
-
-#qunit-fixture {
-       position: absolute;
-       top: -10000px;
-       left: -10000px;
-       width: 1000px;
-       height: 1000px;
-}
diff --git a/resources/lib/jquery/jquery.qunit.js b/resources/lib/jquery/jquery.qunit.js
deleted file mode 100644 (file)
index 82020d4..0000000
+++ /dev/null
@@ -1,2819 +0,0 @@
-/*!
- * QUnit 1.16.0
- * http://qunitjs.com/
- *
- * Copyright 2006, 2014 jQuery Foundation and other contributors
- * Released under the MIT license
- * http://jquery.org/license
- *
- * Date: 2014-12-03T16:32Z
- */
-
-(function( window ) {
-
-var QUnit,
-       config,
-       onErrorFnPrev,
-       loggingCallbacks = {},
-       fileName = ( sourceFromStacktrace( 0 ) || "" ).replace( /(:\d+)+\)?/, "" ).replace( /.+\//, "" ),
-       toString = Object.prototype.toString,
-       hasOwn = Object.prototype.hasOwnProperty,
-       // Keep a local reference to Date (GH-283)
-       Date = window.Date,
-       now = Date.now || function() {
-               return new Date().getTime();
-       },
-       globalStartCalled = false,
-       runStarted = false,
-       setTimeout = window.setTimeout,
-       clearTimeout = window.clearTimeout,
-       defined = {
-               document: window.document !== undefined,
-               setTimeout: window.setTimeout !== undefined,
-               sessionStorage: (function() {
-                       var x = "qunit-test-string";
-                       try {
-                               sessionStorage.setItem( x, x );
-                               sessionStorage.removeItem( x );
-                               return true;
-                       } catch ( e ) {
-                               return false;
-                       }
-               }())
-       },
-       /**
-        * Provides a normalized error string, correcting an issue
-        * with IE 7 (and prior) where Error.prototype.toString is
-        * not properly implemented
-        *
-        * Based on http://es5.github.com/#x15.11.4.4
-        *
-        * @param {String|Error} error
-        * @return {String} error message
-        */
-       errorString = function( error ) {
-               var name, message,
-                       errorString = error.toString();
-               if ( errorString.substring( 0, 7 ) === "[object" ) {
-                       name = error.name ? error.name.toString() : "Error";
-                       message = error.message ? error.message.toString() : "";
-                       if ( name && message ) {
-                               return name + ": " + message;
-                       } else if ( name ) {
-                               return name;
-                       } else if ( message ) {
-                               return message;
-                       } else {
-                               return "Error";
-                       }
-               } else {
-                       return errorString;
-               }
-       },
-       /**
-        * Makes a clone of an object using only Array or Object as base,
-        * and copies over the own enumerable properties.
-        *
-        * @param {Object} obj
-        * @return {Object} New object with only the own properties (recursively).
-        */
-       objectValues = function( obj ) {
-               var key, val,
-                       vals = QUnit.is( "array", obj ) ? [] : {};
-               for ( key in obj ) {
-                       if ( hasOwn.call( obj, key ) ) {
-                               val = obj[ key ];
-                               vals[ key ] = val === Object( val ) ? objectValues( val ) : val;
-                       }
-               }
-               return vals;
-       };
-
-QUnit = {};
-
-/**
- * Config object: Maintain internal state
- * Later exposed as QUnit.config
- * `config` initialized at top of scope
- */
-config = {
-       // The queue of tests to run
-       queue: [],
-
-       // block until document ready
-       blocking: true,
-
-       // when enabled, show only failing tests
-       // gets persisted through sessionStorage and can be changed in UI via checkbox
-       hidepassed: false,
-
-       // by default, run previously failed tests first
-       // very useful in combination with "Hide passed tests" checked
-       reorder: true,
-
-       // by default, modify document.title when suite is done
-       altertitle: true,
-
-       // by default, scroll to top of the page when suite is done
-       scrolltop: true,
-
-       // when enabled, all tests must call expect()
-       requireExpects: false,
-
-       // add checkboxes that are persisted in the query-string
-       // when enabled, the id is set to `true` as a `QUnit.config` property
-       urlConfig: [
-               {
-                       id: "hidepassed",
-                       label: "Hide passed tests",
-                       tooltip: "Only show tests and assertions that fail. Stored as query-strings."
-               },
-               {
-                       id: "noglobals",
-                       label: "Check for Globals",
-                       tooltip: "Enabling this will test if any test introduces new properties on the " +
-                               "`window` object. Stored as query-strings."
-               },
-               {
-                       id: "notrycatch",
-                       label: "No try-catch",
-                       tooltip: "Enabling this will run tests outside of a try-catch block. Makes debugging " +
-                               "exceptions in IE reasonable. Stored as query-strings."
-               }
-       ],
-
-       // Set of all modules.
-       modules: [],
-
-       // The first unnamed module
-       currentModule: {
-               name: "",
-               tests: []
-       },
-
-       callbacks: {}
-};
-
-// Push a loose unnamed module to the modules collection
-config.modules.push( config.currentModule );
-
-// Initialize more QUnit.config and QUnit.urlParams
-(function() {
-       var i, current,
-               location = window.location || { search: "", protocol: "file:" },
-               params = location.search.slice( 1 ).split( "&" ),
-               length = params.length,
-               urlParams = {};
-
-       if ( params[ 0 ] ) {
-               for ( i = 0; i < length; i++ ) {
-                       current = params[ i ].split( "=" );
-                       current[ 0 ] = decodeURIComponent( current[ 0 ] );
-
-                       // allow just a key to turn on a flag, e.g., test.html?noglobals
-                       current[ 1 ] = current[ 1 ] ? decodeURIComponent( current[ 1 ] ) : true;
-                       if ( urlParams[ current[ 0 ] ] ) {
-                               urlParams[ current[ 0 ] ] = [].concat( urlParams[ current[ 0 ] ], current[ 1 ] );
-                       } else {
-                               urlParams[ current[ 0 ] ] = current[ 1 ];
-                       }
-               }
-       }
-
-       QUnit.urlParams = urlParams;
-
-       // String search anywhere in moduleName+testName
-       config.filter = urlParams.filter;
-
-       config.testId = [];
-       if ( urlParams.testId ) {
-
-               // Ensure that urlParams.testId is an array
-               urlParams.testId = [].concat( urlParams.testId );
-               for ( i = 0; i < urlParams.testId.length; i++ ) {
-                       config.testId.push( urlParams.testId[ i ] );
-               }
-       }
-
-       // Figure out if we're running the tests from a server or not
-       QUnit.isLocal = location.protocol === "file:";
-}());
-
-// Root QUnit object.
-// `QUnit` initialized at top of scope
-extend( QUnit, {
-
-       // call on start of module test to prepend name to all tests
-       module: function( name, testEnvironment ) {
-               var currentModule = {
-                       name: name,
-                       testEnvironment: testEnvironment,
-                       tests: []
-               };
-
-               // DEPRECATED: handles setup/teardown functions,
-               // beforeEach and afterEach should be used instead
-               if ( testEnvironment && testEnvironment.setup ) {
-                       testEnvironment.beforeEach = testEnvironment.setup;
-                       delete testEnvironment.setup;
-               }
-               if ( testEnvironment && testEnvironment.teardown ) {
-                       testEnvironment.afterEach = testEnvironment.teardown;
-                       delete testEnvironment.teardown;
-               }
-
-               config.modules.push( currentModule );
-               config.currentModule = currentModule;
-       },
-
-       // DEPRECATED: QUnit.asyncTest() will be removed in QUnit 2.0.
-       asyncTest: function( testName, expected, callback ) {
-               if ( arguments.length === 2 ) {
-                       callback = expected;
-                       expected = null;
-               }
-
-               QUnit.test( testName, expected, callback, true );
-       },
-
-       test: function( testName, expected, callback, async ) {
-               var test;
-
-               if ( arguments.length === 2 ) {
-                       callback = expected;
-                       expected = null;
-               }
-
-               test = new Test({
-                       testName: testName,
-                       expected: expected,
-                       async: async,
-                       callback: callback
-               });
-
-               test.queue();
-       },
-
-       skip: function( testName ) {
-               var test = new Test({
-                       testName: testName,
-                       skip: true
-               });
-
-               test.queue();
-       },
-
-       // DEPRECATED: The functionality of QUnit.start() will be altered in QUnit 2.0.
-       // In QUnit 2.0, invoking it will ONLY affect the `QUnit.config.autostart` blocking behavior.
-       start: function( count ) {
-               var globalStartAlreadyCalled = globalStartCalled;
-
-               if ( !config.current ) {
-                       globalStartCalled = true;
-
-                       if ( runStarted ) {
-                               throw new Error( "Called start() outside of a test context while already started" );
-                       } else if ( globalStartAlreadyCalled || count > 1 ) {
-                               throw new Error( "Called start() outside of a test context too many times" );
-                       } else if ( config.autostart ) {
-                               throw new Error( "Called start() outside of a test context when " +
-                                       "QUnit.config.autostart was true" );
-                       } else if ( !config.pageLoaded ) {
-
-                               // The page isn't completely loaded yet, so bail out and let `QUnit.load` handle it
-                               config.autostart = true;
-                               return;
-                       }
-               } else {
-
-                       // If a test is running, adjust its semaphore
-                       config.current.semaphore -= count || 1;
-
-                       // Don't start until equal number of stop-calls
-                       if ( config.current.semaphore > 0 ) {
-                               return;
-                       }
-
-                       // throw an Error if start is called more often than stop
-                       if ( config.current.semaphore < 0 ) {
-                               config.current.semaphore = 0;
-
-                               QUnit.pushFailure(
-                                       "Called start() while already started (test's semaphore was 0 already)",
-                                       sourceFromStacktrace( 2 )
-                               );
-                               return;
-                       }
-               }
-
-               resumeProcessing();
-       },
-
-       // DEPRECATED: QUnit.stop() will be removed in QUnit 2.0.
-       stop: function( count ) {
-
-               // If there isn't a test running, don't allow QUnit.stop() to be called
-               if ( !config.current ) {
-                       throw new Error( "Called stop() outside of a test context" );
-               }
-
-               // If a test is running, adjust its semaphore
-               config.current.semaphore += count || 1;
-
-               pauseProcessing();
-       },
-
-       config: config,
-
-       // Safe object type checking
-       is: function( type, obj ) {
-               return QUnit.objectType( obj ) === type;
-       },
-
-       objectType: function( obj ) {
-               if ( typeof obj === "undefined" ) {
-                       return "undefined";
-               }
-
-               // Consider: typeof null === object
-               if ( obj === null ) {
-                       return "null";
-               }
-
-               var match = toString.call( obj ).match( /^\[object\s(.*)\]$/ ),
-                       type = match && match[ 1 ] || "";
-
-               switch ( type ) {
-                       case "Number":
-                               if ( isNaN( obj ) ) {
-                                       return "nan";
-                               }
-                               return "number";
-                       case "String":
-                       case "Boolean":
-                       case "Array":
-                       case "Date":
-                       case "RegExp":
-                       case "Function":
-                               return type.toLowerCase();
-               }
-               if ( typeof obj === "object" ) {
-                       return "object";
-               }
-               return undefined;
-       },
-
-       url: function( params ) {
-               params = extend( extend( {}, QUnit.urlParams ), params );
-               var key,
-                       querystring = "?";
-
-               for ( key in params ) {
-                       if ( hasOwn.call( params, key ) ) {
-                               querystring += encodeURIComponent( key );
-                               if ( params[ key ] !== true ) {
-                                       querystring += "=" + encodeURIComponent( params[ key ] );
-                               }
-                               querystring += "&";
-                       }
-               }
-               return location.protocol + "//" + location.host +
-                       location.pathname + querystring.slice( 0, -1 );
-       },
-
-       extend: extend,
-
-       load: function() {
-               config.pageLoaded = true;
-
-               // Initialize the configuration options
-               extend( config, {
-                       stats: { all: 0, bad: 0 },
-                       moduleStats: { all: 0, bad: 0 },
-                       started: 0,
-                       updateRate: 1000,
-                       autostart: true,
-                       filter: ""
-               }, true );
-
-               config.blocking = false;
-
-               if ( config.autostart ) {
-                       resumeProcessing();
-               }
-       }
-});
-
-// Register logging callbacks
-(function() {
-       var i, l, key,
-               callbacks = [ "begin", "done", "log", "testStart", "testDone",
-                       "moduleStart", "moduleDone" ];
-
-       function registerLoggingCallback( key ) {
-               var loggingCallback = function( callback ) {
-                       if ( QUnit.objectType( callback ) !== "function" ) {
-                               throw new Error(
-                                       "QUnit logging methods require a callback function as their first parameters."
-                               );
-                       }
-
-                       config.callbacks[ key ].push( callback );
-               };
-
-               // DEPRECATED: This will be removed on QUnit 2.0.0+
-               // Stores the registered functions allowing restoring
-               // at verifyLoggingCallbacks() if modified
-               loggingCallbacks[ key ] = loggingCallback;
-
-               return loggingCallback;
-       }
-
-       for ( i = 0, l = callbacks.length; i < l; i++ ) {
-               key = callbacks[ i ];
-
-               // Initialize key collection of logging callback
-               if ( QUnit.objectType( config.callbacks[ key ] ) === "undefined" ) {
-                       config.callbacks[ key ] = [];
-               }
-
-               QUnit[ key ] = registerLoggingCallback( key );
-       }
-})();
-
-// `onErrorFnPrev` initialized at top of scope
-// Preserve other handlers
-onErrorFnPrev = window.onerror;
-
-// Cover uncaught exceptions
-// Returning true will suppress the default browser handler,
-// returning false will let it run.
-window.onerror = function( error, filePath, linerNr ) {
-       var ret = false;
-       if ( onErrorFnPrev ) {
-               ret = onErrorFnPrev( error, filePath, linerNr );
-       }
-
-       // Treat return value as window.onerror itself does,
-       // Only do our handling if not suppressed.
-       if ( ret !== true ) {
-               if ( QUnit.config.current ) {
-                       if ( QUnit.config.current.ignoreGlobalErrors ) {
-                               return true;
-                       }
-                       QUnit.pushFailure( error, filePath + ":" + linerNr );
-               } else {
-                       QUnit.test( "global failure", extend(function() {
-                               QUnit.pushFailure( error, filePath + ":" + linerNr );
-                       }, { validTest: true } ) );
-               }
-               return false;
-       }
-
-       return ret;
-};
-
-function done() {
-       var runtime, passed;
-
-       config.autorun = true;
-
-       // Log the last module results
-       if ( config.previousModule ) {
-               runLoggingCallbacks( "moduleDone", {
-                       name: config.previousModule.name,
-                       tests: config.previousModule.tests,
-                       failed: config.moduleStats.bad,
-                       passed: config.moduleStats.all - config.moduleStats.bad,
-                       total: config.moduleStats.all,
-                       runtime: now() - config.moduleStats.started
-               });
-       }
-       delete config.previousModule;
-
-       runtime = now() - config.started;
-       passed = config.stats.all - config.stats.bad;
-
-       runLoggingCallbacks( "done", {
-               failed: config.stats.bad,
-               passed: passed,
-               total: config.stats.all,
-               runtime: runtime
-       });
-}
-
-// Doesn't support IE6 to IE9
-// See also https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Error/Stack
-function extractStacktrace( e, offset ) {
-       offset = offset === undefined ? 4 : offset;
-
-       var stack, include, i;
-
-       if ( e.stacktrace ) {
-
-               // Opera 12.x
-               return e.stacktrace.split( "\n" )[ offset + 3 ];
-       } else if ( e.stack ) {
-
-               // Firefox, Chrome, Safari 6+, IE10+, PhantomJS and Node
-               stack = e.stack.split( "\n" );
-               if ( /^error$/i.test( stack[ 0 ] ) ) {
-                       stack.shift();
-               }
-               if ( fileName ) {
-                       include = [];
-                       for ( i = offset; i < stack.length; i++ ) {
-                               if ( stack[ i ].indexOf( fileName ) !== -1 ) {
-                                       break;
-                               }
-                               include.push( stack[ i ] );
-                       }
-                       if ( include.length ) {
-                               return include.join( "\n" );
-                       }
-               }
-               return stack[ offset ];
-       } else if ( e.sourceURL ) {
-
-               // Safari < 6
-               // exclude useless self-reference for generated Error objects
-               if ( /qunit.js$/.test( e.sourceURL ) ) {
-                       return;
-               }
-
-               // for actual exceptions, this is useful
-               return e.sourceURL + ":" + e.line;
-       }
-}
-
-function sourceFromStacktrace( offset ) {
-       var e = new Error();
-       if ( !e.stack ) {
-               try {
-                       throw e;
-               } catch ( err ) {
-                       // This should already be true in most browsers
-                       e = err;
-               }
-       }
-       return extractStacktrace( e, offset );
-}
-
-function synchronize( callback, last ) {
-       if ( QUnit.objectType( callback ) === "array" ) {
-               while ( callback.length ) {
-                       synchronize( callback.shift() );
-               }
-               return;
-       }
-       config.queue.push( callback );
-
-       if ( config.autorun && !config.blocking ) {
-               process( last );
-       }
-}
-
-function process( last ) {
-       function next() {
-               process( last );
-       }
-       var start = now();
-       config.depth = config.depth ? config.depth + 1 : 1;
-
-       while ( config.queue.length && !config.blocking ) {
-               if ( !defined.setTimeout || config.updateRate <= 0 ||
-                               ( ( now() - start ) < config.updateRate ) ) {
-                       if ( config.current ) {
-
-                               // Reset async tracking for each phase of the Test lifecycle
-                               config.current.usedAsync = false;
-                       }
-                       config.queue.shift()();
-               } else {
-                       setTimeout( next, 13 );
-                       break;
-               }
-       }
-       config.depth--;
-       if ( last && !config.blocking && !config.queue.length && config.depth === 0 ) {
-               done();
-       }
-}
-
-function begin() {
-       var i, l,
-               modulesLog = [];
-
-       // If the test run hasn't officially begun yet
-       if ( !config.started ) {
-
-               // Record the time of the test run's beginning
-               config.started = now();
-
-               verifyLoggingCallbacks();
-
-               // Delete the loose unnamed module if unused.
-               if ( config.modules[ 0 ].name === "" && config.modules[ 0 ].tests.length === 0 ) {
-                       config.modules.shift();
-               }
-
-               // Avoid unnecessary information by not logging modules' test environments
-               for ( i = 0, l = config.modules.length; i < l; i++ ) {
-                       modulesLog.push({
-                               name: config.modules[ i ].name,
-                               tests: config.modules[ i ].tests
-                       });
-               }
-
-               // The test run is officially beginning now
-               runLoggingCallbacks( "begin", {
-                       totalTests: Test.count,
-                       modules: modulesLog
-               });
-       }
-
-       config.blocking = false;
-       process( true );
-}
-
-function resumeProcessing() {
-       runStarted = true;
-
-       // A slight delay to allow this iteration of the event loop to finish (more assertions, etc.)
-       if ( defined.setTimeout ) {
-               setTimeout(function() {
-                       if ( config.current && config.current.semaphore > 0 ) {
-                               return;
-                       }
-                       if ( config.timeout ) {
-                               clearTimeout( config.timeout );
-                       }
-
-                       begin();
-               }, 13 );
-       } else {
-               begin();
-       }
-}
-
-function pauseProcessing() {
-       config.blocking = true;
-
-       if ( config.testTimeout && defined.setTimeout ) {
-               clearTimeout( config.timeout );
-               config.timeout = setTimeout(function() {
-                       if ( config.current ) {
-                               config.current.semaphore = 0;
-                               QUnit.pushFailure( "Test timed out", sourceFromStacktrace( 2 ) );
-                       } else {
-                               throw new Error( "Test timed out" );
-                       }
-                       resumeProcessing();
-               }, config.testTimeout );
-       }
-}
-
-function saveGlobal() {
-       config.pollution = [];
-
-       if ( config.noglobals ) {
-               for ( var key in window ) {
-                       if ( hasOwn.call( window, key ) ) {
-                               // in Opera sometimes DOM element ids show up here, ignore them
-                               if ( /^qunit-test-output/.test( key ) ) {
-                                       continue;
-                               }
-                               config.pollution.push( key );
-                       }
-               }
-       }
-}
-
-function checkPollution() {
-       var newGlobals,
-               deletedGlobals,
-               old = config.pollution;
-
-       saveGlobal();
-
-       newGlobals = diff( config.pollution, old );
-       if ( newGlobals.length > 0 ) {
-               QUnit.pushFailure( "Introduced global variable(s): " + newGlobals.join( ", " ) );
-       }
-
-       deletedGlobals = diff( old, config.pollution );
-       if ( deletedGlobals.length > 0 ) {
-               QUnit.pushFailure( "Deleted global variable(s): " + deletedGlobals.join( ", " ) );
-       }
-}
-
-// returns a new Array with the elements that are in a but not in b
-function diff( a, b ) {
-       var i, j,
-               result = a.slice();
-
-       for ( i = 0; i < result.length; i++ ) {
-               for ( j = 0; j < b.length; j++ ) {
-                       if ( result[ i ] === b[ j ] ) {
-                               result.splice( i, 1 );
-                               i--;
-                               break;
-                       }
-               }
-       }
-       return result;
-}
-
-function extend( a, b, undefOnly ) {
-       for ( var prop in b ) {
-               if ( hasOwn.call( b, prop ) ) {
-
-                       // Avoid "Member not found" error in IE8 caused by messing with window.constructor
-                       if ( !( prop === "constructor" && a === window ) ) {
-                               if ( b[ prop ] === undefined ) {
-                                       delete a[ prop ];
-                               } else if ( !( undefOnly && typeof a[ prop ] !== "undefined" ) ) {
-                                       a[ prop ] = b[ prop ];
-                               }
-                       }
-               }
-       }
-
-       return a;
-}
-
-function runLoggingCallbacks( key, args ) {
-       var i, l, callbacks;
-
-       callbacks = config.callbacks[ key ];
-       for ( i = 0, l = callbacks.length; i < l; i++ ) {
-               callbacks[ i ]( args );
-       }
-}
-
-// DEPRECATED: This will be removed on 2.0.0+
-// This function verifies if the loggingCallbacks were modified by the user
-// If so, it will restore it, assign the given callback and print a console warning
-function verifyLoggingCallbacks() {
-       var loggingCallback, userCallback;
-
-       for ( loggingCallback in loggingCallbacks ) {
-               if ( QUnit[ loggingCallback ] !== loggingCallbacks[ loggingCallback ] ) {
-
-                       userCallback = QUnit[ loggingCallback ];
-
-                       // Restore the callback function
-                       QUnit[ loggingCallback ] = loggingCallbacks[ loggingCallback ];
-
-                       // Assign the deprecated given callback
-                       QUnit[ loggingCallback ]( userCallback );
-
-                       if ( window.console && window.console.warn ) {
-                               window.console.warn(
-                                       "QUnit." + loggingCallback + " was replaced with a new value.\n" +
-                                       "Please, check out the documentation on how to apply logging callbacks.\n" +
-                                       "Reference: http://api.qunitjs.com/category/callbacks/"
-                               );
-                       }
-               }
-       }
-}
-
-// from jquery.js
-function inArray( elem, array ) {
-       if ( array.indexOf ) {
-               return array.indexOf( elem );
-       }
-
-       for ( var i = 0, length = array.length; i < length; i++ ) {
-               if ( array[ i ] === elem ) {
-                       return i;
-               }
-       }
-
-       return -1;
-}
-
-function Test( settings ) {
-       var i, l;
-
-       ++Test.count;
-
-       extend( this, settings );
-       this.assertions = [];
-       this.semaphore = 0;
-       this.usedAsync = false;
-       this.module = config.currentModule;
-       this.stack = sourceFromStacktrace( 3 );
-
-       // Register unique strings
-       for ( i = 0, l = this.module.tests; i < l.length; i++ ) {
-               if ( this.module.tests[ i ].name === this.testName ) {
-                       this.testName += " ";
-               }
-       }
-
-       this.testId = generateHash( this.module.name, this.testName );
-
-       this.module.tests.push({
-               name: this.testName,
-               testId: this.testId
-       });
-
-       if ( settings.skip ) {
-
-               // Skipped tests will fully ignore any sent callback
-               this.callback = function() {};
-               this.async = false;
-               this.expected = 0;
-       } else {
-               this.assert = new Assert( this );
-       }
-}
-
-Test.count = 0;
-
-Test.prototype = {
-       before: function() {
-               if (
-
-                       // Emit moduleStart when we're switching from one module to another
-                       this.module !== config.previousModule ||
-
-                               // They could be equal (both undefined) but if the previousModule property doesn't
-                               // yet exist it means this is the first test in a suite that isn't wrapped in a
-                               // module, in which case we'll just emit a moduleStart event for 'undefined'.
-                               // Without this, reporters can get testStart before moduleStart  which is a problem.
-                               !hasOwn.call( config, "previousModule" )
-               ) {
-                       if ( hasOwn.call( config, "previousModule" ) ) {
-                               runLoggingCallbacks( "moduleDone", {
-                                       name: config.previousModule.name,
-                                       tests: config.previousModule.tests,
-                                       failed: config.moduleStats.bad,
-                                       passed: config.moduleStats.all - config.moduleStats.bad,
-                                       total: config.moduleStats.all,
-                                       runtime: now() - config.moduleStats.started
-                               });
-                       }
-                       config.previousModule = this.module;
-                       config.moduleStats = { all: 0, bad: 0, started: now() };
-                       runLoggingCallbacks( "moduleStart", {
-                               name: this.module.name,
-                               tests: this.module.tests
-                       });
-               }
-
-               config.current = this;
-
-               this.testEnvironment = extend( {}, this.module.testEnvironment );
-               delete this.testEnvironment.beforeEach;
-               delete this.testEnvironment.afterEach;
-
-               this.started = now();
-               runLoggingCallbacks( "testStart", {
-                       name: this.testName,
-                       module: this.module.name,
-                       testId: this.testId
-               });
-
-               if ( !config.pollution ) {
-                       saveGlobal();
-               }
-       },
-
-       run: function() {
-               var promise;
-
-               config.current = this;
-
-               if ( this.async ) {
-                       QUnit.stop();
-               }
-
-               this.callbackStarted = now();
-
-               if ( config.notrycatch ) {
-                       promise = this.callback.call( this.testEnvironment, this.assert );
-                       this.resolvePromise( promise );
-                       return;
-               }
-
-               try {
-                       promise = this.callback.call( this.testEnvironment, this.assert );
-                       this.resolvePromise( promise );
-               } catch ( e ) {
-                       this.pushFailure( "Died on test #" + ( this.assertions.length + 1 ) + " " +
-                               this.stack + ": " + ( e.message || e ), extractStacktrace( e, 0 ) );
-
-                       // else next test will carry the responsibility
-                       saveGlobal();
-
-                       // Restart the tests if they're blocking
-                       if ( config.blocking ) {
-                               QUnit.start();
-                       }
-               }
-       },
-
-       after: function() {
-               checkPollution();
-       },
-
-       queueHook: function( hook, hookName ) {
-               var promise,
-                       test = this;
-               return function runHook() {
-                       config.current = test;
-                       if ( config.notrycatch ) {
-                               promise = hook.call( test.testEnvironment, test.assert );
-                               test.resolvePromise( promise, hookName );
-                               return;
-                       }
-                       try {
-                               promise = hook.call( test.testEnvironment, test.assert );
-                               test.resolvePromise( promise, hookName );
-                       } catch ( error ) {
-                               test.pushFailure( hookName + " failed on " + test.testName + ": " +
-                                       ( error.message || error ), extractStacktrace( error, 0 ) );
-                       }
-               };
-       },
-
-       // Currently only used for module level hooks, can be used to add global level ones
-       hooks: function( handler ) {
-               var hooks = [];
-
-               // Hooks are ignored on skipped tests
-               if ( this.skip ) {
-                       return hooks;
-               }
-
-               if ( this.module.testEnvironment &&
-                               QUnit.objectType( this.module.testEnvironment[ handler ] ) === "function" ) {
-                       hooks.push( this.queueHook( this.module.testEnvironment[ handler ], handler ) );
-               }
-
-               return hooks;
-       },
-
-       finish: function() {
-               config.current = this;
-               if ( config.requireExpects && this.expected === null ) {
-                       this.pushFailure( "Expected number of assertions to be defined, but expect() was " +
-                               "not called.", this.stack );
-               } else if ( this.expected !== null && this.expected !== this.assertions.length ) {
-                       this.pushFailure( "Expected " + this.expected + " assertions, but " +
-                               this.assertions.length + " were run", this.stack );
-               } else if ( this.expected === null && !this.assertions.length ) {
-                       this.pushFailure( "Expected at least one assertion, but none were run - call " +
-                               "expect(0) to accept zero assertions.", this.stack );
-               }
-
-               var i,
-                       bad = 0;
-
-               this.runtime = now() - this.started;
-               config.stats.all += this.assertions.length;
-               config.moduleStats.all += this.assertions.length;
-
-               for ( i = 0; i < this.assertions.length; i++ ) {
-                       if ( !this.assertions[ i ].result ) {
-                               bad++;
-                               config.stats.bad++;
-                               config.moduleStats.bad++;
-                       }
-               }
-
-               runLoggingCallbacks( "testDone", {
-                       name: this.testName,
-                       module: this.module.name,
-                       skipped: !!this.skip,
-                       failed: bad,
-                       passed: this.assertions.length - bad,
-                       total: this.assertions.length,
-                       runtime: this.runtime,
-
-                       // HTML Reporter use
-                       assertions: this.assertions,
-                       testId: this.testId,
-
-                       // DEPRECATED: this property will be removed in 2.0.0, use runtime instead
-                       duration: this.runtime
-               });
-
-               // QUnit.reset() is deprecated and will be replaced for a new
-               // fixture reset function on QUnit 2.0/2.1.
-               // It's still called here for backwards compatibility handling
-               QUnit.reset();
-
-               config.current = undefined;
-       },
-
-       queue: function() {
-               var bad,
-                       test = this;
-
-               if ( !this.valid() ) {
-                       return;
-               }
-
-               function run() {
-
-                       // each of these can by async
-                       synchronize([
-                               function() {
-                                       test.before();
-                               },
-
-                               test.hooks( "beforeEach" ),
-
-                               function() {
-                                       test.run();
-                               },
-
-                               test.hooks( "afterEach" ).reverse(),
-
-                               function() {
-                                       test.after();
-                               },
-                               function() {
-                                       test.finish();
-                               }
-                       ]);
-               }
-
-               // `bad` initialized at top of scope
-               // defer when previous test run passed, if storage is available
-               bad = QUnit.config.reorder && defined.sessionStorage &&
-                               +sessionStorage.getItem( "qunit-test-" + this.module.name + "-" + this.testName );
-
-               if ( bad ) {
-                       run();
-               } else {
-                       synchronize( run, true );
-               }
-       },
-
-       push: function( result, actual, expected, message ) {
-               var source,
-                       details = {
-                               module: this.module.name,
-                               name: this.testName,
-                               result: result,
-                               message: message,
-                               actual: actual,
-                               expected: expected,
-                               testId: this.testId,
-                               runtime: now() - this.started
-                       };
-
-               if ( !result ) {
-                       source = sourceFromStacktrace();
-
-                       if ( source ) {
-                               details.source = source;
-                       }
-               }
-
-               runLoggingCallbacks( "log", details );
-
-               this.assertions.push({
-                       result: !!result,
-                       message: message
-               });
-       },
-
-       pushFailure: function( message, source, actual ) {
-               if ( !this instanceof Test ) {
-                       throw new Error( "pushFailure() assertion outside test context, was " +
-                               sourceFromStacktrace( 2 ) );
-               }
-
-               var details = {
-                               module: this.module.name,
-                               name: this.testName,
-                               result: false,
-                               message: message || "error",
-                               actual: actual || null,
-                               testId: this.testId,
-                               runtime: now() - this.started
-                       };
-
-               if ( source ) {
-                       details.source = source;
-               }
-
-               runLoggingCallbacks( "log", details );
-
-               this.assertions.push({
-                       result: false,
-                       message: message
-               });
-       },
-
-       resolvePromise: function( promise, phase ) {
-               var then, message,
-                       test = this;
-               if ( promise != null ) {
-                       then = promise.then;
-                       if ( QUnit.objectType( then ) === "function" ) {
-                               QUnit.stop();
-                               then.call(
-                                       promise,
-                                       QUnit.start,
-                                       function( error ) {
-                                               message = "Promise rejected " +
-                                                       ( !phase ? "during" : phase.replace( /Each$/, "" ) ) +
-                                                       " " + test.testName + ": " + ( error.message || error );
-                                               test.pushFailure( message, extractStacktrace( error, 0 ) );
-
-                                               // else next test will carry the responsibility
-                                               saveGlobal();
-
-                                               // Unblock
-                                               QUnit.start();
-                                       }
-                               );
-                       }
-               }
-       },
-
-       valid: function() {
-               var include,
-                       filter = config.filter && config.filter.toLowerCase(),
-                       module = QUnit.urlParams.module && QUnit.urlParams.module.toLowerCase(),
-                       fullName = ( this.module.name + ": " + this.testName ).toLowerCase();
-
-               // Internally-generated tests are always valid
-               if ( this.callback && this.callback.validTest ) {
-                       return true;
-               }
-
-               if ( config.testId.length > 0 && inArray( this.testId, config.testId ) < 0 ) {
-                       return false;
-               }
-
-               if ( module && ( !this.module.name || this.module.name.toLowerCase() !== module ) ) {
-                       return false;
-               }
-
-               if ( !filter ) {
-                       return true;
-               }
-
-               include = filter.charAt( 0 ) !== "!";
-               if ( !include ) {
-                       filter = filter.slice( 1 );
-               }
-
-               // If the filter matches, we need to honour include
-               if ( fullName.indexOf( filter ) !== -1 ) {
-                       return include;
-               }
-
-               // Otherwise, do the opposite
-               return !include;
-       }
-
-};
-
-// Resets the test setup. Useful for tests that modify the DOM.
-/*
-DEPRECATED: Use multiple tests instead of resetting inside a test.
-Use testStart or testDone for custom cleanup.
-This method will throw an error in 2.0, and will be removed in 2.1
-*/
-QUnit.reset = function() {
-
-       // Return on non-browser environments
-       // This is necessary to not break on node tests
-       if ( typeof window === "undefined" ) {
-               return;
-       }
-
-       var fixture = defined.document && document.getElementById &&
-                       document.getElementById( "qunit-fixture" );
-
-       if ( fixture ) {
-               fixture.innerHTML = config.fixture;
-       }
-};
-
-QUnit.pushFailure = function() {
-       if ( !QUnit.config.current ) {
-               throw new Error( "pushFailure() assertion outside test context, in " +
-                       sourceFromStacktrace( 2 ) );
-       }
-
-       // Gets current test obj
-       var currentTest = QUnit.config.current;
-
-       return currentTest.pushFailure.apply( currentTest, arguments );
-};
-
-// Based on Java's String.hashCode, a simple but not
-// rigorously collision resistant hashing function
-function generateHash( module, testName ) {
-       var hex,
-               i = 0,
-               hash = 0,
-               str = module + "\x1C" + testName,
-               len = str.length;
-
-       for ( ; i < len; i++ ) {
-               hash  = ( ( hash << 5 ) - hash ) + str.charCodeAt( i );
-               hash |= 0;
-       }
-
-       // Convert the possibly negative integer hash code into an 8 character hex string, which isn't
-       // strictly necessary but increases user understanding that the id is a SHA-like hash
-       hex = ( 0x100000000 + hash ).toString( 16 );
-       if ( hex.length < 8 ) {
-               hex = "0000000" + hex;
-       }
-
-       return hex.slice( -8 );
-}
-
-function Assert( testContext ) {
-       this.test = testContext;
-}
-
-// Assert helpers
-QUnit.assert = Assert.prototype = {
-
-       // Specify the number of expected assertions to guarantee that failed test
-       // (no assertions are run at all) don't slip through.
-       expect: function( asserts ) {
-               if ( arguments.length === 1 ) {
-                       this.test.expected = asserts;
-               } else {
-                       return this.test.expected;
-               }
-       },
-
-       // Increment this Test's semaphore counter, then return a single-use function that
-       // decrements that counter a maximum of once.
-       async: function() {
-               var test = this.test,
-                       popped = false;
-
-               test.semaphore += 1;
-               test.usedAsync = true;
-               pauseProcessing();
-
-               return function done() {
-                       if ( !popped ) {
-                               test.semaphore -= 1;
-                               popped = true;
-                               resumeProcessing();
-                       } else {
-                               test.pushFailure( "Called the callback returned from `assert.async` more than once",
-                                       sourceFromStacktrace( 2 ) );
-                       }
-               };
-       },
-
-       // Exports test.push() to the user API
-       push: function( /* result, actual, expected, message */ ) {
-               var assert = this,
-                       currentTest = ( assert instanceof Assert && assert.test ) || QUnit.config.current;
-
-               // Backwards compatibility fix.
-               // Allows the direct use of global exported assertions and QUnit.assert.*
-               // Although, it's use is not recommended as it can leak assertions
-               // to other tests from async tests, because we only get a reference to the current test,
-               // not exactly the test where assertion were intended to be called.
-               if ( !currentTest ) {
-                       throw new Error( "assertion outside test context, in " + sourceFromStacktrace( 2 ) );
-               }
-
-               if ( currentTest.usedAsync === true && currentTest.semaphore === 0 ) {
-                       currentTest.pushFailure( "Assertion after the final `assert.async` was resolved",
-                               sourceFromStacktrace( 2 ) );
-
-                       // Allow this assertion to continue running anyway...
-               }
-
-               if ( !( assert instanceof Assert ) ) {
-                       assert = currentTest.assert;
-               }
-               return assert.test.push.apply( assert.test, arguments );
-       },
-
-       /**
-        * Asserts rough true-ish result.
-        * @name ok
-        * @function
-        * @example ok( "asdfasdf".length > 5, "There must be at least 5 chars" );
-        */
-       ok: function( result, message ) {
-               message = message || ( result ? "okay" : "failed, expected argument to be truthy, was: " +
-                       QUnit.dump.parse( result ) );
-               this.push( !!result, result, true, message );
-       },
-
-       /**
-        * Assert that the first two arguments are equal, with an optional message.
-        * Prints out both actual and expected values.
-        * @name equal
-        * @function
-        * @example equal( format( "{0} bytes.", 2), "2 bytes.", "replaces {0} with next argument" );
-        */
-       equal: function( actual, expected, message ) {
-               /*jshint eqeqeq:false */
-               this.push( expected == actual, actual, expected, message );
-       },
-
-       /**
-        * @name notEqual
-        * @function
-        */
-       notEqual: function( actual, expected, message ) {
-               /*jshint eqeqeq:false */
-               this.push( expected != actual, actual, expected, message );
-       },
-
-       /**
-        * @name propEqual
-        * @function
-        */
-       propEqual: function( actual, expected, message ) {
-               actual = objectValues( actual );
-               expected = objectValues( expected );
-               this.push( QUnit.equiv( actual, expected ), actual, expected, message );
-       },
-
-       /**
-        * @name notPropEqual
-        * @function
-        */
-       notPropEqual: function( actual, expected, message ) {
-               actual = objectValues( actual );
-               expected = objectValues( expected );
-               this.push( !QUnit.equiv( actual, expected ), actual, expected, message );
-       },
-
-       /**
-        * @name deepEqual
-        * @function
-        */
-       deepEqual: function( actual, expected, message ) {
-               this.push( QUnit.equiv( actual, expected ), actual, expected, message );
-       },
-
-       /**
-        * @name notDeepEqual
-        * @function
-        */
-       notDeepEqual: function( actual, expected, message ) {
-               this.push( !QUnit.equiv( actual, expected ), actual, expected, message );
-       },
-
-       /**
-        * @name strictEqual
-        * @function
-        */
-       strictEqual: function( actual, expected, message ) {
-               this.push( expected === actual, actual, expected, message );
-       },
-
-       /**
-        * @name notStrictEqual
-        * @function
-        */
-       notStrictEqual: function( actual, expected, message ) {
-               this.push( expected !== actual, actual, expected, message );
-       },
-
-       "throws": function( block, expected, message ) {
-               var actual, expectedType,
-                       expectedOutput = expected,
-                       ok = false;
-
-               // 'expected' is optional unless doing string comparison
-               if ( message == null && typeof expected === "string" ) {
-                       message = expected;
-                       expected = null;
-               }
-
-               this.test.ignoreGlobalErrors = true;
-               try {
-                       block.call( this.test.testEnvironment );
-               } catch (e) {
-                       actual = e;
-               }
-               this.test.ignoreGlobalErrors = false;
-
-               if ( actual ) {
-                       expectedType = QUnit.objectType( expected );
-
-                       // we don't want to validate thrown error
-                       if ( !expected ) {
-                               ok = true;
-                               expectedOutput = null;
-
-                       // expected is a regexp
-                       } else if ( expectedType === "regexp" ) {
-                               ok = expected.test( errorString( actual ) );
-
-                       // expected is a string
-                       } else if ( expectedType === "string" ) {
-                               ok = expected === errorString( actual );
-
-                       // expected is a constructor, maybe an Error constructor
-                       } else if ( expectedType === "function" && actual instanceof expected ) {
-                               ok = true;
-
-                       // expected is an Error object
-                       } else if ( expectedType === "object" ) {
-                               ok = actual instanceof expected.constructor &&
-                                       actual.name === expected.name &&
-                                       actual.message === expected.message;
-
-                       // expected is a validation function which returns true if validation passed
-                       } else if ( expectedType === "function" && expected.call( {}, actual ) === true ) {
-                               expectedOutput = null;
-                               ok = true;
-                       }
-
-                       this.push( ok, actual, expectedOutput, message );
-               } else {
-                       this.test.pushFailure( message, null, "No exception was thrown." );
-               }
-       }
-};
-
-// Provide an alternative to assert.throws(), for enviroments that consider throws a reserved word
-// Known to us are: Closure Compiler, Narwhal
-(function() {
-       /*jshint sub:true */
-       Assert.prototype.raises = Assert.prototype[ "throws" ];
-}());
-
-// Test for equality any JavaScript type.
-// Author: Philippe Rathé <prathe@gmail.com>
-QUnit.equiv = (function() {
-
-       // Call the o related callback with the given arguments.
-       function bindCallbacks( o, callbacks, args ) {
-               var prop = QUnit.objectType( o );
-               if ( prop ) {
-                       if ( QUnit.objectType( callbacks[ prop ] ) === "function" ) {
-                               return callbacks[ prop ].apply( callbacks, args );
-                       } else {
-                               return callbacks[ prop ]; // or undefined
-                       }
-               }
-       }
-
-       // the real equiv function
-       var innerEquiv,
-
-               // stack to decide between skip/abort functions
-               callers = [],
-
-               // stack to avoiding loops from circular referencing
-               parents = [],
-               parentsB = [],
-
-               getProto = Object.getPrototypeOf || function( obj ) {
-                       /* jshint camelcase: false, proto: true */
-                       return obj.__proto__;
-               },
-               callbacks = (function() {
-
-                       // for string, boolean, number and null
-                       function useStrictEquality( b, a ) {
-
-                               /*jshint eqeqeq:false */
-                               if ( b instanceof a.constructor || a instanceof b.constructor ) {
-
-                                       // to catch short annotation VS 'new' annotation of a
-                                       // declaration
-                                       // e.g. var i = 1;
-                                       // var j = new Number(1);
-                                       return a == b;
-                               } else {
-                                       return a === b;
-                               }
-                       }
-
-                       return {
-                               "string": useStrictEquality,
-                               "boolean": useStrictEquality,
-                               "number": useStrictEquality,
-                               "null": useStrictEquality,
-                               "undefined": useStrictEquality,
-
-                               "nan": function( b ) {
-                                       return isNaN( b );
-                               },
-
-                               "date": function( b, a ) {
-                                       return QUnit.objectType( b ) === "date" && a.valueOf() === b.valueOf();
-                               },
-
-                               "regexp": function( b, a ) {
-                                       return QUnit.objectType( b ) === "regexp" &&
-
-                                               // the regex itself
-                                               a.source === b.source &&
-
-                                               // and its modifiers
-                                               a.global === b.global &&
-
-                                               // (gmi) ...
-                                               a.ignoreCase === b.ignoreCase &&
-                                               a.multiline === b.multiline &&
-                                               a.sticky === b.sticky;
-                               },
-
-                               // - skip when the property is a method of an instance (OOP)
-                               // - abort otherwise,
-                               // initial === would have catch identical references anyway
-                               "function": function() {
-                                       var caller = callers[ callers.length - 1 ];
-                                       return caller !== Object && typeof caller !== "undefined";
-                               },
-
-                               "array": function( b, a ) {
-                                       var i, j, len, loop, aCircular, bCircular;
-
-                                       // b could be an object literal here
-                                       if ( QUnit.objectType( b ) !== "array" ) {
-                                               return false;
-                                       }
-
-                                       len = a.length;
-                                       if ( len !== b.length ) {
-                                               // safe and faster
-                                               return false;
-                                       }
-
-                                       // track reference to avoid circular references
-                                       parents.push( a );
-                                       parentsB.push( b );
-                                       for ( i = 0; i < len; i++ ) {
-                                               loop = false;
-                                               for ( j = 0; j < parents.length; j++ ) {
-                                                       aCircular = parents[ j ] === a[ i ];
-                                                       bCircular = parentsB[ j ] === b[ i ];
-                                                       if ( aCircular || bCircular ) {
-                                                               if ( a[ i ] === b[ i ] || aCircular && bCircular ) {
-                                                                       loop = true;
-                                                               } else {
-                                                                       parents.pop();
-                                                                       parentsB.pop();
-                                                                       return false;
-                                                               }
-                                                       }
-                                               }
-                                               if ( !loop && !innerEquiv( a[ i ], b[ i ] ) ) {
-                                                       parents.pop();
-                                                       parentsB.pop();
-                                                       return false;
-                                               }
-                                       }
-                                       parents.pop();
-                                       parentsB.pop();
-                                       return true;
-                               },
-
-                               "object": function( b, a ) {
-
-                                       /*jshint forin:false */
-                                       var i, j, loop, aCircular, bCircular,
-                                               // Default to true
-                                               eq = true,
-                                               aProperties = [],
-                                               bProperties = [];
-
-                                       // comparing constructors is more strict than using
-                                       // instanceof
-                                       if ( a.constructor !== b.constructor ) {
-
-                                               // Allow objects with no prototype to be equivalent to
-                                               // objects with Object as their constructor.
-                                               if ( !( ( getProto( a ) === null && getProto( b ) === Object.prototype ) ||
-                                                       ( getProto( b ) === null && getProto( a ) === Object.prototype ) ) ) {
-                                                       return false;
-                                               }
-                                       }
-
-                                       // stack constructor before traversing properties
-                                       callers.push( a.constructor );
-
-                                       // track reference to avoid circular references
-                                       parents.push( a );
-                                       parentsB.push( b );
-
-                                       // be strict: don't ensure hasOwnProperty and go deep
-                                       for ( i in a ) {
-                                               loop = false;
-                                               for ( j = 0; j < parents.length; j++ ) {
-                                                       aCircular = parents[ j ] === a[ i ];
-                                                       bCircular = parentsB[ j ] === b[ i ];
-                                                       if ( aCircular || bCircular ) {
-                                                               if ( a[ i ] === b[ i ] || aCircular && bCircular ) {
-                                                                       loop = true;
-                                                               } else {
-                                                                       eq = false;
-                                                                       break;
-                                                               }
-                                                       }
-                                               }
-                                               aProperties.push( i );
-                                               if ( !loop && !innerEquiv( a[ i ], b[ i ] ) ) {
-                                                       eq = false;
-                                                       break;
-                                               }
-                                       }
-
-                                       parents.pop();
-                                       parentsB.pop();
-                                       callers.pop(); // unstack, we are done
-
-                                       for ( i in b ) {
-                                               bProperties.push( i ); // collect b's properties
-                                       }
-
-                                       // Ensures identical properties name
-                                       return eq && innerEquiv( aProperties.sort(), bProperties.sort() );
-                               }
-                       };
-               }());
-
-       innerEquiv = function() { // can take multiple arguments
-               var args = [].slice.apply( arguments );
-               if ( args.length < 2 ) {
-                       return true; // end transition
-               }
-
-               return ( (function( a, b ) {
-                       if ( a === b ) {
-                               return true; // catch the most you can
-                       } else if ( a === null || b === null || typeof a === "undefined" ||
-                                       typeof b === "undefined" ||
-                                       QUnit.objectType( a ) !== QUnit.objectType( b ) ) {
-
-                               // don't lose time with error prone cases
-                               return false;
-                       } else {
-                               return bindCallbacks( a, callbacks, [ b, a ] );
-                       }
-
-                       // apply transition with (1..n) arguments
-               }( args[ 0 ], args[ 1 ] ) ) &&
-                       innerEquiv.apply( this, args.splice( 1, args.length - 1 ) ) );
-       };
-
-       return innerEquiv;
-}());
-
-// Based on jsDump by Ariel Flesler
-// http://flesler.blogspot.com/2008/05/jsdump-pretty-dump-of-any-javascript.html
-QUnit.dump = (function() {
-       function quote( str ) {
-               return "\"" + str.toString().replace( /"/g, "\\\"" ) + "\"";
-       }
-       function literal( o ) {
-               return o + "";
-       }
-       function join( pre, arr, post ) {
-               var s = dump.separator(),
-                       base = dump.indent(),
-                       inner = dump.indent( 1 );
-               if ( arr.join ) {
-                       arr = arr.join( "," + s + inner );
-               }
-               if ( !arr ) {
-                       return pre + post;
-               }
-               return [ pre, inner + arr, base + post ].join( s );
-       }
-       function array( arr, stack ) {
-               var i = arr.length,
-                       ret = new Array( i );
-
-               if ( dump.maxDepth && dump.depth > dump.maxDepth ) {
-                       return "[object Array]";
-               }
-
-               this.up();
-               while ( i-- ) {
-                       ret[ i ] = this.parse( arr[ i ], undefined, stack );
-               }
-               this.down();
-               return join( "[", ret, "]" );
-       }
-
-       var reName = /^function (\w+)/,
-               dump = {
-
-                       // objType is used mostly internally, you can fix a (custom) type in advance
-                       parse: function( obj, objType, stack ) {
-                               stack = stack || [];
-                               var res, parser, parserType,
-                                       inStack = inArray( obj, stack );
-
-                               if ( inStack !== -1 ) {
-                                       return "recursion(" + ( inStack - stack.length ) + ")";
-                               }
-
-                               objType = objType || this.typeOf( obj  );
-                               parser = this.parsers[ objType ];
-                               parserType = typeof parser;
-
-                               if ( parserType === "function" ) {
-                                       stack.push( obj );
-                                       res = parser.call( this, obj, stack );
-                                       stack.pop();
-                                       return res;
-                               }
-                               return ( parserType === "string" ) ? parser : this.parsers.error;
-                       },
-                       typeOf: function( obj ) {
-                               var type;
-                               if ( obj === null ) {
-                                       type = "null";
-                               } else if ( typeof obj === "undefined" ) {
-                                       type = "undefined";
-                               } else if ( QUnit.is( "regexp", obj ) ) {
-                                       type = "regexp";
-                               } else if ( QUnit.is( "date", obj ) ) {
-                                       type = "date";
-                               } else if ( QUnit.is( "function", obj ) ) {
-                                       type = "function";
-                               } else if ( obj.setInterval !== undefined &&
-                                               obj.document !== undefined &&
-                                               obj.nodeType === undefined ) {
-                                       type = "window";
-                               } else if ( obj.nodeType === 9 ) {
-                                       type = "document";
-                               } else if ( obj.nodeType ) {
-                                       type = "node";
-                               } else if (
-
-                                       // native arrays
-                                       toString.call( obj ) === "[object Array]" ||
-
-                                       // NodeList objects
-                                       ( typeof obj.length === "number" && obj.item !== undefined &&
-                                       ( obj.length ? obj.item( 0 ) === obj[ 0 ] : ( obj.item( 0 ) === null &&
-                                       obj[ 0 ] === undefined ) ) )
-                               ) {
-                                       type = "array";
-                               } else if ( obj.constructor === Error.prototype.constructor ) {
-                                       type = "error";
-                               } else {
-                                       type = typeof obj;
-                               }
-                               return type;
-                       },
-                       separator: function() {
-                               return this.multiline ? this.HTML ? "<br />" : "\n" : this.HTML ? "&#160;" : " ";
-                       },
-                       // extra can be a number, shortcut for increasing-calling-decreasing
-                       indent: function( extra ) {
-                               if ( !this.multiline ) {
-                                       return "";
-                               }
-                               var chr = this.indentChar;
-                               if ( this.HTML ) {
-                                       chr = chr.replace( /\t/g, "   " ).replace( / /g, "&#160;" );
-                               }
-                               return new Array( this.depth + ( extra || 0 ) ).join( chr );
-                       },
-                       up: function( a ) {
-                               this.depth += a || 1;
-                       },
-                       down: function( a ) {
-                               this.depth -= a || 1;
-                       },
-                       setParser: function( name, parser ) {
-                               this.parsers[ name ] = parser;
-                       },
-                       // The next 3 are exposed so you can use them
-                       quote: quote,
-                       literal: literal,
-                       join: join,
-                       //
-                       depth: 1,
-                       maxDepth: 5,
-
-                       // This is the list of parsers, to modify them, use dump.setParser
-                       parsers: {
-                               window: "[Window]",
-                               document: "[Document]",
-                               error: function( error ) {
-                                       return "Error(\"" + error.message + "\")";
-                               },
-                               unknown: "[Unknown]",
-                               "null": "null",
-                               "undefined": "undefined",
-                               "function": function( fn ) {
-                                       var ret = "function",
-
-                                               // functions never have name in IE
-                                               name = "name" in fn ? fn.name : ( reName.exec( fn ) || [] )[ 1 ];
-
-                                       if ( name ) {
-                                               ret += " " + name;
-                                       }
-                                       ret += "( ";
-
-                                       ret = [ ret, dump.parse( fn, "functionArgs" ), "){" ].join( "" );
-                                       return join( ret, dump.parse( fn, "functionCode" ), "}" );
-                               },
-                               array: array,
-                               nodelist: array,
-                               "arguments": array,
-                               object: function( map, stack ) {
-                                       var keys, key, val, i, nonEnumerableProperties,
-                                               ret = [];
-
-                                       if ( dump.maxDepth && dump.depth > dump.maxDepth ) {
-                                               return "[object Object]";
-                                       }
-
-                                       dump.up();
-                                       keys = [];
-                                       for ( key in map ) {
-                                               keys.push( key );
-                                       }
-
-                                       // Some properties are not always enumerable on Error objects.
-                                       nonEnumerableProperties = [ "message", "name" ];
-                                       for ( i in nonEnumerableProperties ) {
-                                               key = nonEnumerableProperties[ i ];
-                                               if ( key in map && !( key in keys ) ) {
-                                                       keys.push( key );
-                                               }
-                                       }
-                                       keys.sort();
-                                       for ( i = 0; i < keys.length; i++ ) {
-                                               key = keys[ i ];
-                                               val = map[ key ];
-                                               ret.push( dump.parse( key, "key" ) + ": " +
-                                                       dump.parse( val, undefined, stack ) );
-                                       }
-                                       dump.down();
-                                       return join( "{", ret, "}" );
-                               },
-                               node: function( node ) {
-                                       var len, i, val,
-                                               open = dump.HTML ? "&lt;" : "<",
-                                               close = dump.HTML ? "&gt;" : ">",
-                                               tag = node.nodeName.toLowerCase(),
-                                               ret = open + tag,
-                                               attrs = node.attributes;
-
-                                       if ( attrs ) {
-                                               for ( i = 0, len = attrs.length; i < len; i++ ) {
-                                                       val = attrs[ i ].nodeValue;
-
-                                                       // IE6 includes all attributes in .attributes, even ones not explicitly
-                                                       // set. Those have values like undefined, null, 0, false, "" or
-                                                       // "inherit".
-                                                       if ( val && val !== "inherit" ) {
-                                                               ret += " " + attrs[ i ].nodeName + "=" +
-                                                                       dump.parse( val, "attribute" );
-                                                       }
-                                               }
-                                       }
-                                       ret += close;
-
-                                       // Show content of TextNode or CDATASection
-                                       if ( node.nodeType === 3 || node.nodeType === 4 ) {
-                                               ret += node.nodeValue;
-                                       }
-
-                                       return ret + open + "/" + tag + close;
-                               },
-
-                               // function calls it internally, it's the arguments part of the function
-                               functionArgs: function( fn ) {
-                                       var args,
-                                               l = fn.length;
-
-                                       if ( !l ) {
-                                               return "";
-                                       }
-
-                                       args = new Array( l );
-                                       while ( l-- ) {
-
-                                               // 97 is 'a'
-                                               args[ l ] = String.fromCharCode( 97 + l );
-                                       }
-                                       return " " + args.join( ", " ) + " ";
-                               },
-                               // object calls it internally, the key part of an item in a map
-                               key: quote,
-                               // function calls it internally, it's the content of the function
-                               functionCode: "[code]",
-                               // node calls it internally, it's an html attribute value
-                               attribute: quote,
-                               string: quote,
-                               date: quote,
-                               regexp: literal,
-                               number: literal,
-                               "boolean": literal
-                       },
-                       // if true, entities are escaped ( <, >, \t, space and \n )
-                       HTML: false,
-                       // indentation unit
-                       indentChar: "  ",
-                       // if true, items in a collection, are separated by a \n, else just a space.
-                       multiline: true
-               };
-
-       return dump;
-}());
-
-// back compat
-QUnit.jsDump = QUnit.dump;
-
-// For browser, export only select globals
-if ( typeof window !== "undefined" ) {
-
-       // Deprecated
-       // Extend assert methods to QUnit and Global scope through Backwards compatibility
-       (function() {
-               var i,
-                       assertions = Assert.prototype;
-
-               function applyCurrent( current ) {
-                       return function() {
-                               var assert = new Assert( QUnit.config.current );
-                               current.apply( assert, arguments );
-                       };
-               }
-
-               for ( i in assertions ) {
-                       QUnit[ i ] = applyCurrent( assertions[ i ] );
-               }
-       })();
-
-       (function() {
-               var i, l,
-                       keys = [
-                               "test",
-                               "module",
-                               "expect",
-                               "asyncTest",
-                               "start",
-                               "stop",
-                               "ok",
-                               "equal",
-                               "notEqual",
-                               "propEqual",
-                               "notPropEqual",
-                               "deepEqual",
-                               "notDeepEqual",
-                               "strictEqual",
-                               "notStrictEqual",
-                               "throws"
-                       ];
-
-               for ( i = 0, l = keys.length; i < l; i++ ) {
-                       window[ keys[ i ] ] = QUnit[ keys[ i ] ];
-               }
-       })();
-
-       window.QUnit = QUnit;
-}
-
-// For nodejs
-if ( typeof module !== "undefined" && module.exports ) {
-       module.exports = QUnit;
-}
-
-// For CommonJS with exports, but without module.exports, like Rhino
-if ( typeof exports !== "undefined" ) {
-       exports.QUnit = QUnit;
-}
-
-// Get a reference to the global object, like window in browsers
-}( (function() {
-       return this;
-})() ));
-
-/*istanbul ignore next */
-// jscs:disable maximumLineLength
-/*
- * Javascript Diff Algorithm
- *  By John Resig (http://ejohn.org/)
- *  Modified by Chu Alan "sprite"
- *
- * Released under the MIT license.
- *
- * More Info:
- *  http://ejohn.org/projects/javascript-diff-algorithm/
- *
- * Usage: QUnit.diff(expected, actual)
- *
- * QUnit.diff( "the quick brown fox jumped over", "the quick fox jumps over" ) == "the  quick <del>brown </del> fox <del>jumped </del><ins>jumps </ins> over"
- */
-QUnit.diff = (function() {
-       var hasOwn = Object.prototype.hasOwnProperty;
-
-       /*jshint eqeqeq:false, eqnull:true */
-       function diff( o, n ) {
-               var i,
-                       ns = {},
-                       os = {};
-
-               for ( i = 0; i < n.length; i++ ) {
-                       if ( !hasOwn.call( ns, n[ i ] ) ) {
-                               ns[ n[ i ] ] = {
-                                       rows: [],
-                                       o: null
-                               };
-                       }
-                       ns[ n[ i ] ].rows.push( i );
-               }
-
-               for ( i = 0; i < o.length; i++ ) {
-                       if ( !hasOwn.call( os, o[ i ] ) ) {
-                               os[ o[ i ] ] = {
-                                       rows: [],
-                                       n: null
-                               };
-                       }
-                       os[ o[ i ] ].rows.push( i );
-               }
-
-               for ( i in ns ) {
-                       if ( hasOwn.call( ns, i ) ) {
-                               if ( ns[ i ].rows.length === 1 && hasOwn.call( os, i ) && os[ i ].rows.length === 1 ) {
-                                       n[ ns[ i ].rows[ 0 ] ] = {
-                                               text: n[ ns[ i ].rows[ 0 ] ],
-                                               row: os[ i ].rows[ 0 ]
-                                       };
-                                       o[ os[ i ].rows[ 0 ] ] = {
-                                               text: o[ os[ i ].rows[ 0 ] ],
-                                               row: ns[ i ].rows[ 0 ]
-                                       };
-                               }
-                       }
-               }
-
-               for ( i = 0; i < n.length - 1; i++ ) {
-                       if ( n[ i ].text != null && n[ i + 1 ].text == null && n[ i ].row + 1 < o.length && o[ n[ i ].row + 1 ].text == null &&
-                               n[ i + 1 ] == o[ n[ i ].row + 1 ] ) {
-
-                               n[ i + 1 ] = {
-                                       text: n[ i + 1 ],
-                                       row: n[ i ].row + 1
-                               };
-                               o[ n[ i ].row + 1 ] = {
-                                       text: o[ n[ i ].row + 1 ],
-                                       row: i + 1
-                               };
-                       }
-               }
-
-               for ( i = n.length - 1; i > 0; i-- ) {
-                       if ( n[ i ].text != null && n[ i - 1 ].text == null && n[ i ].row > 0 && o[ n[ i ].row - 1 ].text == null &&
-                               n[ i - 1 ] == o[ n[ i ].row - 1 ] ) {
-
-                               n[ i - 1 ] = {
-                                       text: n[ i - 1 ],
-                                       row: n[ i ].row - 1
-                               };
-                               o[ n[ i ].row - 1 ] = {
-                                       text: o[ n[ i ].row - 1 ],
-                                       row: i - 1
-                               };
-                       }
-               }
-
-               return {
-                       o: o,
-                       n: n
-               };
-       }
-
-       return function( o, n ) {
-               o = o.replace( /\s+$/, "" );
-               n = n.replace( /\s+$/, "" );
-
-               var i, pre,
-                       str = "",
-                       out = diff( o === "" ? [] : o.split( /\s+/ ), n === "" ? [] : n.split( /\s+/ ) ),
-                       oSpace = o.match( /\s+/g ),
-                       nSpace = n.match( /\s+/g );
-
-               if ( oSpace == null ) {
-                       oSpace = [ " " ];
-               } else {
-                       oSpace.push( " " );
-               }
-
-               if ( nSpace == null ) {
-                       nSpace = [ " " ];
-               } else {
-                       nSpace.push( " " );
-               }
-
-               if ( out.n.length === 0 ) {
-                       for ( i = 0; i < out.o.length; i++ ) {
-                               str += "<del>" + out.o[ i ] + oSpace[ i ] + "</del>";
-                       }
-               } else {
-                       if ( out.n[ 0 ].text == null ) {
-                               for ( n = 0; n < out.o.length && out.o[ n ].text == null; n++ ) {
-                                       str += "<del>" + out.o[ n ] + oSpace[ n ] + "</del>";
-                               }
-                       }
-
-                       for ( i = 0; i < out.n.length; i++ ) {
-                               if ( out.n[ i ].text == null ) {
-                                       str += "<ins>" + out.n[ i ] + nSpace[ i ] + "</ins>";
-                               } else {
-
-                                       // `pre` initialized at top of scope
-                                       pre = "";
-
-                                       for ( n = out.n[ i ].row + 1; n < out.o.length && out.o[ n ].text == null; n++ ) {
-                                               pre += "<del>" + out.o[ n ] + oSpace[ n ] + "</del>";
-                                       }
-                                       str += " " + out.n[ i ].text + nSpace[ i ] + pre;
-                               }
-                       }
-               }
-
-               return str;
-       };
-}());
-// jscs:enable
-
-(function() {
-
-// Deprecated QUnit.init - Ref #530
-// Re-initialize the configuration options
-QUnit.init = function() {
-       var tests, banner, result, qunit,
-               config = QUnit.config;
-
-       config.stats = { all: 0, bad: 0 };
-       config.moduleStats = { all: 0, bad: 0 };
-       config.started = 0;
-       config.updateRate = 1000;
-       config.blocking = false;
-       config.autostart = true;
-       config.autorun = false;
-       config.filter = "";
-       config.queue = [];
-
-       // Return on non-browser environments
-       // This is necessary to not break on node tests
-       if ( typeof window === "undefined" ) {
-               return;
-       }
-
-       qunit = id( "qunit" );
-       if ( qunit ) {
-               qunit.innerHTML =
-                       "<h1 id='qunit-header'>" + escapeText( document.title ) + "</h1>" +
-                       "<h2 id='qunit-banner'></h2>" +
-                       "<div id='qunit-testrunner-toolbar'></div>" +
-                       "<h2 id='qunit-userAgent'></h2>" +
-                       "<ol id='qunit-tests'></ol>";
-       }
-
-       tests = id( "qunit-tests" );
-       banner = id( "qunit-banner" );
-       result = id( "qunit-testresult" );
-
-       if ( tests ) {
-               tests.innerHTML = "";
-       }
-
-       if ( banner ) {
-               banner.className = "";
-       }
-
-       if ( result ) {
-               result.parentNode.removeChild( result );
-       }
-
-       if ( tests ) {
-               result = document.createElement( "p" );
-               result.id = "qunit-testresult";
-               result.className = "result";
-               tests.parentNode.insertBefore( result, tests );
-               result.innerHTML = "Running...<br />&#160;";
-       }
-};
-
-// Don't load the HTML Reporter on non-Browser environments
-if ( typeof window === "undefined" ) {
-       return;
-}
-
-var config = QUnit.config,
-       hasOwn = Object.prototype.hasOwnProperty,
-       defined = {
-               document: window.document !== undefined,
-               sessionStorage: (function() {
-                       var x = "qunit-test-string";
-                       try {
-                               sessionStorage.setItem( x, x );
-                               sessionStorage.removeItem( x );
-                               return true;
-                       } catch ( e ) {
-                               return false;
-                       }
-               }())
-       },
-       modulesList = [];
-
-/**
-* Escape text for attribute or text content.
-*/
-function escapeText( s ) {
-       if ( !s ) {
-               return "";
-       }
-       s = s + "";
-
-       // Both single quotes and double quotes (for attributes)
-       return s.replace( /['"<>&]/g, function( s ) {
-               switch ( s ) {
-               case "'":
-                       return "&#039;";
-               case "\"":
-                       return "&quot;";
-               case "<":
-                       return "&lt;";
-               case ">":
-                       return "&gt;";
-               case "&":
-                       return "&amp;";
-               }
-       });
-}
-
-/**
- * @param {HTMLElement} elem
- * @param {string} type
- * @param {Function} fn
- */
-function addEvent( elem, type, fn ) {
-       if ( elem.addEventListener ) {
-
-               // Standards-based browsers
-               elem.addEventListener( type, fn, false );
-       } else if ( elem.attachEvent ) {
-
-               // support: IE <9
-               elem.attachEvent( "on" + type, fn );
-       }
-}
-
-/**
- * @param {Array|NodeList} elems
- * @param {string} type
- * @param {Function} fn
- */
-function addEvents( elems, type, fn ) {
-       var i = elems.length;
-       while ( i-- ) {
-               addEvent( elems[ i ], type, fn );
-       }
-}
-
-function hasClass( elem, name ) {
-       return ( " " + elem.className + " " ).indexOf( " " + name + " " ) >= 0;
-}
-
-function addClass( elem, name ) {
-       if ( !hasClass( elem, name ) ) {
-               elem.className += ( elem.className ? " " : "" ) + name;
-       }
-}
-
-function toggleClass( elem, name ) {
-       if ( hasClass( elem, name ) ) {
-               removeClass( elem, name );
-       } else {
-               addClass( elem, name );
-       }
-}
-
-function removeClass( elem, name ) {
-       var set = " " + elem.className + " ";
-
-       // Class name may appear multiple times
-       while ( set.indexOf( " " + name + " " ) >= 0 ) {
-               set = set.replace( " " + name + " ", " " );
-       }
-
-       // trim for prettiness
-       elem.className = typeof set.trim === "function" ? set.trim() : set.replace( /^\s+|\s+$/g, "" );
-}
-
-function id( name ) {
-       return defined.document && document.getElementById && document.getElementById( name );
-}
-
-function getUrlConfigHtml() {
-       var i, j, val,
-               escaped, escapedTooltip,
-               selection = false,
-               len = config.urlConfig.length,
-               urlConfigHtml = "";
-
-       for ( i = 0; i < len; i++ ) {
-               val = config.urlConfig[ i ];
-               if ( typeof val === "string" ) {
-                       val = {
-                               id: val,
-                               label: val
-                       };
-               }
-
-               escaped = escapeText( val.id );
-               escapedTooltip = escapeText( val.tooltip );
-
-               config[ val.id ] = QUnit.urlParams[ val.id ];
-               if ( !val.value || typeof val.value === "string" ) {
-                       urlConfigHtml += "<input id='qunit-urlconfig-" + escaped +
-                               "' name='" + escaped + "' type='checkbox'" +
-                               ( val.value ? " value='" + escapeText( val.value ) + "'" : "" ) +
-                               ( config[ val.id ] ? " checked='checked'" : "" ) +
-                               " title='" + escapedTooltip + "' /><label for='qunit-urlconfig-" + escaped +
-                               "' title='" + escapedTooltip + "'>" + val.label + "</label>";
-               } else {
-                       urlConfigHtml += "<label for='qunit-urlconfig-" + escaped +
-                               "' title='" + escapedTooltip + "'>" + val.label +
-                               ": </label><select id='qunit-urlconfig-" + escaped +
-                               "' name='" + escaped + "' title='" + escapedTooltip + "'><option></option>";
-
-                       if ( QUnit.is( "array", val.value ) ) {
-                               for ( j = 0; j < val.value.length; j++ ) {
-                                       escaped = escapeText( val.value[ j ] );
-                                       urlConfigHtml += "<option value='" + escaped + "'" +
-                                               ( config[ val.id ] === val.value[ j ] ?
-                                                       ( selection = true ) && " selected='selected'" : "" ) +
-                                               ">" + escaped + "</option>";
-                               }
-                       } else {
-                               for ( j in val.value ) {
-                                       if ( hasOwn.call( val.value, j ) ) {
-                                               urlConfigHtml += "<option value='" + escapeText( j ) + "'" +
-                                                       ( config[ val.id ] === j ?
-                                                               ( selection = true ) && " selected='selected'" : "" ) +
-                                                       ">" + escapeText( val.value[ j ] ) + "</option>";
-                                       }
-                               }
-                       }
-                       if ( config[ val.id ] && !selection ) {
-                               escaped = escapeText( config[ val.id ] );
-                               urlConfigHtml += "<option value='" + escaped +
-                                       "' selected='selected' disabled='disabled'>" + escaped + "</option>";
-                       }
-                       urlConfigHtml += "</select>";
-               }
-       }
-
-       return urlConfigHtml;
-}
-
-// Handle "click" events on toolbar checkboxes and "change" for select menus.
-// Updates the URL with the new state of `config.urlConfig` values.
-function toolbarChanged() {
-       var updatedUrl, value,
-               field = this,
-               params = {};
-
-       // Detect if field is a select menu or a checkbox
-       if ( "selectedIndex" in field ) {
-               value = field.options[ field.selectedIndex ].value || undefined;
-       } else {
-               value = field.checked ? ( field.defaultValue || true ) : undefined;
-       }
-
-       params[ field.name ] = value;
-       updatedUrl = QUnit.url( params );
-
-       if ( "hidepassed" === field.name && "replaceState" in window.history ) {
-               config[ field.name ] = value || false;
-               if ( value ) {
-                       addClass( id( "qunit-tests" ), "hidepass" );
-               } else {
-                       removeClass( id( "qunit-tests" ), "hidepass" );
-               }
-
-               // It is not necessary to refresh the whole page
-               window.history.replaceState( null, "", updatedUrl );
-       } else {
-               window.location = updatedUrl;
-       }
-}
-
-function toolbarUrlConfigContainer() {
-       var urlConfigContainer = document.createElement( "span" );
-
-       urlConfigContainer.innerHTML = getUrlConfigHtml();
-
-       // For oldIE support:
-       // * Add handlers to the individual elements instead of the container
-       // * Use "click" instead of "change" for checkboxes
-       addEvents( urlConfigContainer.getElementsByTagName( "input" ), "click", toolbarChanged );
-       addEvents( urlConfigContainer.getElementsByTagName( "select" ), "change", toolbarChanged );
-
-       return urlConfigContainer;
-}
-
-function toolbarModuleFilterHtml() {
-       var i,
-               moduleFilterHtml = "";
-
-       if ( !modulesList.length ) {
-               return false;
-       }
-
-       modulesList.sort(function( a, b ) {
-               return a.localeCompare( b );
-       });
-
-       moduleFilterHtml += "<label for='qunit-modulefilter'>Module: </label>" +
-               "<select id='qunit-modulefilter' name='modulefilter'><option value='' " +
-               ( QUnit.urlParams.module === undefined ? "selected='selected'" : "" ) +
-               ">< All Modules ></option>";
-
-       for ( i = 0; i < modulesList.length; i++ ) {
-               moduleFilterHtml += "<option value='" +
-                       escapeText( encodeURIComponent( modulesList[ i ] ) ) + "' " +
-                       ( QUnit.urlParams.module === modulesList[ i ] ? "selected='selected'" : "" ) +
-                       ">" + escapeText( modulesList[ i ] ) + "</option>";
-       }
-       moduleFilterHtml += "</select>";
-
-       return moduleFilterHtml;
-}
-
-function toolbarModuleFilter() {
-       var toolbar = id( "qunit-testrunner-toolbar" ),
-               moduleFilter = document.createElement( "span" ),
-               moduleFilterHtml = toolbarModuleFilterHtml();
-
-       if ( !moduleFilterHtml ) {
-               return false;
-       }
-
-       moduleFilter.setAttribute( "id", "qunit-modulefilter-container" );
-       moduleFilter.innerHTML = moduleFilterHtml;
-
-       addEvent( moduleFilter.lastChild, "change", function() {
-               var selectBox = moduleFilter.getElementsByTagName( "select" )[ 0 ],
-                       selection = decodeURIComponent( selectBox.options[ selectBox.selectedIndex ].value );
-
-               window.location = QUnit.url({
-                       module: ( selection === "" ) ? undefined : selection,
-
-                       // Remove any existing filters
-                       filter: undefined,
-                       testId: undefined
-               });
-       });
-
-       toolbar.appendChild( moduleFilter );
-}
-
-function appendToolbar() {
-       var toolbar = id( "qunit-testrunner-toolbar" );
-
-       if ( toolbar ) {
-               toolbar.appendChild( toolbarUrlConfigContainer() );
-       }
-}
-
-function appendBanner() {
-       var banner = id( "qunit-banner" );
-
-       if ( banner ) {
-               banner.className = "";
-               banner.innerHTML = "<a href='" +
-                       QUnit.url({ filter: undefined, module: undefined, testId: undefined }) +
-                       "'>" + banner.innerHTML + "</a> ";
-       }
-}
-
-function appendTestResults() {
-       var tests = id( "qunit-tests" ),
-               result = id( "qunit-testresult" );
-
-       if ( result ) {
-               result.parentNode.removeChild( result );
-       }
-
-       if ( tests ) {
-               tests.innerHTML = "";
-               result = document.createElement( "p" );
-               result.id = "qunit-testresult";
-               result.className = "result";
-               tests.parentNode.insertBefore( result, tests );
-               result.innerHTML = "Running...<br />&#160;";
-       }
-}
-
-function storeFixture() {
-       var fixture = id( "qunit-fixture" );
-       if ( fixture ) {
-               config.fixture = fixture.innerHTML;
-       }
-}
-
-function appendUserAgent() {
-       var userAgent = id( "qunit-userAgent" );
-       if ( userAgent ) {
-               userAgent.innerHTML = navigator.userAgent;
-       }
-}
-
-function appendTestsList( modules ) {
-       var i, l, x, z, test, moduleObj;
-
-       for ( i = 0, l = modules.length; i < l; i++ ) {
-               moduleObj = modules[ i ];
-
-               if ( moduleObj.name ) {
-                       modulesList.push( moduleObj.name );
-               }
-
-               for ( x = 0, z = moduleObj.tests.length; x < z; x++ ) {
-                       test = moduleObj.tests[ x ];
-
-                       appendTest( test.name, test.testId, moduleObj.name );
-               }
-       }
-}
-
-function appendTest( name, testId, moduleName ) {
-       var title, rerunTrigger, testBlock, assertList,
-               tests = id( "qunit-tests" );
-
-       if ( !tests ) {
-               return;
-       }
-
-       title = document.createElement( "strong" );
-       title.innerHTML = getNameHtml( name, moduleName );
-
-       rerunTrigger = document.createElement( "a" );
-       rerunTrigger.innerHTML = "Rerun";
-       rerunTrigger.href = QUnit.url({ testId: testId });
-
-       testBlock = document.createElement( "li" );
-       testBlock.appendChild( title );
-       testBlock.appendChild( rerunTrigger );
-       testBlock.id = "qunit-test-output-" + testId;
-
-       assertList = document.createElement( "ol" );
-       assertList.className = "qunit-assert-list";
-
-       testBlock.appendChild( assertList );
-
-       tests.appendChild( testBlock );
-}
-
-// HTML Reporter initialization and load
-QUnit.begin(function( details ) {
-       var qunit = id( "qunit" );
-
-       // Fixture is the only one necessary to run without the #qunit element
-       storeFixture();
-
-       if ( !qunit ) {
-               return;
-       }
-
-       qunit.innerHTML =
-               "<h1 id='qunit-header'>" + escapeText( document.title ) + "</h1>" +
-               "<h2 id='qunit-banner'></h2>" +
-               "<div id='qunit-testrunner-toolbar'></div>" +
-               "<h2 id='qunit-userAgent'></h2>" +
-               "<ol id='qunit-tests'></ol>";
-
-       appendBanner();
-       appendTestResults();
-       appendUserAgent();
-       appendToolbar();
-       appendTestsList( details.modules );
-       toolbarModuleFilter();
-
-       if ( config.hidepassed ) {
-               addClass( qunit.lastChild, "hidepass" );
-       }
-});
-
-QUnit.done(function( details ) {
-       var i, key,
-               banner = id( "qunit-banner" ),
-               tests = id( "qunit-tests" ),
-               html = [
-                       "Tests completed in ",
-                       details.runtime,
-                       " milliseconds.<br />",
-                       "<span class='passed'>",
-                       details.passed,
-                       "</span> assertions of <span class='total'>",
-                       details.total,
-                       "</span> passed, <span class='failed'>",
-                       details.failed,
-                       "</span> failed."
-               ].join( "" );
-
-       if ( banner ) {
-               banner.className = details.failed ? "qunit-fail" : "qunit-pass";
-       }
-
-       if ( tests ) {
-               id( "qunit-testresult" ).innerHTML = html;
-       }
-
-       if ( config.altertitle && defined.document && document.title ) {
-
-               // show ✖ for good, ✔ for bad suite result in title
-               // use escape sequences in case file gets loaded with non-utf-8-charset
-               document.title = [
-                       ( details.failed ? "\u2716" : "\u2714" ),
-                       document.title.replace( /^[\u2714\u2716] /i, "" )
-               ].join( " " );
-       }
-
-       // clear own sessionStorage items if all tests passed
-       if ( config.reorder && defined.sessionStorage && details.failed === 0 ) {
-               for ( i = 0; i < sessionStorage.length; i++ ) {
-                       key = sessionStorage.key( i++ );
-                       if ( key.indexOf( "qunit-test-" ) === 0 ) {
-                               sessionStorage.removeItem( key );
-                       }
-               }
-       }
-
-       // scroll back to top to show results
-       if ( config.scrolltop && window.scrollTo ) {
-               window.scrollTo( 0, 0 );
-       }
-});
-
-function getNameHtml( name, module ) {
-       var nameHtml = "";
-
-       if ( module ) {
-               nameHtml = "<span class='module-name'>" + escapeText( module ) + "</span>: ";
-       }
-
-       nameHtml += "<span class='test-name'>" + escapeText( name ) + "</span>";
-
-       return nameHtml;
-}
-
-QUnit.testStart(function( details ) {
-       var running, testBlock;
-
-       testBlock = id( "qunit-test-output-" + details.testId );
-       if ( testBlock ) {
-               testBlock.className = "running";
-       } else {
-
-               // Report later registered tests
-               appendTest( details.name, details.testId, details.module );
-       }
-
-       running = id( "qunit-testresult" );
-       if ( running ) {
-               running.innerHTML = "Running: <br />" + getNameHtml( details.name, details.module );
-       }
-
-});
-
-QUnit.log(function( details ) {
-       var assertList, assertLi,
-               message, expected, actual,
-               testItem = id( "qunit-test-output-" + details.testId );
-
-       if ( !testItem ) {
-               return;
-       }
-
-       message = escapeText( details.message ) || ( details.result ? "okay" : "failed" );
-       message = "<span class='test-message'>" + message + "</span>";
-       message += "<span class='runtime'>@ " + details.runtime + " ms</span>";
-
-       // pushFailure doesn't provide details.expected
-       // when it calls, it's implicit to also not show expected and diff stuff
-       // Also, we need to check details.expected existence, as it can exist and be undefined
-       if ( !details.result && hasOwn.call( details, "expected" ) ) {
-               expected = escapeText( QUnit.dump.parse( details.expected ) );
-               actual = escapeText( QUnit.dump.parse( details.actual ) );
-               message += "<table><tr class='test-expected'><th>Expected: </th><td><pre>" +
-                       expected +
-                       "</pre></td></tr>";
-
-               if ( actual !== expected ) {
-                       message += "<tr class='test-actual'><th>Result: </th><td><pre>" +
-                               actual + "</pre></td></tr>" +
-                               "<tr class='test-diff'><th>Diff: </th><td><pre>" +
-                               QUnit.diff( expected, actual ) + "</pre></td></tr>";
-               }
-
-               if ( details.source ) {
-                       message += "<tr class='test-source'><th>Source: </th><td><pre>" +
-                               escapeText( details.source ) + "</pre></td></tr>";
-               }
-
-               message += "</table>";
-
-       // this occours when pushFailure is set and we have an extracted stack trace
-       } else if ( !details.result && details.source ) {
-               message += "<table>" +
-                       "<tr class='test-source'><th>Source: </th><td><pre>" +
-                       escapeText( details.source ) + "</pre></td></tr>" +
-                       "</table>";
-       }
-
-       assertList = testItem.getElementsByTagName( "ol" )[ 0 ];
-
-       assertLi = document.createElement( "li" );
-       assertLi.className = details.result ? "pass" : "fail";
-       assertLi.innerHTML = message;
-       assertList.appendChild( assertLi );
-});
-
-QUnit.testDone(function( details ) {
-       var testTitle, time, testItem, assertList,
-               good, bad, testCounts, skipped,
-               tests = id( "qunit-tests" );
-
-       if ( !tests ) {
-               return;
-       }
-
-       testItem = id( "qunit-test-output-" + details.testId );
-
-       assertList = testItem.getElementsByTagName( "ol" )[ 0 ];
-
-       good = details.passed;
-       bad = details.failed;
-
-       // store result when possible
-       if ( config.reorder && defined.sessionStorage ) {
-               if ( bad ) {
-                       sessionStorage.setItem( "qunit-test-" + details.module + "-" + details.name, bad );
-               } else {
-                       sessionStorage.removeItem( "qunit-test-" + details.module + "-" + details.name );
-               }
-       }
-
-       if ( bad === 0 ) {
-               addClass( assertList, "qunit-collapsed" );
-       }
-
-       // testItem.firstChild is the test name
-       testTitle = testItem.firstChild;
-
-       testCounts = bad ?
-               "<b class='failed'>" + bad + "</b>, " + "<b class='passed'>" + good + "</b>, " :
-               "";
-
-       testTitle.innerHTML += " <b class='counts'>(" + testCounts +
-               details.assertions.length + ")</b>";
-
-       if ( details.skipped ) {
-               addClass( testItem, "skipped" );
-               skipped = document.createElement( "em" );
-               skipped.className = "qunit-skipped-label";
-               skipped.innerHTML = "skipped";
-               testItem.insertBefore( skipped, testTitle );
-       } else {
-               addEvent( testTitle, "click", function() {
-                       toggleClass( assertList, "qunit-collapsed" );
-               });
-
-               testItem.className = bad ? "fail" : "pass";
-
-               time = document.createElement( "span" );
-               time.className = "runtime";
-               time.innerHTML = details.runtime + " ms";
-               testItem.insertBefore( time, assertList );
-       }
-});
-
-if ( !defined.document || document.readyState === "complete" ) {
-       config.pageLoaded = true;
-       config.autorun = true;
-}
-
-if ( defined.document ) {
-       addEvent( window, "load", QUnit.load );
-}
-
-})();
diff --git a/resources/lib/oojs-ui/i18n/awa.json b/resources/lib/oojs-ui/i18n/awa.json
new file mode 100644 (file)
index 0000000..f78ed32
--- /dev/null
@@ -0,0 +1,8 @@
+{
+       "@metadata": {
+               "authors": [
+                       "1AnuraagPandey"
+               ]
+       },
+       "ooui-toolbar-more": "अउर"
+}
index 1247241..562dc3d 100644 (file)
@@ -9,6 +9,8 @@
        "ooui-outline-control-move-up": "Лаккха яккха элемент",
        "ooui-outline-control-remove": "ДӀадаха меттиг",
        "ooui-toolbar-more": "Кхин",
+       "ooui-toolgroup-expand": "Дукха",
+       "ooui-toolgroup-collapse": "КӀезиг",
        "ooui-dialog-message-accept": "ХӀаъ",
        "ooui-dialog-message-reject": "Цаоьшу",
        "ooui-dialog-process-continue": "Кхин дӀа"
index 63902f3..196dc2c 100644 (file)
@@ -8,13 +8,15 @@
                        "아라",
                        "고기랑",
                        "Ryuch",
-                       "Revi"
+                       "Revi",
+                       "Infinity"
                ]
        },
        "ooui-outline-control-move-down": "항목을 아래로 옮기기",
        "ooui-outline-control-move-up": "항목을 위로 옮기기",
        "ooui-outline-control-remove": "항목 지우기",
        "ooui-toolbar-more": "더 보기",
+       "ooui-toolgroup-expand": "더 보기",
        "ooui-dialog-message-accept": "확인",
        "ooui-dialog-message-reject": "취소",
        "ooui-dialog-process-error": "무언가가 잘못되었습니다",
index dea35fd..cf051b4 100644 (file)
@@ -1,12 +1,12 @@
 /*!
- * OOjs UI v0.6.4
+ * OOjs UI v0.7.0
  * https://www.mediawiki.org/wiki/OOjs_UI
  *
  * Copyright 2011–2015 OOjs Team and other contributors.
  * Released under the MIT license
  * http://oojs.mit-license.org
  *
- * Date: 2015-01-31T01:16:05Z
+ * Date: 2015-02-12T00:04:52Z
  */
 .oo-ui-progressBarWidget-slide-frames from {
        margin-left: -40%;
@@ -62,6 +62,9 @@
 .oo-ui-ltr {
        direction: ltr;
 }
+.oo-ui-element-hidden {
+       display: none !important;
+}
 .oo-ui-buttonElement > .oo-ui-buttonElement-button {
        cursor: pointer;
        display: inline-block;
 .oo-ui-buttonElement-frameless.oo-ui-widget-enabled > .oo-ui-buttonElement-button > .oo-ui-labelElement-label {
        color: #757575;
 }
-.oo-ui-buttonElement-frameless.oo-ui-widget-enabled.oo-ui-buttonElement-active > .oo-ui-buttonElement-button > .oo-ui-labelElement-label,
 .oo-ui-buttonElement-frameless.oo-ui-widget-enabled.oo-ui-buttonElement-pressed > .oo-ui-buttonElement-button > .oo-ui-labelElement-label {
        color: #444444;
 }
        color: #777777;
 }
 .oo-ui-buttonElement-frameless.oo-ui-widget-enabled.oo-ui-flaggedElement-progressive.oo-ui-widget-enabled > .oo-ui-buttonElement-button:active > .oo-ui-labelElement-label,
-.oo-ui-buttonElement-frameless.oo-ui-widget-enabled.oo-ui-flaggedElement-progressive.oo-ui-widget-enabled.oo-ui-buttonElement-active > .oo-ui-buttonElement-button > .oo-ui-labelElement-label,
 .oo-ui-buttonElement-frameless.oo-ui-widget-enabled.oo-ui-flaggedElement-progressive.oo-ui-widget-enabled.oo-ui-buttonElement-pressed > .oo-ui-buttonElement-button > .oo-ui-labelElement-label {
        color: #015ccc;
        box-shadow: none;
        color: #777777;
 }
 .oo-ui-buttonElement-frameless.oo-ui-widget-enabled.oo-ui-flaggedElement-constructive.oo-ui-widget-enabled > .oo-ui-buttonElement-button:active > .oo-ui-labelElement-label,
-.oo-ui-buttonElement-frameless.oo-ui-widget-enabled.oo-ui-flaggedElement-constructive.oo-ui-widget-enabled.oo-ui-buttonElement-active > .oo-ui-buttonElement-button > .oo-ui-labelElement-label,
 .oo-ui-buttonElement-frameless.oo-ui-widget-enabled.oo-ui-flaggedElement-constructive.oo-ui-widget-enabled.oo-ui-buttonElement-pressed > .oo-ui-buttonElement-button > .oo-ui-labelElement-label {
        color: #008c6d;
        box-shadow: none;
        color: #777777;
 }
 .oo-ui-buttonElement-frameless.oo-ui-widget-enabled.oo-ui-flaggedElement-destructive.oo-ui-widget-enabled > .oo-ui-buttonElement-button:active > .oo-ui-labelElement-label,
-.oo-ui-buttonElement-frameless.oo-ui-widget-enabled.oo-ui-flaggedElement-destructive.oo-ui-widget-enabled.oo-ui-buttonElement-active > .oo-ui-buttonElement-button > .oo-ui-labelElement-label,
 .oo-ui-buttonElement-frameless.oo-ui-widget-enabled.oo-ui-flaggedElement-destructive.oo-ui-widget-enabled.oo-ui-buttonElement-pressed > .oo-ui-buttonElement-button > .oo-ui-labelElement-label {
        color: #a7170f;
        box-shadow: none;
 }
 .oo-ui-buttonElement-frameless.oo-ui-widget-disabled > .oo-ui-buttonElement-button {
-       color: #eeeeee;
+       color: #cccccc;
 }
 .oo-ui-buttonElement-framed > .oo-ui-buttonElement-button {
        margin: 0.1em 0;
 }
 .oo-ui-buttonElement-framed.oo-ui-widget-disabled > .oo-ui-buttonElement-button {
        color: #ffffff;
-       background: #eeeeee;
-       border: 1px solid #eeeeee;
+       background: #dddddd;
+       border: 1px solid #dddddd;
 }
 .oo-ui-buttonElement-framed.oo-ui-widget-enabled > .oo-ui-buttonElement-button {
        color: #757575;
        box-shadow: inset 0 0 0 1px rgba(0, 0, 0, 0.2);
 }
 .oo-ui-buttonElement-framed.oo-ui-widget-enabled > .oo-ui-buttonElement-button:active,
-.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-buttonElement-active > .oo-ui-buttonElement-button,
 .oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-buttonElement-pressed > .oo-ui-buttonElement-button {
        background-color: #d0d0d0;
        border-color: #d0d0d0;
        box-shadow: none;
 }
+.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-buttonElement-active > .oo-ui-buttonElement-button {
+       background-color: #999999;
+       color: #ffffff;
+}
 .oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-progressive > .oo-ui-buttonElement-button {
        color: #0274ff;
 }
        border-color: #015ccc;
 }
 .oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-progressive.oo-ui-widget-enabled .oo-ui-buttonElement-button:active,
-.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-progressive.oo-ui-widget-enabled.oo-ui-buttonElement-active > .oo-ui-buttonElement-button,
 .oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-progressive.oo-ui-widget-enabled.oo-ui-buttonElement-pressed > .oo-ui-buttonElement-button {
        color: #015ccc;
        border-color: #d0d0d0;
        box-shadow: none;
 }
+.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-progressive.oo-ui-widget-enabled.oo-ui-buttonElement-active > .oo-ui-buttonElement-button {
+       background-color: #999999;
+       color: #ffffff;
+}
 .oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-constructive > .oo-ui-buttonElement-button {
        color: #00af89;
 }
        border-color: #008c6d;
 }
 .oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-constructive.oo-ui-widget-enabled .oo-ui-buttonElement-button:active,
-.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-constructive.oo-ui-widget-enabled.oo-ui-buttonElement-active > .oo-ui-buttonElement-button,
 .oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-constructive.oo-ui-widget-enabled.oo-ui-buttonElement-pressed > .oo-ui-buttonElement-button {
        color: #008c6d;
        border-color: #d0d0d0;
        box-shadow: none;
 }
+.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-constructive.oo-ui-widget-enabled.oo-ui-buttonElement-active > .oo-ui-buttonElement-button {
+       background-color: #999999;
+       color: #ffffff;
+}
 .oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-destructive > .oo-ui-buttonElement-button {
        color: #d11d13;
 }
        border-color: #a7170f;
 }
 .oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-destructive.oo-ui-widget-enabled .oo-ui-buttonElement-button:active,
-.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-destructive.oo-ui-widget-enabled.oo-ui-buttonElement-active > .oo-ui-buttonElement-button,
 .oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-destructive.oo-ui-widget-enabled.oo-ui-buttonElement-pressed > .oo-ui-buttonElement-button {
        color: #a7170f;
        border-color: #d0d0d0;
        box-shadow: none;
 }
+.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-destructive.oo-ui-widget-enabled.oo-ui-buttonElement-active > .oo-ui-buttonElement-button {
+       background-color: #999999;
+       color: #ffffff;
+}
 .oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-primary.oo-ui-flaggedElement-progressive > .oo-ui-buttonElement-button {
        color: #ffffff;
        background-color: #0274ff;
        border-color: #015ccc;
 }
 .oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-primary.oo-ui-flaggedElement-progressive.oo-ui-widget-enabled .oo-ui-buttonElement-button:active,
-.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-primary.oo-ui-flaggedElement-progressive.oo-ui-widget-enabled.oo-ui-buttonElement-active > .oo-ui-buttonElement-button,
 .oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-primary.oo-ui-flaggedElement-progressive.oo-ui-widget-enabled.oo-ui-buttonElement-pressed > .oo-ui-buttonElement-button {
+       color: #ffffff;
        background-color: #015ccc;
        border-color: #015ccc;
        box-shadow: none;
 }
+.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-primary.oo-ui-flaggedElement-progressive.oo-ui-widget-enabled.oo-ui-buttonElement-active > .oo-ui-buttonElement-button {
+       background-color: #999999;
+       color: #ffffff;
+}
 .oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-primary.oo-ui-flaggedElement-constructive > .oo-ui-buttonElement-button {
        color: #ffffff;
        background-color: #00af89;
        border-color: #008c6d;
 }
 .oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-primary.oo-ui-flaggedElement-constructive.oo-ui-widget-enabled .oo-ui-buttonElement-button:active,
-.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-primary.oo-ui-flaggedElement-constructive.oo-ui-widget-enabled.oo-ui-buttonElement-active > .oo-ui-buttonElement-button,
 .oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-primary.oo-ui-flaggedElement-constructive.oo-ui-widget-enabled.oo-ui-buttonElement-pressed > .oo-ui-buttonElement-button {
+       color: #ffffff;
        background-color: #008c6d;
        border-color: #008c6d;
        box-shadow: none;
 }
+.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-primary.oo-ui-flaggedElement-constructive.oo-ui-widget-enabled.oo-ui-buttonElement-active > .oo-ui-buttonElement-button {
+       background-color: #999999;
+       color: #ffffff;
+}
 .oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-primary.oo-ui-flaggedElement-destructive > .oo-ui-buttonElement-button {
        color: #ffffff;
        background-color: #d11d13;
        border-color: #a7170f;
 }
 .oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-primary.oo-ui-flaggedElement-destructive.oo-ui-widget-enabled .oo-ui-buttonElement-button:active,
-.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-primary.oo-ui-flaggedElement-destructive.oo-ui-widget-enabled.oo-ui-buttonElement-active > .oo-ui-buttonElement-button,
 .oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-primary.oo-ui-flaggedElement-destructive.oo-ui-widget-enabled.oo-ui-buttonElement-pressed > .oo-ui-buttonElement-button {
+       color: #ffffff;
        background-color: #a7170f;
        border-color: #a7170f;
        box-shadow: none;
 }
+.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-primary.oo-ui-flaggedElement-destructive.oo-ui-widget-enabled.oo-ui-buttonElement-active > .oo-ui-buttonElement-button {
+       background-color: #999999;
+       color: #ffffff;
+}
 .oo-ui-clippableElement-clippable {
        -webkit-box-sizing: border-box;
           -moz-box-sizing: border-box;
 }
 .oo-ui-fieldLayout > .oo-ui-popupButtonWidget {
        margin-right: 0;
+       margin-top: 0.25em;
 }
 .oo-ui-fieldLayout > .oo-ui-popupButtonWidget:last-child {
        margin-right: 0;
 }
-.oo-ui-fieldLayout > .oo-ui-popupButtonWidget > .oo-ui-buttonElement-button > .oo-ui-iconElement-icon {
-       margin-top: 0.25em;
-}
 .oo-ui-fieldLayout-disabled .oo-ui-labelElement-label {
        color: #cccccc;
 }
        width: 1.5em;
        height: 1.5em;
 }
+.oo-ui-fieldsetLayout > .oo-ui-popupButtonWidget {
+       margin-right: 0;
+}
+.oo-ui-fieldsetLayout > .oo-ui-popupButtonWidget:last-child {
+       margin-right: 0;
+}
 .oo-ui-gridLayout {
        position: absolute;
        top: 0;
        left: 0;
        top: 0;
 }
+.oo-ui-menuLayout-top .oo-ui-menuLayout-content {
+       right: 0 !important;
+       bottom: 0 !important;
+       left: 0 !important;
+}
+.oo-ui-menuLayout-after .oo-ui-menuLayout-content {
+       bottom: 0 !important;
+       left: 0 !important;
+       top: 0 !important;
+}
+.oo-ui-menuLayout-bottom .oo-ui-menuLayout-content {
+       left: 0 !important;
+       top: 0 !important;
+       right: 0 !important;
+}
+.oo-ui-menuLayout-before .oo-ui-menuLayout-content {
+       top: 0 !important;
+       right: 0 !important;
+       bottom: 0 !important;
+}
 .oo-ui-panelLayout {
        position: relative;
 }
 .oo-ui-panelLayout-padded {
        padding: 1.25em;
 }
-.oo-ui-stackLayout > .oo-ui-panelLayout {
-       display: none;
-}
 .oo-ui-stackLayout-continuous > .oo-ui-panelLayout {
        display: block;
        position: relative;
        background-image: none;
 }
 .oo-ui-menuToolGroup .oo-ui-tool-active .oo-ui-tool-link .oo-ui-iconElement-icon {
-       background-image: /* @embed */ url(themes/mediawiki/images/icons/check.svg);
+       background-image: /* @embed */ url(themes/mediawiki/images/icons/check.png);
 }
 .oo-ui-menuToolGroup .oo-ui-tool.oo-ui-widget-enabled:hover {
        background-color: #eeeeee;
 .oo-ui-buttonSelectWidget:last-child {
        margin-right: 0;
 }
-.oo-ui-buttonSelectWidget .oo-ui-buttonOptionWidget.oo-ui-buttonElement-active .oo-ui-buttonElement-button {
-       background: #999999;
-       color: #ffffff;
-}
 .oo-ui-buttonSelectWidget .oo-ui-buttonOptionWidget .oo-ui-buttonElement-button {
        border-radius: 0;
        margin-left: -1px;
 .oo-ui-buttonGroupWidget .oo-ui-buttonWidget:last-child {
        margin-right: 0;
 }
-.oo-ui-buttonGroupWidget .oo-ui-buttonElement-framed.oo-ui-buttonElement-active .oo-ui-buttonElement-button {
-       background: #999999;
-       color: #ffffff;
-}
 .oo-ui-buttonGroupWidget .oo-ui-buttonElement-framed .oo-ui-buttonElement-button {
        border-radius: 0;
        margin-left: -1px;
 }
 .oo-ui-progressBarWidget {
        max-width: 50em;
-       border: solid 1px #0274ff;
+       border: solid 1px #cccccc;
        border-radius: 0.1em;
        overflow: hidden;
 }
 .oo-ui-progressBarWidget-bar {
        height: 1em;
-       background: #0274ff;
+       background: #dddddd;
        -webkit-transition: width 200ms, margin-left 200ms;
           -moz-transition: width 200ms, margin-left 200ms;
            -ms-transition: width 200ms, margin-left 200ms;
        border-left-width: 1px;
 }
 .oo-ui-progressBarWidget.oo-ui-widget-disabled {
-       opacity: 0.2;
+       opacity: 0.6;
 }
 .oo-ui-actionWidget.oo-ui-pendingElement-pending {
        background-image: /* @embed */ url(themes/mediawiki/images/textures/pending.gif);
 }
 .oo-ui-checkboxInputWidget input[type="checkbox"] {
        opacity: 0;
+       position: relative;
+       z-index: 1;
        margin: 0;
        width: 1.6em;
        height: 1.6em;
        height: 1.6em;
        background-color: white;
        border: 1px solid #777777;
-       background-image: /* @embed */ url(themes/mediawiki/images/icons/check-constructive.svg);
+       background-image: /* @embed */ url(themes/mediawiki/images/icons/check-constructive.png);
        background-repeat: no-repeat;
        background-position: center center;
        background-origin: border-box;
        border-color: #eeeeee;
 }
 .oo-ui-checkboxInputWidget input[type="checkbox"]:disabled:checked + span::before {
-       background-image: /* @embed */ url(themes/mediawiki/images/icons/check-invert.svg);
+       background-image: /* @embed */ url(themes/mediawiki/images/icons/check-invert.png);
 }
 .oo-ui-dropdownInputWidget {
        position: relative;
 }
 .oo-ui-radioInputWidget input[type="radio"] {
        opacity: 0;
+       position: relative;
+       z-index: 1;
        margin: 0;
        width: 1.6em;
        height: 1.6em;
        height: 1.6em;
        background: white;
        border: 1px solid #777777;
-       background-image: /* @embed */ url(themes/mediawiki/images/icons/circle-constructive.svg);
+       background-image: /* @embed */ url(themes/mediawiki/images/icons/circle-constructive.png);
        background-repeat: no-repeat;
        background-position: center center;
        background-origin: border-box;
        border-color: #eeeeee;
 }
 .oo-ui-radioInputWidget input[type="radio"]:disabled:checked + span::before {
-       background-image: /* @embed */ url(themes/mediawiki/images/icons/circle-invert.svg);
+       background-image: /* @embed */ url(themes/mediawiki/images/icons/circle-invert.png);
 }
 .oo-ui-textInputWidget {
        position: relative;
           -moz-box-sizing: border-box;
                box-sizing: border-box;
 }
-.oo-ui-window-frame > iframe {
-       width: 100%;
-       height: 100%;
-       margin: 0;
-       padding: 0;
-}
 .oo-ui-window-content:focus {
        outline: none;
 }
        height: 0;
        overflow: hidden;
 }
-.oo-ui-windowManager-modal > .oo-ui-dialog.oo-ui-window-load {
+.oo-ui-windowManager-modal > .oo-ui-dialog.oo-ui-window-active {
        width: auto;
        height: auto;
        top: 0;
        overflow: hidden;
        max-width: 100%;
        max-height: 100%;
-       visibility: visible;
-}
-.oo-ui-windowManager-modal > .oo-ui-dialog.oo-ui-window-setup > .oo-ui-window-frame > iframe {
-       width: 100%;
-       height: 100%;
-}
-.oo-ui-windowManager-modal > .oo-ui-dialog > .oo-ui-window-frame {
-       visibility: hidden;
 }
 .oo-ui-windowManager-fullscreen > .oo-ui-dialog > .oo-ui-window-frame {
        width: 100%;
        top: 1em;
        bottom: 1em;
        background-color: #ffffff;
+       opacity: 0;
        -webkit-transform: scale(0.5);
           -moz-transform: scale(0.5);
            -ms-transform: scale(0.5);
             -o-transition: all 250ms ease-in-out;
                transition: all 250ms ease-in-out;
 }
-.oo-ui-windowManager-modal > .oo-ui-dialog.oo-ui-window-load {
+.oo-ui-windowManager-modal > .oo-ui-dialog.oo-ui-window-ready {
+       /* Fade window overlay */
        opacity: 1;
 }
 .oo-ui-windowManager-modal > .oo-ui-dialog.oo-ui-window-ready > .oo-ui-window-frame {
+       /* Fade frame */
+       opacity: 1;
        -webkit-transform: scale(1);
           -moz-transform: scale(1);
            -ms-transform: scale(1);
index 75ffcc1..42e3053 100644 (file)
@@ -1,12 +1,12 @@
 /*!
- * OOjs UI v0.6.4
+ * OOjs UI v0.7.0
  * https://www.mediawiki.org/wiki/OOjs_UI
  *
  * Copyright 2011–2015 OOjs Team and other contributors.
  * Released under the MIT license
  * http://oojs.mit-license.org
  *
- * Date: 2015-01-31T01:15:57Z
+ * Date: 2015-02-12T00:04:43Z
  */
 /**
  * @class
index f4e7371..0d16099 100644 (file)
@@ -1,12 +1,12 @@
 /*!
- * OOjs UI v0.6.4
+ * OOjs UI v0.7.0
  * https://www.mediawiki.org/wiki/OOjs_UI
  *
  * Copyright 2011–2015 OOjs Team and other contributors.
  * Released under the MIT license
  * http://oojs.mit-license.org
  *
- * Date: 2015-01-31T01:16:05Z
+ * Date: 2015-02-12T00:04:52Z
  */
 .oo-ui-progressBarWidget-slide-frames from {
        margin-left: -40%;
@@ -62,6 +62,9 @@
 .oo-ui-ltr {
        direction: ltr;
 }
+.oo-ui-element-hidden {
+       display: none !important;
+}
 .oo-ui-buttonElement > .oo-ui-buttonElement-button {
        cursor: pointer;
        display: inline-block;
 .oo-ui-buttonElement-frameless.oo-ui-widget-enabled > .oo-ui-buttonElement-button > .oo-ui-labelElement-label {
        color: #757575;
 }
-.oo-ui-buttonElement-frameless.oo-ui-widget-enabled.oo-ui-buttonElement-active > .oo-ui-buttonElement-button > .oo-ui-labelElement-label,
 .oo-ui-buttonElement-frameless.oo-ui-widget-enabled.oo-ui-buttonElement-pressed > .oo-ui-buttonElement-button > .oo-ui-labelElement-label {
        color: #444444;
 }
        color: #777777;
 }
 .oo-ui-buttonElement-frameless.oo-ui-widget-enabled.oo-ui-flaggedElement-progressive.oo-ui-widget-enabled > .oo-ui-buttonElement-button:active > .oo-ui-labelElement-label,
-.oo-ui-buttonElement-frameless.oo-ui-widget-enabled.oo-ui-flaggedElement-progressive.oo-ui-widget-enabled.oo-ui-buttonElement-active > .oo-ui-buttonElement-button > .oo-ui-labelElement-label,
 .oo-ui-buttonElement-frameless.oo-ui-widget-enabled.oo-ui-flaggedElement-progressive.oo-ui-widget-enabled.oo-ui-buttonElement-pressed > .oo-ui-buttonElement-button > .oo-ui-labelElement-label {
        color: #015ccc;
        box-shadow: none;
        color: #777777;
 }
 .oo-ui-buttonElement-frameless.oo-ui-widget-enabled.oo-ui-flaggedElement-constructive.oo-ui-widget-enabled > .oo-ui-buttonElement-button:active > .oo-ui-labelElement-label,
-.oo-ui-buttonElement-frameless.oo-ui-widget-enabled.oo-ui-flaggedElement-constructive.oo-ui-widget-enabled.oo-ui-buttonElement-active > .oo-ui-buttonElement-button > .oo-ui-labelElement-label,
 .oo-ui-buttonElement-frameless.oo-ui-widget-enabled.oo-ui-flaggedElement-constructive.oo-ui-widget-enabled.oo-ui-buttonElement-pressed > .oo-ui-buttonElement-button > .oo-ui-labelElement-label {
        color: #008c6d;
        box-shadow: none;
        color: #777777;
 }
 .oo-ui-buttonElement-frameless.oo-ui-widget-enabled.oo-ui-flaggedElement-destructive.oo-ui-widget-enabled > .oo-ui-buttonElement-button:active > .oo-ui-labelElement-label,
-.oo-ui-buttonElement-frameless.oo-ui-widget-enabled.oo-ui-flaggedElement-destructive.oo-ui-widget-enabled.oo-ui-buttonElement-active > .oo-ui-buttonElement-button > .oo-ui-labelElement-label,
 .oo-ui-buttonElement-frameless.oo-ui-widget-enabled.oo-ui-flaggedElement-destructive.oo-ui-widget-enabled.oo-ui-buttonElement-pressed > .oo-ui-buttonElement-button > .oo-ui-labelElement-label {
        color: #a7170f;
        box-shadow: none;
 }
 .oo-ui-buttonElement-frameless.oo-ui-widget-disabled > .oo-ui-buttonElement-button {
-       color: #eeeeee;
+       color: #cccccc;
 }
 .oo-ui-buttonElement-framed > .oo-ui-buttonElement-button {
        margin: 0.1em 0;
 }
 .oo-ui-buttonElement-framed.oo-ui-widget-disabled > .oo-ui-buttonElement-button {
        color: #ffffff;
-       background: #eeeeee;
-       border: 1px solid #eeeeee;
+       background: #dddddd;
+       border: 1px solid #dddddd;
 }
 .oo-ui-buttonElement-framed.oo-ui-widget-enabled > .oo-ui-buttonElement-button {
        color: #757575;
        box-shadow: inset 0 0 0 1px rgba(0, 0, 0, 0.2);
 }
 .oo-ui-buttonElement-framed.oo-ui-widget-enabled > .oo-ui-buttonElement-button:active,
-.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-buttonElement-active > .oo-ui-buttonElement-button,
 .oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-buttonElement-pressed > .oo-ui-buttonElement-button {
        background-color: #d0d0d0;
        border-color: #d0d0d0;
        box-shadow: none;
 }
+.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-buttonElement-active > .oo-ui-buttonElement-button {
+       background-color: #999999;
+       color: #ffffff;
+}
 .oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-progressive > .oo-ui-buttonElement-button {
        color: #0274ff;
 }
        border-color: #015ccc;
 }
 .oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-progressive.oo-ui-widget-enabled .oo-ui-buttonElement-button:active,
-.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-progressive.oo-ui-widget-enabled.oo-ui-buttonElement-active > .oo-ui-buttonElement-button,
 .oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-progressive.oo-ui-widget-enabled.oo-ui-buttonElement-pressed > .oo-ui-buttonElement-button {
        color: #015ccc;
        border-color: #d0d0d0;
        box-shadow: none;
 }
+.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-progressive.oo-ui-widget-enabled.oo-ui-buttonElement-active > .oo-ui-buttonElement-button {
+       background-color: #999999;
+       color: #ffffff;
+}
 .oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-constructive > .oo-ui-buttonElement-button {
        color: #00af89;
 }
        border-color: #008c6d;
 }
 .oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-constructive.oo-ui-widget-enabled .oo-ui-buttonElement-button:active,
-.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-constructive.oo-ui-widget-enabled.oo-ui-buttonElement-active > .oo-ui-buttonElement-button,
 .oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-constructive.oo-ui-widget-enabled.oo-ui-buttonElement-pressed > .oo-ui-buttonElement-button {
        color: #008c6d;
        border-color: #d0d0d0;
        box-shadow: none;
 }
+.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-constructive.oo-ui-widget-enabled.oo-ui-buttonElement-active > .oo-ui-buttonElement-button {
+       background-color: #999999;
+       color: #ffffff;
+}
 .oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-destructive > .oo-ui-buttonElement-button {
        color: #d11d13;
 }
        border-color: #a7170f;
 }
 .oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-destructive.oo-ui-widget-enabled .oo-ui-buttonElement-button:active,
-.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-destructive.oo-ui-widget-enabled.oo-ui-buttonElement-active > .oo-ui-buttonElement-button,
 .oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-destructive.oo-ui-widget-enabled.oo-ui-buttonElement-pressed > .oo-ui-buttonElement-button {
        color: #a7170f;
        border-color: #d0d0d0;
        box-shadow: none;
 }
+.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-destructive.oo-ui-widget-enabled.oo-ui-buttonElement-active > .oo-ui-buttonElement-button {
+       background-color: #999999;
+       color: #ffffff;
+}
 .oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-primary.oo-ui-flaggedElement-progressive > .oo-ui-buttonElement-button {
        color: #ffffff;
        background-color: #0274ff;
        border-color: #015ccc;
 }
 .oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-primary.oo-ui-flaggedElement-progressive.oo-ui-widget-enabled .oo-ui-buttonElement-button:active,
-.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-primary.oo-ui-flaggedElement-progressive.oo-ui-widget-enabled.oo-ui-buttonElement-active > .oo-ui-buttonElement-button,
 .oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-primary.oo-ui-flaggedElement-progressive.oo-ui-widget-enabled.oo-ui-buttonElement-pressed > .oo-ui-buttonElement-button {
+       color: #ffffff;
        background-color: #015ccc;
        border-color: #015ccc;
        box-shadow: none;
 }
+.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-primary.oo-ui-flaggedElement-progressive.oo-ui-widget-enabled.oo-ui-buttonElement-active > .oo-ui-buttonElement-button {
+       background-color: #999999;
+       color: #ffffff;
+}
 .oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-primary.oo-ui-flaggedElement-constructive > .oo-ui-buttonElement-button {
        color: #ffffff;
        background-color: #00af89;
        border-color: #008c6d;
 }
 .oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-primary.oo-ui-flaggedElement-constructive.oo-ui-widget-enabled .oo-ui-buttonElement-button:active,
-.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-primary.oo-ui-flaggedElement-constructive.oo-ui-widget-enabled.oo-ui-buttonElement-active > .oo-ui-buttonElement-button,
 .oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-primary.oo-ui-flaggedElement-constructive.oo-ui-widget-enabled.oo-ui-buttonElement-pressed > .oo-ui-buttonElement-button {
+       color: #ffffff;
        background-color: #008c6d;
        border-color: #008c6d;
        box-shadow: none;
 }
+.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-primary.oo-ui-flaggedElement-constructive.oo-ui-widget-enabled.oo-ui-buttonElement-active > .oo-ui-buttonElement-button {
+       background-color: #999999;
+       color: #ffffff;
+}
 .oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-primary.oo-ui-flaggedElement-destructive > .oo-ui-buttonElement-button {
        color: #ffffff;
        background-color: #d11d13;
        border-color: #a7170f;
 }
 .oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-primary.oo-ui-flaggedElement-destructive.oo-ui-widget-enabled .oo-ui-buttonElement-button:active,
-.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-primary.oo-ui-flaggedElement-destructive.oo-ui-widget-enabled.oo-ui-buttonElement-active > .oo-ui-buttonElement-button,
 .oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-primary.oo-ui-flaggedElement-destructive.oo-ui-widget-enabled.oo-ui-buttonElement-pressed > .oo-ui-buttonElement-button {
+       color: #ffffff;
        background-color: #a7170f;
        border-color: #a7170f;
        box-shadow: none;
 }
+.oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-primary.oo-ui-flaggedElement-destructive.oo-ui-widget-enabled.oo-ui-buttonElement-active > .oo-ui-buttonElement-button {
+       background-color: #999999;
+       color: #ffffff;
+}
 .oo-ui-clippableElement-clippable {
        -webkit-box-sizing: border-box;
           -moz-box-sizing: border-box;
 }
 .oo-ui-fieldLayout > .oo-ui-popupButtonWidget {
        margin-right: 0;
+       margin-top: 0.25em;
 }
 .oo-ui-fieldLayout > .oo-ui-popupButtonWidget:last-child {
        margin-right: 0;
 }
-.oo-ui-fieldLayout > .oo-ui-popupButtonWidget > .oo-ui-buttonElement-button > .oo-ui-iconElement-icon {
-       margin-top: 0.25em;
-}
 .oo-ui-fieldLayout-disabled .oo-ui-labelElement-label {
        color: #cccccc;
 }
        width: 1.5em;
        height: 1.5em;
 }
+.oo-ui-fieldsetLayout > .oo-ui-popupButtonWidget {
+       margin-right: 0;
+}
+.oo-ui-fieldsetLayout > .oo-ui-popupButtonWidget:last-child {
+       margin-right: 0;
+}
 .oo-ui-gridLayout {
        position: absolute;
        top: 0;
        left: 0;
        top: 0;
 }
+.oo-ui-menuLayout-top .oo-ui-menuLayout-content {
+       right: 0 !important;
+       bottom: 0 !important;
+       left: 0 !important;
+}
+.oo-ui-menuLayout-after .oo-ui-menuLayout-content {
+       bottom: 0 !important;
+       left: 0 !important;
+       top: 0 !important;
+}
+.oo-ui-menuLayout-bottom .oo-ui-menuLayout-content {
+       left: 0 !important;
+       top: 0 !important;
+       right: 0 !important;
+}
+.oo-ui-menuLayout-before .oo-ui-menuLayout-content {
+       top: 0 !important;
+       right: 0 !important;
+       bottom: 0 !important;
+}
 .oo-ui-panelLayout {
        position: relative;
 }
 .oo-ui-panelLayout-padded {
        padding: 1.25em;
 }
-.oo-ui-stackLayout > .oo-ui-panelLayout {
-       display: none;
-}
 .oo-ui-stackLayout-continuous > .oo-ui-panelLayout {
        display: block;
        position: relative;
 .oo-ui-buttonSelectWidget:last-child {
        margin-right: 0;
 }
-.oo-ui-buttonSelectWidget .oo-ui-buttonOptionWidget.oo-ui-buttonElement-active .oo-ui-buttonElement-button {
-       background: #999999;
-       color: #ffffff;
-}
 .oo-ui-buttonSelectWidget .oo-ui-buttonOptionWidget .oo-ui-buttonElement-button {
        border-radius: 0;
        margin-left: -1px;
 .oo-ui-buttonGroupWidget .oo-ui-buttonWidget:last-child {
        margin-right: 0;
 }
-.oo-ui-buttonGroupWidget .oo-ui-buttonElement-framed.oo-ui-buttonElement-active .oo-ui-buttonElement-button {
-       background: #999999;
-       color: #ffffff;
-}
 .oo-ui-buttonGroupWidget .oo-ui-buttonElement-framed .oo-ui-buttonElement-button {
        border-radius: 0;
        margin-left: -1px;
 }
 .oo-ui-progressBarWidget {
        max-width: 50em;
-       border: solid 1px #0274ff;
+       border: solid 1px #cccccc;
        border-radius: 0.1em;
        overflow: hidden;
 }
 .oo-ui-progressBarWidget-bar {
        height: 1em;
-       background: #0274ff;
+       background: #dddddd;
        -webkit-transition: width 200ms, margin-left 200ms;
           -moz-transition: width 200ms, margin-left 200ms;
            -ms-transition: width 200ms, margin-left 200ms;
        border-left-width: 1px;
 }
 .oo-ui-progressBarWidget.oo-ui-widget-disabled {
-       opacity: 0.2;
+       opacity: 0.6;
 }
 .oo-ui-actionWidget.oo-ui-pendingElement-pending {
        background-image: /* @embed */ url(themes/mediawiki/images/textures/pending.gif);
 }
 .oo-ui-checkboxInputWidget input[type="checkbox"] {
        opacity: 0;
+       position: relative;
+       z-index: 1;
        margin: 0;
        width: 1.6em;
        height: 1.6em;
 }
 .oo-ui-radioInputWidget input[type="radio"] {
        opacity: 0;
+       position: relative;
+       z-index: 1;
        margin: 0;
        width: 1.6em;
        height: 1.6em;
           -moz-box-sizing: border-box;
                box-sizing: border-box;
 }
-.oo-ui-window-frame > iframe {
-       width: 100%;
-       height: 100%;
-       margin: 0;
-       padding: 0;
-}
 .oo-ui-window-content:focus {
        outline: none;
 }
        height: 0;
        overflow: hidden;
 }
-.oo-ui-windowManager-modal > .oo-ui-dialog.oo-ui-window-load {
+.oo-ui-windowManager-modal > .oo-ui-dialog.oo-ui-window-active {
        width: auto;
        height: auto;
        top: 0;
        overflow: hidden;
        max-width: 100%;
        max-height: 100%;
-       visibility: visible;
-}
-.oo-ui-windowManager-modal > .oo-ui-dialog.oo-ui-window-setup > .oo-ui-window-frame > iframe {
-       width: 100%;
-       height: 100%;
-}
-.oo-ui-windowManager-modal > .oo-ui-dialog > .oo-ui-window-frame {
-       visibility: hidden;
 }
 .oo-ui-windowManager-fullscreen > .oo-ui-dialog > .oo-ui-window-frame {
        width: 100%;
        top: 1em;
        bottom: 1em;
        background-color: #ffffff;
+       opacity: 0;
        -webkit-transform: scale(0.5);
           -moz-transform: scale(0.5);
            -ms-transform: scale(0.5);
             -o-transition: all 250ms ease-in-out;
                transition: all 250ms ease-in-out;
 }
-.oo-ui-windowManager-modal > .oo-ui-dialog.oo-ui-window-load {
+.oo-ui-windowManager-modal > .oo-ui-dialog.oo-ui-window-ready {
+       /* Fade window overlay */
        opacity: 1;
 }
 .oo-ui-windowManager-modal > .oo-ui-dialog.oo-ui-window-ready > .oo-ui-window-frame {
+       /* Fade frame */
+       opacity: 1;
        -webkit-transform: scale(1);
           -moz-transform: scale(1);
            -ms-transform: scale(1);
index f013b06..f85202e 100644 (file)
@@ -1,12 +1,12 @@
 /*!
- * OOjs UI v0.6.4
+ * OOjs UI v0.7.0
  * https://www.mediawiki.org/wiki/OOjs_UI
  *
  * Copyright 2011–2015 OOjs Team and other contributors.
  * Released under the MIT license
  * http://oojs.mit-license.org
  *
- * Date: 2015-01-31T01:15:57Z
+ * Date: 2015-02-12T00:04:43Z
  */
 ( function ( OO ) {
 
@@ -720,7 +720,6 @@ OO.ui.ActionSet.prototype.organize = function () {
  *
  * @constructor
  * @param {Object} [config] Configuration options
- * @cfg {Function} [$] jQuery for the frame the widget is in
  * @cfg {string[]} [classes] CSS class names to add
  * @cfg {string} [id] HTML id attribute
  * @cfg {string} [text] Text to insert
@@ -732,9 +731,9 @@ OO.ui.Element = function OoUiElement( config ) {
        config = config || {};
 
        // Properties
-       this.$ = config.$ || OO.ui.Element.static.getJQuery( document );
+       this.$ = $;
        this.data = config.data;
-       this.$element = this.$( this.$.context.createElement( this.getTagName() ) );
+       this.$element = $( document.createElement( this.getTagName() ) );
        this.elementGroup = null;
        this.debouncedUpdateThemeClassesHandler = this.debouncedUpdateThemeClasses.bind( this );
        this.updateThemeClassesPending = false;
@@ -1259,7 +1258,6 @@ OO.ui.Element.prototype.isElementAttached = function () {
  * @return {HTMLDocument} Document object
  */
 OO.ui.Element.prototype.getElementDocument = function () {
-       // Don't use this.$.context because subclasses can rebind this.$
        // Don't cache this in other ways either because subclasses could can change this.$element
        return OO.ui.Element.static.getDocument( this.$element );
 };
@@ -1445,7 +1443,7 @@ OO.ui.Widget.prototype.toggle = function ( show ) {
 
        if ( show !== this.isVisible() ) {
                this.visible = show;
-               this.$element.toggle( show );
+               this.$element.toggleClass( 'oo-ui-element-hidden', !this.visible );
                this.emit( 'toggle', show );
        }
 
@@ -1463,7 +1461,7 @@ OO.ui.Widget.prototype.updateDisabled = function () {
 };
 
 /**
- * Container for elements in a child frame.
+ * Encapsulation of an user interface.
  *
  * Use together with OO.ui.WindowManager.
  *
@@ -1514,25 +1512,29 @@ OO.ui.Window = function OoUiWindow( config ) {
 
        // Properties
        this.manager = null;
-       this.initialized = false;
-       this.visible = false;
-       this.opening = null;
-       this.closing = null;
-       this.opened = null;
-       this.timing = null;
-       this.loading = null;
        this.size = config.size || this.constructor.static.size;
-       this.$frame = this.$( '<div>' );
-       this.$overlay = this.$( '<div>' );
+       this.$frame = $( '<div>' );
+       this.$overlay = $( '<div>' );
+       this.$content = $( '<div>' );
 
        // Initialization
+       this.$overlay.addClass( 'oo-ui-window-overlay' );
+       this.$content
+               .addClass( 'oo-ui-window-content' )
+               .attr( 'tabIndex', 0 );
+       this.$frame
+               .addClass( 'oo-ui-window-frame' )
+               .append( this.$content );
+
        this.$element
                .addClass( 'oo-ui-window' )
                .append( this.$frame, this.$overlay );
-       this.$frame.addClass( 'oo-ui-window-frame' );
-       this.$overlay.addClass( 'oo-ui-window-overlay' );
 
-       // NOTE: Additional initialization will occur when #setManager is called
+       // Initially hidden - using #toggle may cause errors if subclasses override toggle with methods
+       // that reference properties not initialized at that time of parent class construction
+       // TODO: Find a better way to handle post-constructor setup
+       this.visible = false;
+       this.$element.addClass( 'oo-ui-element-hidden' );
 };
 
 /* Setup */
@@ -1553,118 +1555,6 @@ OO.mixinClass( OO.ui.Window, OO.EventEmitter );
  */
 OO.ui.Window.static.size = 'medium';
 
-/* Static Methods */
-
-/**
- * Transplant the CSS styles from as parent document to a frame's document.
- *
- * This loops over the style sheets in the parent document, and copies their nodes to the
- * frame's document. It then polls the document to see when all styles have loaded, and once they
- * have, resolves the promise.
- *
- * If the styles still haven't loaded after a long time (5 seconds by default), we give up waiting
- * and resolve the promise anyway. This protects against cases like a display: none; iframe in
- * Firefox, where the styles won't load until the iframe becomes visible.
- *
- * For details of how we arrived at the strategy used in this function, see #load.
- *
- * @static
- * @inheritable
- * @param {HTMLDocument} parentDoc Document to transplant styles from
- * @param {HTMLDocument} frameDoc Document to transplant styles to
- * @param {number} [timeout=5000] How long to wait before giving up (in ms). If 0, never give up.
- * @return {jQuery.Promise} Promise resolved when styles have loaded
- */
-OO.ui.Window.static.transplantStyles = function ( parentDoc, frameDoc, timeout ) {
-       var i, numSheets, styleNode, styleText, newNode, timeoutID, pollNodeId, $pendingPollNodes,
-               $pollNodes = $( [] ),
-               // Fake font-family value
-               fontFamily = 'oo-ui-frame-transplantStyles-loaded',
-               nextIndex = parentDoc.oouiFrameTransplantStylesNextIndex || 0,
-               deferred = $.Deferred();
-
-       for ( i = 0, numSheets = parentDoc.styleSheets.length; i < numSheets; i++ ) {
-               styleNode = parentDoc.styleSheets[ i ].ownerNode;
-               if ( styleNode.disabled ) {
-                       continue;
-               }
-
-               if ( styleNode.nodeName.toLowerCase() === 'link' ) {
-                       // External stylesheet; use @import
-                       styleText = '@import url(' + styleNode.href + ');';
-               } else {
-                       // Internal stylesheet; just copy the text
-                       // For IE10 we need to fall back to .cssText, BUT that's undefined in
-                       // other browsers, so fall back to '' rather than 'undefined'
-                       styleText = styleNode.textContent || parentDoc.styleSheets[ i ].cssText || '';
-               }
-
-               // Create a node with a unique ID that we're going to monitor to see when the CSS
-               // has loaded
-               if ( styleNode.oouiFrameTransplantStylesId ) {
-                       // If we're nesting transplantStyles operations and this node already has
-                       // a CSS rule to wait for loading, reuse it
-                       pollNodeId = styleNode.oouiFrameTransplantStylesId;
-               } else {
-                       // Otherwise, create a new ID
-                       pollNodeId = 'oo-ui-frame-transplantStyles-loaded-' + nextIndex;
-                       nextIndex++;
-
-                       // Add #pollNodeId { font-family: ... } to the end of the stylesheet / after the @import
-                       // The font-family rule will only take effect once the @import finishes
-                       styleText += '\n' + '#' + pollNodeId + ' { font-family: ' + fontFamily + '; }';
-               }
-
-               // Create a node with id=pollNodeId
-               $pollNodes = $pollNodes.add( $( '<div>', frameDoc )
-                       .attr( 'id', pollNodeId )
-                       .appendTo( frameDoc.body )
-               );
-
-               // Add our modified CSS as a <style> tag
-               newNode = frameDoc.createElement( 'style' );
-               newNode.textContent = styleText;
-               newNode.oouiFrameTransplantStylesId = pollNodeId;
-               frameDoc.head.appendChild( newNode );
-       }
-       frameDoc.oouiFrameTransplantStylesNextIndex = nextIndex;
-
-       // Poll every 100ms until all external stylesheets have loaded
-       $pendingPollNodes = $pollNodes;
-       timeoutID = setTimeout( function pollExternalStylesheets() {
-               while (
-                       $pendingPollNodes.length > 0 &&
-                       $pendingPollNodes.eq( 0 ).css( 'font-family' ) === fontFamily
-               ) {
-                       $pendingPollNodes = $pendingPollNodes.slice( 1 );
-               }
-
-               if ( $pendingPollNodes.length === 0 ) {
-                       // We're done!
-                       if ( timeoutID !== null ) {
-                               timeoutID = null;
-                               $pollNodes.remove();
-                               deferred.resolve();
-                       }
-               } else {
-                       timeoutID = setTimeout( pollExternalStylesheets, 100 );
-               }
-       }, 100 );
-       // ...but give up after a while
-       if ( timeout !== 0 ) {
-               setTimeout( function () {
-                       if ( timeoutID ) {
-                               clearTimeout( timeoutID );
-                               timeoutID = null;
-                               $pollNodes.remove();
-                               deferred.reject();
-                       }
-               }, timeout || 5000 );
-       }
-
-       return deferred.promise();
-};
-
 /* Methods */
 
 /**
@@ -1682,10 +1572,12 @@ OO.ui.Window.prototype.onMouseDown = function ( e ) {
 /**
  * Check if window has been initialized.
  *
+ * Initialization occurs when a window is added to a manager.
+ *
  * @return {boolean} Window has been initialized
  */
 OO.ui.Window.prototype.isInitialized = function () {
-       return this.initialized;
+       return !!this.manager;
 };
 
 /**
@@ -1697,24 +1589,6 @@ OO.ui.Window.prototype.isVisible = function () {
        return this.visible;
 };
 
-/**
- * Check if window is loading.
- *
- * @return {boolean} Window is loading
- */
-OO.ui.Window.prototype.isLoading = function () {
-       return this.loading && this.loading.state() === 'pending';
-};
-
-/**
- * Check if window is loaded.
- *
- * @return {boolean} Window is loaded
- */
-OO.ui.Window.prototype.isLoaded = function () {
-       return this.loading && this.loading.state() === 'resolved';
-};
-
 /**
  * Check if window is opening.
  *
@@ -1913,9 +1787,6 @@ OO.ui.Window.prototype.getTeardownProcess = function () {
 /**
  * Toggle visibility of window.
  *
- * If the window is isolated and hasn't fully loaded yet, the visibility property will be used
- * instead of display.
- *
  * @param {boolean} [show] Make window visible, omit to toggle visibility
  * @fires toggle
  * @chainable
@@ -1925,14 +1796,7 @@ OO.ui.Window.prototype.toggle = function ( show ) {
 
        if ( show !== this.isVisible() ) {
                this.visible = show;
-
-               if ( this.isolated && !this.isLoaded() ) {
-                       // Hide the window using visibility instead of display until loading is complete
-                       // Can't use display: none; because that prevents the iframe from loading in Firefox
-                       this.$element.css( 'visibility', show ? 'visible' : 'hidden' );
-               } else {
-                       this.$element.toggle( show ).css( 'visibility', '' );
-               }
+               this.$element.toggleClass( 'oo-ui-element-hidden', !this.visible );
                this.emit( 'toggle', show );
        }
 
@@ -1942,7 +1806,7 @@ OO.ui.Window.prototype.toggle = function ( show ) {
 /**
  * Set the window manager.
  *
- * This must be called before initialize. Calling it more than once will cause an error.
+ * This will cause the window to initialize. Calling it more than once will cause an error.
  *
  * @param {OO.ui.WindowManager} manager Manager for this window
  * @throws {Error} If called more than once
@@ -1953,29 +1817,8 @@ OO.ui.Window.prototype.setManager = function ( manager ) {
                throw new Error( 'Cannot set window manager, window already has a manager' );
        }
 
-       // Properties
        this.manager = manager;
-       this.isolated = manager.shouldIsolate();
-
-       // Initialization
-       if ( this.isolated ) {
-               this.$iframe = this.$( '<iframe>' );
-               this.$iframe.attr( { frameborder: 0, scrolling: 'no' } );
-               this.$frame.append( this.$iframe );
-               this.$ = function () {
-                       throw new Error( 'this.$() cannot be used until the frame has been initialized.' );
-               };
-               // WARNING: Do not use this.$ again until #initialize is called
-       } else {
-               this.$content = this.$( '<div>' );
-               this.$document = $( this.getElementDocument() );
-               this.$content.addClass( 'oo-ui-window-content' ).attr( 'tabIndex', 0 );
-               this.$frame.append( this.$content );
-       }
-       this.toggle( false );
-
-       // Figure out directionality:
-       this.dir = OO.ui.Element.static.getDir( this.$iframe || this.$content ) || 'ltr';
+       this.initialize();
 
        return this;
 };
@@ -1995,10 +1838,16 @@ OO.ui.Window.prototype.setSize = function ( size ) {
 /**
  * Update the window size.
  *
+ * @throws {Error} If not attached to a manager
  * @chainable
  */
 OO.ui.Window.prototype.updateSize = function () {
+       if ( !this.manager ) {
+               throw new Error( 'Cannot update window size, must be attached to a manager' );
+       }
+
        this.manager.updateWindowSize( this );
+
        return this;
 };
 
@@ -2048,10 +1897,9 @@ OO.ui.Window.prototype.setDimensions = function ( dim ) {
 /**
  * Initialize window contents.
  *
- * The first time the window is opened, #initialize is called when it's safe to begin populating
- * its contents. See #getSetupProcess for a way to make changes each time the window opens.
- *
- * Once this method is called, this.$ can be used to create elements within the frame.
+ * The first time the window is opened, #initialize is called so that changes to the window that
+ * will persist between openings can be made. See #getSetupProcess for a way to make changes each
+ * time the window opens.
  *
  * @throws {Error} If not attached to a manager
  * @chainable
@@ -2062,10 +1910,12 @@ OO.ui.Window.prototype.initialize = function () {
        }
 
        // Properties
-       this.$head = this.$( '<div>' );
-       this.$body = this.$( '<div>' );
-       this.$foot = this.$( '<div>' );
-       this.$innerOverlay = this.$( '<div>' );
+       this.$head = $( '<div>' );
+       this.$body = $( '<div>' );
+       this.$foot = $( '<div>' );
+       this.$innerOverlay = $( '<div>' );
+       this.dir = OO.ui.Element.static.getDir( this.$content ) || 'ltr';
+       this.$document = $( this.getElementDocument() );
 
        // Events
        this.$element.on( 'mousedown', this.onMouseDown.bind( this ) );
@@ -2089,8 +1939,13 @@ OO.ui.Window.prototype.initialize = function () {
  * @param {Object} [data] Window opening data
  * @return {jQuery.Promise} Promise resolved when window is opened; when the promise is resolved the
  *   first argument will be a promise which will be resolved when the window begins closing
+ * @throws {Error} If not attached to a manager
  */
 OO.ui.Window.prototype.open = function ( data ) {
+       if ( !this.manager ) {
+               throw new Error( 'Cannot open window, must be attached to a manager' );
+       }
+
        return this.manager.openWindow( this, data );
 };
 
@@ -2102,8 +1957,13 @@ OO.ui.Window.prototype.open = function ( data ) {
  *
  * @param {Object} [data] Window closing data
  * @return {jQuery.Promise} Promise resolved when window is closed
+ * @throws {Error} If not attached to a manager
  */
 OO.ui.Window.prototype.close = function ( data ) {
+       if ( !this.manager ) {
+               throw new Error( 'Cannot close window, must be attached to a manager' );
+       }
+
        return this.manager.closeWindow( this, data );
 };
 
@@ -2120,11 +1980,11 @@ OO.ui.Window.prototype.setup = function ( data ) {
        var win = this,
                deferred = $.Deferred();
 
-       this.$element.show();
-       this.visible = true;
+       this.toggle( true );
+
        this.getSetupProcess( data ).execute().done( function () {
                // Force redraw by asking the browser to measure the elements' widths
-               win.$element.addClass( 'oo-ui-window-setup' ).width();
+               win.$element.addClass( 'oo-ui-window-active oo-ui-window-setup' ).width();
                win.$content.addClass( 'oo-ui-window-content-setup' ).width();
                deferred.resolve();
        } );
@@ -2197,117 +2057,15 @@ OO.ui.Window.prototype.hold = function ( data ) {
  * @return {jQuery.Promise} Promise resolved when window is torn down
  */
 OO.ui.Window.prototype.teardown = function ( data ) {
-       var win = this,
-               deferred = $.Deferred();
-
-       this.getTeardownProcess( data ).execute().done( function () {
-               // Force redraw by asking the browser to measure the elements' widths
-               win.$element.removeClass( 'oo-ui-window-load oo-ui-window-setup' ).width();
-               win.$content.removeClass( 'oo-ui-window-content-setup' ).width();
-               win.$element.hide();
-               win.visible = false;
-               deferred.resolve();
-       } );
-
-       return deferred.promise();
-};
-
-/**
- * Load the frame contents.
- *
- * Once the iframe's stylesheets are loaded the returned promise will be resolved. Calling while
- * loading will return a promise but not trigger a new loading cycle. Calling after loading is
- * complete will return a promise that's already been resolved.
- *
- * Sounds simple right? Read on...
- *
- * When you create a dynamic iframe using open/write/close, the window.load event for the
- * iframe is triggered when you call close, and there's no further load event to indicate that
- * everything is actually loaded.
- *
- * In Chrome, stylesheets don't show up in document.styleSheets until they have loaded, so we could
- * just poll that array and wait for it to have the right length. However, in Firefox, stylesheets
- * are added to document.styleSheets immediately, and the only way you can determine whether they've
- * loaded is to attempt to access .cssRules and wait for that to stop throwing an exception. But
- * cross-domain stylesheets never allow .cssRules to be accessed even after they have loaded.
- *
- * The workaround is to change all `<link href="...">` tags to `<style>@import url(...)</style>`
- * tags. Because `@import` is blocking, Chrome won't add the stylesheet to document.styleSheets
- * until the `@import` has finished, and Firefox won't allow .cssRules to be accessed until the
- * `@import` has finished. And because the contents of the `<style>` tag are from the same origin,
- * accessing .cssRules is allowed.
- *
- * However, now that we control the styles we're injecting, we might as well do away with
- * browser-specific polling hacks like document.styleSheets and .cssRules, and instead inject
- * `<style>@import url(...); #foo { font-family: someValue; }</style>`, then create `<div id="foo">`
- * and wait for its font-family to change to someValue. Because `@import` is blocking, the
- * font-family rule is not applied until after the `@import` finishes.
- *
- * All this stylesheet injection and polling magic is in #transplantStyles.
- *
- * @return {jQuery.Promise} Promise resolved when loading is complete
- */
-OO.ui.Window.prototype.load = function () {
-       var sub, doc, loading,
-               win = this;
-
-       this.$element.addClass( 'oo-ui-window-load' );
-
-       // Non-isolated windows are already "loaded"
-       if ( !this.loading && !this.isolated ) {
-               this.loading = $.Deferred().resolve();
-               this.initialize();
-               // Set initialized state after so sub-classes aren't confused by it being set by calling
-               // their parent initialize method
-               this.initialized = true;
-       }
-
-       // Return existing promise if already loading or loaded
-       if ( this.loading ) {
-               return this.loading.promise();
-       }
-
-       // Load the frame
-       loading = this.loading = $.Deferred();
-       sub = this.$iframe.prop( 'contentWindow' );
-       doc = sub.document;
-
-       // Initialize contents
-       doc.open();
-       doc.write(
-               '<!doctype html>' +
-               '<html>' +
-                       '<body class="oo-ui-window-isolated oo-ui-' + this.dir + '"' +
-                               ' style="direction:' + this.dir + ';" dir="' + this.dir + '">' +
-                               '<div class="oo-ui-window-content"></div>' +
-                       '</body>' +
-               '</html>'
-       );
-       doc.close();
-
-       // Properties
-       this.$ = OO.ui.Element.static.getJQuery( doc, this.$iframe );
-       this.$content = this.$( '.oo-ui-window-content' ).attr( 'tabIndex', 0 );
-       this.$document = this.$( doc );
-
-       // Initialization
-       this.constructor.static.transplantStyles( this.getElementDocument(), this.$document[ 0 ] )
-               .always( function () {
-                       // Initialize isolated windows
-                       win.initialize();
-                       // Set initialized state after so sub-classes aren't confused by it being set by calling
-                       // their parent initialize method
-                       win.initialized = true;
-                       // Undo the visibility: hidden; hack and apply display: none;
-                       // We can do this safely now that the iframe has initialized
-                       // (don't do this from within #initialize because it has to happen
-                       // after the all subclasses have been handled as well).
-                       win.toggle( win.isVisible() );
-
-                       loading.resolve();
+       var win = this;
+
+       return this.getTeardownProcess( data ).execute()
+               .done( function () {
+                       // Force redraw by asking the browser to measure the elements' widths
+                       win.$element.removeClass( 'oo-ui-window-active oo-ui-window-setup' ).width();
+                       win.$content.removeClass( 'oo-ui-window-content-setup' ).width();
+                       win.toggle( false );
                } );
-
-       return loading.promise();
 };
 
 /**
@@ -2511,7 +2269,7 @@ OO.ui.Dialog.prototype.getSetupProcess = function ( data ) {
                        );
                        for ( i = 0, len = actions.length; i < len; i++ ) {
                                items.push(
-                                       new OO.ui.ActionWidget( $.extend( { $: this.$ }, actions[ i ] ) )
+                                       new OO.ui.ActionWidget( actions[ i ] )
                                );
                        }
                        this.actions.add( items );
@@ -2546,7 +2304,7 @@ OO.ui.Dialog.prototype.initialize = function () {
        OO.ui.Dialog.super.prototype.initialize.call( this );
 
        // Properties
-       this.title = new OO.ui.LabelWidget( { $: this.$ } );
+       this.title = new OO.ui.LabelWidget();
 
        // Initialization
        this.$content.addClass( 'oo-ui-dialog-content' );
@@ -2628,7 +2386,6 @@ OO.ui.Dialog.prototype.executeAction = function ( action ) {
  *
  * @constructor
  * @param {Object} [config] Configuration options
- * @cfg {boolean} [isolate] Configure managed windows to isolate their content using inline frames
  * @cfg {OO.Factory} [factory] Window factory to use for automatic instantiation
  * @cfg {boolean} [modal=true] Prevent interaction outside the dialog
  */
@@ -2645,22 +2402,17 @@ OO.ui.WindowManager = function OoUiWindowManager( config ) {
        // Properties
        this.factory = config.factory;
        this.modal = config.modal === undefined || !!config.modal;
-       this.isolate = !!config.isolate;
        this.windows = {};
        this.opening = null;
        this.opened = null;
        this.closing = null;
        this.preparingToOpen = null;
        this.preparingToClose = null;
-       this.size = null;
        this.currentWindow = null;
        this.$ariaHidden = null;
-       this.requestedSize = null;
        this.onWindowResizeTimeout = null;
        this.onWindowResizeHandler = this.onWindowResize.bind( this );
        this.afterWindowResizeHandler = this.afterWindowResize.bind( this );
-       this.onWindowMouseWheelHandler = this.onWindowMouseWheel.bind( this );
-       this.onDocumentKeyDownHandler = this.onDocumentKeyDown.bind( this );
 
        // Initialization
        this.$element
@@ -2772,36 +2524,6 @@ OO.ui.WindowManager.prototype.afterWindowResize = function () {
        }
 };
 
-/**
- * Handle window mouse wheel events.
- *
- * @param {jQuery.Event} e Mouse wheel event
- */
-OO.ui.WindowManager.prototype.onWindowMouseWheel = function () {
-       // Kill all events in the parent window if the child window is isolated
-       return !this.shouldIsolate();
-};
-
-/**
- * Handle document key down events.
- *
- * @param {jQuery.Event} e Key down event
- */
-OO.ui.WindowManager.prototype.onDocumentKeyDown = function ( e ) {
-       switch ( e.which ) {
-               case OO.ui.Keys.PAGEUP:
-               case OO.ui.Keys.PAGEDOWN:
-               case OO.ui.Keys.END:
-               case OO.ui.Keys.HOME:
-               case OO.ui.Keys.LEFT:
-               case OO.ui.Keys.UP:
-               case OO.ui.Keys.RIGHT:
-               case OO.ui.Keys.DOWN:
-                       // Kill all events in the parent window if the child window is isolated
-                       return !this.shouldIsolate();
-       }
-};
-
 /**
  * Check if window is opening.
  *
@@ -2829,17 +2551,6 @@ OO.ui.WindowManager.prototype.isOpened = function ( win ) {
        return win === this.currentWindow && !!this.opened && this.opened.state() === 'pending';
 };
 
-/**
- * Check if window contents should be isolated.
- *
- * Window content isolation is done using inline frames.
- *
- * @return {boolean} Window contents should be isolated
- */
-OO.ui.WindowManager.prototype.shouldIsolate = function () {
-       return this.isolate;
-};
-
 /**
  * Check if a window is being managed.
  *
@@ -2923,7 +2634,7 @@ OO.ui.WindowManager.prototype.getWindow = function ( name ) {
                                        'Cannot auto-instantiate window: symbolic name is unrecognized by the factory'
                                ) );
                        } else {
-                               win = this.factory.create( name, this, { $: this.$ } );
+                               win = this.factory.create( name, this );
                                this.addWindows( [ win ] );
                                deferred.resolve( win );
                        }
@@ -2959,7 +2670,6 @@ OO.ui.WindowManager.prototype.getCurrentWindow = function () {
  */
 OO.ui.WindowManager.prototype.openWindow = function ( win, data ) {
        var manager = this,
-               preparing = [],
                opening = $.Deferred();
 
        // Argument handling
@@ -2982,17 +2692,8 @@ OO.ui.WindowManager.prototype.openWindow = function ( win, data ) {
 
        // Window opening
        if ( opening.state() !== 'rejected' ) {
-               if ( !win.getManager() ) {
-                       win.setManager( this );
-               }
-               preparing.push( win.load() );
-
-               if ( this.closing ) {
-                       // If a window is currently closing, wait for it to complete
-                       preparing.push( this.closing );
-               }
-
-               this.preparingToOpen = $.when.apply( $, preparing );
+               // If a window is currently closing, wait for it to complete
+               this.preparingToOpen = $.when( this.closing );
                // Ensure handlers get called after preparingToOpen is set
                this.preparingToOpen.done( function () {
                        if ( manager.modal ) {
@@ -3035,7 +2736,6 @@ OO.ui.WindowManager.prototype.openWindow = function ( win, data ) {
  */
 OO.ui.WindowManager.prototype.closeWindow = function ( win, data ) {
        var manager = this,
-               preparing = [],
                closing = $.Deferred(),
                opened;
 
@@ -3063,12 +2763,8 @@ OO.ui.WindowManager.prototype.closeWindow = function ( win, data ) {
 
        // Window closing
        if ( closing.state() !== 'rejected' ) {
-               if ( this.opening ) {
-                       // If the window is currently opening, close it when it's done
-                       preparing.push( this.opening );
-               }
-
-               this.preparingToClose = $.when.apply( $, preparing );
+               // If the window is currently opening, close it when it's done
+               this.preparingToClose = $.when( this.opening );
                // Ensure handlers get called after preparingToClose is set
                this.preparingToClose.done( function () {
                        manager.closing = closing;
@@ -3127,8 +2823,9 @@ OO.ui.WindowManager.prototype.addWindows = function ( windows ) {
        // Add windows
        for ( name in list ) {
                win = list[ name ];
-               this.windows[ name ] = win;
+               this.windows[ name ] = win.toggle( false );
                this.$element.append( win.$element );
+               win.setManager( this );
        }
 };
 
@@ -3218,37 +2915,19 @@ OO.ui.WindowManager.prototype.toggleGlobalEvents = function ( on ) {
 
        if ( on ) {
                if ( !this.globalEvents ) {
-                       this.$( this.getElementDocument() ).on( {
-                               // Prevent scrolling by keys in top-level window
-                               keydown: this.onDocumentKeyDownHandler
-                       } );
-                       this.$( this.getElementWindow() ).on( {
-                               // Prevent scrolling by wheel in top-level window
-                               mousewheel: this.onWindowMouseWheelHandler,
+                       $( this.getElementWindow() ).on( {
                                // Start listening for top-level window dimension changes
                                'orientationchange resize': this.onWindowResizeHandler
                        } );
-                       // Disable window scrolling in isolated windows
-                       if ( !this.shouldIsolate() ) {
-                               $( this.getElementDocument().body ).css( 'overflow', 'hidden' );
-                       }
+                       $( this.getElementDocument().body ).css( 'overflow', 'hidden' );
                        this.globalEvents = true;
                }
        } else if ( this.globalEvents ) {
-               // Unbind global events
-               this.$( this.getElementDocument() ).off( {
-                       // Allow scrolling by keys in top-level window
-                       keydown: this.onDocumentKeyDownHandler
-               } );
-               this.$( this.getElementWindow() ).off( {
-                       // Allow scrolling by wheel in top-level window
-                       mousewheel: this.onWindowMouseWheelHandler,
+               $( this.getElementWindow() ).off( {
                        // Stop listening for top-level window dimension changes
                        'orientationchange resize': this.onWindowResizeHandler
                } );
-               if ( !this.shouldIsolate() ) {
-                       $( this.getElementDocument().body ).css( 'overflow', '' );
-               }
+               $( this.getElementDocument().body ).css( 'overflow', '' );
                this.globalEvents = false;
        }
 
@@ -3742,6 +3421,9 @@ OO.ui.TabIndexedElement = function OoUiTabIndexedElement( config ) {
        this.$tabIndexed = null;
        this.tabIndex = null;
 
+       // Events
+       this.connect( this, { disable: 'onDisable' } );
+
        // Initialization
        this.setTabIndex( config.tabIndex || 0 );
        this.setTabIndexedElement( config.$tabIndexed || this.$element );
@@ -3762,12 +3444,17 @@ OO.initClass( OO.ui.TabIndexedElement );
  */
 OO.ui.TabIndexedElement.prototype.setTabIndexedElement = function ( $tabIndexed ) {
        if ( this.$tabIndexed ) {
-               this.$tabIndexed.removeAttr( 'tabindex' );
+               this.$tabIndexed.removeAttr( 'tabindex aria-disabled' );
        }
 
        this.$tabIndexed = $tabIndexed;
        if ( this.tabIndex !== null ) {
-               this.$tabIndexed.attr( 'tabindex', this.tabIndex );
+               this.$tabIndexed.attr( {
+                       // Do not index over disabled elements
+                       tabindex: this.isDisabled() ? -1 : this.tabIndex,
+                       // ChromeVox and NVDA do not seem to inherit this from parent elements
+                       'aria-disabled': this.isDisabled().toString()
+               } );
        }
 };
 
@@ -3778,14 +3465,19 @@ OO.ui.TabIndexedElement.prototype.setTabIndexedElement = function ( $tabIndexed
  * @chainable
  */
 OO.ui.TabIndexedElement.prototype.setTabIndex = function ( tabIndex ) {
-       tabIndex = typeof tabIndex === 'number' && tabIndex >= 0 ? tabIndex : null;
+       tabIndex = typeof tabIndex === 'number' ? tabIndex : null;
 
        if ( this.tabIndex !== tabIndex ) {
                if ( this.$tabIndexed ) {
                        if ( tabIndex !== null ) {
-                               this.$tabIndexed.attr( 'tabindex', tabIndex );
+                               this.$tabIndexed.attr( {
+                                       // Do not index over disabled elements
+                                       tabindex: this.isDisabled() ? -1 : tabIndex,
+                                       // ChromeVox and NVDA do not seem to inherit this from parent elements
+                                       'aria-disabled': this.isDisabled().toString()
+                               } );
                        } else {
-                               this.$tabIndexed.removeAttr( 'tabindex' );
+                               this.$tabIndexed.removeAttr( 'tabindex aria-disabled' );
                        }
                }
                this.tabIndex = tabIndex;
@@ -3794,6 +3486,22 @@ OO.ui.TabIndexedElement.prototype.setTabIndex = function ( tabIndex ) {
        return this;
 };
 
+/**
+ * Handle disable events.
+ *
+ * @param {boolean} disabled Element is disabled
+ */
+OO.ui.TabIndexedElement.prototype.onDisable = function ( disabled ) {
+       if ( this.$tabIndexed && this.tabIndex !== null ) {
+               this.$tabIndexed.attr( {
+                       // Do not index over disabled elements
+                       tabindex: disabled ? -1 : this.tabIndex,
+                       // ChromeVox and NVDA do not seem to inherit this from parent elements
+                       'aria-disabled': disabled.toString()
+               } );
+       }
+};
+
 /**
  * Get tab index value.
  *
@@ -3823,12 +3531,16 @@ OO.ui.ButtonElement = function OoUiButtonElement( config ) {
        config = config || {};
 
        // Properties
-       this.$button = config.$button || this.$( '<a>' );
+       this.$button = config.$button || $( '<a>' );
        this.framed = null;
        this.accessKey = null;
        this.active = false;
        this.onMouseUpHandler = this.onMouseUp.bind( this );
        this.onMouseDownHandler = this.onMouseDown.bind( this );
+       this.onKeyDownHandler = this.onKeyDown.bind( this );
+       this.onKeyUpHandler = this.onKeyUp.bind( this );
+       this.onClickHandler = this.onClick.bind( this );
+       this.onKeyPressHandler = this.onKeyPress.bind( this );
 
        // Initialization
        this.$element.addClass( 'oo-ui-buttonElement' );
@@ -3852,6 +3564,12 @@ OO.initClass( OO.ui.ButtonElement );
  */
 OO.ui.ButtonElement.static.cancelButtonMouseDownEvents = true;
 
+/* Events */
+
+/**
+ * @event click
+ */
+
 /* Methods */
 
 /**
@@ -3866,13 +3584,23 @@ OO.ui.ButtonElement.prototype.setButtonElement = function ( $button ) {
                this.$button
                        .removeClass( 'oo-ui-buttonElement-button' )
                        .removeAttr( 'role accesskey' )
-                       .off( 'mousedown', this.onMouseDownHandler );
+                       .off( {
+                               mousedown: this.onMouseDownHandler,
+                               keydown: this.onKeyDownHandler,
+                               click: this.onClickHandler,
+                               keypress: this.onKeyPressHandler
+                       } );
        }
 
        this.$button = $button
                .addClass( 'oo-ui-buttonElement-button' )
                .attr( { role: 'button', accesskey: this.accessKey } )
-               .on( 'mousedown', this.onMouseDownHandler );
+               .on( {
+                       mousedown: this.onMouseDownHandler,
+                       keydown: this.onKeyDownHandler,
+                       click: this.onClickHandler,
+                       keypress: this.onKeyPressHandler
+               } );
 };
 
 /**
@@ -3882,9 +3610,12 @@ OO.ui.ButtonElement.prototype.setButtonElement = function ( $button ) {
  */
 OO.ui.ButtonElement.prototype.onMouseDown = function ( e ) {
        if ( this.isDisabled() || e.which !== 1 ) {
-               return false;
+               return;
        }
        this.$element.addClass( 'oo-ui-buttonElement-pressed' );
+       // Run the mouseup handler no matter where the mouse is when the button is let go, so we can
+       // reliably remove the pressed class
+       this.getElementDocument().addEventListener( 'mouseup', this.onMouseUpHandler, true );
        // Prevent change of focus unless specifically configured otherwise
        if ( this.constructor.static.cancelButtonMouseDownEvents ) {
                return false;
@@ -3898,9 +3629,66 @@ OO.ui.ButtonElement.prototype.onMouseDown = function ( e ) {
  */
 OO.ui.ButtonElement.prototype.onMouseUp = function ( e ) {
        if ( this.isDisabled() || e.which !== 1 ) {
-               return false;
+               return;
+       }
+       this.$element.removeClass( 'oo-ui-buttonElement-pressed' );
+       // Stop listening for mouseup, since we only needed this once
+       this.getElementDocument().removeEventListener( 'mouseup', this.onMouseUpHandler, true );
+};
+
+/**
+ * Handles mouse click events.
+ *
+ * @param {jQuery.Event} e Mouse click event
+ * @fires click
+ */
+OO.ui.ButtonElement.prototype.onClick = function ( e ) {
+       if ( !this.isDisabled() && e.which === 1 ) {
+               this.emit( 'click' );
+       }
+       return false;
+};
+
+/**
+ * Handles key down events.
+ *
+ * @param {jQuery.Event} e Key down event
+ */
+OO.ui.ButtonElement.prototype.onKeyDown = function ( e ) {
+       if ( this.isDisabled() || ( e.which !== OO.ui.Keys.SPACE && e.which !== OO.ui.Keys.ENTER ) ) {
+               return;
+       }
+       this.$element.addClass( 'oo-ui-buttonElement-pressed' );
+       // Run the keyup handler no matter where the key is when the button is let go, so we can
+       // reliably remove the pressed class
+       this.getElementDocument().addEventListener( 'keyup', this.onKeyUpHandler, true );
+};
+
+/**
+ * Handles key up events.
+ *
+ * @param {jQuery.Event} e Key up event
+ */
+OO.ui.ButtonElement.prototype.onKeyUp = function ( e ) {
+       if ( this.isDisabled() || ( e.which !== OO.ui.Keys.SPACE && e.which !== OO.ui.Keys.ENTER ) ) {
+               return;
        }
        this.$element.removeClass( 'oo-ui-buttonElement-pressed' );
+       // Stop listening for keyup, since we only needed this once
+       this.getElementDocument().removeEventListener( 'keyup', this.onKeyUpHandler, true );
+};
+
+/**
+ * Handles key press events.
+ *
+ * @param {jQuery.Event} e Key press event
+ * @fires click
+ */
+OO.ui.ButtonElement.prototype.onKeyPress = function ( e ) {
+       if ( !this.isDisabled() && ( e.which === OO.ui.Keys.SPACE || e.which === OO.ui.Keys.ENTER ) ) {
+               this.emit( 'click' );
+       }
+       return false;
 };
 
 /**
@@ -3985,7 +3773,7 @@ OO.ui.GroupElement = function OoUiGroupElement( config ) {
        this.aggregateItemEvents = {};
 
        // Initialization
-       this.setGroupElement( config.$group || this.$( '<div>' ) );
+       this.setGroupElement( config.$group || $( '<div>' ) );
 };
 
 /* Methods */
@@ -4264,6 +4052,8 @@ OO.ui.DraggableElement = function OoUiDraggableElement() {
                } );
 };
 
+OO.initClass( OO.ui.DraggableElement );
+
 /* Events */
 
 /**
@@ -4279,6 +4069,13 @@ OO.ui.DraggableElement = function OoUiDraggableElement() {
  * @event drop
  */
 
+/* Static Properties */
+
+/**
+ * @inheritdoc OO.ui.ButtonElement
+ */
+OO.ui.DraggableElement.static.cancelButtonMouseDownEvents = false;
+
 /* Methods */
 
 /**
@@ -4476,6 +4273,7 @@ OO.ui.DraggableGroupElement.prototype.onItemDrop = function ( item ) {
                // Emit change event
                this.emit( 'reorder', this.getDragItem(), toIndex );
        }
+       this.unsetDragItem();
        // Return false to prevent propogation
        return false;
 };
@@ -4487,7 +4285,7 @@ OO.ui.DraggableGroupElement.prototype.onDragLeave = function () {
        // This means the item was dragged outside the widget
        this.$placeholder
                .css( 'left', 0 )
-               .hide();
+               .addClass( 'oo-ui-element-hidden' );
 };
 
 /**
@@ -4548,23 +4346,14 @@ OO.ui.DraggableGroupElement.prototype.onDragOver = function ( e ) {
                        this.sideInsertion = dragPosition < itemMidpoint ? 'before' : 'after';
                }
                // Add drop indicator between objects
-               if ( this.sideInsertion ) {
-                       this.$placeholder
-                               .css( cssOutput )
-                               .show();
-               } else {
-                       this.$placeholder
-                               .css( {
-                                       left: 0,
-                                       top: 0
-                               } )
-                               .hide();
-               }
+               this.$placeholder
+                       .css( cssOutput )
+                       .removeClass( 'oo-ui-element-hidden' );
        } else {
                // This means the item was dragged outside the widget
                this.$placeholder
                        .css( 'left', 0 )
-                       .hide();
+                       .addClass( 'oo-ui-element-hidden' );
        }
        // Prevent default
        e.preventDefault();
@@ -4584,7 +4373,7 @@ OO.ui.DraggableGroupElement.prototype.setDragItem = function ( item ) {
 OO.ui.DraggableGroupElement.prototype.unsetDragItem = function () {
        this.dragItem = null;
        this.itemDragOver = null;
-       this.$placeholder.hide();
+       this.$placeholder.addClass( 'oo-ui-element-hidden' );
        this.sideInsertion = '';
 };
 
@@ -4635,7 +4424,7 @@ OO.ui.IconElement = function OoUiIconElement( config ) {
        // Initialization
        this.setIcon( config.icon || this.constructor.static.icon );
        this.setIconTitle( config.iconTitle || this.constructor.static.iconTitle );
-       this.setIconElement( config.$icon || this.$( '<span>' ) );
+       this.setIconElement( config.$icon || $( '<span>' ) );
 };
 
 /* Setup */
@@ -4801,7 +4590,7 @@ OO.ui.IndicatorElement = function OoUiIndicatorElement( config ) {
        // Initialization
        this.setIndicator( config.indicator || this.constructor.static.indicator );
        this.setIndicatorTitle( config.indicatorTitle || this.constructor.static.indicatorTitle );
-       this.setIndicatorElement( config.$indicator || this.$( '<span>' ) );
+       this.setIndicatorElement( config.$indicator || $( '<span>' ) );
 };
 
 /* Setup */
@@ -4947,7 +4736,7 @@ OO.ui.LabelElement = function OoUiLabelElement( config ) {
 
        // Initialization
        this.setLabel( config.label || this.constructor.static.label );
-       this.setLabelElement( config.$label || this.$( '<span>' ) );
+       this.setLabelElement( config.$label || $( '<span>' ) );
 };
 
 /* Setup */
@@ -5087,7 +4876,6 @@ OO.ui.LookupElement = function OoUiLookupElement( config ) {
        // Properties
        this.$overlay = config.$overlay || this.$element;
        this.lookupMenu = new OO.ui.TextInputMenuSelectWidget( this, {
-               $: OO.ui.Element.static.getJQuery( this.$overlay ),
                $container: config.$container
        } );
        this.lookupCache = {};
@@ -5400,7 +5188,7 @@ OO.ui.LookupElement.prototype.getLookupMenuOptionsFromData = function () {
  * @constructor
  * @param {Object} [config] Configuration options
  * @cfg {Object} [popup] Configuration to pass to popup
- * @cfg {boolean} [autoClose=true] Popup auto-closes when it loses focus
+ * @cfg {boolean} [popup.autoClose=true] Popup auto-closes when it loses focus
  */
 OO.ui.PopupElement = function OoUiPopupElement( config ) {
        // Configuration initialization
@@ -5410,7 +5198,7 @@ OO.ui.PopupElement = function OoUiPopupElement( config ) {
        this.popup = new OO.ui.PopupWidget( $.extend(
                { autoClose: true },
                config.popup,
-               { $: this.$, $autoCloseIgnore: this.$element }
+               { $autoCloseIgnore: this.$element }
        ) );
 };
 
@@ -5759,14 +5547,14 @@ OO.ui.ClippableElement.prototype.toggleClipping = function ( clipping ) {
        if ( this.clipping !== clipping ) {
                this.clipping = clipping;
                if ( clipping ) {
-                       this.$clippableContainer = this.$( this.getClosestScrollableElementContainer() );
+                       this.$clippableContainer = $( this.getClosestScrollableElementContainer() );
                        // If the clippable container is the root, we have to listen to scroll events and check
                        // jQuery.scrollTop on the window because of browser inconsistencies
                        this.$clippableScroller = this.$clippableContainer.is( 'html, body' ) ?
-                               this.$( OO.ui.Element.static.getWindow( this.$clippableContainer ) ) :
+                               $( OO.ui.Element.static.getWindow( this.$clippableContainer ) ) :
                                this.$clippableContainer;
                        this.$clippableScroller.on( 'scroll', this.onClippableContainerScrollHandler );
-                       this.$clippableWindow = this.$( this.getElementWindow() )
+                       this.$clippableWindow = $( this.getElementWindow() )
                                .on( 'resize', this.onClippableWindowResizeHandler );
                        // Initial clip after visible
                        this.clip();
@@ -5926,9 +5714,9 @@ OO.ui.Tool = function OoUiTool( toolGroup, config ) {
        this.toolGroup = toolGroup;
        this.toolbar = this.toolGroup.getToolbar();
        this.active = false;
-       this.$title = this.$( '<span>' );
-       this.$accel = this.$( '<span>' );
-       this.$link = this.$( '<a>' );
+       this.$title = $( '<span>' );
+       this.$accel = $( '<span>' );
+       this.$link = $( '<a>' );
        this.title = null;
 
        // Events
@@ -6189,8 +5977,8 @@ OO.ui.Toolbar = function OoUiToolbar( toolFactory, toolGroupFactory, config ) {
        this.toolGroupFactory = toolGroupFactory;
        this.groups = [];
        this.tools = {};
-       this.$bar = this.$( '<div>' );
-       this.$actions = this.$( '<div>' );
+       this.$bar = $( '<div>' );
+       this.$actions = $( '<div>' );
        this.initialized = false;
 
        // Events
@@ -6244,7 +6032,7 @@ OO.ui.Toolbar.prototype.getToolGroupFactory = function () {
  * @param {jQuery.Event} e Mouse down event
  */
 OO.ui.Toolbar.prototype.onPointerDown = function ( e ) {
-       var $closestWidgetToEvent = this.$( e.target ).closest( '.oo-ui-widget' ),
+       var $closestWidgetToEvent = $( e.target ).closest( '.oo-ui-widget' ),
                $closestWidgetToToolbar = this.$element.closest( '.oo-ui-widget' );
        if ( !$closestWidgetToEvent.length || $closestWidgetToEvent[ 0 ] === $closestWidgetToToolbar[ 0 ] ) {
                return false;
@@ -6297,7 +6085,7 @@ OO.ui.Toolbar.prototype.setup = function ( groups ) {
                // Check type has been registered
                type = this.getToolGroupFactory().lookup( group.type ) ? group.type : defaultType;
                items.push(
-                       this.getToolGroupFactory().create( type, this, $.extend( { $: this.$ }, group ) )
+                       this.getToolGroupFactory().create( type, this, group )
                );
        }
        this.addItems( items );
@@ -6583,7 +6371,7 @@ OO.ui.ToolGroup.prototype.onMouseOut = function ( e ) {
  */
 OO.ui.ToolGroup.prototype.getTargetTool = function ( e ) {
        var tool,
-               $item = this.$( e.target ).closest( '.oo-ui-tool-link' );
+               $item = $( e.target ).closest( '.oo-ui-tool-link' );
 
        if ( $item.length ) {
                tool = $item.parent().data( 'oo-ui-tool' );
@@ -6894,15 +6682,15 @@ OO.ui.MessageDialog.prototype.initialize = function () {
        OO.ui.MessageDialog.super.prototype.initialize.call( this );
 
        // Properties
-       this.$actions = this.$( '<div>' );
+       this.$actions = $( '<div>' );
        this.container = new OO.ui.PanelLayout( {
-               $: this.$, scrollable: true, classes: [ 'oo-ui-messageDialog-container' ]
+               scrollable: true, classes: [ 'oo-ui-messageDialog-container' ]
        } );
        this.text = new OO.ui.PanelLayout( {
-               $: this.$, padded: true, expanded: false, classes: [ 'oo-ui-messageDialog-text' ]
+               padded: true, expanded: false, classes: [ 'oo-ui-messageDialog-text' ]
        } );
        this.message = new OO.ui.LabelWidget( {
-               $: this.$, classes: [ 'oo-ui-messageDialog-message' ]
+               classes: [ 'oo-ui-messageDialog-message' ]
        } );
 
        // Initialization
@@ -6969,8 +6757,10 @@ OO.ui.MessageDialog.prototype.fitActions = function () {
                }
        }
 
+       // Move the body out of the way of the foot
+       this.$body.css( 'bottom', this.$foot.outerHeight( true ) );
+
        if ( this.verticalActionLayout !== previous ) {
-               this.$body.css( 'bottom', this.$foot.outerHeight( true ) );
                // We changed the layout, window height might need to be updated.
                this.updateSize();
        }
@@ -7053,18 +6843,17 @@ OO.ui.ProcessDialog.prototype.initialize = function () {
        OO.ui.ProcessDialog.super.prototype.initialize.call( this );
 
        // Properties
-       this.$navigation = this.$( '<div>' );
-       this.$location = this.$( '<div>' );
-       this.$safeActions = this.$( '<div>' );
-       this.$primaryActions = this.$( '<div>' );
-       this.$otherActions = this.$( '<div>' );
+       this.$navigation = $( '<div>' );
+       this.$location = $( '<div>' );
+       this.$safeActions = $( '<div>' );
+       this.$primaryActions = $( '<div>' );
+       this.$otherActions = $( '<div>' );
        this.dismissButton = new OO.ui.ButtonWidget( {
-               $: this.$,
                label: OO.ui.msg( 'ooui-dialog-process-dismiss' )
        } );
-       this.retryButton = new OO.ui.ButtonWidget( { $: this.$ } );
-       this.$errors = this.$( '<div>' );
-       this.$errorsTitle = this.$( '<div>' );
+       this.retryButton = new OO.ui.ButtonWidget();
+       this.$errors = $( '<div>' );
+       this.$errorsTitle = $( '<div>' );
 
        // Events
        this.dismissButton.connect( this, { click: 'onDismissErrorButtonClick' } );
@@ -7166,12 +6955,12 @@ OO.ui.ProcessDialog.prototype.showErrors = function ( errors ) {
                if ( errors[ i ].isWarning() ) {
                        warning = true;
                }
-               $item = this.$( '<div>' )
+               $item = $( '<div>' )
                        .addClass( 'oo-ui-processDialog-error' )
                        .append( errors[ i ].getMessage() );
                items.push( $item[ 0 ] );
        }
-       this.$errorItems = this.$( items );
+       this.$errorItems = $( items );
        if ( recoverable ) {
                this.retryButton.clearFlags().setFlags( this.currentAction.getFlags() );
        } else {
@@ -7184,1144 +6973,1130 @@ OO.ui.ProcessDialog.prototype.showErrors = function ( errors ) {
        }
        this.retryButton.toggle( recoverable );
        this.$errorsTitle.after( this.$errorItems );
-       this.$errors.show().scrollTop( 0 );
+       this.$errors.removeClass( 'oo-ui-widget-hidden' ).scrollTop( 0 );
 };
 
 /**
  * Hide errors.
  */
 OO.ui.ProcessDialog.prototype.hideErrors = function () {
-       this.$errors.hide();
+       this.$errors.addClass( 'oo-ui-widget-hidden' );
        this.$errorItems.remove();
        this.$errorItems = null;
 };
 
 /**
- * Layout containing a series of pages.
+ * Layout made of a field and optional label.
+ *
+ * Available label alignment modes include:
+ *  - left: Label is before the field and aligned away from it, best for when the user will be
+ *    scanning for a specific label in a form with many fields
+ *  - right: Label is before the field and aligned toward it, best for forms the user is very
+ *    familiar with and will tab through field checking quickly to verify which field they are in
+ *  - top: Label is before the field and above it, best for when the user will need to fill out all
+ *    fields from top to bottom in a form with few fields
+ *  - inline: Label is after the field and aligned toward it, best for small boolean fields like
+ *    checkboxes or radio buttons
  *
  * @class
  * @extends OO.ui.Layout
+ * @mixins OO.ui.LabelElement
  *
  * @constructor
+ * @param {OO.ui.Widget} fieldWidget Field widget
  * @param {Object} [config] Configuration options
- * @cfg {boolean} [continuous=false] Show all pages, one after another
- * @cfg {boolean} [autoFocus=true] Focus on the first focusable element when changing to a page
- * @cfg {boolean} [outlined=false] Show an outline
- * @cfg {boolean} [editable=false] Show controls for adding, removing and reordering pages
+ * @cfg {string} [align='left'] Alignment mode, either 'left', 'right', 'top' or 'inline'
+ * @cfg {string} [help] Explanatory text shown as a '?' icon.
  */
-OO.ui.BookletLayout = function OoUiBookletLayout( config ) {
+OO.ui.FieldLayout = function OoUiFieldLayout( fieldWidget, config ) {
+       var hasInputWidget = fieldWidget instanceof OO.ui.InputWidget;
+
        // Configuration initialization
-       config = config || {};
+       config = $.extend( { align: 'left' }, config );
 
-       // Parent constructor
-       OO.ui.BookletLayout.super.call( this, config );
+       // Properties (must be set before parent constructor, which calls #getTagName)
+       this.fieldWidget = fieldWidget;
+
+       // Parent constructor
+       OO.ui.FieldLayout.super.call( this, config );
+
+       // Mixin constructors
+       OO.ui.LabelElement.call( this, config );
 
        // Properties
-       this.currentPageName = null;
-       this.pages = {};
-       this.ignoreFocus = false;
-       this.stackLayout = new OO.ui.StackLayout( { $: this.$, continuous: !!config.continuous } );
-       this.autoFocus = config.autoFocus === undefined || !!config.autoFocus;
-       this.outlineVisible = false;
-       this.outlined = !!config.outlined;
-       if ( this.outlined ) {
-               this.editable = !!config.editable;
-               this.outlineControlsWidget = null;
-               this.outlineSelectWidget = new OO.ui.OutlineSelectWidget( { $: this.$ } );
-               this.outlinePanel = new OO.ui.PanelLayout( { $: this.$, scrollable: true } );
-               this.gridLayout = new OO.ui.GridLayout(
-                       [ this.outlinePanel, this.stackLayout ],
-                       { $: this.$, widths: [ 1, 2 ] }
+       this.$field = $( '<div>' );
+       this.$body = $( '<' + ( hasInputWidget ? 'label' : 'div' ) + '>' );
+       this.align = null;
+       if ( config.help ) {
+               this.popupButtonWidget = new OO.ui.PopupButtonWidget( {
+                       classes: [ 'oo-ui-fieldLayout-help' ],
+                       framed: false,
+                       icon: 'info'
+               } );
+
+               this.popupButtonWidget.getPopup().$body.append(
+                       $( '<div>' )
+                               .text( config.help )
+                               .addClass( 'oo-ui-fieldLayout-help-content' )
                );
-               this.outlineVisible = true;
-               if ( this.editable ) {
-                       this.outlineControlsWidget = new OO.ui.OutlineControlsWidget(
-                               this.outlineSelectWidget, { $: this.$ }
-                       );
-               }
+               this.$help = this.popupButtonWidget.$element;
+       } else {
+               this.$help = $( [] );
        }
 
        // Events
-       this.stackLayout.connect( this, { set: 'onStackLayoutSet' } );
-       if ( this.outlined ) {
-               this.outlineSelectWidget.connect( this, { select: 'onOutlineSelectWidgetSelect' } );
-       }
-       if ( this.autoFocus ) {
-               // Event 'focus' does not bubble, but 'focusin' does
-               this.stackLayout.$element.on( 'focusin', this.onStackLayoutFocus.bind( this ) );
+       if ( hasInputWidget ) {
+               this.$label.on( 'click', this.onLabelClick.bind( this ) );
        }
+       this.fieldWidget.connect( this, { disable: 'onFieldDisable' } );
 
        // Initialization
-       this.$element.addClass( 'oo-ui-bookletLayout' );
-       this.stackLayout.$element.addClass( 'oo-ui-bookletLayout-stackLayout' );
-       if ( this.outlined ) {
-               this.outlinePanel.$element
-                       .addClass( 'oo-ui-bookletLayout-outlinePanel' )
-                       .append( this.outlineSelectWidget.$element );
-               if ( this.editable ) {
-                       this.outlinePanel.$element
-                               .addClass( 'oo-ui-bookletLayout-outlinePanel-editable' )
-                               .append( this.outlineControlsWidget.$element );
-               }
-               this.$element.append( this.gridLayout.$element );
-       } else {
-               this.$element.append( this.stackLayout.$element );
-       }
+       this.$element
+               .addClass( 'oo-ui-fieldLayout' )
+               .append( this.$help, this.$body );
+       this.$body.addClass( 'oo-ui-fieldLayout-body' );
+       this.$field
+               .addClass( 'oo-ui-fieldLayout-field' )
+               .toggleClass( 'oo-ui-fieldLayout-disable', this.fieldWidget.isDisabled() )
+               .append( this.fieldWidget.$element );
+
+       this.setAlignment( config.align );
 };
 
 /* Setup */
 
-OO.inheritClass( OO.ui.BookletLayout, OO.ui.Layout );
-
-/* Events */
-
-/**
- * @event set
- * @param {OO.ui.PageLayout} page Current page
- */
-
-/**
- * @event add
- * @param {OO.ui.PageLayout[]} page Added pages
- * @param {number} index Index pages were added at
- */
-
-/**
- * @event remove
- * @param {OO.ui.PageLayout[]} pages Removed pages
- */
+OO.inheritClass( OO.ui.FieldLayout, OO.ui.Layout );
+OO.mixinClass( OO.ui.FieldLayout, OO.ui.LabelElement );
 
 /* Methods */
 
 /**
- * Handle stack layout focus.
+ * Handle field disable events.
  *
- * @param {jQuery.Event} e Focusin event
+ * @param {boolean} value Field is disabled
  */
-OO.ui.BookletLayout.prototype.onStackLayoutFocus = function ( e ) {
-       var name, $target;
-
-       // Find the page that an element was focused within
-       $target = $( e.target ).closest( '.oo-ui-pageLayout' );
-       for ( name in this.pages ) {
-               // Check for page match, exclude current page to find only page changes
-               if ( this.pages[ name ].$element[ 0 ] === $target[ 0 ] && name !== this.currentPageName ) {
-                       this.setPage( name );
-                       break;
-               }
-       }
+OO.ui.FieldLayout.prototype.onFieldDisable = function ( value ) {
+       this.$element.toggleClass( 'oo-ui-fieldLayout-disabled', value );
 };
 
 /**
- * Handle stack layout set events.
+ * Handle label mouse click events.
  *
- * @param {OO.ui.PanelLayout|null} page The page panel that is now the current panel
+ * @param {jQuery.Event} e Mouse click event
  */
-OO.ui.BookletLayout.prototype.onStackLayoutSet = function ( page ) {
-       var layout = this;
-       if ( page ) {
-               page.scrollElementIntoView( { complete: function () {
-                       if ( layout.autoFocus ) {
-                               layout.focus();
-                       }
-               } } );
-       }
+OO.ui.FieldLayout.prototype.onLabelClick = function () {
+       this.fieldWidget.simulateLabelClick();
+       return false;
 };
 
 /**
- * Focus the first input in the current page.
+ * Get the field.
  *
- * If no page is selected, the first selectable page will be selected.
- * If the focus is already in an element on the current page, nothing will happen.
+ * @return {OO.ui.Widget} Field widget
  */
-OO.ui.BookletLayout.prototype.focus = function () {
-       var $input, page = this.stackLayout.getCurrentItem();
-       if ( !page && this.outlined ) {
-               this.selectFirstSelectablePage();
-               page = this.stackLayout.getCurrentItem();
-       }
-       if ( !page ) {
-               return;
-       }
-       // Only change the focus if is not already in the current page
-       if ( !page.$element.find( ':focus' ).length ) {
-               $input = page.$element.find( ':input:first' );
-               if ( $input.length ) {
-                       $input[ 0 ].focus();
-               }
-       }
+OO.ui.FieldLayout.prototype.getField = function () {
+       return this.fieldWidget;
 };
 
 /**
- * Handle outline widget select events.
+ * Set the field alignment mode.
  *
- * @param {OO.ui.OptionWidget|null} item Selected item
+ * @private
+ * @param {string} value Alignment mode, either 'left', 'right', 'top' or 'inline'
+ * @chainable
  */
-OO.ui.BookletLayout.prototype.onOutlineSelectWidgetSelect = function ( item ) {
-       if ( item ) {
-               this.setPage( item.getData() );
+OO.ui.FieldLayout.prototype.setAlignment = function ( value ) {
+       if ( value !== this.align ) {
+               // Default to 'left'
+               if ( [ 'left', 'right', 'top', 'inline' ].indexOf( value ) === -1 ) {
+                       value = 'left';
+               }
+               // Reorder elements
+               if ( value === 'inline' ) {
+                       this.$body.append( this.$field, this.$label );
+               } else {
+                       this.$body.append( this.$label, this.$field );
+               }
+               // Set classes. The following classes can be used here:
+               // * oo-ui-fieldLayout-align-left
+               // * oo-ui-fieldLayout-align-right
+               // * oo-ui-fieldLayout-align-top
+               // * oo-ui-fieldLayout-align-inline
+               if ( this.align ) {
+                       this.$element.removeClass( 'oo-ui-fieldLayout-align-' + this.align );
+               }
+               this.$element.addClass( 'oo-ui-fieldLayout-align-' + value );
+               this.align = value;
        }
-};
 
-/**
- * Check if booklet has an outline.
- *
- * @return {boolean}
- */
-OO.ui.BookletLayout.prototype.isOutlined = function () {
-       return this.outlined;
+       return this;
 };
 
 /**
- * Check if booklet has editing controls.
+ * Layout made of a field, a button, and an optional label.
  *
- * @return {boolean}
- */
-OO.ui.BookletLayout.prototype.isEditable = function () {
-       return this.editable;
-};
-
-/**
- * Check if booklet has a visible outline.
+ * @class
+ * @extends OO.ui.FieldLayout
  *
- * @return {boolean}
+ * @constructor
+ * @param {OO.ui.Widget} fieldWidget Field widget
+ * @param {OO.ui.ButtonWidget} buttonWidget Button widget
+ * @param {Object} [config] Configuration options
+ * @cfg {string} [align='left'] Alignment mode, either 'left', 'right', 'top' or 'inline'
+ * @cfg {string} [help] Explanatory text shown as a '?' icon.
  */
-OO.ui.BookletLayout.prototype.isOutlineVisible = function () {
-       return this.outlined && this.outlineVisible;
-};
+OO.ui.ActionFieldLayout = function OoUiActionFieldLayout( fieldWidget, buttonWidget, config ) {
+       // Configuration initialization
+       config = $.extend( { align: 'left' }, config );
 
-/**
- * Hide or show the outline.
- *
- * @param {boolean} [show] Show outline, omit to invert current state
- * @chainable
- */
-OO.ui.BookletLayout.prototype.toggleOutline = function ( show ) {
-       if ( this.outlined ) {
-               show = show === undefined ? !this.outlineVisible : !!show;
-               this.outlineVisible = show;
-               this.gridLayout.layout( show ? [ 1, 2 ] : [ 0, 1 ], [ 1 ] );
-       }
+       // Properties (must be set before parent constructor, which calls #getTagName)
+       this.fieldWidget = fieldWidget;
+       this.buttonWidget = buttonWidget;
 
-       return this;
+       // Parent constructor
+       OO.ui.ActionFieldLayout.super.call( this, fieldWidget, config );
+
+       // Mixin constructors
+       OO.ui.LabelElement.call( this, config );
+
+       // Properties
+       this.$button = $( '<div>' )
+               .addClass( 'oo-ui-actionFieldLayout-button' )
+               .append( this.buttonWidget.$element );
+
+       this.$input = $( '<div>' )
+               .addClass( 'oo-ui-actionFieldLayout-input' )
+               .append( this.fieldWidget.$element );
+
+       this.$field
+               .addClass( 'oo-ui-actionFieldLayout' )
+               .append( this.$input, this.$button );
 };
 
+/* Setup */
+
+OO.inheritClass( OO.ui.ActionFieldLayout, OO.ui.FieldLayout );
+
 /**
- * Get the outline widget.
+ * Layout made of a fieldset and optional legend.
  *
- * @param {OO.ui.PageLayout} page Page to be selected
- * @return {OO.ui.PageLayout|null} Closest page to another
- */
-OO.ui.BookletLayout.prototype.getClosestPage = function ( page ) {
-       var next, prev, level,
-               pages = this.stackLayout.getItems(),
-               index = $.inArray( page, pages );
-
-       if ( index !== -1 ) {
-               next = pages[ index + 1 ];
-               prev = pages[ index - 1 ];
-               // Prefer adjacent pages at the same level
-               if ( this.outlined ) {
-                       level = this.outlineSelectWidget.getItemFromData( page.getName() ).getLevel();
-                       if (
-                               prev &&
-                               level === this.outlineSelectWidget.getItemFromData( prev.getName() ).getLevel()
-                       ) {
-                               return prev;
-                       }
-                       if (
-                               next &&
-                               level === this.outlineSelectWidget.getItemFromData( next.getName() ).getLevel()
-                       ) {
-                               return next;
-                       }
-               }
-       }
-       return prev || next || null;
-};
-
-/**
- * Get the outline widget.
- *
- * @return {OO.ui.OutlineSelectWidget|null} Outline widget, or null if booklet has no outline
- */
-OO.ui.BookletLayout.prototype.getOutline = function () {
-       return this.outlineSelectWidget;
-};
-
-/**
- * Get the outline controls widget. If the outline is not editable, null is returned.
+ * Just add OO.ui.FieldLayout items.
  *
- * @return {OO.ui.OutlineControlsWidget|null} The outline controls widget.
- */
-OO.ui.BookletLayout.prototype.getOutlineControls = function () {
-       return this.outlineControlsWidget;
-};
-
-/**
- * Get a page by name.
+ * @class
+ * @extends OO.ui.Layout
+ * @mixins OO.ui.IconElement
+ * @mixins OO.ui.LabelElement
+ * @mixins OO.ui.GroupElement
  *
- * @param {string} name Symbolic name of page
- * @return {OO.ui.PageLayout|undefined} Page, if found
+ * @constructor
+ * @param {Object} [config] Configuration options
+ * @cfg {OO.ui.FieldLayout[]} [items] Items to add
  */
-OO.ui.BookletLayout.prototype.getPage = function ( name ) {
-       return this.pages[ name ];
-};
+OO.ui.FieldsetLayout = function OoUiFieldsetLayout( config ) {
+       // Configuration initialization
+       config = config || {};
 
-/**
- * Get the current page name.
- *
- * @return {string|null} Current page name
- */
-OO.ui.BookletLayout.prototype.getCurrentPageName = function () {
-       return this.currentPageName;
-};
+       // Parent constructor
+       OO.ui.FieldsetLayout.super.call( this, config );
 
-/**
- * Add a page to the layout.
- *
- * When pages are added with the same names as existing pages, the existing pages will be
- * automatically removed before the new pages are added.
- *
- * @param {OO.ui.PageLayout[]} pages Pages to add
- * @param {number} index Index to insert pages after
- * @fires add
- * @chainable
- */
-OO.ui.BookletLayout.prototype.addPages = function ( pages, index ) {
-       var i, len, name, page, item, currentIndex,
-               stackLayoutPages = this.stackLayout.getItems(),
-               remove = [],
-               items = [];
+       // Mixin constructors
+       OO.ui.IconElement.call( this, config );
+       OO.ui.LabelElement.call( this, config );
+       OO.ui.GroupElement.call( this, config );
 
-       // Remove pages with same names
-       for ( i = 0, len = pages.length; i < len; i++ ) {
-               page = pages[ i ];
-               name = page.getName();
+       if ( config.help ) {
+               this.popupButtonWidget = new OO.ui.PopupButtonWidget( {
+                       classes: [ 'oo-ui-fieldsetLayout-help' ],
+                       framed: false,
+                       icon: 'info'
+               } );
 
-               if ( Object.prototype.hasOwnProperty.call( this.pages, name ) ) {
-                       // Correct the insertion index
-                       currentIndex = $.inArray( this.pages[ name ], stackLayoutPages );
-                       if ( currentIndex !== -1 && currentIndex + 1 < index ) {
-                               index--;
-                       }
-                       remove.push( this.pages[ name ] );
-               }
-       }
-       if ( remove.length ) {
-               this.removePages( remove );
+               this.popupButtonWidget.getPopup().$body.append(
+                       $( '<div>' )
+                               .text( config.help )
+                               .addClass( 'oo-ui-fieldsetLayout-help-content' )
+               );
+               this.$help = this.popupButtonWidget.$element;
+       } else {
+               this.$help = $( [] );
        }
 
-       // Add new pages
-       for ( i = 0, len = pages.length; i < len; i++ ) {
-               page = pages[ i ];
-               name = page.getName();
-               this.pages[ page.getName() ] = page;
-               if ( this.outlined ) {
-                       item = new OO.ui.OutlineOptionWidget( { $: this.$, data: name } );
-                       page.setOutlineItem( item );
-                       items.push( item );
-               }
+       // Initialization
+       this.$element
+               .addClass( 'oo-ui-fieldsetLayout' )
+               .prepend( this.$help, this.$icon, this.$label, this.$group );
+       if ( $.isArray( config.items ) ) {
+               this.addItems( config.items );
        }
+};
 
-       if ( this.outlined && items.length ) {
-               this.outlineSelectWidget.addItems( items, index );
-               this.selectFirstSelectablePage();
-       }
-       this.stackLayout.addItems( pages, index );
-       this.emit( 'add', pages, index );
+/* Setup */
 
-       return this;
-};
+OO.inheritClass( OO.ui.FieldsetLayout, OO.ui.Layout );
+OO.mixinClass( OO.ui.FieldsetLayout, OO.ui.IconElement );
+OO.mixinClass( OO.ui.FieldsetLayout, OO.ui.LabelElement );
+OO.mixinClass( OO.ui.FieldsetLayout, OO.ui.GroupElement );
 
 /**
- * Remove a page from the layout.
+ * Layout with an HTML form.
  *
- * @fires remove
- * @chainable
+ * @class
+ * @extends OO.ui.Layout
+ *
+ * @constructor
+ * @param {Object} [config] Configuration options
+ * @cfg {string} [method] HTML form `method` attribute
+ * @cfg {string} [action] HTML form `action` attribute
+ * @cfg {string} [enctype] HTML form `enctype` attribute
  */
-OO.ui.BookletLayout.prototype.removePages = function ( pages ) {
-       var i, len, name, page,
-               items = [];
+OO.ui.FormLayout = function OoUiFormLayout( config ) {
+       // Configuration initialization
+       config = config || {};
 
-       for ( i = 0, len = pages.length; i < len; i++ ) {
-               page = pages[ i ];
-               name = page.getName();
-               delete this.pages[ name ];
-               if ( this.outlined ) {
-                       items.push( this.outlineSelectWidget.getItemFromData( name ) );
-                       page.setOutlineItem( null );
-               }
-       }
-       if ( this.outlined && items.length ) {
-               this.outlineSelectWidget.removeItems( items );
-               this.selectFirstSelectablePage();
-       }
-       this.stackLayout.removeItems( pages );
-       this.emit( 'remove', pages );
+       // Parent constructor
+       OO.ui.FormLayout.super.call( this, config );
 
-       return this;
-};
+       // Events
+       this.$element.on( 'submit', this.onFormSubmit.bind( this ) );
 
-/**
- * Clear all pages from the layout.
- *
- * @fires remove
- * @chainable
- */
-OO.ui.BookletLayout.prototype.clearPages = function () {
-       var i, len,
-               pages = this.stackLayout.getItems();
+       // Initialization
+       this.$element
+               .addClass( 'oo-ui-formLayout' )
+               .attr( {
+                       method: config.method,
+                       action: config.action,
+                       enctype: config.enctype
+               } );
+};
 
-       this.pages = {};
-       this.currentPageName = null;
-       if ( this.outlined ) {
-               this.outlineSelectWidget.clearItems();
-               for ( i = 0, len = pages.length; i < len; i++ ) {
-                       pages[ i ].setOutlineItem( null );
-               }
-       }
-       this.stackLayout.clearItems();
+/* Setup */
 
-       this.emit( 'remove', pages );
+OO.inheritClass( OO.ui.FormLayout, OO.ui.Layout );
 
-       return this;
-};
+/* Events */
 
 /**
- * Set the current page by name.
- *
- * @fires set
- * @param {string} name Symbolic name of page
+ * @event submit
  */
-OO.ui.BookletLayout.prototype.setPage = function ( name ) {
-       var selectedItem,
-               $focused,
-               page = this.pages[ name ];
 
-       if ( name !== this.currentPageName ) {
-               if ( this.outlined ) {
-                       selectedItem = this.outlineSelectWidget.getSelectedItem();
-                       if ( selectedItem && selectedItem.getData() !== name ) {
-                               this.outlineSelectWidget.selectItem( this.outlineSelectWidget.getItemFromData( name ) );
-                       }
-               }
-               if ( page ) {
-                       if ( this.currentPageName && this.pages[ this.currentPageName ] ) {
-                               this.pages[ this.currentPageName ].setActive( false );
-                               // Blur anything focused if the next page doesn't have anything focusable - this
-                               // is not needed if the next page has something focusable because once it is focused
-                               // this blur happens automatically
-                               if ( this.autoFocus && !page.$element.find( ':input' ).length ) {
-                                       $focused = this.pages[ this.currentPageName ].$element.find( ':focus' );
-                                       if ( $focused.length ) {
-                                               $focused[ 0 ].blur();
-                                       }
-                               }
-                       }
-                       this.currentPageName = name;
-                       this.stackLayout.setItem( page );
-                       page.setActive( true );
-                       this.emit( 'set', page );
-               }
-       }
-};
+/* Static Properties */
+
+OO.ui.FormLayout.static.tagName = 'form';
+
+/* Methods */
 
 /**
- * Select the first selectable page.
+ * Handle form submit events.
  *
- * @chainable
+ * @param {jQuery.Event} e Submit event
+ * @fires submit
  */
-OO.ui.BookletLayout.prototype.selectFirstSelectablePage = function () {
-       if ( !this.outlineSelectWidget.getSelectedItem() ) {
-               this.outlineSelectWidget.selectItem( this.outlineSelectWidget.getFirstSelectableItem() );
-       }
-
-       return this;
+OO.ui.FormLayout.prototype.onFormSubmit = function () {
+       this.emit( 'submit' );
+       return false;
 };
 
 /**
- * Layout made of a field and optional label.
- *
- * Available label alignment modes include:
- *  - left: Label is before the field and aligned away from it, best for when the user will be
- *    scanning for a specific label in a form with many fields
- *  - right: Label is before the field and aligned toward it, best for forms the user is very
- *    familiar with and will tab through field checking quickly to verify which field they are in
- *  - top: Label is before the field and above it, best for when the user will need to fill out all
- *    fields from top to bottom in a form with few fields
- *  - inline: Label is after the field and aligned toward it, best for small boolean fields like
- *    checkboxes or radio buttons
+ * Layout made of proportionally sized columns and rows.
  *
  * @class
  * @extends OO.ui.Layout
- * @mixins OO.ui.LabelElement
+ * @deprecated Use OO.ui.MenuLayout or plain CSS instead.
  *
  * @constructor
- * @param {OO.ui.Widget} fieldWidget Field widget
+ * @param {OO.ui.PanelLayout[]} panels Panels in the grid
  * @param {Object} [config] Configuration options
- * @cfg {string} [align='left'] Alignment mode, either 'left', 'right', 'top' or 'inline'
- * @cfg {string} [help] Explanatory text shown as a '?' icon.
+ * @cfg {number[]} [widths] Widths of columns as ratios
+ * @cfg {number[]} [heights] Heights of rows as ratios
  */
-OO.ui.FieldLayout = function OoUiFieldLayout( fieldWidget, config ) {
-       var hasInputWidget = fieldWidget instanceof OO.ui.InputWidget;
+OO.ui.GridLayout = function OoUiGridLayout( panels, config ) {
+       var i, len, widths;
 
        // Configuration initialization
-       config = $.extend( { align: 'left' }, config );
-
-       // Properties (must be set before parent constructor, which calls #getTagName)
-       this.fieldWidget = fieldWidget;
+       config = config || {};
 
        // Parent constructor
-       OO.ui.FieldLayout.super.call( this, config );
-
-       // Mixin constructors
-       OO.ui.LabelElement.call( this, config );
+       OO.ui.GridLayout.super.call( this, config );
 
        // Properties
-       this.$field = this.$( '<div>' );
-       this.$body = this.$( '<' + ( hasInputWidget ? 'label' : 'div' ) + '>' );
-       this.align = null;
-       if ( config.help ) {
-               this.popupButtonWidget = new OO.ui.PopupButtonWidget( {
-                       $: this.$,
-                       classes: [ 'oo-ui-fieldLayout-help' ],
-                       framed: false,
-                       icon: 'info'
-               } );
+       this.panels = [];
+       this.widths = [];
+       this.heights = [];
 
-               this.popupButtonWidget.getPopup().$body.append(
-                       this.$( '<div>' )
-                               .text( config.help )
-                               .addClass( 'oo-ui-fieldLayout-help-content' )
-               );
-               this.$help = this.popupButtonWidget.$element;
-       } else {
-               this.$help = this.$( [] );
+       // Initialization
+       this.$element.addClass( 'oo-ui-gridLayout' );
+       for ( i = 0, len = panels.length; i < len; i++ ) {
+               this.panels.push( panels[ i ] );
+               this.$element.append( panels[ i ].$element );
        }
-
-       // Events
-       if ( hasInputWidget ) {
-               this.$label.on( 'click', this.onLabelClick.bind( this ) );
+       if ( config.widths || config.heights ) {
+               this.layout( config.widths || [ 1 ], config.heights || [ 1 ] );
+       } else {
+               // Arrange in columns by default
+               widths = this.panels.map( function () { return 1; } );
+               this.layout( widths, [ 1 ] );
        }
-       this.fieldWidget.connect( this, { disable: 'onFieldDisable' } );
-
-       // Initialization
-       this.$element
-               .addClass( 'oo-ui-fieldLayout' )
-               .append( this.$help, this.$body );
-       this.$body.addClass( 'oo-ui-fieldLayout-body' );
-       this.$field
-               .addClass( 'oo-ui-fieldLayout-field' )
-               .toggleClass( 'oo-ui-fieldLayout-disable', this.fieldWidget.isDisabled() )
-               .append( this.fieldWidget.$element );
-
-       this.setAlignment( config.align );
 };
 
 /* Setup */
 
-OO.inheritClass( OO.ui.FieldLayout, OO.ui.Layout );
-OO.mixinClass( OO.ui.FieldLayout, OO.ui.LabelElement );
+OO.inheritClass( OO.ui.GridLayout, OO.ui.Layout );
 
-/* Methods */
+/* Events */
 
 /**
- * Handle field disable events.
- *
- * @param {boolean} value Field is disabled
+ * @event layout
  */
-OO.ui.FieldLayout.prototype.onFieldDisable = function ( value ) {
-       this.$element.toggleClass( 'oo-ui-fieldLayout-disabled', value );
-};
 
 /**
- * Handle label mouse click events.
- *
- * @param {jQuery.Event} e Mouse click event
+ * @event update
  */
-OO.ui.FieldLayout.prototype.onLabelClick = function () {
-       this.fieldWidget.simulateLabelClick();
-       return false;
-};
 
-/**
- * Get the field.
- *
- * @return {OO.ui.Widget} Field widget
- */
-OO.ui.FieldLayout.prototype.getField = function () {
-       return this.fieldWidget;
-};
+/* Methods */
 
 /**
- * Set the field alignment mode.
+ * Set grid dimensions.
  *
- * @private
- * @param {string} value Alignment mode, either 'left', 'right', 'top' or 'inline'
- * @chainable
+ * @param {number[]} widths Widths of columns as ratios
+ * @param {number[]} heights Heights of rows as ratios
+ * @fires layout
+ * @throws {Error} If grid is not large enough to fit all panels
  */
-OO.ui.FieldLayout.prototype.setAlignment = function ( value ) {
-       if ( value !== this.align ) {
-               // Default to 'left'
-               if ( [ 'left', 'right', 'top', 'inline' ].indexOf( value ) === -1 ) {
-                       value = 'left';
-               }
-               // Reorder elements
-               if ( value === 'inline' ) {
-                       this.$body.append( this.$field, this.$label );
-               } else {
-                       this.$body.append( this.$label, this.$field );
-               }
-               // Set classes. The following classes can be used here:
-               // * oo-ui-fieldLayout-align-left
-               // * oo-ui-fieldLayout-align-right
-               // * oo-ui-fieldLayout-align-top
-               // * oo-ui-fieldLayout-align-inline
-               if ( this.align ) {
-                       this.$element.removeClass( 'oo-ui-fieldLayout-align-' + this.align );
-               }
-               this.$element.addClass( 'oo-ui-fieldLayout-align-' + value );
-               this.align = value;
+OO.ui.GridLayout.prototype.layout = function ( widths, heights ) {
+       var x, y,
+               xd = 0,
+               yd = 0,
+               cols = widths.length,
+               rows = heights.length;
+
+       // Verify grid is big enough to fit panels
+       if ( cols * rows < this.panels.length ) {
+               throw new Error( 'Grid is not large enough to fit ' + this.panels.length + 'panels' );
        }
 
-       return this;
+       // Sum up denominators
+       for ( x = 0; x < cols; x++ ) {
+               xd += widths[ x ];
+       }
+       for ( y = 0; y < rows; y++ ) {
+               yd += heights[ y ];
+       }
+       // Store factors
+       this.widths = [];
+       this.heights = [];
+       for ( x = 0; x < cols; x++ ) {
+               this.widths[ x ] = widths[ x ] / xd;
+       }
+       for ( y = 0; y < rows; y++ ) {
+               this.heights[ y ] = heights[ y ] / yd;
+       }
+       // Synchronize view
+       this.update();
+       this.emit( 'layout' );
 };
 
 /**
- * Layout made of a field, a button, and an optional label.
- *
- * @class
- * @extends OO.ui.FieldLayout
+ * Update panel positions and sizes.
  *
- * @constructor
- * @param {OO.ui.Widget} fieldWidget Field widget
- * @param {OO.ui.ButtonWidget} buttonWidget Button widget
- * @param {Object} [config] Configuration options
- * @cfg {string} [align='left'] Alignment mode, either 'left', 'right', 'top' or 'inline'
- * @cfg {string} [help] Explanatory text shown as a '?' icon.
+ * @fires update
  */
-OO.ui.ActionFieldLayout = function OoUiActionFieldLayout( fieldWidget, buttonWidget, config ) {
-       // Configuration initialization
-       config = $.extend( { align: 'left' }, config );
-
-       // Properties (must be set before parent constructor, which calls #getTagName)
-       this.fieldWidget = fieldWidget;
-       this.buttonWidget = buttonWidget;
-
-       // Parent constructor
-       OO.ui.ActionFieldLayout.super.call( this, fieldWidget, config );
-
-       // Mixin constructors
-       OO.ui.LabelElement.call( this, config );
-
-       // Properties
-       this.$button = this.$( '<div>' )
-               .addClass( 'oo-ui-actionFieldLayout-button' )
-               .append( this.buttonWidget.$element );
+OO.ui.GridLayout.prototype.update = function () {
+       var x, y, panel, width, height, dimensions,
+               i = 0,
+               top = 0,
+               left = 0,
+               cols = this.widths.length,
+               rows = this.heights.length;
 
-       this.$input = this.$( '<div>' )
-               .addClass( 'oo-ui-actionFieldLayout-input' )
-               .append( this.fieldWidget.$element );
+       for ( y = 0; y < rows; y++ ) {
+               height = this.heights[ y ];
+               for ( x = 0; x < cols; x++ ) {
+                       width = this.widths[ x ];
+                       panel = this.panels[ i ];
+                       dimensions = {
+                               width: ( width * 100 ) + '%',
+                               height: ( height * 100 ) + '%',
+                               top: ( top * 100 ) + '%'
+                       };
+                       // If RTL, reverse:
+                       if ( OO.ui.Element.static.getDir( document ) === 'rtl' ) {
+                               dimensions.right = ( left * 100 ) + '%';
+                       } else {
+                               dimensions.left = ( left * 100 ) + '%';
+                       }
+                       // HACK: Work around IE bug by setting visibility: hidden; if width or height is zero
+                       if ( width === 0 || height === 0 ) {
+                               dimensions.visibility = 'hidden';
+                       } else {
+                               dimensions.visibility = '';
+                       }
+                       panel.$element.css( dimensions );
+                       i++;
+                       left += width;
+               }
+               top += height;
+               left = 0;
+       }
 
-       this.$field
-               .addClass( 'oo-ui-actionFieldLayout' )
-               .append( this.$input, this.$button );
+       this.emit( 'update' );
 };
 
-/* Setup */
-
-OO.inheritClass( OO.ui.ActionFieldLayout, OO.ui.FieldLayout );
+/**
+ * Get a panel at a given position.
+ *
+ * The x and y position is affected by the current grid layout.
+ *
+ * @param {number} x Horizontal position
+ * @param {number} y Vertical position
+ * @return {OO.ui.PanelLayout} The panel at the given position
+ */
+OO.ui.GridLayout.prototype.getPanel = function ( x, y ) {
+       return this.panels[ ( x * this.widths.length ) + y ];
+};
 
 /**
- * Layout made of a fieldset and optional legend.
+ * Layout with a content and menu area.
  *
- * Just add OO.ui.FieldLayout items.
+ * The menu area can be positioned at the top, after, bottom or before. The content area will fill
+ * all remaining space.
  *
  * @class
  * @extends OO.ui.Layout
- * @mixins OO.ui.IconElement
- * @mixins OO.ui.LabelElement
- * @mixins OO.ui.GroupElement
  *
  * @constructor
  * @param {Object} [config] Configuration options
- * @cfg {OO.ui.FieldLayout[]} [items] Items to add
+ * @cfg {number|string} [menuSize='18em'] Size of menu in pixels or any CSS unit
+ * @cfg {boolean} [showMenu=true] Show menu
+ * @cfg {string} [position='before'] Position of menu, either `top`, `after`, `bottom` or `before`
+ * @cfg {boolean} [collapse] Collapse the menu out of view
  */
-OO.ui.FieldsetLayout = function OoUiFieldsetLayout( config ) {
+OO.ui.MenuLayout = function OoUiMenuLayout( config ) {
+       var positions = this.constructor.static.menuPositions;
+
        // Configuration initialization
        config = config || {};
 
        // Parent constructor
-       OO.ui.FieldsetLayout.super.call( this, config );
-
-       // Mixin constructors
-       OO.ui.IconElement.call( this, config );
-       OO.ui.LabelElement.call( this, config );
-       OO.ui.GroupElement.call( this, config );
+       OO.ui.MenuLayout.super.call( this, config );
 
-       if ( config.help ) {
-               this.popupButtonWidget = new OO.ui.PopupButtonWidget( {
-                       $: this.$,
-                       classes: [ 'oo-ui-fieldsetLayout-help' ],
-                       framed: false,
-                       icon: 'info'
-               } );
+       // Properties
+       this.showMenu = config.showMenu !== false;
+       this.menuSize = config.menuSize || '18em';
+       this.menuPosition = positions[ config.menuPosition ] || positions.before;
 
-               this.popupButtonWidget.getPopup().$body.append(
-                       this.$( '<div>' )
-                               .text( config.help )
-                               .addClass( 'oo-ui-fieldsetLayout-help-content' )
-               );
-               this.$help = this.popupButtonWidget.$element;
-       } else {
-               this.$help = this.$( [] );
-       }
+       /**
+        * Menu DOM node
+        *
+        * @property {jQuery}
+        */
+       this.$menu = $( '<div>' );
+       /**
+        * Content DOM node
+        *
+        * @property {jQuery}
+        */
+       this.$content = $( '<div>' );
 
        // Initialization
+       this.toggleMenu( this.showMenu );
+       this.updateSizes();
+       this.$menu
+               .addClass( 'oo-ui-menuLayout-menu' )
+               .css( this.menuPosition.sizeProperty, this.menuSize );
+       this.$content.addClass( 'oo-ui-menuLayout-content' );
        this.$element
-               .addClass( 'oo-ui-fieldsetLayout' )
-               .prepend( this.$help, this.$icon, this.$label, this.$group );
-       if ( $.isArray( config.items ) ) {
-               this.addItems( config.items );
-       }
+               .addClass( 'oo-ui-menuLayout ' + this.menuPosition.className )
+               .append( this.$content, this.$menu );
 };
 
 /* Setup */
 
-OO.inheritClass( OO.ui.FieldsetLayout, OO.ui.Layout );
-OO.mixinClass( OO.ui.FieldsetLayout, OO.ui.IconElement );
-OO.mixinClass( OO.ui.FieldsetLayout, OO.ui.LabelElement );
-OO.mixinClass( OO.ui.FieldsetLayout, OO.ui.GroupElement );
+OO.inheritClass( OO.ui.MenuLayout, OO.ui.Layout );
+
+/* Static Properties */
+
+OO.ui.MenuLayout.static.menuPositions = {
+       top: {
+               sizeProperty: 'height',
+               className: 'oo-ui-menuLayout-top'
+       },
+       after: {
+               sizeProperty: 'width',
+               className: 'oo-ui-menuLayout-after'
+       },
+       bottom: {
+               sizeProperty: 'height',
+               className: 'oo-ui-menuLayout-bottom'
+       },
+       before: {
+               sizeProperty: 'width',
+               className: 'oo-ui-menuLayout-before'
+       }
+};
+
+/* Methods */
 
 /**
- * Layout with an HTML form.
- *
- * @class
- * @extends OO.ui.Layout
+ * Toggle menu.
  *
- * @constructor
- * @param {Object} [config] Configuration options
- * @cfg {string} [method] HTML form `method` attribute
- * @cfg {string} [action] HTML form `action` attribute
- * @cfg {string} [enctype] HTML form `enctype` attribute
+ * @param {boolean} showMenu Show menu, omit to toggle
+ * @chainable
  */
-OO.ui.FormLayout = function OoUiFormLayout( config ) {
-       // Configuration initialization
-       config = config || {};
+OO.ui.MenuLayout.prototype.toggleMenu = function ( showMenu ) {
+       showMenu = showMenu === undefined ? !this.showMenu : !!showMenu;
 
-       // Parent constructor
-       OO.ui.FormLayout.super.call( this, config );
+       if ( this.showMenu !== showMenu ) {
+               this.showMenu = showMenu;
+               this.updateSizes();
+       }
 
-       // Events
-       this.$element.on( 'submit', this.onFormSubmit.bind( this ) );
+       return this;
+};
 
-       // Initialization
-       this.$element
-               .addClass( 'oo-ui-formLayout' )
-               .attr( {
-                       method: config.method,
-                       action: config.action,
-                       enctype: config.enctype
-               } );
+/**
+ * Check if menu is visible
+ *
+ * @return {boolean} Menu is visible
+ */
+OO.ui.MenuLayout.prototype.isMenuVisible = function () {
+       return this.showMenu;
 };
 
-/* Setup */
+/**
+ * Set menu size.
+ *
+ * @param {number|string} size Size of menu in pixels or any CSS unit
+ * @chainable
+ */
+OO.ui.MenuLayout.prototype.setMenuSize = function ( size ) {
+       this.menuSize = size;
+       this.updateSizes();
 
-OO.inheritClass( OO.ui.FormLayout, OO.ui.Layout );
+       return this;
+};
 
-/* Events */
+/**
+ * Update menu and content CSS based on current menu size and visibility
+ *
+ * This method is called internally when size or position is changed.
+ */
+OO.ui.MenuLayout.prototype.updateSizes = function () {
+       if ( this.showMenu ) {
+               this.$menu
+                       .css( this.menuPosition.sizeProperty, this.menuSize )
+                       .css( 'overflow', '' );
+               // Set offsets on all sides. CSS resets all but one with
+               // 'important' rules so directionality flips are supported
+               this.$content.css( {
+                       top: this.menuSize,
+                       right: this.menuSize,
+                       bottom: this.menuSize,
+                       left: this.menuSize
+               } );
+       } else {
+               this.$menu
+                       .css( this.menuPosition.sizeProperty, 0 )
+                       .css( 'overflow', 'hidden' );
+               this.$content.css( {
+                       top: 0,
+                       right: 0,
+                       bottom: 0,
+                       left: 0
+               } );
+       }
+};
 
 /**
- * @event submit
+ * Get menu size.
+ *
+ * @return {number|string} Menu size
  */
+OO.ui.MenuLayout.prototype.getMenuSize = function () {
+       return this.menuSize;
+};
 
-/* Static Properties */
+/**
+ * Set menu position.
+ *
+ * @param {string} position Position of menu, either `top`, `after`, `bottom` or `before`
+ * @throws {Error} If position value is not supported
+ * @chainable
+ */
+OO.ui.MenuLayout.prototype.setMenuPosition = function ( position ) {
+       var positions = this.constructor.static.menuPositions;
 
-OO.ui.FormLayout.static.tagName = 'form';
+       if ( !positions[ position ] ) {
+               throw new Error( 'Cannot set position; unsupported position value: ' + position );
+       }
 
-/* Methods */
+       this.$menu.css( this.menuPosition.sizeProperty, '' );
+       this.$element.removeClass( this.menuPosition.className );
+
+       this.menuPosition = positions[ position ];
+
+       this.updateSizes();
+       this.$element.addClass( this.menuPosition.className );
+
+       return this;
+};
 
 /**
- * Handle form submit events.
+ * Get menu position.
  *
- * @param {jQuery.Event} e Submit event
- * @fires submit
+ * @return {string} Menu position
  */
-OO.ui.FormLayout.prototype.onFormSubmit = function () {
-       this.emit( 'submit' );
-       return false;
+OO.ui.MenuLayout.prototype.getMenuPosition = function () {
+       return this.menuPosition;
 };
 
 /**
- * Layout made of proportionally sized columns and rows.
+ * Layout containing a series of pages.
  *
  * @class
- * @extends OO.ui.Layout
+ * @extends OO.ui.MenuLayout
  *
  * @constructor
- * @param {OO.ui.PanelLayout[]} panels Panels in the grid
  * @param {Object} [config] Configuration options
- * @cfg {number[]} [widths] Widths of columns as ratios
- * @cfg {number[]} [heights] Heights of rows as ratios
+ * @cfg {boolean} [continuous=false] Show all pages, one after another
+ * @cfg {boolean} [autoFocus=true] Focus on the first focusable element when changing to a page
+ * @cfg {boolean} [outlined=false] Show an outline
+ * @cfg {boolean} [editable=false] Show controls for adding, removing and reordering pages
  */
-OO.ui.GridLayout = function OoUiGridLayout( panels, config ) {
-       var i, len, widths;
-
+OO.ui.BookletLayout = function OoUiBookletLayout( config ) {
        // Configuration initialization
        config = config || {};
 
        // Parent constructor
-       OO.ui.GridLayout.super.call( this, config );
+       OO.ui.BookletLayout.super.call( this, config );
+
+       // Properties
+       this.currentPageName = null;
+       this.pages = {};
+       this.ignoreFocus = false;
+       this.stackLayout = new OO.ui.StackLayout( { continuous: !!config.continuous } );
+       this.$content.append( this.stackLayout.$element );
+       this.autoFocus = config.autoFocus === undefined || !!config.autoFocus;
+       this.outlineVisible = false;
+       this.outlined = !!config.outlined;
+       if ( this.outlined ) {
+               this.editable = !!config.editable;
+               this.outlineControlsWidget = null;
+               this.outlineSelectWidget = new OO.ui.OutlineSelectWidget();
+               this.outlinePanel = new OO.ui.PanelLayout( { scrollable: true } );
+               this.$menu.append( this.outlinePanel.$element );
+               this.outlineVisible = true;
+               if ( this.editable ) {
+                       this.outlineControlsWidget = new OO.ui.OutlineControlsWidget(
+                               this.outlineSelectWidget
+                       );
+               }
+       }
+       this.toggleMenu( this.outlined );
 
-       // Properties
-       this.panels = [];
-       this.widths = [];
-       this.heights = [];
+       // Events
+       this.stackLayout.connect( this, { set: 'onStackLayoutSet' } );
+       if ( this.outlined ) {
+               this.outlineSelectWidget.connect( this, { select: 'onOutlineSelectWidgetSelect' } );
+       }
+       if ( this.autoFocus ) {
+               // Event 'focus' does not bubble, but 'focusin' does
+               this.stackLayout.$element.on( 'focusin', this.onStackLayoutFocus.bind( this ) );
+       }
 
        // Initialization
-       this.$element.addClass( 'oo-ui-gridLayout' );
-       for ( i = 0, len = panels.length; i < len; i++ ) {
-               this.panels.push( panels[ i ] );
-               this.$element.append( panels[ i ].$element );
-       }
-       if ( config.widths || config.heights ) {
-               this.layout( config.widths || [ 1 ], config.heights || [ 1 ] );
-       } else {
-               // Arrange in columns by default
-               widths = this.panels.map( function () { return 1; } );
-               this.layout( widths, [ 1 ] );
+       this.$element.addClass( 'oo-ui-bookletLayout' );
+       this.stackLayout.$element.addClass( 'oo-ui-bookletLayout-stackLayout' );
+       if ( this.outlined ) {
+               this.outlinePanel.$element
+                       .addClass( 'oo-ui-bookletLayout-outlinePanel' )
+                       .append( this.outlineSelectWidget.$element );
+               if ( this.editable ) {
+                       this.outlinePanel.$element
+                               .addClass( 'oo-ui-bookletLayout-outlinePanel-editable' )
+                               .append( this.outlineControlsWidget.$element );
+               }
        }
 };
 
 /* Setup */
 
-OO.inheritClass( OO.ui.GridLayout, OO.ui.Layout );
+OO.inheritClass( OO.ui.BookletLayout, OO.ui.MenuLayout );
 
 /* Events */
 
 /**
- * @event layout
+ * @event set
+ * @param {OO.ui.PageLayout} page Current page
  */
 
 /**
- * @event update
+ * @event add
+ * @param {OO.ui.PageLayout[]} page Added pages
+ * @param {number} index Index pages were added at
+ */
+
+/**
+ * @event remove
+ * @param {OO.ui.PageLayout[]} pages Removed pages
  */
 
 /* Methods */
 
 /**
- * Set grid dimensions.
+ * Handle stack layout focus.
  *
- * @param {number[]} widths Widths of columns as ratios
- * @param {number[]} heights Heights of rows as ratios
- * @fires layout
- * @throws {Error} If grid is not large enough to fit all panels
+ * @param {jQuery.Event} e Focusin event
  */
-OO.ui.GridLayout.prototype.layout = function ( widths, heights ) {
-       var x, y,
-               xd = 0,
-               yd = 0,
-               cols = widths.length,
-               rows = heights.length;
+OO.ui.BookletLayout.prototype.onStackLayoutFocus = function ( e ) {
+       var name, $target;
 
-       // Verify grid is big enough to fit panels
-       if ( cols * rows < this.panels.length ) {
-               throw new Error( 'Grid is not large enough to fit ' + this.panels.length + 'panels' );
+       // Find the page that an element was focused within
+       $target = $( e.target ).closest( '.oo-ui-pageLayout' );
+       for ( name in this.pages ) {
+               // Check for page match, exclude current page to find only page changes
+               if ( this.pages[ name ].$element[ 0 ] === $target[ 0 ] && name !== this.currentPageName ) {
+                       this.setPage( name );
+                       break;
+               }
        }
+};
 
-       // Sum up denominators
-       for ( x = 0; x < cols; x++ ) {
-               xd += widths[ x ];
-       }
-       for ( y = 0; y < rows; y++ ) {
-               yd += heights[ y ];
-       }
-       // Store factors
-       this.widths = [];
-       this.heights = [];
-       for ( x = 0; x < cols; x++ ) {
-               this.widths[ x ] = widths[ x ] / xd;
-       }
-       for ( y = 0; y < rows; y++ ) {
-               this.heights[ y ] = heights[ y ] / yd;
+/**
+ * Handle stack layout set events.
+ *
+ * @param {OO.ui.PanelLayout|null} page The page panel that is now the current panel
+ */
+OO.ui.BookletLayout.prototype.onStackLayoutSet = function ( page ) {
+       var layout = this;
+       if ( page ) {
+               page.scrollElementIntoView( { complete: function () {
+                       if ( layout.autoFocus ) {
+                               layout.focus();
+                       }
+               } } );
        }
-       // Synchronize view
-       this.update();
-       this.emit( 'layout' );
 };
 
 /**
- * Update panel positions and sizes.
+ * Focus the first input in the current page.
  *
- * @fires update
+ * If no page is selected, the first selectable page will be selected.
+ * If the focus is already in an element on the current page, nothing will happen.
  */
-OO.ui.GridLayout.prototype.update = function () {
-       var x, y, panel, width, height, dimensions,
-               i = 0,
-               top = 0,
-               left = 0,
-               cols = this.widths.length,
-               rows = this.heights.length;
-
-       for ( y = 0; y < rows; y++ ) {
-               height = this.heights[ y ];
-               for ( x = 0; x < cols; x++ ) {
-                       width = this.widths[ x ];
-                       panel = this.panels[ i ];
-                       dimensions = {
-                               width: ( width * 100 ) + '%',
-                               height: ( height * 100 ) + '%',
-                               top: ( top * 100 ) + '%'
-                       };
-                       // If RTL, reverse:
-                       if ( OO.ui.Element.static.getDir( this.$.context ) === 'rtl' ) {
-                               dimensions.right = ( left * 100 ) + '%';
-                       } else {
-                               dimensions.left = ( left * 100 ) + '%';
-                       }
-                       // HACK: Work around IE bug by setting visibility: hidden; if width or height is zero
-                       if ( width === 0 || height === 0 ) {
-                               dimensions.visibility = 'hidden';
-                       } else {
-                               dimensions.visibility = '';
-                       }
-                       panel.$element.css( dimensions );
-                       i++;
-                       left += width;
+OO.ui.BookletLayout.prototype.focus = function () {
+       var $input, page = this.stackLayout.getCurrentItem();
+       if ( !page && this.outlined ) {
+               this.selectFirstSelectablePage();
+               page = this.stackLayout.getCurrentItem();
+       }
+       if ( !page ) {
+               return;
+       }
+       // Only change the focus if is not already in the current page
+       if ( !page.$element.find( ':focus' ).length ) {
+               $input = page.$element.find( ':input:first' );
+               if ( $input.length ) {
+                       $input[ 0 ].focus();
                }
-               top += height;
-               left = 0;
        }
-
-       this.emit( 'update' );
 };
 
 /**
- * Get a panel at a given position.
- *
- * The x and y position is affected by the current grid layout.
+ * Handle outline widget select events.
  *
- * @param {number} x Horizontal position
- * @param {number} y Vertical position
- * @return {OO.ui.PanelLayout} The panel at the given position
+ * @param {OO.ui.OptionWidget|null} item Selected item
  */
-OO.ui.GridLayout.prototype.getPanel = function ( x, y ) {
-       return this.panels[ ( x * this.widths.length ) + y ];
+OO.ui.BookletLayout.prototype.onOutlineSelectWidgetSelect = function ( item ) {
+       if ( item ) {
+               this.setPage( item.getData() );
+       }
 };
 
 /**
- * Layout with a content and menu area.
- *
- * The menu area can be positioned at the top, after, bottom or before. The content area will fill
- * all remaining space.
- *
- * @class
- * @extends OO.ui.Layout
+ * Check if booklet has an outline.
  *
- * @constructor
- * @param {Object} [config] Configuration options
- * @cfg {number|string} [menuSize='18em'] Size of menu in pixels or any CSS unit
- * @cfg {boolean} [showMenu=true] Show menu
- * @cfg {string} [position='before'] Position of menu, either `top`, `after`, `bottom` or `before`
- * @cfg {boolean} [collapse] Collapse the menu out of view
+ * @return {boolean}
  */
-OO.ui.MenuLayout = function OoUiMenuLayout( config ) {
-       var positions = this.constructor.static.menuPositions;
-
-       // Configuration initialization
-       config = config || {};
-
-       // Parent constructor
-       OO.ui.MenuLayout.super.call( this, config );
-
-       // Properties
-       this.showMenu = config.showMenu !== false;
-       this.menuSize = config.menuSize || '18em';
-       this.menuPosition = positions[ config.menuPosition ] || positions.before;
-
-       /**
-        * Menu DOM node
-        *
-        * @property {jQuery}
-        */
-       this.$menu = this.$( '<div>' );
-       /**
-        * Content DOM node
-        *
-        * @property {jQuery}
-        */
-       this.$content = this.$( '<div>' );
-
-       // Events
-       this.$element.on( 'DOMNodeInsertedIntoDocument', this.onElementAttach.bind( this ) );
-
-       // Initialization
-       this.toggleMenu( this.showMenu );
-       this.$menu
-               .addClass( 'oo-ui-menuLayout-menu' )
-               .css( this.menuPosition.sizeProperty, this.menuSize );
-       this.$content.addClass( 'oo-ui-menuLayout-content' );
-       this.$element
-               .addClass( 'oo-ui-menuLayout ' + this.menuPosition.className )
-               .append( this.$content, this.$menu );
+OO.ui.BookletLayout.prototype.isOutlined = function () {
+       return this.outlined;
 };
-
-/* Setup */
-
-OO.inheritClass( OO.ui.MenuLayout, OO.ui.Layout );
-
-/* Static Properties */
-
-OO.ui.MenuLayout.static.menuPositions = {
-       top: {
-               sizeProperty: 'height',
-               positionProperty: 'top',
-               className: 'oo-ui-menuLayout-top'
-       },
-       after: {
-               sizeProperty: 'width',
-               positionProperty: 'right',
-               rtlPositionProperty: 'left',
-               className: 'oo-ui-menuLayout-after'
-       },
-       bottom: {
-               sizeProperty: 'height',
-               positionProperty: 'bottom',
-               className: 'oo-ui-menuLayout-bottom'
-       },
-       before: {
-               sizeProperty: 'width',
-               positionProperty: 'left',
-               rtlPositionProperty: 'right',
-               className: 'oo-ui-menuLayout-before'
-       }
+
+/**
+ * Check if booklet has editing controls.
+ *
+ * @return {boolean}
+ */
+OO.ui.BookletLayout.prototype.isEditable = function () {
+       return this.editable;
 };
 
-/* Methods */
+/**
+ * Check if booklet has a visible outline.
+ *
+ * @return {boolean}
+ */
+OO.ui.BookletLayout.prototype.isOutlineVisible = function () {
+       return this.outlined && this.outlineVisible;
+};
 
 /**
- * Handle DOM attachment events
+ * Hide or show the outline.
+ *
+ * @param {boolean} [show] Show outline, omit to invert current state
+ * @chainable
  */
-OO.ui.MenuLayout.prototype.onElementAttach = function () {
-       // getPositionProperty won't know about directionality until the layout is attached
-       if ( this.showMenu ) {
-               this.$content.css( this.getPositionProperty(), this.menuSize );
+OO.ui.BookletLayout.prototype.toggleOutline = function ( show ) {
+       if ( this.outlined ) {
+               show = show === undefined ? !this.outlineVisible : !!show;
+               this.outlineVisible = show;
+               this.toggleMenu( show );
        }
+
+       return this;
 };
 
 /**
- * Toggle menu.
+ * Get the outline widget.
  *
- * @param {boolean} showMenu Show menu, omit to toggle
- * @chainable
+ * @param {OO.ui.PageLayout} page Page to be selected
+ * @return {OO.ui.PageLayout|null} Closest page to another
  */
-OO.ui.MenuLayout.prototype.toggleMenu = function ( showMenu ) {
-       showMenu = showMenu === undefined ? !this.showMenu : !!showMenu;
+OO.ui.BookletLayout.prototype.getClosestPage = function ( page ) {
+       var next, prev, level,
+               pages = this.stackLayout.getItems(),
+               index = $.inArray( page, pages );
 
-       if ( this.showMenu !== showMenu ) {
-               this.showMenu = showMenu;
-               this.updateSizes();
+       if ( index !== -1 ) {
+               next = pages[ index + 1 ];
+               prev = pages[ index - 1 ];
+               // Prefer adjacent pages at the same level
+               if ( this.outlined ) {
+                       level = this.outlineSelectWidget.getItemFromData( page.getName() ).getLevel();
+                       if (
+                               prev &&
+                               level === this.outlineSelectWidget.getItemFromData( prev.getName() ).getLevel()
+                       ) {
+                               return prev;
+                       }
+                       if (
+                               next &&
+                               level === this.outlineSelectWidget.getItemFromData( next.getName() ).getLevel()
+                       ) {
+                               return next;
+                       }
+               }
        }
+       return prev || next || null;
+};
 
-       return this;
+/**
+ * Get the outline widget.
+ *
+ * @return {OO.ui.OutlineSelectWidget|null} Outline widget, or null if booklet has no outline
+ */
+OO.ui.BookletLayout.prototype.getOutline = function () {
+       return this.outlineSelectWidget;
 };
 
 /**
- * Check if menu is visible
+ * Get the outline controls widget. If the outline is not editable, null is returned.
  *
- * @return {boolean} Menu is visible
+ * @return {OO.ui.OutlineControlsWidget|null} The outline controls widget.
  */
-OO.ui.MenuLayout.prototype.isMenuVisible = function () {
-       return this.showMenu;
+OO.ui.BookletLayout.prototype.getOutlineControls = function () {
+       return this.outlineControlsWidget;
 };
 
 /**
- * Set menu size.
+ * Get a page by name.
  *
- * @param {number|string} size Size of menu in pixels or any CSS unit
- * @chainable
+ * @param {string} name Symbolic name of page
+ * @return {OO.ui.PageLayout|undefined} Page, if found
  */
-OO.ui.MenuLayout.prototype.setMenuSize = function ( size ) {
-       this.menuSize = size;
-       this.updateSizes();
+OO.ui.BookletLayout.prototype.getPage = function ( name ) {
+       return this.pages[ name ];
+};
 
-       return this;
+/**
+ * Get the current page
+ *
+ * @return {OO.ui.PageLayout|undefined} Current page, if found
+ */
+OO.ui.BookletLayout.prototype.getCurrentPage = function () {
+       var name = this.getCurrentPageName();
+       return name ? this.getPage( name ) : undefined;
 };
 
 /**
- * Update menu and content CSS based on current menu size and visibility
+ * Get the current page name.
+ *
+ * @return {string|null} Current page name
  */
-OO.ui.MenuLayout.prototype.updateSizes = function () {
-       if ( this.showMenu ) {
-               this.$menu
-                       .css( this.menuPosition.sizeProperty, this.menuSize )
-                       .css( 'overflow', '' );
-               this.$content.css( this.getPositionProperty(), this.menuSize );
-       } else {
-               this.$menu
-                       .css( this.menuPosition.sizeProperty, 0 )
-                       .css( 'overflow', 'hidden' );
-               this.$content.css( this.getPositionProperty(), 0 );
-       }
+OO.ui.BookletLayout.prototype.getCurrentPageName = function () {
+       return this.currentPageName;
 };
 
 /**
- * Get menu size.
+ * Add a page to the layout.
  *
- * @return {number|string} Menu size
+ * When pages are added with the same names as existing pages, the existing pages will be
+ * automatically removed before the new pages are added.
+ *
+ * @param {OO.ui.PageLayout[]} pages Pages to add
+ * @param {number} index Index to insert pages after
+ * @fires add
+ * @chainable
  */
-OO.ui.MenuLayout.prototype.getMenuSize = function () {
-       return this.menuSize;
+OO.ui.BookletLayout.prototype.addPages = function ( pages, index ) {
+       var i, len, name, page, item, currentIndex,
+               stackLayoutPages = this.stackLayout.getItems(),
+               remove = [],
+               items = [];
+
+       // Remove pages with same names
+       for ( i = 0, len = pages.length; i < len; i++ ) {
+               page = pages[ i ];
+               name = page.getName();
+
+               if ( Object.prototype.hasOwnProperty.call( this.pages, name ) ) {
+                       // Correct the insertion index
+                       currentIndex = $.inArray( this.pages[ name ], stackLayoutPages );
+                       if ( currentIndex !== -1 && currentIndex + 1 < index ) {
+                               index--;
+                       }
+                       remove.push( this.pages[ name ] );
+               }
+       }
+       if ( remove.length ) {
+               this.removePages( remove );
+       }
+
+       // Add new pages
+       for ( i = 0, len = pages.length; i < len; i++ ) {
+               page = pages[ i ];
+               name = page.getName();
+               this.pages[ page.getName() ] = page;
+               if ( this.outlined ) {
+                       item = new OO.ui.OutlineOptionWidget( { data: name } );
+                       page.setOutlineItem( item );
+                       items.push( item );
+               }
+       }
+
+       if ( this.outlined && items.length ) {
+               this.outlineSelectWidget.addItems( items, index );
+               this.selectFirstSelectablePage();
+       }
+       this.stackLayout.addItems( pages, index );
+       this.emit( 'add', pages, index );
+
+       return this;
 };
 
 /**
- * Set menu position.
+ * Remove a page from the layout.
  *
- * @param {string} position Position of menu, either `top`, `after`, `bottom` or `before`
- * @throws {Error} If position value is not supported
+ * @fires remove
  * @chainable
  */
-OO.ui.MenuLayout.prototype.setMenuPosition = function ( position ) {
-       var positionProperty, positions = this.constructor.static.menuPositions;
+OO.ui.BookletLayout.prototype.removePages = function ( pages ) {
+       var i, len, name, page,
+               items = [];
 
-       if ( !positions[ position ] ) {
-               throw new Error( 'Cannot set position; unsupported position value: ' + position );
+       for ( i = 0, len = pages.length; i < len; i++ ) {
+               page = pages[ i ];
+               name = page.getName();
+               delete this.pages[ name ];
+               if ( this.outlined ) {
+                       items.push( this.outlineSelectWidget.getItemFromData( name ) );
+                       page.setOutlineItem( null );
+               }
+       }
+       if ( this.outlined && items.length ) {
+               this.outlineSelectWidget.removeItems( items );
+               this.selectFirstSelectablePage();
        }
+       this.stackLayout.removeItems( pages );
+       this.emit( 'remove', pages );
 
-       positionProperty = this.getPositionProperty();
-       this.$menu.css( this.menuPosition.sizeProperty, '' );
-       this.$content.css( positionProperty, '' );
-       this.$element.removeClass( this.menuPosition.className );
+       return this;
+};
 
-       this.menuPosition = positions[ position ];
+/**
+ * Clear all pages from the layout.
+ *
+ * @fires remove
+ * @chainable
+ */
+OO.ui.BookletLayout.prototype.clearPages = function () {
+       var i, len,
+               pages = this.stackLayout.getItems();
 
-       this.updateSizes();
-       this.$element.addClass( this.menuPosition.className );
+       this.pages = {};
+       this.currentPageName = null;
+       if ( this.outlined ) {
+               this.outlineSelectWidget.clearItems();
+               for ( i = 0, len = pages.length; i < len; i++ ) {
+                       pages[ i ].setOutlineItem( null );
+               }
+       }
+       this.stackLayout.clearItems();
+
+       this.emit( 'remove', pages );
 
        return this;
 };
 
 /**
- * Get menu position.
+ * Set the current page by name.
  *
- * @return {string} Menu position
+ * @fires set
+ * @param {string} name Symbolic name of page
  */
-OO.ui.MenuLayout.prototype.getMenuPosition = function () {
-       return this.menuPosition;
+OO.ui.BookletLayout.prototype.setPage = function ( name ) {
+       var selectedItem,
+               $focused,
+               page = this.pages[ name ];
+
+       if ( name !== this.currentPageName ) {
+               if ( this.outlined ) {
+                       selectedItem = this.outlineSelectWidget.getSelectedItem();
+                       if ( selectedItem && selectedItem.getData() !== name ) {
+                               this.outlineSelectWidget.selectItem( this.outlineSelectWidget.getItemFromData( name ) );
+                       }
+               }
+               if ( page ) {
+                       if ( this.currentPageName && this.pages[ this.currentPageName ] ) {
+                               this.pages[ this.currentPageName ].setActive( false );
+                               // Blur anything focused if the next page doesn't have anything focusable - this
+                               // is not needed if the next page has something focusable because once it is focused
+                               // this blur happens automatically
+                               if ( this.autoFocus && !page.$element.find( ':input' ).length ) {
+                                       $focused = this.pages[ this.currentPageName ].$element.find( ':focus' );
+                                       if ( $focused.length ) {
+                                               $focused[ 0 ].blur();
+                                       }
+                               }
+                       }
+                       this.currentPageName = name;
+                       this.stackLayout.setItem( page );
+                       page.setActive( true );
+                       this.emit( 'set', page );
+               }
+       }
 };
 
 /**
- * Get the menu position property.
+ * Select the first selectable page.
  *
- * @return {string} Menu position CSS property
+ * @chainable
  */
-OO.ui.MenuLayout.prototype.getPositionProperty = function () {
-       if ( this.menuPosition.rtlPositionProperty && this.$element.css( 'direction' ) === 'rtl' ) {
-               return this.menuPosition.rtlPositionProperty;
-       } else {
-               return this.menuPosition.positionProperty;
+OO.ui.BookletLayout.prototype.selectFirstSelectablePage = function () {
+       if ( !this.outlineSelectWidget.getSelectedItem() ) {
+               this.outlineSelectWidget.selectItem( this.outlineSelectWidget.getFirstSelectableItem() );
        }
+
+       return this;
 };
 
 /**
@@ -8563,6 +8338,9 @@ OO.ui.StackLayout.prototype.unsetCurrentItem = function () {
  * @chainable
  */
 OO.ui.StackLayout.prototype.addItems = function ( items, index ) {
+       // Update the visibility
+       this.updateHiddenState( items, this.currentItem );
+
        // Mixin method
        OO.ui.GroupElement.prototype.addItems.call( this, items, index );
 
@@ -8625,18 +8403,10 @@ OO.ui.StackLayout.prototype.clearItems = function () {
  * @fires set
  */
 OO.ui.StackLayout.prototype.setItem = function ( item ) {
-       var i, len;
-
        if ( item !== this.currentItem ) {
-               if ( !this.continuous ) {
-                       for ( i = 0, len = this.items.length; i < len; i++ ) {
-                               this.items[ i ].$element.css( 'display', '' );
-                       }
-               }
+               this.updateHiddenState( this.items, item );
+
                if ( $.inArray( item, this.items ) !== -1 ) {
-                       if ( !this.continuous ) {
-                               item.$element.css( 'display', 'block' );
-                       }
                        this.currentItem = item;
                        this.emit( 'set', item );
                } else {
@@ -8647,6 +8417,30 @@ OO.ui.StackLayout.prototype.setItem = function ( item ) {
        return this;
 };
 
+/**
+ * Update the visibility of all items in case of non-continuous view.
+ *
+ * Ensure all items are hidden except for the selected one.
+ * This method does nothing when the stack is continuous.
+ *
+ * @param {OO.ui.Layout[]} items Item list iterate over
+ * @param {OO.ui.Layout} [selectedItem] Selected item to show
+ */
+OO.ui.StackLayout.prototype.updateHiddenState = function ( items, selectedItem ) {
+       var i, len;
+
+       if ( !this.continuous ) {
+               for ( i = 0, len = items.length; i < len; i++ ) {
+                       if ( !selectedItem || selectedItem !== items[ i ] ) {
+                               items[ i ].$element.addClass( 'oo-ui-element-hidden' );
+                       }
+               }
+               if ( selectedItem ) {
+                       selectedItem.$element.removeClass( 'oo-ui-element-hidden' );
+               }
+       }
+};
+
 /**
  * Horizontal bar layout of tools as icon buttons.
  *
@@ -8712,7 +8506,7 @@ OO.ui.PopupToolGroup = function OoUiPopupToolGroup( toolbar, config ) {
        this.active = false;
        this.dragging = false;
        this.onBlurHandler = this.onBlur.bind( this );
-       this.$handle = this.$( '<span>' );
+       this.$handle = $( '<span>' );
 
        // Events
        this.$handle.on( {
@@ -8729,7 +8523,7 @@ OO.ui.PopupToolGroup = function OoUiPopupToolGroup( toolbar, config ) {
        // OO.ui.HeaderedElement mixin constructor.
        if ( config.header !== undefined ) {
                this.$group
-                       .prepend( this.$( '<span>' )
+                       .prepend( $( '<span>' )
                                .addClass( 'oo-ui-popupToolGroup-header' )
                                .text( config.header )
                        );
@@ -8773,7 +8567,7 @@ OO.ui.PopupToolGroup.prototype.setDisabled = function () {
  */
 OO.ui.PopupToolGroup.prototype.onBlur = function ( e ) {
        // Only deactivate when clicking outside the dropdown element
-       if ( this.$( e.target ).closest( '.oo-ui-popupToolGroup' )[ 0 ] !== this.$element[ 0 ] ) {
+       if ( $( e.target ).closest( '.oo-ui-popupToolGroup' )[ 0 ] !== this.$element[ 0 ] ) {
                this.setActive( false );
        }
 };
@@ -8920,14 +8714,6 @@ OO.ui.ListToolGroup.prototype.populate = function () {
        this.$group.append( this.getExpandCollapseTool().$element );
 
        this.getExpandCollapseTool().toggle( this.collapsibleTools.length !== 0 );
-
-       // Calling jQuery's .hide() and then .show() on a detached element caches the default value of its
-       // 'display' attribute and restores it, and the tool uses a <span> and can be hidden and re-shown.
-       // Is this a jQuery bug? http://jsfiddle.net/gtj4hu3h/
-       if ( this.getExpandCollapseTool().$element.css( 'display' ) === 'inline' ) {
-               this.getExpandCollapseTool().$element.css( 'display', 'block' );
-       }
-
        this.updateCollapsibleState();
 };
 
@@ -8962,7 +8748,7 @@ OO.ui.ListToolGroup.prototype.onPointerUp = function ( e ) {
        var ret = OO.ui.ListToolGroup.super.prototype.onPointerUp.call( this, e );
 
        // Do not close the popup when the user wants to show more/fewer tools
-       if ( this.$( e.target ).closest( '.oo-ui-tool-name-more-fewer' ).length ) {
+       if ( $( e.target ).closest( '.oo-ui-tool-name-more-fewer' ).length ) {
                // Prevent the popup list from being hidden
                this.setActive( true );
        }
@@ -9198,7 +8984,7 @@ OO.ui.ItemWidget.prototype.setElementGroup = function ( group ) {
  *
  * @class
  * @abstract
- * @deprecated Use LookupElement instead.
+ * @deprecated Use OO.ui.LookupElement instead.
  *
  * @constructor
  * @param {OO.ui.TextInputWidget} input Input widget
@@ -9214,7 +9000,6 @@ OO.ui.LookupInputWidget = function OoUiLookupInputWidget( input, config ) {
        this.lookupInput = input;
        this.$overlay = config.$overlay || this.$element;
        this.lookupMenu = new OO.ui.TextInputMenuSelectWidget( this, {
-               $: OO.ui.Element.static.getJQuery( this.$overlay ),
                input: this.lookupInput,
                $container: config.$container
        } );
@@ -9527,21 +9312,18 @@ OO.ui.OutlineControlsWidget = function OoUiOutlineControlsWidget( outline, confi
 
        // Properties
        this.outline = outline;
-       this.$movers = this.$( '<div>' );
+       this.$movers = $( '<div>' );
        this.upButton = new OO.ui.ButtonWidget( {
-               $: this.$,
                framed: false,
                icon: 'collapse',
                title: OO.ui.msg( 'ooui-outline-control-move-up' )
        } );
        this.downButton = new OO.ui.ButtonWidget( {
-               $: this.$,
                framed: false,
                icon: 'expand',
                title: OO.ui.msg( 'ooui-outline-control-move-down' )
        } );
        this.removeButton = new OO.ui.ButtonWidget( {
-               $: this.$,
                framed: false,
                icon: 'remove',
                title: OO.ui.msg( 'ooui-outline-control-remove' )
@@ -9712,7 +9494,12 @@ OO.inheritClass( OO.ui.ButtonGroupWidget, OO.ui.Widget );
 OO.mixinClass( OO.ui.ButtonGroupWidget, OO.ui.GroupElement );
 
 /**
- * Generic widget for buttons.
+ * ButtonWidget is a generic widget for buttons. A wide variety of looks,
+ * feels, and functionality can be customized via the class’s configuration options
+ * and methods. Please see the OOjs UI documentation on MediaWiki for more information
+ * and examples.
+ *
+ * NOTE: HTML form buttons should use the OO.ui.ButtonInputWidget class.
  *
  * @class
  * @extends OO.ui.Widget
@@ -9728,6 +9515,7 @@ OO.mixinClass( OO.ui.ButtonGroupWidget, OO.ui.GroupElement );
  * @param {Object} [config] Configuration options
  * @cfg {string} [href] Hyperlink to visit when clicked
  * @cfg {string} [target] Target to open hyperlink in
+ * @cfg {boolean} [nofollow] Search engine traversal hint (default: true)
  */
 OO.ui.ButtonWidget = function OoUiButtonWidget( config ) {
        // Configuration initialization
@@ -9748,14 +9536,9 @@ OO.ui.ButtonWidget = function OoUiButtonWidget( config ) {
        // Properties
        this.href = null;
        this.target = null;
+       this.nofollow = false;
        this.isHyperlink = false;
 
-       // Events
-       this.$button.on( {
-               click: this.onClick.bind( this ),
-               keypress: this.onKeyPress.bind( this )
-       } );
-
        // Initialization
        this.$button.append( this.$icon, this.$label, this.$indicator );
        this.$element
@@ -9763,6 +9546,7 @@ OO.ui.ButtonWidget = function OoUiButtonWidget( config ) {
                .append( this.$button );
        this.setHref( config.href );
        this.setTarget( config.target );
+       this.setNoFollow( config.nofollow );
 };
 
 /* Setup */
@@ -9776,69 +9560,52 @@ OO.mixinClass( OO.ui.ButtonWidget, OO.ui.TitledElement );
 OO.mixinClass( OO.ui.ButtonWidget, OO.ui.FlaggedElement );
 OO.mixinClass( OO.ui.ButtonWidget, OO.ui.TabIndexedElement );
 
-/* Events */
-
-/**
- * @event click
- */
-
 /* Methods */
 
 /**
- * Handles mouse click events.
- *
- * @param {jQuery.Event} e Mouse click event
- * @fires click
+ * @inheritdoc
  */
-OO.ui.ButtonWidget.prototype.onClick = function () {
+OO.ui.ButtonWidget.prototype.onMouseDown = function ( e ) {
        if ( !this.isDisabled() ) {
-               this.emit( 'click' );
-               if ( this.isHyperlink ) {
-                       return true;
-               }
+               // Remove the tab-index while the button is down to prevent the button from stealing focus
+               this.$button.removeAttr( 'tabindex' );
        }
-       return false;
+
+       return OO.ui.ButtonElement.prototype.onMouseDown.call( this, e );
 };
 
 /**
  * @inheritdoc
  */
-OO.ui.ButtonWidget.prototype.onMouseDown = function ( e ) {
-       // Remove the tab-index while the button is down to prevent the button from stealing focus
-       this.$button.removeAttr( 'tabindex' );
-       // Run the mouseup handler no matter where the mouse is when the button is let go, so we can
-       // reliably reapply the tabindex and remove the pressed class
-       this.getElementDocument().addEventListener( 'mouseup', this.onMouseUpHandler, true );
+OO.ui.ButtonWidget.prototype.onMouseUp = function ( e ) {
+       if ( !this.isDisabled() ) {
+               // Restore the tab-index after the button is up to restore the button's accessibility
+               this.$button.attr( 'tabindex', this.tabIndex );
+       }
 
-       return OO.ui.ButtonElement.prototype.onMouseDown.call( this, e );
+       return OO.ui.ButtonElement.prototype.onMouseUp.call( this, e );
 };
 
 /**
  * @inheritdoc
  */
-OO.ui.ButtonWidget.prototype.onMouseUp = function ( e ) {
-       // Restore the tab-index after the button is up to restore the button's accessibility
-       this.$button.attr( 'tabindex', this.tabIndex );
-       // Stop listening for mouseup, since we only needed this once
-       this.getElementDocument().removeEventListener( 'mouseup', this.onMouseUpHandler, true );
-
-       return OO.ui.ButtonElement.prototype.onMouseUp.call( this, e );
+OO.ui.ButtonWidget.prototype.onClick = function ( e ) {
+       var ret = OO.ui.ButtonElement.prototype.onClick.call( this, e );
+       if ( this.isHyperlink ) {
+               return true;
+       }
+       return ret;
 };
 
 /**
- * Handles keypress events.
- *
- * @param {jQuery.Event} e Keypress event
- * @fires click
+ * @inheritdoc
  */
 OO.ui.ButtonWidget.prototype.onKeyPress = function ( e ) {
-       if ( !this.isDisabled() && ( e.which === OO.ui.Keys.SPACE || e.which === OO.ui.Keys.ENTER ) ) {
-               this.emit( 'click' );
-               if ( this.isHyperlink ) {
-                       return true;
-               }
+       var ret = OO.ui.ButtonElement.prototype.onKeyPress.call( this, e );
+       if ( this.isHyperlink ) {
+               return true;
        }
-       return false;
+       return ret;
 };
 
 /**
@@ -9859,6 +9626,15 @@ OO.ui.ButtonWidget.prototype.getTarget = function () {
        return this.target;
 };
 
+/**
+ * Get search engine traversal hint.
+ *
+ * @return {boolean} Whether search engines should avoid traversing this hyperlink
+ */
+OO.ui.ButtonWidget.prototype.getNoFollow = function () {
+       return this.nofollow;
+};
+
 /**
  * Set hyperlink location.
  *
@@ -9901,6 +9677,26 @@ OO.ui.ButtonWidget.prototype.setTarget = function ( target ) {
        return this;
 };
 
+/**
+ * Set search engine traversal hint.
+ *
+ * @param {boolean} nofollow True if search engines should avoid traversing this hyperlink
+ */
+OO.ui.ButtonWidget.prototype.setNoFollow = function ( nofollow ) {
+       nofollow = typeof nofollow === 'boolean' ? nofollow : true;
+
+       if ( nofollow !== this.nofollow ) {
+               this.nofollow = nofollow;
+               if ( nofollow ) {
+                       this.$button.attr( 'rel', 'nofollow' );
+               } else {
+                       this.$button.removeAttr( 'rel' );
+               }
+       }
+
+       return this;
+};
+
 /**
  * Button widget that executes an action and is managed by an OO.ui.ActionSet.
  *
@@ -10072,6 +9868,9 @@ OO.ui.PopupButtonWidget = function OoUiPopupButtonWidget( config ) {
        // Mixin constructors
        OO.ui.PopupElement.call( this, config );
 
+       // Events
+       this.connect( this, { click: 'onAction' } );
+
        // Initialization
        this.$element
                .addClass( 'oo-ui-popupButtonWidget' )
@@ -10087,22 +9886,10 @@ OO.mixinClass( OO.ui.PopupButtonWidget, OO.ui.PopupElement );
 /* Methods */
 
 /**
- * Handles mouse click events.
- *
- * @param {jQuery.Event} e Mouse click event
+ * Handle the button action being triggered.
  */
-OO.ui.PopupButtonWidget.prototype.onClick = function ( e ) {
-       // Skip clicks within the popup
-       if ( $.contains( this.popup.$element[ 0 ], e.target ) ) {
-               return;
-       }
-
-       if ( !this.isDisabled() ) {
-               this.popup.toggle();
-               // Parent method
-               OO.ui.PopupButtonWidget.super.prototype.onClick.call( this );
-       }
-       return false;
+OO.ui.PopupButtonWidget.prototype.onAction = function () {
+       this.popup.toggle();
 };
 
 /**
@@ -10126,6 +9913,9 @@ OO.ui.ToggleButtonWidget = function OoUiToggleButtonWidget( config ) {
        // Mixin constructors
        OO.ui.ToggleWidget.call( this, config );
 
+       // Events
+       this.connect( this, { click: 'onAction' } );
+
        // Initialization
        this.$element.addClass( 'oo-ui-toggleButtonWidget' );
 };
@@ -10138,15 +9928,10 @@ OO.mixinClass( OO.ui.ToggleButtonWidget, OO.ui.ToggleWidget );
 /* Methods */
 
 /**
- * @inheritdoc
+ * Handle the button action being triggered.
  */
-OO.ui.ToggleButtonWidget.prototype.onClick = function () {
-       if ( !this.isDisabled() ) {
-               this.setValue( !this.value );
-       }
-
-       // Parent method
-       return OO.ui.ToggleButtonWidget.super.prototype.onClick.call( this );
+OO.ui.ToggleButtonWidget.prototype.onAction = function () {
+       this.setValue( !this.value );
 };
 
 /**
@@ -10179,6 +9964,7 @@ OO.ui.ToggleButtonWidget.prototype.setValue = function ( value ) {
  * @mixins OO.ui.IndicatorElement
  * @mixins OO.ui.LabelElement
  * @mixins OO.ui.TitledElement
+ * @mixins OO.ui.TabIndexedElement
  *
  * @constructor
  * @param {Object} [config] Configuration options
@@ -10191,18 +9977,24 @@ OO.ui.DropdownWidget = function OoUiDropdownWidget( config ) {
        // Parent constructor
        OO.ui.DropdownWidget.super.call( this, config );
 
+       // Properties (must be set before TabIndexedElement constructor call)
+       this.$handle = this.$( '<span>' );
+
        // Mixin constructors
        OO.ui.IconElement.call( this, config );
        OO.ui.IndicatorElement.call( this, config );
        OO.ui.LabelElement.call( this, config );
        OO.ui.TitledElement.call( this, $.extend( {}, config, { $titled: this.$label } ) );
+       OO.ui.TabIndexedElement.call( this, $.extend( {}, config, { $tabIndexed: this.$handle } ) );
 
        // Properties
-       this.menu = new OO.ui.MenuSelectWidget( $.extend( { $: this.$, widget: this }, config.menu ) );
-       this.$handle = this.$( '<span>' );
+       this.menu = new OO.ui.MenuSelectWidget( $.extend( { widget: this }, config.menu ) );
 
        // Events
-       this.$element.on( { click: this.onClick.bind( this ) } );
+       this.$handle.on( {
+               click: this.onClick.bind( this ),
+               keypress: this.onKeyPress.bind( this )
+       } );
        this.menu.connect( this, { select: 'onMenuSelect' } );
 
        // Initialization
@@ -10221,6 +10013,7 @@ OO.mixinClass( OO.ui.DropdownWidget, OO.ui.IconElement );
 OO.mixinClass( OO.ui.DropdownWidget, OO.ui.IndicatorElement );
 OO.mixinClass( OO.ui.DropdownWidget, OO.ui.LabelElement );
 OO.mixinClass( OO.ui.DropdownWidget, OO.ui.TitledElement );
+OO.mixinClass( OO.ui.DropdownWidget, OO.ui.TabIndexedElement );
 
 /* Methods */
 
@@ -10256,17 +10049,28 @@ OO.ui.DropdownWidget.prototype.onMenuSelect = function ( item ) {
 };
 
 /**
- * Handles mouse click events.
+ * Handle mouse click events.
  *
  * @param {jQuery.Event} e Mouse click event
  */
 OO.ui.DropdownWidget.prototype.onClick = function ( e ) {
-       // Skip clicks within the menu
-       if ( $.contains( this.menu.$element[ 0 ], e.target ) ) {
-               return;
+       if ( !this.isDisabled() && e.which === 1 ) {
+               if ( this.menu.isVisible() ) {
+                       this.menu.toggle( false );
+               } else {
+                       this.menu.toggle( true );
+               }
        }
+       return false;
+};
 
-       if ( !this.isDisabled() ) {
+/**
+ * Handle key press events.
+ *
+ * @param {jQuery.Event} e Key press event
+ */
+OO.ui.DropdownWidget.prototype.onKeyPress = function ( e ) {
+       if ( !this.isDisabled() && ( e.which === OO.ui.Keys.SPACE || e.which === OO.ui.Keys.ENTER ) ) {
                if ( this.menu.isVisible() ) {
                        this.menu.toggle( false );
                } else {
@@ -10420,7 +10224,7 @@ OO.mixinClass( OO.ui.InputWidget, OO.ui.TabIndexedElement );
  * @return {jQuery} Input element
  */
 OO.ui.InputWidget.prototype.getInputElement = function () {
-       return this.$( '<input>' );
+       return $( '<input>' );
 };
 
 /**
@@ -10584,12 +10388,6 @@ OO.ui.ButtonInputWidget = function OoUiButtonInputWidget( config ) {
        OO.ui.TitledElement.call( this, $.extend( {}, config, { $titled: this.$input } ) );
        OO.ui.FlaggedElement.call( this, config );
 
-       // Events
-       this.$input.on( {
-               click: this.onClick.bind( this ),
-               keypress: this.onKeyPress.bind( this )
-       } );
-
        // Initialization
        if ( !config.useInputTag ) {
                this.$input.append( this.$icon, this.$label, this.$indicator );
@@ -10607,12 +10405,6 @@ OO.mixinClass( OO.ui.ButtonInputWidget, OO.ui.LabelElement );
 OO.mixinClass( OO.ui.ButtonInputWidget, OO.ui.TitledElement );
 OO.mixinClass( OO.ui.ButtonInputWidget, OO.ui.FlaggedElement );
 
-/* Events */
-
-/**
- * @event click
- */
-
 /* Methods */
 
 /**
@@ -10621,7 +10413,7 @@ OO.mixinClass( OO.ui.ButtonInputWidget, OO.ui.FlaggedElement );
  */
 OO.ui.ButtonInputWidget.prototype.getInputElement = function ( config ) {
        var html = '<' + ( config.useInputTag ? 'input' : 'button' ) + ' type="' + config.type + '">';
-       return this.$( html );
+       return $( html );
 };
 
 /**
@@ -10667,32 +10459,6 @@ OO.ui.ButtonInputWidget.prototype.setValue = function ( value ) {
        return this;
 };
 
-/**
- * Handles mouse click events.
- *
- * @param {jQuery.Event} e Mouse click event
- * @fires click
- */
-OO.ui.ButtonInputWidget.prototype.onClick = function () {
-       if ( !this.isDisabled() ) {
-               this.emit( 'click' );
-       }
-       return false;
-};
-
-/**
- * Handles keypress events.
- *
- * @param {jQuery.Event} e Keypress event
- * @fires click
- */
-OO.ui.ButtonInputWidget.prototype.onKeyPress = function ( e ) {
-       if ( !this.isDisabled() && ( e.which === OO.ui.Keys.SPACE || e.which === OO.ui.Keys.ENTER ) ) {
-               this.emit( 'click' );
-       }
-       return false;
-};
-
 /**
  * Checkbox input widget.
  *
@@ -10704,6 +10470,9 @@ OO.ui.ButtonInputWidget.prototype.onKeyPress = function ( e ) {
  * @cfg {boolean} [selected=false] Whether the checkbox is initially selected
  */
 OO.ui.CheckboxInputWidget = function OoUiCheckboxInputWidget( config ) {
+       // Configuration initialization
+       config = config || {};
+
        // Parent constructor
        OO.ui.CheckboxInputWidget.super.call( this, config );
 
@@ -10723,7 +10492,7 @@ OO.inheritClass( OO.ui.CheckboxInputWidget, OO.ui.InputWidget );
  * @private
  */
 OO.ui.CheckboxInputWidget.prototype.getInputElement = function () {
-       return this.$( '<input type="checkbox" />' );
+       return $( '<input type="checkbox" />' );
 };
 
 /**
@@ -10786,9 +10555,7 @@ OO.ui.DropdownInputWidget = function OoUiDropdownInputWidget( config ) {
        config = config || {};
 
        // Properties (must be done before parent constructor which calls #setDisabled)
-       this.dropdownWidget = new OO.ui.DropdownWidget( {
-               $: this.$
-       } );
+       this.dropdownWidget = new OO.ui.DropdownWidget();
 
        // Parent constructor
        OO.ui.DropdownInputWidget.super.call( this, config );
@@ -10814,7 +10581,7 @@ OO.inheritClass( OO.ui.DropdownInputWidget, OO.ui.InputWidget );
  * @private
  */
 OO.ui.DropdownInputWidget.prototype.getInputElement = function () {
-       return this.$( '<input type="hidden">' );
+       return $( '<input type="hidden">' );
 };
 
 /**
@@ -10910,6 +10677,9 @@ OO.ui.DropdownInputWidget.prototype.blur = function () {
  * @cfg {boolean} [selected=false] Whether the radio button is initially selected
  */
 OO.ui.RadioInputWidget = function OoUiRadioInputWidget( config ) {
+       // Configuration initialization
+       config = config || {};
+
        // Parent constructor
        OO.ui.RadioInputWidget.super.call( this, config );
 
@@ -10929,7 +10699,7 @@ OO.inheritClass( OO.ui.RadioInputWidget, OO.ui.InputWidget );
  * @private
  */
 OO.ui.RadioInputWidget.prototype.getInputElement = function () {
-       return this.$( '<input type="radio" />' );
+       return $( '<input type="radio" />' );
 };
 
 /**
@@ -10981,6 +10751,7 @@ OO.ui.RadioInputWidget.prototype.isSelected = function () {
  * @cfg {boolean} [autosize=false] Automatically resize to fit content
  * @cfg {boolean} [maxRows=10] Maximum number of rows to make visible when autosizing
  * @cfg {string} [labelPosition='after'] Label position, 'before' or 'after'
+ * @cfg {boolean} [required=false] Mark the field as required
  * @cfg {RegExp|string} [validate] Regular expression to validate against (or symbolic name referencing
  *  one, see #static-validationPatterns)
  */
@@ -11007,14 +10778,14 @@ OO.ui.TextInputWidget = function OoUiTextInputWidget( config ) {
        this.autosize = !!config.autosize;
        this.maxRows = config.maxRows;
        this.validate = null;
-       this.attached = false;
 
        // Clone for resizing
        if ( this.autosize ) {
                this.$clone = this.$input
                        .clone()
                        .insertAfter( this.$input )
-                       .hide();
+                       .attr( 'aria-hidden', 'true' )
+                       .addClass( 'oo-ui-element-hidden' );
        }
 
        this.setValidation( config.validate );
@@ -11026,7 +10797,6 @@ OO.ui.TextInputWidget = function OoUiTextInputWidget( config ) {
                blur: this.setValidityFlag.bind( this )
        } );
        this.$element.on( 'DOMNodeInsertedIntoDocument', this.onElementAttach.bind( this ) );
-       this.$element.on( 'DOMNodeRemovedFromDocument', this.onElementDetach.bind( this ) );
        this.$icon.on( 'mousedown', this.onIconMouseDown.bind( this ) );
        this.$indicator.on( 'mousedown', this.onIndicatorMouseDown.bind( this ) );
        this.on( 'labelChange', this.updatePosition.bind( this ) );
@@ -11045,6 +10815,9 @@ OO.ui.TextInputWidget = function OoUiTextInputWidget( config ) {
        if ( config.autofocus ) {
                this.$input.attr( 'autofocus', 'autofocus' );
        }
+       if ( config.required ) {
+               this.$input.attr( 'required', 'true' );
+       }
 };
 
 /* Setup */
@@ -11132,22 +10905,12 @@ OO.ui.TextInputWidget.prototype.onKeyPress = function ( e ) {
  * @param {jQuery.Event} e Element attach event
  */
 OO.ui.TextInputWidget.prototype.onElementAttach = function () {
-       this.attached = true;
-       // If we reattached elsewhere, the valCache is now invalid
+       // Any previously calculated size is now probably invalid if we reattached elsewhere
        this.valCache = null;
        this.adjustSize();
        this.positionLabel();
 };
 
-/**
- * Handle element detach events.
- *
- * @param {jQuery.Event} e Element detach event
- */
-OO.ui.TextInputWidget.prototype.onElementDetach = function () {
-       this.attached = false;
-};
-
 /**
  * @inheritdoc
  */
@@ -11203,14 +10966,14 @@ OO.ui.TextInputWidget.prototype.setReadOnly = function ( state ) {
 OO.ui.TextInputWidget.prototype.adjustSize = function () {
        var scrollHeight, innerHeight, outerHeight, maxInnerHeight, measurementError, idealHeight;
 
-       if ( this.multiline && this.autosize && this.attached && this.$input.val() !== this.valCache ) {
+       if ( this.multiline && this.autosize && this.$input.val() !== this.valCache ) {
                this.$clone
                        .val( this.$input.val() )
                        .attr( 'rows', '' )
                        // Set inline height property to 0 to measure scroll height
                        .css( 'height', 0 );
 
-               this.$clone[ 0 ].style.display = 'block';
+               this.$clone.removeClass( 'oo-ui-element-hidden' );
 
                this.valCache = this.$input.val();
 
@@ -11233,7 +10996,7 @@ OO.ui.TextInputWidget.prototype.adjustSize = function () {
                measurementError = maxInnerHeight - this.$clone[ 0 ].scrollHeight;
                idealHeight = Math.min( maxInnerHeight, scrollHeight + measurementError );
 
-               this.$clone[ 0 ].style.display = 'none';
+               this.$clone.addClass( 'oo-ui-element-hidden' );
 
                // Only apply inline height when expansion beyond natural height is needed
                if ( idealHeight > innerHeight ) {
@@ -11251,7 +11014,7 @@ OO.ui.TextInputWidget.prototype.adjustSize = function () {
  * @private
  */
 OO.ui.TextInputWidget.prototype.getInputElement = function ( config ) {
-       return config.multiline ? this.$( '<textarea>' ) : this.$( '<input type="' + config.type + '" />' );
+       return config.multiline ? $( '<textarea>' ) : $( '<input type="' + config.type + '" />' );
 };
 
 /**
@@ -11378,6 +11141,7 @@ OO.ui.TextInputWidget.prototype.positionLabel = function () {
  *
  * @class
  * @extends OO.ui.Widget
+ * @mixins OO.ui.TabIndexedElement
  *
  * @constructor
  * @param {Object} [config] Configuration options
@@ -11392,15 +11156,24 @@ OO.ui.ComboBoxWidget = function OoUiComboBoxWidget( config ) {
        // Parent constructor
        OO.ui.ComboBoxWidget.super.call( this, config );
 
+       // Properties (must be set before TabIndexedElement constructor call)
+       this.$indicator = this.$( '<span>' );
+
+       // Mixin constructors
+       OO.ui.TabIndexedElement.call( this, $.extend( {}, config, { $tabIndexed: this.$indicator } ) );
+
        // Properties
        this.$overlay = config.$overlay || this.$element;
        this.input = new OO.ui.TextInputWidget( $.extend(
-               { $: this.$, indicator: 'down', disabled: this.isDisabled() },
+               {
+                       indicator: 'down',
+                       $indicator: this.$indicator,
+                       disabled: this.isDisabled()
+               },
                config.input
        ) );
        this.menu = new OO.ui.TextInputMenuSelectWidget( this.input, $.extend(
                {
-                       $: OO.ui.Element.static.getJQuery( this.$overlay ),
                        widget: this,
                        input: this.input,
                        disabled: this.isDisabled()
@@ -11409,9 +11182,12 @@ OO.ui.ComboBoxWidget = function OoUiComboBoxWidget( config ) {
        ) );
 
        // Events
+       this.$indicator.on( {
+               click: this.onClick.bind( this ),
+               keypress: this.onKeyPress.bind( this )
+       } );
        this.input.connect( this, {
                change: 'onInputChange',
-               indicator: 'onInputIndicator',
                enter: 'onInputEnter'
        } );
        this.menu.connect( this, {
@@ -11429,6 +11205,7 @@ OO.ui.ComboBoxWidget = function OoUiComboBoxWidget( config ) {
 /* Setup */
 
 OO.inheritClass( OO.ui.ComboBoxWidget, OO.ui.Widget );
+OO.mixinClass( OO.ui.ComboBoxWidget, OO.ui.TabIndexedElement );
 
 /* Methods */
 
@@ -11456,12 +11233,29 @@ OO.ui.ComboBoxWidget.prototype.onInputChange = function ( value ) {
 };
 
 /**
- * Handle input indicator events.
+ * Handle mouse click events.
+ *
+ * @param {jQuery.Event} e Mouse click event
  */
-OO.ui.ComboBoxWidget.prototype.onInputIndicator = function () {
-       if ( !this.isDisabled() ) {
+OO.ui.ComboBoxWidget.prototype.onClick = function ( e ) {
+       if ( !this.isDisabled() && e.which === 1 ) {
+               this.menu.toggle();
+               this.input.$input[ 0 ].focus();
+       }
+       return false;
+};
+
+/**
+ * Handle key press events.
+ *
+ * @param {jQuery.Event} e Key press event
+ */
+OO.ui.ComboBoxWidget.prototype.onKeyPress = function ( e ) {
+       if ( !this.isDisabled() && ( e.which === OO.ui.Keys.SPACE || e.which === OO.ui.Keys.ENTER ) ) {
                this.menu.toggle();
+               this.input.$input[ 0 ].focus();
        }
+       return false;
 };
 
 /**
@@ -11684,7 +11478,9 @@ OO.ui.OptionWidget.prototype.isPressed = function () {
 OO.ui.OptionWidget.prototype.setSelected = function ( state ) {
        if ( this.constructor.static.selectable ) {
                this.selected = !!state;
-               this.$element.toggleClass( 'oo-ui-optionWidget-selected', state );
+               this.$element
+                       .toggleClass( 'oo-ui-optionWidget-selected', state )
+                       .attr( 'aria-selected', state.toString() );
                if ( state && this.constructor.static.scrollIntoViewOnSelect ) {
                        this.scrollElementIntoView();
                }
@@ -11842,8 +11638,12 @@ OO.inheritClass( OO.ui.RadioOptionWidget, OO.ui.OptionWidget );
 
 OO.ui.RadioOptionWidget.static.highlightable = false;
 
+OO.ui.RadioOptionWidget.static.scrollIntoViewOnSelect = true;
+
 OO.ui.RadioOptionWidget.static.pressable = false;
 
+OO.ui.RadioOptionWidget.static.tagName = 'label';
+
 /* Methods */
 
 /**
@@ -11883,6 +11683,10 @@ OO.ui.MenuOptionWidget = function OoUiMenuOptionWidget( config ) {
 
 OO.inheritClass( OO.ui.MenuOptionWidget, OO.ui.DecoratedOptionWidget );
 
+/* Static Properties */
+
+OO.ui.MenuOptionWidget.static.scrollIntoViewOnSelect = true;
+
 /**
  * Section to group one or more items in a OO.ui.MenuSelectWidget.
  *
@@ -12065,16 +11869,17 @@ OO.ui.PopupWidget = function OoUiPopupWidget( config ) {
        // Parent constructor
        OO.ui.PopupWidget.super.call( this, config );
 
+       // Properties (must be set before ClippableElement constructor call)
+       this.$body = $( '<div>' );
+
        // Mixin constructors
        OO.ui.LabelElement.call( this, config );
-       OO.ui.ClippableElement.call( this, config );
+       OO.ui.ClippableElement.call( this, $.extend( {}, config, { $clippable: this.$body } ) );
 
        // Properties
-       this.visible = false;
-       this.$popup = this.$( '<div>' );
-       this.$head = this.$( '<div>' );
-       this.$body = this.$( '<div>' );
-       this.$anchor = this.$( '<div>' );
+       this.$popup = $( '<div>' );
+       this.$head = $( '<div>' );
+       this.$anchor = $( '<div>' );
        // If undefined, will be computed lazily in updateDimensions()
        this.$container = config.$container;
        this.containerPadding = config.containerPadding !== undefined ? config.containerPadding : 10;
@@ -12085,7 +11890,7 @@ OO.ui.PopupWidget = function OoUiPopupWidget( config ) {
        this.width = config.width !== undefined ? config.width : 320;
        this.height = config.height !== undefined ? config.height : null;
        this.align = config.align || 'center';
-       this.closeButton = new OO.ui.ButtonWidget( { $: this.$, framed: false, icon: 'close' } );
+       this.closeButton = new OO.ui.ButtonWidget( { framed: false, icon: 'close' } );
        this.onMouseDownHandler = this.onMouseDown.bind( this );
 
        // Events
@@ -12099,13 +11904,12 @@ OO.ui.PopupWidget = function OoUiPopupWidget( config ) {
                .addClass( 'oo-ui-popupWidget-head' )
                .append( this.$label, this.closeButton.$element );
        if ( !config.head ) {
-               this.$head.hide();
+               this.$head.addClass( 'oo-ui-element-hidden' );
        }
        this.$popup
                .addClass( 'oo-ui-popupWidget-popup' )
                .append( this.$head, this.$body );
        this.$element
-               .hide()
                .addClass( 'oo-ui-popupWidget' )
                .append( this.$popup, this.$anchor );
        // Move content, which was added to #$element by OO.ui.Widget, to the body
@@ -12115,7 +11919,12 @@ OO.ui.PopupWidget = function OoUiPopupWidget( config ) {
        if ( config.padded ) {
                this.$body.addClass( 'oo-ui-popupWidget-body-padded' );
        }
-       this.setClippableElement( this.$body );
+
+       // Initially hidden - using #toggle may cause errors if subclasses override toggle with methods
+       // that reference properties not initialized at that time of parent class construction
+       // TODO: Find a better way to handle post-constructor setup
+       this.visible = false;
+       this.$element.addClass( 'oo-ui-element-hidden' );
 };
 
 /* Setup */
@@ -12255,7 +12064,7 @@ OO.ui.PopupWidget.prototype.updateDimensions = function ( transition ) {
 
        if ( !this.$container ) {
                // Lazy-initialize $container if not specified in constructor
-               this.$container = this.$( this.getClosestScrollableElementContainer() );
+               this.$container = $( this.getClosestScrollableElementContainer() );
        }
 
        // Set height and width before measuring things, since it might cause our measurements
@@ -12339,7 +12148,7 @@ OO.ui.ProgressBarWidget = function OoUiProgressBarWidget( config ) {
        OO.ui.ProgressBarWidget.super.call( this, config );
 
        // Properties
-       this.$bar = this.$( '<div>' );
+       this.$bar = $( '<div>' );
        this.progress = null;
 
        // Initialization
@@ -12415,14 +12224,13 @@ OO.ui.SearchWidget = function OoUiSearchWidget( config ) {
 
        // Properties
        this.query = new OO.ui.TextInputWidget( {
-               $: this.$,
                icon: 'search',
                placeholder: config.placeholder,
                value: config.value
        } );
-       this.results = new OO.ui.SelectWidget( { $: this.$ } );
-       this.$query = this.$( '<div>' );
-       this.$results = this.$( '<div>' );
+       this.results = new OO.ui.SelectWidget();
+       this.$query = $( '<div>' );
+       this.$results = $( '<div>' );
 
        // Events
        this.query.connect( this, {
@@ -12587,7 +12395,9 @@ OO.ui.SelectWidget = function OoUiSelectWidget( config ) {
        } );
 
        // Initialization
-       this.$element.addClass( 'oo-ui-selectWidget oo-ui-selectWidget-depressed' );
+       this.$element
+               .addClass( 'oo-ui-selectWidget oo-ui-selectWidget-depressed' )
+               .attr( 'role', 'listbox' );
        if ( $.isArray( config.items ) ) {
                this.addItems( config.items );
        }
@@ -12758,7 +12568,7 @@ OO.ui.SelectWidget.prototype.onMouseLeave = function () {
  * @return {OO.ui.OptionWidget|null} Outline item widget, `null` if none was found
  */
 OO.ui.SelectWidget.prototype.getTargetItem = function ( e ) {
-       var $item = this.$( e.target ).closest( '.oo-ui-optionWidget' );
+       var $item = $( e.target ).closest( '.oo-ui-optionWidget' );
        if ( $item.length ) {
                return $item.data( 'oo-ui-optionWidget' );
        }
@@ -13100,21 +12910,23 @@ OO.ui.MenuSelectWidget = function OoUiMenuSelectWidget( config ) {
        OO.ui.ClippableElement.call( this, $.extend( {}, config, { $clippable: this.$group } ) );
 
        // Properties
-       this.visible = false;
        this.newItems = null;
        this.autoHide = config.autoHide === undefined || !!config.autoHide;
        this.$input = config.input ? config.input.$input : null;
        this.$widget = config.widget ? config.widget.$element : null;
-       this.$previousFocus = null;
-       this.isolated = !config.input;
        this.onKeyDownHandler = this.onKeyDown.bind( this );
        this.onDocumentMouseDownHandler = this.onDocumentMouseDown.bind( this );
 
        // Initialization
        this.$element
-               .hide()
-               .attr( 'role', 'menu' )
-               .addClass( 'oo-ui-menuSelectWidget' );
+               .addClass( 'oo-ui-menuSelectWidget' )
+               .attr( 'role', 'menu' );
+
+       // Initially hidden - using #toggle may cause errors if subclasses override toggle with methods
+       // that reference properties not initialized at that time of parent class construction
+       // TODO: Find a better way to handle post-constructor setup
+       this.visible = false;
+       this.$element.addClass( 'oo-ui-element-hidden' );
 };
 
 /* Setup */
@@ -13166,11 +12978,13 @@ OO.ui.MenuSelectWidget.prototype.onKeyDown = function ( e ) {
                                handled = true;
                                break;
                        case OO.ui.Keys.ESCAPE:
+                       case OO.ui.Keys.TAB:
                                if ( highlightItem ) {
                                        highlightItem.setHighlighted( false );
                                }
                                this.toggle( false );
-                               handled = true;
+                               // Don't prevent tabbing away
+                               handled = ( e.keyCode === OO.ui.Keys.ESCAPE );
                                break;
                }
 
@@ -13204,7 +13018,7 @@ OO.ui.MenuSelectWidget.prototype.bindKeyDownListener = function () {
  */
 OO.ui.MenuSelectWidget.prototype.unbindKeyDownListener = function () {
        if ( this.$input ) {
-               this.$input.off( 'keydown' );
+               this.$input.off( 'keydown', this.onKeyDownHandler );
        } else {
                this.getElementWindow().removeEventListener( 'keydown', this.onKeyDownHandler, true );
        }
@@ -13287,9 +13101,7 @@ OO.ui.MenuSelectWidget.prototype.toggle = function ( visible ) {
        visible = ( visible === undefined ? !this.visible : !!visible ) && !!this.items.length;
 
        var i, len,
-               change = visible !== this.isVisible(),
-               elementDoc = this.getElementDocument(),
-               widgetDoc = this.$widget ? this.$widget[ 0 ].ownerDocument : null;
+               change = visible !== this.isVisible();
 
        // Parent method
        OO.ui.MenuSelectWidget.super.prototype.toggle.call( this, visible );
@@ -13298,11 +13110,6 @@ OO.ui.MenuSelectWidget.prototype.toggle = function ( visible ) {
                if ( visible ) {
                        this.bindKeyDownListener();
 
-                       // Change focus to enable keyboard navigation
-                       if ( this.isolated && this.$input && !this.$input.is( ':focus' ) ) {
-                               this.$previousFocus = this.$( ':focus' );
-                               this.$input[ 0 ].focus();
-                       }
                        if ( this.newItems && this.newItems.length ) {
                                for ( i = 0, len = this.newItems.length; i < len; i++ ) {
                                        this.newItems[ i ].fitLabel();
@@ -13313,31 +13120,15 @@ OO.ui.MenuSelectWidget.prototype.toggle = function ( visible ) {
 
                        // Auto-hide
                        if ( this.autoHide ) {
-                               elementDoc.addEventListener(
+                               this.getElementDocument().addEventListener(
                                        'mousedown', this.onDocumentMouseDownHandler, true
                                );
-                               // Support $widget being in a different document
-                               if ( widgetDoc && widgetDoc !== elementDoc ) {
-                                       widgetDoc.addEventListener(
-                                               'mousedown', this.onDocumentMouseDownHandler, true
-                                       );
-                               }
                        }
                } else {
                        this.unbindKeyDownListener();
-                       if ( this.isolated && this.$previousFocus ) {
-                               this.$previousFocus[ 0 ].focus();
-                               this.$previousFocus = null;
-                       }
-                       elementDoc.removeEventListener(
+                       this.getElementDocument().removeEventListener(
                                'mousedown', this.onDocumentMouseDownHandler, true
                        );
-                       // Support $widget being in a different document
-                       if ( widgetDoc && widgetDoc !== elementDoc ) {
-                               widgetDoc.removeEventListener(
-                                       'mousedown', this.onDocumentMouseDownHandler, true
-                               );
-                       }
                        this.toggleClipping( false );
                }
        }
@@ -13348,9 +13139,8 @@ OO.ui.MenuSelectWidget.prototype.toggle = function ( visible ) {
 /**
  * Menu for a text input widget.
  *
- * This menu is specially designed to be positioned beneath the text input widget. Even if the input
- * is in a different frame, the menu's position is automatically calculated and maintained when the
- * menu is toggled or the window is resized.
+ * This menu is specially designed to be positioned beneath a text input widget. The menu's position
+ * is automatically calculated and maintained when the menu is toggled or the window is resized.
  *
  * @class
  * @extends OO.ui.MenuSelectWidget
@@ -13412,9 +13202,9 @@ OO.ui.TextInputMenuSelectWidget.prototype.toggle = function ( visible ) {
        if ( change ) {
                if ( this.isVisible() ) {
                        this.position();
-                       this.$( this.getElementWindow() ).on( 'resize', this.onWindowResizeHandler );
+                       $( this.getElementWindow() ).on( 'resize', this.onWindowResizeHandler );
                } else {
-                       this.$( this.getElementWindow() ).off( 'resize', this.onWindowResizeHandler );
+                       $( this.getElementWindow() ).off( 'resize', this.onWindowResizeHandler );
                }
        }
 
@@ -13474,6 +13264,7 @@ OO.inheritClass( OO.ui.OutlineSelectWidget, OO.ui.SelectWidget );
  * @class
  * @extends OO.ui.Widget
  * @mixins OO.ui.ToggleWidget
+ * @mixins OO.ui.TabIndexedElement
  *
  * @constructor
  * @param {Object} [config] Configuration options
@@ -13485,22 +13276,27 @@ OO.ui.ToggleSwitchWidget = function OoUiToggleSwitchWidget( config ) {
 
        // Mixin constructors
        OO.ui.ToggleWidget.call( this, config );
+       OO.ui.TabIndexedElement.call( this, config );
 
        // Properties
        this.dragging = false;
        this.dragStart = null;
        this.sliding = false;
-       this.$glow = this.$( '<span>' );
-       this.$grip = this.$( '<span>' );
+       this.$glow = $( '<span>' );
+       this.$grip = $( '<span>' );
 
        // Events
-       this.$element.on( 'click', this.onClick.bind( this ) );
+       this.$element.on( {
+               click: this.onClick.bind( this ),
+               keypress: this.onKeyPress.bind( this )
+       } );
 
        // Initialization
        this.$glow.addClass( 'oo-ui-toggleSwitchWidget-glow' );
        this.$grip.addClass( 'oo-ui-toggleSwitchWidget-grip' );
        this.$element
                .addClass( 'oo-ui-toggleSwitchWidget' )
+               .attr( 'role', 'checkbox' )
                .append( this.$glow, this.$grip );
 };
 
@@ -13508,18 +13304,32 @@ OO.ui.ToggleSwitchWidget = function OoUiToggleSwitchWidget( config ) {
 
 OO.inheritClass( OO.ui.ToggleSwitchWidget, OO.ui.Widget );
 OO.mixinClass( OO.ui.ToggleSwitchWidget, OO.ui.ToggleWidget );
+OO.mixinClass( OO.ui.ToggleSwitchWidget, OO.ui.TabIndexedElement );
 
 /* Methods */
 
 /**
- * Handle mouse down events.
+ * Handle mouse click events.
  *
- * @param {jQuery.Event} e Mouse down event
+ * @param {jQuery.Event} e Mouse click event
  */
 OO.ui.ToggleSwitchWidget.prototype.onClick = function ( e ) {
        if ( !this.isDisabled() && e.which === 1 ) {
                this.setValue( !this.value );
        }
+       return false;
+};
+
+/**
+ * Handle key press events.
+ *
+ * @param {jQuery.Event} e Key press event
+ */
+OO.ui.ToggleSwitchWidget.prototype.onKeyPress = function ( e ) {
+       if ( !this.isDisabled() && ( e.which === OO.ui.Keys.SPACE || e.which === OO.ui.Keys.ENTER ) ) {
+               this.setValue( !this.value );
+       }
+       return false;
 };
 
 }( OO ) );
diff --git a/resources/lib/qunitjs/qunit.css b/resources/lib/qunitjs/qunit.css
new file mode 100644 (file)
index 0000000..0eb0b01
--- /dev/null
@@ -0,0 +1,280 @@
+/*!
+ * QUnit 1.17.1
+ * http://qunitjs.com/
+ *
+ * Copyright jQuery Foundation and other contributors
+ * Released under the MIT license
+ * http://jquery.org/license
+ *
+ * Date: 2015-01-20T19:39Z
+ */
+
+/** Font Family and Sizes */
+
+#qunit-tests, #qunit-header, #qunit-banner, #qunit-testrunner-toolbar, #qunit-userAgent, #qunit-testresult {
+       font-family: "Helvetica Neue Light", "HelveticaNeue-Light", "Helvetica Neue", Calibri, Helvetica, Arial, sans-serif;
+}
+
+#qunit-testrunner-toolbar, #qunit-userAgent, #qunit-testresult, #qunit-tests li { font-size: small; }
+#qunit-tests { font-size: smaller; }
+
+
+/** Resets */
+
+#qunit-tests, #qunit-header, #qunit-banner, #qunit-userAgent, #qunit-testresult, #qunit-modulefilter {
+       margin: 0;
+       padding: 0;
+}
+
+
+/** Header */
+
+#qunit-header {
+       padding: 0.5em 0 0.5em 1em;
+
+       color: #8699A4;
+       background-color: #0D3349;
+
+       font-size: 1.5em;
+       line-height: 1em;
+       font-weight: 400;
+
+       border-radius: 5px 5px 0 0;
+}
+
+#qunit-header a {
+       text-decoration: none;
+       color: #C2CCD1;
+}
+
+#qunit-header a:hover,
+#qunit-header a:focus {
+       color: #FFF;
+}
+
+#qunit-testrunner-toolbar label {
+       display: inline-block;
+       padding: 0 0.5em 0 0.1em;
+}
+
+#qunit-banner {
+       height: 5px;
+}
+
+#qunit-testrunner-toolbar {
+       padding: 0.5em 1em 0.5em 1em;
+       color: #5E740B;
+       background-color: #EEE;
+       overflow: hidden;
+}
+
+#qunit-userAgent {
+       padding: 0.5em 1em 0.5em 1em;
+       background-color: #2B81AF;
+       color: #FFF;
+       text-shadow: rgba(0, 0, 0, 0.5) 2px 2px 1px;
+}
+
+#qunit-modulefilter-container {
+       float: right;
+       padding: 0.2em;
+}
+
+.qunit-url-config {
+       display: inline-block;
+       padding: 0.1em;
+}
+
+.qunit-filter {
+       display: block;
+       float: right;
+       margin-left: 1em;
+}
+
+/** Tests: Pass/Fail */
+
+#qunit-tests {
+       list-style-position: inside;
+}
+
+#qunit-tests li {
+       padding: 0.4em 1em 0.4em 1em;
+       border-bottom: 1px solid #FFF;
+       list-style-position: inside;
+}
+
+#qunit-tests > li {
+       display: none;
+}
+
+#qunit-tests li.running,
+#qunit-tests li.pass,
+#qunit-tests li.fail,
+#qunit-tests li.skipped {
+       display: list-item;
+}
+
+#qunit-tests.hidepass li.running,
+#qunit-tests.hidepass li.pass {
+       display: none;
+}
+
+#qunit-tests li strong {
+       cursor: pointer;
+}
+
+#qunit-tests li.skipped strong {
+       cursor: default;
+}
+
+#qunit-tests li a {
+       padding: 0.5em;
+       color: #C2CCD1;
+       text-decoration: none;
+}
+#qunit-tests li a:hover,
+#qunit-tests li a:focus {
+       color: #000;
+}
+
+#qunit-tests li .runtime {
+       float: right;
+       font-size: smaller;
+}
+
+.qunit-assert-list {
+       margin-top: 0.5em;
+       padding: 0.5em;
+
+       background-color: #FFF;
+
+       border-radius: 5px;
+}
+
+.qunit-collapsed {
+       display: none;
+}
+
+#qunit-tests table {
+       border-collapse: collapse;
+       margin-top: 0.2em;
+}
+
+#qunit-tests th {
+       text-align: right;
+       vertical-align: top;
+       padding: 0 0.5em 0 0;
+}
+
+#qunit-tests td {
+       vertical-align: top;
+}
+
+#qunit-tests pre {
+       margin: 0;
+       white-space: pre-wrap;
+       word-wrap: break-word;
+}
+
+#qunit-tests del {
+       background-color: #E0F2BE;
+       color: #374E0C;
+       text-decoration: none;
+}
+
+#qunit-tests ins {
+       background-color: #FFCACA;
+       color: #500;
+       text-decoration: none;
+}
+
+/*** Test Counts */
+
+#qunit-tests b.counts                       { color: #000; }
+#qunit-tests b.passed                       { color: #5E740B; }
+#qunit-tests b.failed                       { color: #710909; }
+
+#qunit-tests li li {
+       padding: 5px;
+       background-color: #FFF;
+       border-bottom: none;
+       list-style-position: inside;
+}
+
+/*** Passing Styles */
+
+#qunit-tests li li.pass {
+       color: #3C510C;
+       background-color: #FFF;
+       border-left: 10px solid #C6E746;
+}
+
+#qunit-tests .pass                          { color: #528CE0; background-color: #D2E0E6; }
+#qunit-tests .pass .test-name               { color: #366097; }
+
+#qunit-tests .pass .test-actual,
+#qunit-tests .pass .test-expected           { color: #999; }
+
+#qunit-banner.qunit-pass                    { background-color: #C6E746; }
+
+/*** Failing Styles */
+
+#qunit-tests li li.fail {
+       color: #710909;
+       background-color: #FFF;
+       border-left: 10px solid #EE5757;
+       white-space: pre;
+}
+
+#qunit-tests > li:last-child {
+       border-radius: 0 0 5px 5px;
+}
+
+#qunit-tests .fail                          { color: #000; background-color: #EE5757; }
+#qunit-tests .fail .test-name,
+#qunit-tests .fail .module-name             { color: #000; }
+
+#qunit-tests .fail .test-actual             { color: #EE5757; }
+#qunit-tests .fail .test-expected           { color: #008000; }
+
+#qunit-banner.qunit-fail                    { background-color: #EE5757; }
+
+/*** Skipped tests */
+
+#qunit-tests .skipped {
+       background-color: #EBECE9;
+}
+
+#qunit-tests .qunit-skipped-label {
+       background-color: #F4FF77;
+       display: inline-block;
+       font-style: normal;
+       color: #366097;
+       line-height: 1.8em;
+       padding: 0 0.5em;
+       margin: -0.4em 0.4em -0.4em 0;
+}
+
+/** Result */
+
+#qunit-testresult {
+       padding: 0.5em 1em 0.5em 1em;
+
+       color: #2B81AF;
+       background-color: #D2E0E6;
+
+       border-bottom: 1px solid #FFF;
+}
+#qunit-testresult .module-name {
+       font-weight: 700;
+}
+
+/** Fixture */
+
+#qunit-fixture {
+       position: absolute;
+       top: -10000px;
+       left: -10000px;
+       width: 1000px;
+       height: 1000px;
+}
diff --git a/resources/lib/qunitjs/qunit.js b/resources/lib/qunitjs/qunit.js
new file mode 100644 (file)
index 0000000..006ca47
--- /dev/null
@@ -0,0 +1,2875 @@
+/*!
+ * QUnit 1.17.1
+ * http://qunitjs.com/
+ *
+ * Copyright jQuery Foundation and other contributors
+ * Released under the MIT license
+ * http://jquery.org/license
+ *
+ * Date: 2015-01-20T19:39Z
+ */
+
+(function( window ) {
+
+var QUnit,
+       config,
+       onErrorFnPrev,
+       loggingCallbacks = {},
+       fileName = ( sourceFromStacktrace( 0 ) || "" ).replace( /(:\d+)+\)?/, "" ).replace( /.+\//, "" ),
+       toString = Object.prototype.toString,
+       hasOwn = Object.prototype.hasOwnProperty,
+       // Keep a local reference to Date (GH-283)
+       Date = window.Date,
+       now = Date.now || function() {
+               return new Date().getTime();
+       },
+       globalStartCalled = false,
+       runStarted = false,
+       setTimeout = window.setTimeout,
+       clearTimeout = window.clearTimeout,
+       defined = {
+               document: window.document !== undefined,
+               setTimeout: window.setTimeout !== undefined,
+               sessionStorage: (function() {
+                       var x = "qunit-test-string";
+                       try {
+                               sessionStorage.setItem( x, x );
+                               sessionStorage.removeItem( x );
+                               return true;
+                       } catch ( e ) {
+                               return false;
+                       }
+               }())
+       },
+       /**
+        * Provides a normalized error string, correcting an issue
+        * with IE 7 (and prior) where Error.prototype.toString is
+        * not properly implemented
+        *
+        * Based on http://es5.github.com/#x15.11.4.4
+        *
+        * @param {String|Error} error
+        * @return {String} error message
+        */
+       errorString = function( error ) {
+               var name, message,
+                       errorString = error.toString();
+               if ( errorString.substring( 0, 7 ) === "[object" ) {
+                       name = error.name ? error.name.toString() : "Error";
+                       message = error.message ? error.message.toString() : "";
+                       if ( name && message ) {
+                               return name + ": " + message;
+                       } else if ( name ) {
+                               return name;
+                       } else if ( message ) {
+                               return message;
+                       } else {
+                               return "Error";
+                       }
+               } else {
+                       return errorString;
+               }
+       },
+       /**
+        * Makes a clone of an object using only Array or Object as base,
+        * and copies over the own enumerable properties.
+        *
+        * @param {Object} obj
+        * @return {Object} New object with only the own properties (recursively).
+        */
+       objectValues = function( obj ) {
+               var key, val,
+                       vals = QUnit.is( "array", obj ) ? [] : {};
+               for ( key in obj ) {
+                       if ( hasOwn.call( obj, key ) ) {
+                               val = obj[ key ];
+                               vals[ key ] = val === Object( val ) ? objectValues( val ) : val;
+                       }
+               }
+               return vals;
+       };
+
+QUnit = {};
+
+/**
+ * Config object: Maintain internal state
+ * Later exposed as QUnit.config
+ * `config` initialized at top of scope
+ */
+config = {
+       // The queue of tests to run
+       queue: [],
+
+       // block until document ready
+       blocking: true,
+
+       // by default, run previously failed tests first
+       // very useful in combination with "Hide passed tests" checked
+       reorder: true,
+
+       // by default, modify document.title when suite is done
+       altertitle: true,
+
+       // by default, scroll to top of the page when suite is done
+       scrolltop: true,
+
+       // when enabled, all tests must call expect()
+       requireExpects: false,
+
+       // add checkboxes that are persisted in the query-string
+       // when enabled, the id is set to `true` as a `QUnit.config` property
+       urlConfig: [
+               {
+                       id: "hidepassed",
+                       label: "Hide passed tests",
+                       tooltip: "Only show tests and assertions that fail. Stored as query-strings."
+               },
+               {
+                       id: "noglobals",
+                       label: "Check for Globals",
+                       tooltip: "Enabling this will test if any test introduces new properties on the " +
+                               "`window` object. Stored as query-strings."
+               },
+               {
+                       id: "notrycatch",
+                       label: "No try-catch",
+                       tooltip: "Enabling this will run tests outside of a try-catch block. Makes debugging " +
+                               "exceptions in IE reasonable. Stored as query-strings."
+               }
+       ],
+
+       // Set of all modules.
+       modules: [],
+
+       // The first unnamed module
+       currentModule: {
+               name: "",
+               tests: []
+       },
+
+       callbacks: {}
+};
+
+// Push a loose unnamed module to the modules collection
+config.modules.push( config.currentModule );
+
+// Initialize more QUnit.config and QUnit.urlParams
+(function() {
+       var i, current,
+               location = window.location || { search: "", protocol: "file:" },
+               params = location.search.slice( 1 ).split( "&" ),
+               length = params.length,
+               urlParams = {};
+
+       if ( params[ 0 ] ) {
+               for ( i = 0; i < length; i++ ) {
+                       current = params[ i ].split( "=" );
+                       current[ 0 ] = decodeURIComponent( current[ 0 ] );
+
+                       // allow just a key to turn on a flag, e.g., test.html?noglobals
+                       current[ 1 ] = current[ 1 ] ? decodeURIComponent( current[ 1 ] ) : true;
+                       if ( urlParams[ current[ 0 ] ] ) {
+                               urlParams[ current[ 0 ] ] = [].concat( urlParams[ current[ 0 ] ], current[ 1 ] );
+                       } else {
+                               urlParams[ current[ 0 ] ] = current[ 1 ];
+                       }
+               }
+       }
+
+       if ( urlParams.filter === true ) {
+               delete urlParams.filter;
+       }
+
+       QUnit.urlParams = urlParams;
+
+       // String search anywhere in moduleName+testName
+       config.filter = urlParams.filter;
+
+       config.testId = [];
+       if ( urlParams.testId ) {
+
+               // Ensure that urlParams.testId is an array
+               urlParams.testId = [].concat( urlParams.testId );
+               for ( i = 0; i < urlParams.testId.length; i++ ) {
+                       config.testId.push( urlParams.testId[ i ] );
+               }
+       }
+
+       // Figure out if we're running the tests from a server or not
+       QUnit.isLocal = location.protocol === "file:";
+}());
+
+// Root QUnit object.
+// `QUnit` initialized at top of scope
+extend( QUnit, {
+
+       // call on start of module test to prepend name to all tests
+       module: function( name, testEnvironment ) {
+               var currentModule = {
+                       name: name,
+                       testEnvironment: testEnvironment,
+                       tests: []
+               };
+
+               // DEPRECATED: handles setup/teardown functions,
+               // beforeEach and afterEach should be used instead
+               if ( testEnvironment && testEnvironment.setup ) {
+                       testEnvironment.beforeEach = testEnvironment.setup;
+                       delete testEnvironment.setup;
+               }
+               if ( testEnvironment && testEnvironment.teardown ) {
+                       testEnvironment.afterEach = testEnvironment.teardown;
+                       delete testEnvironment.teardown;
+               }
+
+               config.modules.push( currentModule );
+               config.currentModule = currentModule;
+       },
+
+       // DEPRECATED: QUnit.asyncTest() will be removed in QUnit 2.0.
+       asyncTest: function( testName, expected, callback ) {
+               if ( arguments.length === 2 ) {
+                       callback = expected;
+                       expected = null;
+               }
+
+               QUnit.test( testName, expected, callback, true );
+       },
+
+       test: function( testName, expected, callback, async ) {
+               var test;
+
+               if ( arguments.length === 2 ) {
+                       callback = expected;
+                       expected = null;
+               }
+
+               test = new Test({
+                       testName: testName,
+                       expected: expected,
+                       async: async,
+                       callback: callback
+               });
+
+               test.queue();
+       },
+
+       skip: function( testName ) {
+               var test = new Test({
+                       testName: testName,
+                       skip: true
+               });
+
+               test.queue();
+       },
+
+       // DEPRECATED: The functionality of QUnit.start() will be altered in QUnit 2.0.
+       // In QUnit 2.0, invoking it will ONLY affect the `QUnit.config.autostart` blocking behavior.
+       start: function( count ) {
+               var globalStartAlreadyCalled = globalStartCalled;
+
+               if ( !config.current ) {
+                       globalStartCalled = true;
+
+                       if ( runStarted ) {
+                               throw new Error( "Called start() outside of a test context while already started" );
+                       } else if ( globalStartAlreadyCalled || count > 1 ) {
+                               throw new Error( "Called start() outside of a test context too many times" );
+                       } else if ( config.autostart ) {
+                               throw new Error( "Called start() outside of a test context when " +
+                                       "QUnit.config.autostart was true" );
+                       } else if ( !config.pageLoaded ) {
+
+                               // The page isn't completely loaded yet, so bail out and let `QUnit.load` handle it
+                               config.autostart = true;
+                               return;
+                       }
+               } else {
+
+                       // If a test is running, adjust its semaphore
+                       config.current.semaphore -= count || 1;
+
+                       // Don't start until equal number of stop-calls
+                       if ( config.current.semaphore > 0 ) {
+                               return;
+                       }
+
+                       // throw an Error if start is called more often than stop
+                       if ( config.current.semaphore < 0 ) {
+                               config.current.semaphore = 0;
+
+                               QUnit.pushFailure(
+                                       "Called start() while already started (test's semaphore was 0 already)",
+                                       sourceFromStacktrace( 2 )
+                               );
+                               return;
+                       }
+               }
+
+               resumeProcessing();
+       },
+
+       // DEPRECATED: QUnit.stop() will be removed in QUnit 2.0.
+       stop: function( count ) {
+
+               // If there isn't a test running, don't allow QUnit.stop() to be called
+               if ( !config.current ) {
+                       throw new Error( "Called stop() outside of a test context" );
+               }
+
+               // If a test is running, adjust its semaphore
+               config.current.semaphore += count || 1;
+
+               pauseProcessing();
+       },
+
+       config: config,
+
+       // Safe object type checking
+       is: function( type, obj ) {
+               return QUnit.objectType( obj ) === type;
+       },
+
+       objectType: function( obj ) {
+               if ( typeof obj === "undefined" ) {
+                       return "undefined";
+               }
+
+               // Consider: typeof null === object
+               if ( obj === null ) {
+                       return "null";
+               }
+
+               var match = toString.call( obj ).match( /^\[object\s(.*)\]$/ ),
+                       type = match && match[ 1 ] || "";
+
+               switch ( type ) {
+                       case "Number":
+                               if ( isNaN( obj ) ) {
+                                       return "nan";
+                               }
+                               return "number";
+                       case "String":
+                       case "Boolean":
+                       case "Array":
+                       case "Date":
+                       case "RegExp":
+                       case "Function":
+                               return type.toLowerCase();
+               }
+               if ( typeof obj === "object" ) {
+                       return "object";
+               }
+               return undefined;
+       },
+
+       extend: extend,
+
+       load: function() {
+               config.pageLoaded = true;
+
+               // Initialize the configuration options
+               extend( config, {
+                       stats: { all: 0, bad: 0 },
+                       moduleStats: { all: 0, bad: 0 },
+                       started: 0,
+                       updateRate: 1000,
+                       autostart: true,
+                       filter: ""
+               }, true );
+
+               config.blocking = false;
+
+               if ( config.autostart ) {
+                       resumeProcessing();
+               }
+       }
+});
+
+// Register logging callbacks
+(function() {
+       var i, l, key,
+               callbacks = [ "begin", "done", "log", "testStart", "testDone",
+                       "moduleStart", "moduleDone" ];
+
+       function registerLoggingCallback( key ) {
+               var loggingCallback = function( callback ) {
+                       if ( QUnit.objectType( callback ) !== "function" ) {
+                               throw new Error(
+                                       "QUnit logging methods require a callback function as their first parameters."
+                               );
+                       }
+
+                       config.callbacks[ key ].push( callback );
+               };
+
+               // DEPRECATED: This will be removed on QUnit 2.0.0+
+               // Stores the registered functions allowing restoring
+               // at verifyLoggingCallbacks() if modified
+               loggingCallbacks[ key ] = loggingCallback;
+
+               return loggingCallback;
+       }
+
+       for ( i = 0, l = callbacks.length; i < l; i++ ) {
+               key = callbacks[ i ];
+
+               // Initialize key collection of logging callback
+               if ( QUnit.objectType( config.callbacks[ key ] ) === "undefined" ) {
+                       config.callbacks[ key ] = [];
+               }
+
+               QUnit[ key ] = registerLoggingCallback( key );
+       }
+})();
+
+// `onErrorFnPrev` initialized at top of scope
+// Preserve other handlers
+onErrorFnPrev = window.onerror;
+
+// Cover uncaught exceptions
+// Returning true will suppress the default browser handler,
+// returning false will let it run.
+window.onerror = function( error, filePath, linerNr ) {
+       var ret = false;
+       if ( onErrorFnPrev ) {
+               ret = onErrorFnPrev( error, filePath, linerNr );
+       }
+
+       // Treat return value as window.onerror itself does,
+       // Only do our handling if not suppressed.
+       if ( ret !== true ) {
+               if ( QUnit.config.current ) {
+                       if ( QUnit.config.current.ignoreGlobalErrors ) {
+                               return true;
+                       }
+                       QUnit.pushFailure( error, filePath + ":" + linerNr );
+               } else {
+                       QUnit.test( "global failure", extend(function() {
+                               QUnit.pushFailure( error, filePath + ":" + linerNr );
+                       }, { validTest: true } ) );
+               }
+               return false;
+       }
+
+       return ret;
+};
+
+function done() {
+       var runtime, passed;
+
+       config.autorun = true;
+
+       // Log the last module results
+       if ( config.previousModule ) {
+               runLoggingCallbacks( "moduleDone", {
+                       name: config.previousModule.name,
+                       tests: config.previousModule.tests,
+                       failed: config.moduleStats.bad,
+                       passed: config.moduleStats.all - config.moduleStats.bad,
+                       total: config.moduleStats.all,
+                       runtime: now() - config.moduleStats.started
+               });
+       }
+       delete config.previousModule;
+
+       runtime = now() - config.started;
+       passed = config.stats.all - config.stats.bad;
+
+       runLoggingCallbacks( "done", {
+               failed: config.stats.bad,
+               passed: passed,
+               total: config.stats.all,
+               runtime: runtime
+       });
+}
+
+// Doesn't support IE6 to IE9
+// See also https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Error/Stack
+function extractStacktrace( e, offset ) {
+       offset = offset === undefined ? 4 : offset;
+
+       var stack, include, i;
+
+       if ( e.stacktrace ) {
+
+               // Opera 12.x
+               return e.stacktrace.split( "\n" )[ offset + 3 ];
+       } else if ( e.stack ) {
+
+               // Firefox, Chrome, Safari 6+, IE10+, PhantomJS and Node
+               stack = e.stack.split( "\n" );
+               if ( /^error$/i.test( stack[ 0 ] ) ) {
+                       stack.shift();
+               }
+               if ( fileName ) {
+                       include = [];
+                       for ( i = offset; i < stack.length; i++ ) {
+                               if ( stack[ i ].indexOf( fileName ) !== -1 ) {
+                                       break;
+                               }
+                               include.push( stack[ i ] );
+                       }
+                       if ( include.length ) {
+                               return include.join( "\n" );
+                       }
+               }
+               return stack[ offset ];
+       } else if ( e.sourceURL ) {
+
+               // Safari < 6
+               // exclude useless self-reference for generated Error objects
+               if ( /qunit.js$/.test( e.sourceURL ) ) {
+                       return;
+               }
+
+               // for actual exceptions, this is useful
+               return e.sourceURL + ":" + e.line;
+       }
+}
+
+function sourceFromStacktrace( offset ) {
+       var e = new Error();
+       if ( !e.stack ) {
+               try {
+                       throw e;
+               } catch ( err ) {
+                       // This should already be true in most browsers
+                       e = err;
+               }
+       }
+       return extractStacktrace( e, offset );
+}
+
+function synchronize( callback, last ) {
+       if ( QUnit.objectType( callback ) === "array" ) {
+               while ( callback.length ) {
+                       synchronize( callback.shift() );
+               }
+               return;
+       }
+       config.queue.push( callback );
+
+       if ( config.autorun && !config.blocking ) {
+               process( last );
+       }
+}
+
+function process( last ) {
+       function next() {
+               process( last );
+       }
+       var start = now();
+       config.depth = ( config.depth || 0 ) + 1;
+
+       while ( config.queue.length && !config.blocking ) {
+               if ( !defined.setTimeout || config.updateRate <= 0 ||
+                               ( ( now() - start ) < config.updateRate ) ) {
+                       if ( config.current ) {
+
+                               // Reset async tracking for each phase of the Test lifecycle
+                               config.current.usedAsync = false;
+                       }
+                       config.queue.shift()();
+               } else {
+                       setTimeout( next, 13 );
+                       break;
+               }
+       }
+       config.depth--;
+       if ( last && !config.blocking && !config.queue.length && config.depth === 0 ) {
+               done();
+       }
+}
+
+function begin() {
+       var i, l,
+               modulesLog = [];
+
+       // If the test run hasn't officially begun yet
+       if ( !config.started ) {
+
+               // Record the time of the test run's beginning
+               config.started = now();
+
+               verifyLoggingCallbacks();
+
+               // Delete the loose unnamed module if unused.
+               if ( config.modules[ 0 ].name === "" && config.modules[ 0 ].tests.length === 0 ) {
+                       config.modules.shift();
+               }
+
+               // Avoid unnecessary information by not logging modules' test environments
+               for ( i = 0, l = config.modules.length; i < l; i++ ) {
+                       modulesLog.push({
+                               name: config.modules[ i ].name,
+                               tests: config.modules[ i ].tests
+                       });
+               }
+
+               // The test run is officially beginning now
+               runLoggingCallbacks( "begin", {
+                       totalTests: Test.count,
+                       modules: modulesLog
+               });
+       }
+
+       config.blocking = false;
+       process( true );
+}
+
+function resumeProcessing() {
+       runStarted = true;
+
+       // A slight delay to allow this iteration of the event loop to finish (more assertions, etc.)
+       if ( defined.setTimeout ) {
+               setTimeout(function() {
+                       if ( config.current && config.current.semaphore > 0 ) {
+                               return;
+                       }
+                       if ( config.timeout ) {
+                               clearTimeout( config.timeout );
+                       }
+
+                       begin();
+               }, 13 );
+       } else {
+               begin();
+       }
+}
+
+function pauseProcessing() {
+       config.blocking = true;
+
+       if ( config.testTimeout && defined.setTimeout ) {
+               clearTimeout( config.timeout );
+               config.timeout = setTimeout(function() {
+                       if ( config.current ) {
+                               config.current.semaphore = 0;
+                               QUnit.pushFailure( "Test timed out", sourceFromStacktrace( 2 ) );
+                       } else {
+                               throw new Error( "Test timed out" );
+                       }
+                       resumeProcessing();
+               }, config.testTimeout );
+       }
+}
+
+function saveGlobal() {
+       config.pollution = [];
+
+       if ( config.noglobals ) {
+               for ( var key in window ) {
+                       if ( hasOwn.call( window, key ) ) {
+                               // in Opera sometimes DOM element ids show up here, ignore them
+                               if ( /^qunit-test-output/.test( key ) ) {
+                                       continue;
+                               }
+                               config.pollution.push( key );
+                       }
+               }
+       }
+}
+
+function checkPollution() {
+       var newGlobals,
+               deletedGlobals,
+               old = config.pollution;
+
+       saveGlobal();
+
+       newGlobals = diff( config.pollution, old );
+       if ( newGlobals.length > 0 ) {
+               QUnit.pushFailure( "Introduced global variable(s): " + newGlobals.join( ", " ) );
+       }
+
+       deletedGlobals = diff( old, config.pollution );
+       if ( deletedGlobals.length > 0 ) {
+               QUnit.pushFailure( "Deleted global variable(s): " + deletedGlobals.join( ", " ) );
+       }
+}
+
+// returns a new Array with the elements that are in a but not in b
+function diff( a, b ) {
+       var i, j,
+               result = a.slice();
+
+       for ( i = 0; i < result.length; i++ ) {
+               for ( j = 0; j < b.length; j++ ) {
+                       if ( result[ i ] === b[ j ] ) {
+                               result.splice( i, 1 );
+                               i--;
+                               break;
+                       }
+               }
+       }
+       return result;
+}
+
+function extend( a, b, undefOnly ) {
+       for ( var prop in b ) {
+               if ( hasOwn.call( b, prop ) ) {
+
+                       // Avoid "Member not found" error in IE8 caused by messing with window.constructor
+                       if ( !( prop === "constructor" && a === window ) ) {
+                               if ( b[ prop ] === undefined ) {
+                                       delete a[ prop ];
+                               } else if ( !( undefOnly && typeof a[ prop ] !== "undefined" ) ) {
+                                       a[ prop ] = b[ prop ];
+                               }
+                       }
+               }
+       }
+
+       return a;
+}
+
+function runLoggingCallbacks( key, args ) {
+       var i, l, callbacks;
+
+       callbacks = config.callbacks[ key ];
+       for ( i = 0, l = callbacks.length; i < l; i++ ) {
+               callbacks[ i ]( args );
+       }
+}
+
+// DEPRECATED: This will be removed on 2.0.0+
+// This function verifies if the loggingCallbacks were modified by the user
+// If so, it will restore it, assign the given callback and print a console warning
+function verifyLoggingCallbacks() {
+       var loggingCallback, userCallback;
+
+       for ( loggingCallback in loggingCallbacks ) {
+               if ( QUnit[ loggingCallback ] !== loggingCallbacks[ loggingCallback ] ) {
+
+                       userCallback = QUnit[ loggingCallback ];
+
+                       // Restore the callback function
+                       QUnit[ loggingCallback ] = loggingCallbacks[ loggingCallback ];
+
+                       // Assign the deprecated given callback
+                       QUnit[ loggingCallback ]( userCallback );
+
+                       if ( window.console && window.console.warn ) {
+                               window.console.warn(
+                                       "QUnit." + loggingCallback + " was replaced with a new value.\n" +
+                                       "Please, check out the documentation on how to apply logging callbacks.\n" +
+                                       "Reference: http://api.qunitjs.com/category/callbacks/"
+                               );
+                       }
+               }
+       }
+}
+
+// from jquery.js
+function inArray( elem, array ) {
+       if ( array.indexOf ) {
+               return array.indexOf( elem );
+       }
+
+       for ( var i = 0, length = array.length; i < length; i++ ) {
+               if ( array[ i ] === elem ) {
+                       return i;
+               }
+       }
+
+       return -1;
+}
+
+function Test( settings ) {
+       var i, l;
+
+       ++Test.count;
+
+       extend( this, settings );
+       this.assertions = [];
+       this.semaphore = 0;
+       this.usedAsync = false;
+       this.module = config.currentModule;
+       this.stack = sourceFromStacktrace( 3 );
+
+       // Register unique strings
+       for ( i = 0, l = this.module.tests; i < l.length; i++ ) {
+               if ( this.module.tests[ i ].name === this.testName ) {
+                       this.testName += " ";
+               }
+       }
+
+       this.testId = generateHash( this.module.name, this.testName );
+
+       this.module.tests.push({
+               name: this.testName,
+               testId: this.testId
+       });
+
+       if ( settings.skip ) {
+
+               // Skipped tests will fully ignore any sent callback
+               this.callback = function() {};
+               this.async = false;
+               this.expected = 0;
+       } else {
+               this.assert = new Assert( this );
+       }
+}
+
+Test.count = 0;
+
+Test.prototype = {
+       before: function() {
+               if (
+
+                       // Emit moduleStart when we're switching from one module to another
+                       this.module !== config.previousModule ||
+
+                               // They could be equal (both undefined) but if the previousModule property doesn't
+                               // yet exist it means this is the first test in a suite that isn't wrapped in a
+                               // module, in which case we'll just emit a moduleStart event for 'undefined'.
+                               // Without this, reporters can get testStart before moduleStart  which is a problem.
+                               !hasOwn.call( config, "previousModule" )
+               ) {
+                       if ( hasOwn.call( config, "previousModule" ) ) {
+                               runLoggingCallbacks( "moduleDone", {
+                                       name: config.previousModule.name,
+                                       tests: config.previousModule.tests,
+                                       failed: config.moduleStats.bad,
+                                       passed: config.moduleStats.all - config.moduleStats.bad,
+                                       total: config.moduleStats.all,
+                                       runtime: now() - config.moduleStats.started
+                               });
+                       }
+                       config.previousModule = this.module;
+                       config.moduleStats = { all: 0, bad: 0, started: now() };
+                       runLoggingCallbacks( "moduleStart", {
+                               name: this.module.name,
+                               tests: this.module.tests
+                       });
+               }
+
+               config.current = this;
+
+               this.testEnvironment = extend( {}, this.module.testEnvironment );
+               delete this.testEnvironment.beforeEach;
+               delete this.testEnvironment.afterEach;
+
+               this.started = now();
+               runLoggingCallbacks( "testStart", {
+                       name: this.testName,
+                       module: this.module.name,
+                       testId: this.testId
+               });
+
+               if ( !config.pollution ) {
+                       saveGlobal();
+               }
+       },
+
+       run: function() {
+               var promise;
+
+               config.current = this;
+
+               if ( this.async ) {
+                       QUnit.stop();
+               }
+
+               this.callbackStarted = now();
+
+               if ( config.notrycatch ) {
+                       promise = this.callback.call( this.testEnvironment, this.assert );
+                       this.resolvePromise( promise );
+                       return;
+               }
+
+               try {
+                       promise = this.callback.call( this.testEnvironment, this.assert );
+                       this.resolvePromise( promise );
+               } catch ( e ) {
+                       this.pushFailure( "Died on test #" + ( this.assertions.length + 1 ) + " " +
+                               this.stack + ": " + ( e.message || e ), extractStacktrace( e, 0 ) );
+
+                       // else next test will carry the responsibility
+                       saveGlobal();
+
+                       // Restart the tests if they're blocking
+                       if ( config.blocking ) {
+                               QUnit.start();
+                       }
+               }
+       },
+
+       after: function() {
+               checkPollution();
+       },
+
+       queueHook: function( hook, hookName ) {
+               var promise,
+                       test = this;
+               return function runHook() {
+                       config.current = test;
+                       if ( config.notrycatch ) {
+                               promise = hook.call( test.testEnvironment, test.assert );
+                               test.resolvePromise( promise, hookName );
+                               return;
+                       }
+                       try {
+                               promise = hook.call( test.testEnvironment, test.assert );
+                               test.resolvePromise( promise, hookName );
+                       } catch ( error ) {
+                               test.pushFailure( hookName + " failed on " + test.testName + ": " +
+                                       ( error.message || error ), extractStacktrace( error, 0 ) );
+                       }
+               };
+       },
+
+       // Currently only used for module level hooks, can be used to add global level ones
+       hooks: function( handler ) {
+               var hooks = [];
+
+               // Hooks are ignored on skipped tests
+               if ( this.skip ) {
+                       return hooks;
+               }
+
+               if ( this.module.testEnvironment &&
+                               QUnit.objectType( this.module.testEnvironment[ handler ] ) === "function" ) {
+                       hooks.push( this.queueHook( this.module.testEnvironment[ handler ], handler ) );
+               }
+
+               return hooks;
+       },
+
+       finish: function() {
+               config.current = this;
+               if ( config.requireExpects && this.expected === null ) {
+                       this.pushFailure( "Expected number of assertions to be defined, but expect() was " +
+                               "not called.", this.stack );
+               } else if ( this.expected !== null && this.expected !== this.assertions.length ) {
+                       this.pushFailure( "Expected " + this.expected + " assertions, but " +
+                               this.assertions.length + " were run", this.stack );
+               } else if ( this.expected === null && !this.assertions.length ) {
+                       this.pushFailure( "Expected at least one assertion, but none were run - call " +
+                               "expect(0) to accept zero assertions.", this.stack );
+               }
+
+               var i,
+                       bad = 0;
+
+               this.runtime = now() - this.started;
+               config.stats.all += this.assertions.length;
+               config.moduleStats.all += this.assertions.length;
+
+               for ( i = 0; i < this.assertions.length; i++ ) {
+                       if ( !this.assertions[ i ].result ) {
+                               bad++;
+                               config.stats.bad++;
+                               config.moduleStats.bad++;
+                       }
+               }
+
+               runLoggingCallbacks( "testDone", {
+                       name: this.testName,
+                       module: this.module.name,
+                       skipped: !!this.skip,
+                       failed: bad,
+                       passed: this.assertions.length - bad,
+                       total: this.assertions.length,
+                       runtime: this.runtime,
+
+                       // HTML Reporter use
+                       assertions: this.assertions,
+                       testId: this.testId,
+
+                       // DEPRECATED: this property will be removed in 2.0.0, use runtime instead
+                       duration: this.runtime
+               });
+
+               // QUnit.reset() is deprecated and will be replaced for a new
+               // fixture reset function on QUnit 2.0/2.1.
+               // It's still called here for backwards compatibility handling
+               QUnit.reset();
+
+               config.current = undefined;
+       },
+
+       queue: function() {
+               var bad,
+                       test = this;
+
+               if ( !this.valid() ) {
+                       return;
+               }
+
+               function run() {
+
+                       // each of these can by async
+                       synchronize([
+                               function() {
+                                       test.before();
+                               },
+
+                               test.hooks( "beforeEach" ),
+
+                               function() {
+                                       test.run();
+                               },
+
+                               test.hooks( "afterEach" ).reverse(),
+
+                               function() {
+                                       test.after();
+                               },
+                               function() {
+                                       test.finish();
+                               }
+                       ]);
+               }
+
+               // `bad` initialized at top of scope
+               // defer when previous test run passed, if storage is available
+               bad = QUnit.config.reorder && defined.sessionStorage &&
+                               +sessionStorage.getItem( "qunit-test-" + this.module.name + "-" + this.testName );
+
+               if ( bad ) {
+                       run();
+               } else {
+                       synchronize( run, true );
+               }
+       },
+
+       push: function( result, actual, expected, message ) {
+               var source,
+                       details = {
+                               module: this.module.name,
+                               name: this.testName,
+                               result: result,
+                               message: message,
+                               actual: actual,
+                               expected: expected,
+                               testId: this.testId,
+                               runtime: now() - this.started
+                       };
+
+               if ( !result ) {
+                       source = sourceFromStacktrace();
+
+                       if ( source ) {
+                               details.source = source;
+                       }
+               }
+
+               runLoggingCallbacks( "log", details );
+
+               this.assertions.push({
+                       result: !!result,
+                       message: message
+               });
+       },
+
+       pushFailure: function( message, source, actual ) {
+               if ( !this instanceof Test ) {
+                       throw new Error( "pushFailure() assertion outside test context, was " +
+                               sourceFromStacktrace( 2 ) );
+               }
+
+               var details = {
+                               module: this.module.name,
+                               name: this.testName,
+                               result: false,
+                               message: message || "error",
+                               actual: actual || null,
+                               testId: this.testId,
+                               runtime: now() - this.started
+                       };
+
+               if ( source ) {
+                       details.source = source;
+               }
+
+               runLoggingCallbacks( "log", details );
+
+               this.assertions.push({
+                       result: false,
+                       message: message
+               });
+       },
+
+       resolvePromise: function( promise, phase ) {
+               var then, message,
+                       test = this;
+               if ( promise != null ) {
+                       then = promise.then;
+                       if ( QUnit.objectType( then ) === "function" ) {
+                               QUnit.stop();
+                               then.call(
+                                       promise,
+                                       QUnit.start,
+                                       function( error ) {
+                                               message = "Promise rejected " +
+                                                       ( !phase ? "during" : phase.replace( /Each$/, "" ) ) +
+                                                       " " + test.testName + ": " + ( error.message || error );
+                                               test.pushFailure( message, extractStacktrace( error, 0 ) );
+
+                                               // else next test will carry the responsibility
+                                               saveGlobal();
+
+                                               // Unblock
+                                               QUnit.start();
+                                       }
+                               );
+                       }
+               }
+       },
+
+       valid: function() {
+               var include,
+                       filter = config.filter,
+                       module = QUnit.urlParams.module && QUnit.urlParams.module.toLowerCase(),
+                       fullName = ( this.module.name + ": " + this.testName ).toLowerCase();
+
+               // Internally-generated tests are always valid
+               if ( this.callback && this.callback.validTest ) {
+                       return true;
+               }
+
+               if ( config.testId.length > 0 && inArray( this.testId, config.testId ) < 0 ) {
+                       return false;
+               }
+
+               if ( module && ( !this.module.name || this.module.name.toLowerCase() !== module ) ) {
+                       return false;
+               }
+
+               if ( !filter ) {
+                       return true;
+               }
+
+               include = filter.charAt( 0 ) !== "!";
+               if ( !include ) {
+                       filter = filter.toLowerCase().slice( 1 );
+               }
+
+               // If the filter matches, we need to honour include
+               if ( fullName.indexOf( filter ) !== -1 ) {
+                       return include;
+               }
+
+               // Otherwise, do the opposite
+               return !include;
+       }
+
+};
+
+// Resets the test setup. Useful for tests that modify the DOM.
+/*
+DEPRECATED: Use multiple tests instead of resetting inside a test.
+Use testStart or testDone for custom cleanup.
+This method will throw an error in 2.0, and will be removed in 2.1
+*/
+QUnit.reset = function() {
+
+       // Return on non-browser environments
+       // This is necessary to not break on node tests
+       if ( typeof window === "undefined" ) {
+               return;
+       }
+
+       var fixture = defined.document && document.getElementById &&
+                       document.getElementById( "qunit-fixture" );
+
+       if ( fixture ) {
+               fixture.innerHTML = config.fixture;
+       }
+};
+
+QUnit.pushFailure = function() {
+       if ( !QUnit.config.current ) {
+               throw new Error( "pushFailure() assertion outside test context, in " +
+                       sourceFromStacktrace( 2 ) );
+       }
+
+       // Gets current test obj
+       var currentTest = QUnit.config.current;
+
+       return currentTest.pushFailure.apply( currentTest, arguments );
+};
+
+// Based on Java's String.hashCode, a simple but not
+// rigorously collision resistant hashing function
+function generateHash( module, testName ) {
+       var hex,
+               i = 0,
+               hash = 0,
+               str = module + "\x1C" + testName,
+               len = str.length;
+
+       for ( ; i < len; i++ ) {
+               hash  = ( ( hash << 5 ) - hash ) + str.charCodeAt( i );
+               hash |= 0;
+       }
+
+       // Convert the possibly negative integer hash code into an 8 character hex string, which isn't
+       // strictly necessary but increases user understanding that the id is a SHA-like hash
+       hex = ( 0x100000000 + hash ).toString( 16 );
+       if ( hex.length < 8 ) {
+               hex = "0000000" + hex;
+       }
+
+       return hex.slice( -8 );
+}
+
+function Assert( testContext ) {
+       this.test = testContext;
+}
+
+// Assert helpers
+QUnit.assert = Assert.prototype = {
+
+       // Specify the number of expected assertions to guarantee that failed test
+       // (no assertions are run at all) don't slip through.
+       expect: function( asserts ) {
+               if ( arguments.length === 1 ) {
+                       this.test.expected = asserts;
+               } else {
+                       return this.test.expected;
+               }
+       },
+
+       // Increment this Test's semaphore counter, then return a single-use function that
+       // decrements that counter a maximum of once.
+       async: function() {
+               var test = this.test,
+                       popped = false;
+
+               test.semaphore += 1;
+               test.usedAsync = true;
+               pauseProcessing();
+
+               return function done() {
+                       if ( !popped ) {
+                               test.semaphore -= 1;
+                               popped = true;
+                               resumeProcessing();
+                       } else {
+                               test.pushFailure( "Called the callback returned from `assert.async` more than once",
+                                       sourceFromStacktrace( 2 ) );
+                       }
+               };
+       },
+
+       // Exports test.push() to the user API
+       push: function( /* result, actual, expected, message */ ) {
+               var assert = this,
+                       currentTest = ( assert instanceof Assert && assert.test ) || QUnit.config.current;
+
+               // Backwards compatibility fix.
+               // Allows the direct use of global exported assertions and QUnit.assert.*
+               // Although, it's use is not recommended as it can leak assertions
+               // to other tests from async tests, because we only get a reference to the current test,
+               // not exactly the test where assertion were intended to be called.
+               if ( !currentTest ) {
+                       throw new Error( "assertion outside test context, in " + sourceFromStacktrace( 2 ) );
+               }
+
+               if ( currentTest.usedAsync === true && currentTest.semaphore === 0 ) {
+                       currentTest.pushFailure( "Assertion after the final `assert.async` was resolved",
+                               sourceFromStacktrace( 2 ) );
+
+                       // Allow this assertion to continue running anyway...
+               }
+
+               if ( !( assert instanceof Assert ) ) {
+                       assert = currentTest.assert;
+               }
+               return assert.test.push.apply( assert.test, arguments );
+       },
+
+       /**
+        * Asserts rough true-ish result.
+        * @name ok
+        * @function
+        * @example ok( "asdfasdf".length > 5, "There must be at least 5 chars" );
+        */
+       ok: function( result, message ) {
+               message = message || ( result ? "okay" : "failed, expected argument to be truthy, was: " +
+                       QUnit.dump.parse( result ) );
+               this.push( !!result, result, true, message );
+       },
+
+       /**
+        * Assert that the first two arguments are equal, with an optional message.
+        * Prints out both actual and expected values.
+        * @name equal
+        * @function
+        * @example equal( format( "{0} bytes.", 2), "2 bytes.", "replaces {0} with next argument" );
+        */
+       equal: function( actual, expected, message ) {
+               /*jshint eqeqeq:false */
+               this.push( expected == actual, actual, expected, message );
+       },
+
+       /**
+        * @name notEqual
+        * @function
+        */
+       notEqual: function( actual, expected, message ) {
+               /*jshint eqeqeq:false */
+               this.push( expected != actual, actual, expected, message );
+       },
+
+       /**
+        * @name propEqual
+        * @function
+        */
+       propEqual: function( actual, expected, message ) {
+               actual = objectValues( actual );
+               expected = objectValues( expected );
+               this.push( QUnit.equiv( actual, expected ), actual, expected, message );
+       },
+
+       /**
+        * @name notPropEqual
+        * @function
+        */
+       notPropEqual: function( actual, expected, message ) {
+               actual = objectValues( actual );
+               expected = objectValues( expected );
+               this.push( !QUnit.equiv( actual, expected ), actual, expected, message );
+       },
+
+       /**
+        * @name deepEqual
+        * @function
+        */
+       deepEqual: function( actual, expected, message ) {
+               this.push( QUnit.equiv( actual, expected ), actual, expected, message );
+       },
+
+       /**
+        * @name notDeepEqual
+        * @function
+        */
+       notDeepEqual: function( actual, expected, message ) {
+               this.push( !QUnit.equiv( actual, expected ), actual, expected, message );
+       },
+
+       /**
+        * @name strictEqual
+        * @function
+        */
+       strictEqual: function( actual, expected, message ) {
+               this.push( expected === actual, actual, expected, message );
+       },
+
+       /**
+        * @name notStrictEqual
+        * @function
+        */
+       notStrictEqual: function( actual, expected, message ) {
+               this.push( expected !== actual, actual, expected, message );
+       },
+
+       "throws": function( block, expected, message ) {
+               var actual, expectedType,
+                       expectedOutput = expected,
+                       ok = false;
+
+               // 'expected' is optional unless doing string comparison
+               if ( message == null && typeof expected === "string" ) {
+                       message = expected;
+                       expected = null;
+               }
+
+               this.test.ignoreGlobalErrors = true;
+               try {
+                       block.call( this.test.testEnvironment );
+               } catch (e) {
+                       actual = e;
+               }
+               this.test.ignoreGlobalErrors = false;
+
+               if ( actual ) {
+                       expectedType = QUnit.objectType( expected );
+
+                       // we don't want to validate thrown error
+                       if ( !expected ) {
+                               ok = true;
+                               expectedOutput = null;
+
+                       // expected is a regexp
+                       } else if ( expectedType === "regexp" ) {
+                               ok = expected.test( errorString( actual ) );
+
+                       // expected is a string
+                       } else if ( expectedType === "string" ) {
+                               ok = expected === errorString( actual );
+
+                       // expected is a constructor, maybe an Error constructor
+                       } else if ( expectedType === "function" && actual instanceof expected ) {
+                               ok = true;
+
+                       // expected is an Error object
+                       } else if ( expectedType === "object" ) {
+                               ok = actual instanceof expected.constructor &&
+                                       actual.name === expected.name &&
+                                       actual.message === expected.message;
+
+                       // expected is a validation function which returns true if validation passed
+                       } else if ( expectedType === "function" && expected.call( {}, actual ) === true ) {
+                               expectedOutput = null;
+                               ok = true;
+                       }
+
+                       this.push( ok, actual, expectedOutput, message );
+               } else {
+                       this.test.pushFailure( message, null, "No exception was thrown." );
+               }
+       }
+};
+
+// Provide an alternative to assert.throws(), for enviroments that consider throws a reserved word
+// Known to us are: Closure Compiler, Narwhal
+(function() {
+       /*jshint sub:true */
+       Assert.prototype.raises = Assert.prototype[ "throws" ];
+}());
+
+// Test for equality any JavaScript type.
+// Author: Philippe Rathé <prathe@gmail.com>
+QUnit.equiv = (function() {
+
+       // Call the o related callback with the given arguments.
+       function bindCallbacks( o, callbacks, args ) {
+               var prop = QUnit.objectType( o );
+               if ( prop ) {
+                       if ( QUnit.objectType( callbacks[ prop ] ) === "function" ) {
+                               return callbacks[ prop ].apply( callbacks, args );
+                       } else {
+                               return callbacks[ prop ]; // or undefined
+                       }
+               }
+       }
+
+       // the real equiv function
+       var innerEquiv,
+
+               // stack to decide between skip/abort functions
+               callers = [],
+
+               // stack to avoiding loops from circular referencing
+               parents = [],
+               parentsB = [],
+
+               getProto = Object.getPrototypeOf || function( obj ) {
+                       /* jshint camelcase: false, proto: true */
+                       return obj.__proto__;
+               },
+               callbacks = (function() {
+
+                       // for string, boolean, number and null
+                       function useStrictEquality( b, a ) {
+
+                               /*jshint eqeqeq:false */
+                               if ( b instanceof a.constructor || a instanceof b.constructor ) {
+
+                                       // to catch short annotation VS 'new' annotation of a
+                                       // declaration
+                                       // e.g. var i = 1;
+                                       // var j = new Number(1);
+                                       return a == b;
+                               } else {
+                                       return a === b;
+                               }
+                       }
+
+                       return {
+                               "string": useStrictEquality,
+                               "boolean": useStrictEquality,
+                               "number": useStrictEquality,
+                               "null": useStrictEquality,
+                               "undefined": useStrictEquality,
+
+                               "nan": function( b ) {
+                                       return isNaN( b );
+                               },
+
+                               "date": function( b, a ) {
+                                       return QUnit.objectType( b ) === "date" && a.valueOf() === b.valueOf();
+                               },
+
+                               "regexp": function( b, a ) {
+                                       return QUnit.objectType( b ) === "regexp" &&
+
+                                               // the regex itself
+                                               a.source === b.source &&
+
+                                               // and its modifiers
+                                               a.global === b.global &&
+
+                                               // (gmi) ...
+                                               a.ignoreCase === b.ignoreCase &&
+                                               a.multiline === b.multiline &&
+                                               a.sticky === b.sticky;
+                               },
+
+                               // - skip when the property is a method of an instance (OOP)
+                               // - abort otherwise,
+                               // initial === would have catch identical references anyway
+                               "function": function() {
+                                       var caller = callers[ callers.length - 1 ];
+                                       return caller !== Object && typeof caller !== "undefined";
+                               },
+
+                               "array": function( b, a ) {
+                                       var i, j, len, loop, aCircular, bCircular;
+
+                                       // b could be an object literal here
+                                       if ( QUnit.objectType( b ) !== "array" ) {
+                                               return false;
+                                       }
+
+                                       len = a.length;
+                                       if ( len !== b.length ) {
+                                               // safe and faster
+                                               return false;
+                                       }
+
+                                       // track reference to avoid circular references
+                                       parents.push( a );
+                                       parentsB.push( b );
+                                       for ( i = 0; i < len; i++ ) {
+                                               loop = false;
+                                               for ( j = 0; j < parents.length; j++ ) {
+                                                       aCircular = parents[ j ] === a[ i ];
+                                                       bCircular = parentsB[ j ] === b[ i ];
+                                                       if ( aCircular || bCircular ) {
+                                                               if ( a[ i ] === b[ i ] || aCircular && bCircular ) {
+                                                                       loop = true;
+                                                               } else {
+                                                                       parents.pop();
+                                                                       parentsB.pop();
+                                                                       return false;
+                                                               }
+                                                       }
+                                               }
+                                               if ( !loop && !innerEquiv( a[ i ], b[ i ] ) ) {
+                                                       parents.pop();
+                                                       parentsB.pop();
+                                                       return false;
+                                               }
+                                       }
+                                       parents.pop();
+                                       parentsB.pop();
+                                       return true;
+                               },
+
+                               "object": function( b, a ) {
+
+                                       /*jshint forin:false */
+                                       var i, j, loop, aCircular, bCircular,
+                                               // Default to true
+                                               eq = true,
+                                               aProperties = [],
+                                               bProperties = [];
+
+                                       // comparing constructors is more strict than using
+                                       // instanceof
+                                       if ( a.constructor !== b.constructor ) {
+
+                                               // Allow objects with no prototype to be equivalent to
+                                               // objects with Object as their constructor.
+                                               if ( !( ( getProto( a ) === null && getProto( b ) === Object.prototype ) ||
+                                                       ( getProto( b ) === null && getProto( a ) === Object.prototype ) ) ) {
+                                                       return false;
+                                               }
+                                       }
+
+                                       // stack constructor before traversing properties
+                                       callers.push( a.constructor );
+
+                                       // track reference to avoid circular references
+                                       parents.push( a );
+                                       parentsB.push( b );
+
+                                       // be strict: don't ensure hasOwnProperty and go deep
+                                       for ( i in a ) {
+                                               loop = false;
+                                               for ( j = 0; j < parents.length; j++ ) {
+                                                       aCircular = parents[ j ] === a[ i ];
+                                                       bCircular = parentsB[ j ] === b[ i ];
+                                                       if ( aCircular || bCircular ) {
+                                                               if ( a[ i ] === b[ i ] || aCircular && bCircular ) {
+                                                                       loop = true;
+                                                               } else {
+                                                                       eq = false;
+                                                                       break;
+                                                               }
+                                                       }
+                                               }
+                                               aProperties.push( i );
+                                               if ( !loop && !innerEquiv( a[ i ], b[ i ] ) ) {
+                                                       eq = false;
+                                                       break;
+                                               }
+                                       }
+
+                                       parents.pop();
+                                       parentsB.pop();
+                                       callers.pop(); // unstack, we are done
+
+                                       for ( i in b ) {
+                                               bProperties.push( i ); // collect b's properties
+                                       }
+
+                                       // Ensures identical properties name
+                                       return eq && innerEquiv( aProperties.sort(), bProperties.sort() );
+                               }
+                       };
+               }());
+
+       innerEquiv = function() { // can take multiple arguments
+               var args = [].slice.apply( arguments );
+               if ( args.length < 2 ) {
+                       return true; // end transition
+               }
+
+               return ( (function( a, b ) {
+                       if ( a === b ) {
+                               return true; // catch the most you can
+                       } else if ( a === null || b === null || typeof a === "undefined" ||
+                                       typeof b === "undefined" ||
+                                       QUnit.objectType( a ) !== QUnit.objectType( b ) ) {
+
+                               // don't lose time with error prone cases
+                               return false;
+                       } else {
+                               return bindCallbacks( a, callbacks, [ b, a ] );
+                       }
+
+                       // apply transition with (1..n) arguments
+               }( args[ 0 ], args[ 1 ] ) ) &&
+                       innerEquiv.apply( this, args.splice( 1, args.length - 1 ) ) );
+       };
+
+       return innerEquiv;
+}());
+
+// Based on jsDump by Ariel Flesler
+// http://flesler.blogspot.com/2008/05/jsdump-pretty-dump-of-any-javascript.html
+QUnit.dump = (function() {
+       function quote( str ) {
+               return "\"" + str.toString().replace( /"/g, "\\\"" ) + "\"";
+       }
+       function literal( o ) {
+               return o + "";
+       }
+       function join( pre, arr, post ) {
+               var s = dump.separator(),
+                       base = dump.indent(),
+                       inner = dump.indent( 1 );
+               if ( arr.join ) {
+                       arr = arr.join( "," + s + inner );
+               }
+               if ( !arr ) {
+                       return pre + post;
+               }
+               return [ pre, inner + arr, base + post ].join( s );
+       }
+       function array( arr, stack ) {
+               var i = arr.length,
+                       ret = new Array( i );
+
+               if ( dump.maxDepth && dump.depth > dump.maxDepth ) {
+                       return "[object Array]";
+               }
+
+               this.up();
+               while ( i-- ) {
+                       ret[ i ] = this.parse( arr[ i ], undefined, stack );
+               }
+               this.down();
+               return join( "[", ret, "]" );
+       }
+
+       var reName = /^function (\w+)/,
+               dump = {
+
+                       // objType is used mostly internally, you can fix a (custom) type in advance
+                       parse: function( obj, objType, stack ) {
+                               stack = stack || [];
+                               var res, parser, parserType,
+                                       inStack = inArray( obj, stack );
+
+                               if ( inStack !== -1 ) {
+                                       return "recursion(" + ( inStack - stack.length ) + ")";
+                               }
+
+                               objType = objType || this.typeOf( obj  );
+                               parser = this.parsers[ objType ];
+                               parserType = typeof parser;
+
+                               if ( parserType === "function" ) {
+                                       stack.push( obj );
+                                       res = parser.call( this, obj, stack );
+                                       stack.pop();
+                                       return res;
+                               }
+                               return ( parserType === "string" ) ? parser : this.parsers.error;
+                       },
+                       typeOf: function( obj ) {
+                               var type;
+                               if ( obj === null ) {
+                                       type = "null";
+                               } else if ( typeof obj === "undefined" ) {
+                                       type = "undefined";
+                               } else if ( QUnit.is( "regexp", obj ) ) {
+                                       type = "regexp";
+                               } else if ( QUnit.is( "date", obj ) ) {
+                                       type = "date";
+                               } else if ( QUnit.is( "function", obj ) ) {
+                                       type = "function";
+                               } else if ( obj.setInterval !== undefined &&
+                                               obj.document !== undefined &&
+                                               obj.nodeType === undefined ) {
+                                       type = "window";
+                               } else if ( obj.nodeType === 9 ) {
+                                       type = "document";
+                               } else if ( obj.nodeType ) {
+                                       type = "node";
+                               } else if (
+
+                                       // native arrays
+                                       toString.call( obj ) === "[object Array]" ||
+
+                                       // NodeList objects
+                                       ( typeof obj.length === "number" && obj.item !== undefined &&
+                                       ( obj.length ? obj.item( 0 ) === obj[ 0 ] : ( obj.item( 0 ) === null &&
+                                       obj[ 0 ] === undefined ) ) )
+                               ) {
+                                       type = "array";
+                               } else if ( obj.constructor === Error.prototype.constructor ) {
+                                       type = "error";
+                               } else {
+                                       type = typeof obj;
+                               }
+                               return type;
+                       },
+                       separator: function() {
+                               return this.multiline ? this.HTML ? "<br />" : "\n" : this.HTML ? "&#160;" : " ";
+                       },
+                       // extra can be a number, shortcut for increasing-calling-decreasing
+                       indent: function( extra ) {
+                               if ( !this.multiline ) {
+                                       return "";
+                               }
+                               var chr = this.indentChar;
+                               if ( this.HTML ) {
+                                       chr = chr.replace( /\t/g, "   " ).replace( / /g, "&#160;" );
+                               }
+                               return new Array( this.depth + ( extra || 0 ) ).join( chr );
+                       },
+                       up: function( a ) {
+                               this.depth += a || 1;
+                       },
+                       down: function( a ) {
+                               this.depth -= a || 1;
+                       },
+                       setParser: function( name, parser ) {
+                               this.parsers[ name ] = parser;
+                       },
+                       // The next 3 are exposed so you can use them
+                       quote: quote,
+                       literal: literal,
+                       join: join,
+                       //
+                       depth: 1,
+                       maxDepth: 5,
+
+                       // This is the list of parsers, to modify them, use dump.setParser
+                       parsers: {
+                               window: "[Window]",
+                               document: "[Document]",
+                               error: function( error ) {
+                                       return "Error(\"" + error.message + "\")";
+                               },
+                               unknown: "[Unknown]",
+                               "null": "null",
+                               "undefined": "undefined",
+                               "function": function( fn ) {
+                                       var ret = "function",
+
+                                               // functions never have name in IE
+                                               name = "name" in fn ? fn.name : ( reName.exec( fn ) || [] )[ 1 ];
+
+                                       if ( name ) {
+                                               ret += " " + name;
+                                       }
+                                       ret += "( ";
+
+                                       ret = [ ret, dump.parse( fn, "functionArgs" ), "){" ].join( "" );
+                                       return join( ret, dump.parse( fn, "functionCode" ), "}" );
+                               },
+                               array: array,
+                               nodelist: array,
+                               "arguments": array,
+                               object: function( map, stack ) {
+                                       var keys, key, val, i, nonEnumerableProperties,
+                                               ret = [];
+
+                                       if ( dump.maxDepth && dump.depth > dump.maxDepth ) {
+                                               return "[object Object]";
+                                       }
+
+                                       dump.up();
+                                       keys = [];
+                                       for ( key in map ) {
+                                               keys.push( key );
+                                       }
+
+                                       // Some properties are not always enumerable on Error objects.
+                                       nonEnumerableProperties = [ "message", "name" ];
+                                       for ( i in nonEnumerableProperties ) {
+                                               key = nonEnumerableProperties[ i ];
+                                               if ( key in map && !( key in keys ) ) {
+                                                       keys.push( key );
+                                               }
+                                       }
+                                       keys.sort();
+                                       for ( i = 0; i < keys.length; i++ ) {
+                                               key = keys[ i ];
+                                               val = map[ key ];
+                                               ret.push( dump.parse( key, "key" ) + ": " +
+                                                       dump.parse( val, undefined, stack ) );
+                                       }
+                                       dump.down();
+                                       return join( "{", ret, "}" );
+                               },
+                               node: function( node ) {
+                                       var len, i, val,
+                                               open = dump.HTML ? "&lt;" : "<",
+                                               close = dump.HTML ? "&gt;" : ">",
+                                               tag = node.nodeName.toLowerCase(),
+                                               ret = open + tag,
+                                               attrs = node.attributes;
+
+                                       if ( attrs ) {
+                                               for ( i = 0, len = attrs.length; i < len; i++ ) {
+                                                       val = attrs[ i ].nodeValue;
+
+                                                       // IE6 includes all attributes in .attributes, even ones not explicitly
+                                                       // set. Those have values like undefined, null, 0, false, "" or
+                                                       // "inherit".
+                                                       if ( val && val !== "inherit" ) {
+                                                               ret += " " + attrs[ i ].nodeName + "=" +
+                                                                       dump.parse( val, "attribute" );
+                                                       }
+                                               }
+                                       }
+                                       ret += close;
+
+                                       // Show content of TextNode or CDATASection
+                                       if ( node.nodeType === 3 || node.nodeType === 4 ) {
+                                               ret += node.nodeValue;
+                                       }
+
+                                       return ret + open + "/" + tag + close;
+                               },
+
+                               // function calls it internally, it's the arguments part of the function
+                               functionArgs: function( fn ) {
+                                       var args,
+                                               l = fn.length;
+
+                                       if ( !l ) {
+                                               return "";
+                                       }
+
+                                       args = new Array( l );
+                                       while ( l-- ) {
+
+                                               // 97 is 'a'
+                                               args[ l ] = String.fromCharCode( 97 + l );
+                                       }
+                                       return " " + args.join( ", " ) + " ";
+                               },
+                               // object calls it internally, the key part of an item in a map
+                               key: quote,
+                               // function calls it internally, it's the content of the function
+                               functionCode: "[code]",
+                               // node calls it internally, it's an html attribute value
+                               attribute: quote,
+                               string: quote,
+                               date: quote,
+                               regexp: literal,
+                               number: literal,
+                               "boolean": literal
+                       },
+                       // if true, entities are escaped ( <, >, \t, space and \n )
+                       HTML: false,
+                       // indentation unit
+                       indentChar: "  ",
+                       // if true, items in a collection, are separated by a \n, else just a space.
+                       multiline: true
+               };
+
+       return dump;
+}());
+
+// back compat
+QUnit.jsDump = QUnit.dump;
+
+// For browser, export only select globals
+if ( typeof window !== "undefined" ) {
+
+       // Deprecated
+       // Extend assert methods to QUnit and Global scope through Backwards compatibility
+       (function() {
+               var i,
+                       assertions = Assert.prototype;
+
+               function applyCurrent( current ) {
+                       return function() {
+                               var assert = new Assert( QUnit.config.current );
+                               current.apply( assert, arguments );
+                       };
+               }
+
+               for ( i in assertions ) {
+                       QUnit[ i ] = applyCurrent( assertions[ i ] );
+               }
+       })();
+
+       (function() {
+               var i, l,
+                       keys = [
+                               "test",
+                               "module",
+                               "expect",
+                               "asyncTest",
+                               "start",
+                               "stop",
+                               "ok",
+                               "equal",
+                               "notEqual",
+                               "propEqual",
+                               "notPropEqual",
+                               "deepEqual",
+                               "notDeepEqual",
+                               "strictEqual",
+                               "notStrictEqual",
+                               "throws"
+                       ];
+
+               for ( i = 0, l = keys.length; i < l; i++ ) {
+                       window[ keys[ i ] ] = QUnit[ keys[ i ] ];
+               }
+       })();
+
+       window.QUnit = QUnit;
+}
+
+// For nodejs
+if ( typeof module !== "undefined" && module && module.exports ) {
+       module.exports = QUnit;
+
+       // For consistency with CommonJS environments' exports
+       module.exports.QUnit = QUnit;
+}
+
+// For CommonJS with exports, but without module.exports, like Rhino
+if ( typeof exports !== "undefined" && exports ) {
+       exports.QUnit = QUnit;
+}
+
+// Get a reference to the global object, like window in browsers
+}( (function() {
+       return this;
+})() ));
+
+/*istanbul ignore next */
+// jscs:disable maximumLineLength
+/*
+ * Javascript Diff Algorithm
+ *  By John Resig (http://ejohn.org/)
+ *  Modified by Chu Alan "sprite"
+ *
+ * Released under the MIT license.
+ *
+ * More Info:
+ *  http://ejohn.org/projects/javascript-diff-algorithm/
+ *
+ * Usage: QUnit.diff(expected, actual)
+ *
+ * QUnit.diff( "the quick brown fox jumped over", "the quick fox jumps over" ) == "the  quick <del>brown </del> fox <del>jumped </del><ins>jumps </ins> over"
+ */
+QUnit.diff = (function() {
+       var hasOwn = Object.prototype.hasOwnProperty;
+
+       /*jshint eqeqeq:false, eqnull:true */
+       function diff( o, n ) {
+               var i,
+                       ns = {},
+                       os = {};
+
+               for ( i = 0; i < n.length; i++ ) {
+                       if ( !hasOwn.call( ns, n[ i ] ) ) {
+                               ns[ n[ i ] ] = {
+                                       rows: [],
+                                       o: null
+                               };
+                       }
+                       ns[ n[ i ] ].rows.push( i );
+               }
+
+               for ( i = 0; i < o.length; i++ ) {
+                       if ( !hasOwn.call( os, o[ i ] ) ) {
+                               os[ o[ i ] ] = {
+                                       rows: [],
+                                       n: null
+                               };
+                       }
+                       os[ o[ i ] ].rows.push( i );
+               }
+
+               for ( i in ns ) {
+                       if ( hasOwn.call( ns, i ) ) {
+                               if ( ns[ i ].rows.length === 1 && hasOwn.call( os, i ) && os[ i ].rows.length === 1 ) {
+                                       n[ ns[ i ].rows[ 0 ] ] = {
+                                               text: n[ ns[ i ].rows[ 0 ] ],
+                                               row: os[ i ].rows[ 0 ]
+                                       };
+                                       o[ os[ i ].rows[ 0 ] ] = {
+                                               text: o[ os[ i ].rows[ 0 ] ],
+                                               row: ns[ i ].rows[ 0 ]
+                                       };
+                               }
+                       }
+               }
+
+               for ( i = 0; i < n.length - 1; i++ ) {
+                       if ( n[ i ].text != null && n[ i + 1 ].text == null && n[ i ].row + 1 < o.length && o[ n[ i ].row + 1 ].text == null &&
+                               n[ i + 1 ] == o[ n[ i ].row + 1 ] ) {
+
+                               n[ i + 1 ] = {
+                                       text: n[ i + 1 ],
+                                       row: n[ i ].row + 1
+                               };
+                               o[ n[ i ].row + 1 ] = {
+                                       text: o[ n[ i ].row + 1 ],
+                                       row: i + 1
+                               };
+                       }
+               }
+
+               for ( i = n.length - 1; i > 0; i-- ) {
+                       if ( n[ i ].text != null && n[ i - 1 ].text == null && n[ i ].row > 0 && o[ n[ i ].row - 1 ].text == null &&
+                               n[ i - 1 ] == o[ n[ i ].row - 1 ] ) {
+
+                               n[ i - 1 ] = {
+                                       text: n[ i - 1 ],
+                                       row: n[ i ].row - 1
+                               };
+                               o[ n[ i ].row - 1 ] = {
+                                       text: o[ n[ i ].row - 1 ],
+                                       row: i - 1
+                               };
+                       }
+               }
+
+               return {
+                       o: o,
+                       n: n
+               };
+       }
+
+       return function( o, n ) {
+               o = o.replace( /\s+$/, "" );
+               n = n.replace( /\s+$/, "" );
+
+               var i, pre,
+                       str = "",
+                       out = diff( o === "" ? [] : o.split( /\s+/ ), n === "" ? [] : n.split( /\s+/ ) ),
+                       oSpace = o.match( /\s+/g ),
+                       nSpace = n.match( /\s+/g );
+
+               if ( oSpace == null ) {
+                       oSpace = [ " " ];
+               } else {
+                       oSpace.push( " " );
+               }
+
+               if ( nSpace == null ) {
+                       nSpace = [ " " ];
+               } else {
+                       nSpace.push( " " );
+               }
+
+               if ( out.n.length === 0 ) {
+                       for ( i = 0; i < out.o.length; i++ ) {
+                               str += "<del>" + out.o[ i ] + oSpace[ i ] + "</del>";
+                       }
+               } else {
+                       if ( out.n[ 0 ].text == null ) {
+                               for ( n = 0; n < out.o.length && out.o[ n ].text == null; n++ ) {
+                                       str += "<del>" + out.o[ n ] + oSpace[ n ] + "</del>";
+                               }
+                       }
+
+                       for ( i = 0; i < out.n.length; i++ ) {
+                               if ( out.n[ i ].text == null ) {
+                                       str += "<ins>" + out.n[ i ] + nSpace[ i ] + "</ins>";
+                               } else {
+
+                                       // `pre` initialized at top of scope
+                                       pre = "";
+
+                                       for ( n = out.n[ i ].row + 1; n < out.o.length && out.o[ n ].text == null; n++ ) {
+                                               pre += "<del>" + out.o[ n ] + oSpace[ n ] + "</del>";
+                                       }
+                                       str += " " + out.n[ i ].text + nSpace[ i ] + pre;
+                               }
+                       }
+               }
+
+               return str;
+       };
+}());
+// jscs:enable
+
+(function() {
+
+// Deprecated QUnit.init - Ref #530
+// Re-initialize the configuration options
+QUnit.init = function() {
+       var tests, banner, result, qunit,
+               config = QUnit.config;
+
+       config.stats = { all: 0, bad: 0 };
+       config.moduleStats = { all: 0, bad: 0 };
+       config.started = 0;
+       config.updateRate = 1000;
+       config.blocking = false;
+       config.autostart = true;
+       config.autorun = false;
+       config.filter = "";
+       config.queue = [];
+
+       // Return on non-browser environments
+       // This is necessary to not break on node tests
+       if ( typeof window === "undefined" ) {
+               return;
+       }
+
+       qunit = id( "qunit" );
+       if ( qunit ) {
+               qunit.innerHTML =
+                       "<h1 id='qunit-header'>" + escapeText( document.title ) + "</h1>" +
+                       "<h2 id='qunit-banner'></h2>" +
+                       "<div id='qunit-testrunner-toolbar'></div>" +
+                       "<h2 id='qunit-userAgent'></h2>" +
+                       "<ol id='qunit-tests'></ol>";
+       }
+
+       tests = id( "qunit-tests" );
+       banner = id( "qunit-banner" );
+       result = id( "qunit-testresult" );
+
+       if ( tests ) {
+               tests.innerHTML = "";
+       }
+
+       if ( banner ) {
+               banner.className = "";
+       }
+
+       if ( result ) {
+               result.parentNode.removeChild( result );
+       }
+
+       if ( tests ) {
+               result = document.createElement( "p" );
+               result.id = "qunit-testresult";
+               result.className = "result";
+               tests.parentNode.insertBefore( result, tests );
+               result.innerHTML = "Running...<br />&#160;";
+       }
+};
+
+// Don't load the HTML Reporter on non-Browser environments
+if ( typeof window === "undefined" ) {
+       return;
+}
+
+var config = QUnit.config,
+       hasOwn = Object.prototype.hasOwnProperty,
+       defined = {
+               document: window.document !== undefined,
+               sessionStorage: (function() {
+                       var x = "qunit-test-string";
+                       try {
+                               sessionStorage.setItem( x, x );
+                               sessionStorage.removeItem( x );
+                               return true;
+                       } catch ( e ) {
+                               return false;
+                       }
+               }())
+       },
+       modulesList = [];
+
+/**
+* Escape text for attribute or text content.
+*/
+function escapeText( s ) {
+       if ( !s ) {
+               return "";
+       }
+       s = s + "";
+
+       // Both single quotes and double quotes (for attributes)
+       return s.replace( /['"<>&]/g, function( s ) {
+               switch ( s ) {
+               case "'":
+                       return "&#039;";
+               case "\"":
+                       return "&quot;";
+               case "<":
+                       return "&lt;";
+               case ">":
+                       return "&gt;";
+               case "&":
+                       return "&amp;";
+               }
+       });
+}
+
+/**
+ * @param {HTMLElement} elem
+ * @param {string} type
+ * @param {Function} fn
+ */
+function addEvent( elem, type, fn ) {
+       if ( elem.addEventListener ) {
+
+               // Standards-based browsers
+               elem.addEventListener( type, fn, false );
+       } else if ( elem.attachEvent ) {
+
+               // support: IE <9
+               elem.attachEvent( "on" + type, fn );
+       }
+}
+
+/**
+ * @param {Array|NodeList} elems
+ * @param {string} type
+ * @param {Function} fn
+ */
+function addEvents( elems, type, fn ) {
+       var i = elems.length;
+       while ( i-- ) {
+               addEvent( elems[ i ], type, fn );
+       }
+}
+
+function hasClass( elem, name ) {
+       return ( " " + elem.className + " " ).indexOf( " " + name + " " ) >= 0;
+}
+
+function addClass( elem, name ) {
+       if ( !hasClass( elem, name ) ) {
+               elem.className += ( elem.className ? " " : "" ) + name;
+       }
+}
+
+function toggleClass( elem, name ) {
+       if ( hasClass( elem, name ) ) {
+               removeClass( elem, name );
+       } else {
+               addClass( elem, name );
+       }
+}
+
+function removeClass( elem, name ) {
+       var set = " " + elem.className + " ";
+
+       // Class name may appear multiple times
+       while ( set.indexOf( " " + name + " " ) >= 0 ) {
+               set = set.replace( " " + name + " ", " " );
+       }
+
+       // trim for prettiness
+       elem.className = typeof set.trim === "function" ? set.trim() : set.replace( /^\s+|\s+$/g, "" );
+}
+
+function id( name ) {
+       return defined.document && document.getElementById && document.getElementById( name );
+}
+
+function getUrlConfigHtml() {
+       var i, j, val,
+               escaped, escapedTooltip,
+               selection = false,
+               len = config.urlConfig.length,
+               urlConfigHtml = "";
+
+       for ( i = 0; i < len; i++ ) {
+               val = config.urlConfig[ i ];
+               if ( typeof val === "string" ) {
+                       val = {
+                               id: val,
+                               label: val
+                       };
+               }
+
+               escaped = escapeText( val.id );
+               escapedTooltip = escapeText( val.tooltip );
+
+               if ( config[ val.id ] === undefined ) {
+                       config[ val.id ] = QUnit.urlParams[ val.id ];
+               }
+
+               if ( !val.value || typeof val.value === "string" ) {
+                       urlConfigHtml += "<input id='qunit-urlconfig-" + escaped +
+                               "' name='" + escaped + "' type='checkbox'" +
+                               ( val.value ? " value='" + escapeText( val.value ) + "'" : "" ) +
+                               ( config[ val.id ] ? " checked='checked'" : "" ) +
+                               " title='" + escapedTooltip + "' /><label for='qunit-urlconfig-" + escaped +
+                               "' title='" + escapedTooltip + "'>" + val.label + "</label>";
+               } else {
+                       urlConfigHtml += "<label for='qunit-urlconfig-" + escaped +
+                               "' title='" + escapedTooltip + "'>" + val.label +
+                               ": </label><select id='qunit-urlconfig-" + escaped +
+                               "' name='" + escaped + "' title='" + escapedTooltip + "'><option></option>";
+
+                       if ( QUnit.is( "array", val.value ) ) {
+                               for ( j = 0; j < val.value.length; j++ ) {
+                                       escaped = escapeText( val.value[ j ] );
+                                       urlConfigHtml += "<option value='" + escaped + "'" +
+                                               ( config[ val.id ] === val.value[ j ] ?
+                                                       ( selection = true ) && " selected='selected'" : "" ) +
+                                               ">" + escaped + "</option>";
+                               }
+                       } else {
+                               for ( j in val.value ) {
+                                       if ( hasOwn.call( val.value, j ) ) {
+                                               urlConfigHtml += "<option value='" + escapeText( j ) + "'" +
+                                                       ( config[ val.id ] === j ?
+                                                               ( selection = true ) && " selected='selected'" : "" ) +
+                                                       ">" + escapeText( val.value[ j ] ) + "</option>";
+                                       }
+                               }
+                       }
+                       if ( config[ val.id ] && !selection ) {
+                               escaped = escapeText( config[ val.id ] );
+                               urlConfigHtml += "<option value='" + escaped +
+                                       "' selected='selected' disabled='disabled'>" + escaped + "</option>";
+                       }
+                       urlConfigHtml += "</select>";
+               }
+       }
+
+       return urlConfigHtml;
+}
+
+// Handle "click" events on toolbar checkboxes and "change" for select menus.
+// Updates the URL with the new state of `config.urlConfig` values.
+function toolbarChanged() {
+       var updatedUrl, value,
+               field = this,
+               params = {};
+
+       // Detect if field is a select menu or a checkbox
+       if ( "selectedIndex" in field ) {
+               value = field.options[ field.selectedIndex ].value || undefined;
+       } else {
+               value = field.checked ? ( field.defaultValue || true ) : undefined;
+       }
+
+       params[ field.name ] = value;
+       updatedUrl = setUrl( params );
+
+       if ( "hidepassed" === field.name && "replaceState" in window.history ) {
+               config[ field.name ] = value || false;
+               if ( value ) {
+                       addClass( id( "qunit-tests" ), "hidepass" );
+               } else {
+                       removeClass( id( "qunit-tests" ), "hidepass" );
+               }
+
+               // It is not necessary to refresh the whole page
+               window.history.replaceState( null, "", updatedUrl );
+       } else {
+               window.location = updatedUrl;
+       }
+}
+
+function setUrl( params ) {
+       var key,
+               querystring = "?";
+
+       params = QUnit.extend( QUnit.extend( {}, QUnit.urlParams ), params );
+
+       for ( key in params ) {
+               if ( hasOwn.call( params, key ) ) {
+                       if ( params[ key ] === undefined ) {
+                               continue;
+                       }
+                       querystring += encodeURIComponent( key );
+                       if ( params[ key ] !== true ) {
+                               querystring += "=" + encodeURIComponent( params[ key ] );
+                       }
+                       querystring += "&";
+               }
+       }
+       return location.protocol + "//" + location.host +
+               location.pathname + querystring.slice( 0, -1 );
+}
+
+function applyUrlParams() {
+       var selectBox = id( "qunit-modulefilter" ),
+               selection = decodeURIComponent( selectBox.options[ selectBox.selectedIndex ].value ),
+               filter = id( "qunit-filter-input" ).value;
+
+       window.location = setUrl({
+               module: ( selection === "" ) ? undefined : selection,
+               filter: ( filter === "" ) ? undefined : filter,
+
+               // Remove testId filter
+               testId: undefined
+       });
+}
+
+function toolbarUrlConfigContainer() {
+       var urlConfigContainer = document.createElement( "span" );
+
+       urlConfigContainer.innerHTML = getUrlConfigHtml();
+       addClass( urlConfigContainer, "qunit-url-config" );
+
+       // For oldIE support:
+       // * Add handlers to the individual elements instead of the container
+       // * Use "click" instead of "change" for checkboxes
+       addEvents( urlConfigContainer.getElementsByTagName( "input" ), "click", toolbarChanged );
+       addEvents( urlConfigContainer.getElementsByTagName( "select" ), "change", toolbarChanged );
+
+       return urlConfigContainer;
+}
+
+function toolbarLooseFilter() {
+       var filter = document.createElement( "form" ),
+               label = document.createElement( "label" ),
+               input = document.createElement( "input" ),
+               button = document.createElement( "button" );
+
+       addClass( filter, "qunit-filter" );
+
+       label.innerHTML = "Filter: ";
+
+       input.type = "text";
+       input.value = config.filter || "";
+       input.name = "filter";
+       input.id = "qunit-filter-input";
+
+       button.innerHTML = "Go";
+
+       label.appendChild( input );
+
+       filter.appendChild( label );
+       filter.appendChild( button );
+       addEvent( filter, "submit", function( ev ) {
+               applyUrlParams();
+
+               if ( ev && ev.preventDefault ) {
+                       ev.preventDefault();
+               }
+
+               return false;
+       });
+
+       return filter;
+}
+
+function toolbarModuleFilterHtml() {
+       var i,
+               moduleFilterHtml = "";
+
+       if ( !modulesList.length ) {
+               return false;
+       }
+
+       modulesList.sort(function( a, b ) {
+               return a.localeCompare( b );
+       });
+
+       moduleFilterHtml += "<label for='qunit-modulefilter'>Module: </label>" +
+               "<select id='qunit-modulefilter' name='modulefilter'><option value='' " +
+               ( QUnit.urlParams.module === undefined ? "selected='selected'" : "" ) +
+               ">< All Modules ></option>";
+
+       for ( i = 0; i < modulesList.length; i++ ) {
+               moduleFilterHtml += "<option value='" +
+                       escapeText( encodeURIComponent( modulesList[ i ] ) ) + "' " +
+                       ( QUnit.urlParams.module === modulesList[ i ] ? "selected='selected'" : "" ) +
+                       ">" + escapeText( modulesList[ i ] ) + "</option>";
+       }
+       moduleFilterHtml += "</select>";
+
+       return moduleFilterHtml;
+}
+
+function toolbarModuleFilter() {
+       var toolbar = id( "qunit-testrunner-toolbar" ),
+               moduleFilter = document.createElement( "span" ),
+               moduleFilterHtml = toolbarModuleFilterHtml();
+
+       if ( !toolbar || !moduleFilterHtml ) {
+               return false;
+       }
+
+       moduleFilter.setAttribute( "id", "qunit-modulefilter-container" );
+       moduleFilter.innerHTML = moduleFilterHtml;
+
+       addEvent( moduleFilter.lastChild, "change", applyUrlParams );
+
+       toolbar.appendChild( moduleFilter );
+}
+
+function appendToolbar() {
+       var toolbar = id( "qunit-testrunner-toolbar" );
+
+       if ( toolbar ) {
+               toolbar.appendChild( toolbarUrlConfigContainer() );
+               toolbar.appendChild( toolbarLooseFilter() );
+       }
+}
+
+function appendHeader() {
+       var header = id( "qunit-header" );
+
+       if ( header ) {
+               header.innerHTML = "<a href='" +
+                       setUrl({ filter: undefined, module: undefined, testId: undefined }) +
+                       "'>" + header.innerHTML + "</a> ";
+       }
+}
+
+function appendBanner() {
+       var banner = id( "qunit-banner" );
+
+       if ( banner ) {
+               banner.className = "";
+       }
+}
+
+function appendTestResults() {
+       var tests = id( "qunit-tests" ),
+               result = id( "qunit-testresult" );
+
+       if ( result ) {
+               result.parentNode.removeChild( result );
+       }
+
+       if ( tests ) {
+               tests.innerHTML = "";
+               result = document.createElement( "p" );
+               result.id = "qunit-testresult";
+               result.className = "result";
+               tests.parentNode.insertBefore( result, tests );
+               result.innerHTML = "Running...<br />&#160;";
+       }
+}
+
+function storeFixture() {
+       var fixture = id( "qunit-fixture" );
+       if ( fixture ) {
+               config.fixture = fixture.innerHTML;
+       }
+}
+
+function appendUserAgent() {
+       var userAgent = id( "qunit-userAgent" );
+       if ( userAgent ) {
+               userAgent.innerHTML = "";
+               userAgent.appendChild( document.createTextNode( navigator.userAgent ) );
+       }
+}
+
+function appendTestsList( modules ) {
+       var i, l, x, z, test, moduleObj;
+
+       for ( i = 0, l = modules.length; i < l; i++ ) {
+               moduleObj = modules[ i ];
+
+               if ( moduleObj.name ) {
+                       modulesList.push( moduleObj.name );
+               }
+
+               for ( x = 0, z = moduleObj.tests.length; x < z; x++ ) {
+                       test = moduleObj.tests[ x ];
+
+                       appendTest( test.name, test.testId, moduleObj.name );
+               }
+       }
+}
+
+function appendTest( name, testId, moduleName ) {
+       var title, rerunTrigger, testBlock, assertList,
+               tests = id( "qunit-tests" );
+
+       if ( !tests ) {
+               return;
+       }
+
+       title = document.createElement( "strong" );
+       title.innerHTML = getNameHtml( name, moduleName );
+
+       rerunTrigger = document.createElement( "a" );
+       rerunTrigger.innerHTML = "Rerun";
+       rerunTrigger.href = setUrl({ testId: testId });
+
+       testBlock = document.createElement( "li" );
+       testBlock.appendChild( title );
+       testBlock.appendChild( rerunTrigger );
+       testBlock.id = "qunit-test-output-" + testId;
+
+       assertList = document.createElement( "ol" );
+       assertList.className = "qunit-assert-list";
+
+       testBlock.appendChild( assertList );
+
+       tests.appendChild( testBlock );
+}
+
+// HTML Reporter initialization and load
+QUnit.begin(function( details ) {
+       var qunit = id( "qunit" );
+
+       // Fixture is the only one necessary to run without the #qunit element
+       storeFixture();
+
+       if ( qunit ) {
+               qunit.innerHTML =
+                       "<h1 id='qunit-header'>" + escapeText( document.title ) + "</h1>" +
+                       "<h2 id='qunit-banner'></h2>" +
+                       "<div id='qunit-testrunner-toolbar'></div>" +
+                       "<h2 id='qunit-userAgent'></h2>" +
+                       "<ol id='qunit-tests'></ol>";
+       }
+
+       appendHeader();
+       appendBanner();
+       appendTestResults();
+       appendUserAgent();
+       appendToolbar();
+       appendTestsList( details.modules );
+       toolbarModuleFilter();
+
+       if ( qunit && config.hidepassed ) {
+               addClass( qunit.lastChild, "hidepass" );
+       }
+});
+
+QUnit.done(function( details ) {
+       var i, key,
+               banner = id( "qunit-banner" ),
+               tests = id( "qunit-tests" ),
+               html = [
+                       "Tests completed in ",
+                       details.runtime,
+                       " milliseconds.<br />",
+                       "<span class='passed'>",
+                       details.passed,
+                       "</span> assertions of <span class='total'>",
+                       details.total,
+                       "</span> passed, <span class='failed'>",
+                       details.failed,
+                       "</span> failed."
+               ].join( "" );
+
+       if ( banner ) {
+               banner.className = details.failed ? "qunit-fail" : "qunit-pass";
+       }
+
+       if ( tests ) {
+               id( "qunit-testresult" ).innerHTML = html;
+       }
+
+       if ( config.altertitle && defined.document && document.title ) {
+
+               // show ✖ for good, ✔ for bad suite result in title
+               // use escape sequences in case file gets loaded with non-utf-8-charset
+               document.title = [
+                       ( details.failed ? "\u2716" : "\u2714" ),
+                       document.title.replace( /^[\u2714\u2716] /i, "" )
+               ].join( " " );
+       }
+
+       // clear own sessionStorage items if all tests passed
+       if ( config.reorder && defined.sessionStorage && details.failed === 0 ) {
+               for ( i = 0; i < sessionStorage.length; i++ ) {
+                       key = sessionStorage.key( i++ );
+                       if ( key.indexOf( "qunit-test-" ) === 0 ) {
+                               sessionStorage.removeItem( key );
+                       }
+               }
+       }
+
+       // scroll back to top to show results
+       if ( config.scrolltop && window.scrollTo ) {
+               window.scrollTo( 0, 0 );
+       }
+});
+
+function getNameHtml( name, module ) {
+       var nameHtml = "";
+
+       if ( module ) {
+               nameHtml = "<span class='module-name'>" + escapeText( module ) + "</span>: ";
+       }
+
+       nameHtml += "<span class='test-name'>" + escapeText( name ) + "</span>";
+
+       return nameHtml;
+}
+
+QUnit.testStart(function( details ) {
+       var running, testBlock;
+
+       testBlock = id( "qunit-test-output-" + details.testId );
+       if ( testBlock ) {
+               testBlock.className = "running";
+       } else {
+
+               // Report later registered tests
+               appendTest( details.name, details.testId, details.module );
+       }
+
+       running = id( "qunit-testresult" );
+       if ( running ) {
+               running.innerHTML = "Running: <br />" + getNameHtml( details.name, details.module );
+       }
+
+});
+
+QUnit.log(function( details ) {
+       var assertList, assertLi,
+               message, expected, actual,
+               testItem = id( "qunit-test-output-" + details.testId );
+
+       if ( !testItem ) {
+               return;
+       }
+
+       message = escapeText( details.message ) || ( details.result ? "okay" : "failed" );
+       message = "<span class='test-message'>" + message + "</span>";
+       message += "<span class='runtime'>@ " + details.runtime + " ms</span>";
+
+       // pushFailure doesn't provide details.expected
+       // when it calls, it's implicit to also not show expected and diff stuff
+       // Also, we need to check details.expected existence, as it can exist and be undefined
+       if ( !details.result && hasOwn.call( details, "expected" ) ) {
+               expected = escapeText( QUnit.dump.parse( details.expected ) );
+               actual = escapeText( QUnit.dump.parse( details.actual ) );
+               message += "<table><tr class='test-expected'><th>Expected: </th><td><pre>" +
+                       expected +
+                       "</pre></td></tr>";
+
+               if ( actual !== expected ) {
+                       message += "<tr class='test-actual'><th>Result: </th><td><pre>" +
+                               actual + "</pre></td></tr>" +
+                               "<tr class='test-diff'><th>Diff: </th><td><pre>" +
+                               QUnit.diff( expected, actual ) + "</pre></td></tr>";
+               }
+
+               if ( details.source ) {
+                       message += "<tr class='test-source'><th>Source: </th><td><pre>" +
+                               escapeText( details.source ) + "</pre></td></tr>";
+               }
+
+               message += "</table>";
+
+       // this occours when pushFailure is set and we have an extracted stack trace
+       } else if ( !details.result && details.source ) {
+               message += "<table>" +
+                       "<tr class='test-source'><th>Source: </th><td><pre>" +
+                       escapeText( details.source ) + "</pre></td></tr>" +
+                       "</table>";
+       }
+
+       assertList = testItem.getElementsByTagName( "ol" )[ 0 ];
+
+       assertLi = document.createElement( "li" );
+       assertLi.className = details.result ? "pass" : "fail";
+       assertLi.innerHTML = message;
+       assertList.appendChild( assertLi );
+});
+
+QUnit.testDone(function( details ) {
+       var testTitle, time, testItem, assertList,
+               good, bad, testCounts, skipped,
+               tests = id( "qunit-tests" );
+
+       if ( !tests ) {
+               return;
+       }
+
+       testItem = id( "qunit-test-output-" + details.testId );
+
+       assertList = testItem.getElementsByTagName( "ol" )[ 0 ];
+
+       good = details.passed;
+       bad = details.failed;
+
+       // store result when possible
+       if ( config.reorder && defined.sessionStorage ) {
+               if ( bad ) {
+                       sessionStorage.setItem( "qunit-test-" + details.module + "-" + details.name, bad );
+               } else {
+                       sessionStorage.removeItem( "qunit-test-" + details.module + "-" + details.name );
+               }
+       }
+
+       if ( bad === 0 ) {
+               addClass( assertList, "qunit-collapsed" );
+       }
+
+       // testItem.firstChild is the test name
+       testTitle = testItem.firstChild;
+
+       testCounts = bad ?
+               "<b class='failed'>" + bad + "</b>, " + "<b class='passed'>" + good + "</b>, " :
+               "";
+
+       testTitle.innerHTML += " <b class='counts'>(" + testCounts +
+               details.assertions.length + ")</b>";
+
+       if ( details.skipped ) {
+               testItem.className = "skipped";
+               skipped = document.createElement( "em" );
+               skipped.className = "qunit-skipped-label";
+               skipped.innerHTML = "skipped";
+               testItem.insertBefore( skipped, testTitle );
+       } else {
+               addEvent( testTitle, "click", function() {
+                       toggleClass( assertList, "qunit-collapsed" );
+               });
+
+               testItem.className = bad ? "fail" : "pass";
+
+               time = document.createElement( "span" );
+               time.className = "runtime";
+               time.innerHTML = details.runtime + " ms";
+               testItem.insertBefore( time, assertList );
+       }
+});
+
+if ( !defined.document || document.readyState === "complete" ) {
+       config.pageLoaded = true;
+       config.autorun = true;
+}
+
+if ( defined.document ) {
+       addEvent( window, "load", QUnit.load );
+}
+
+})();
index dc7aaa4..e6e33ad 100644 (file)
                        return str.charAt( 0 ).toUpperCase() + str.slice( 1 );
                },
                escapeRE: function ( str ) {
-                       return str.replace ( /([\\{}()|.?*+\-\^$\[\]])/g, '\\$1' );
+                       return str.replace( /([\\{}()|.?*+\-\^$\[\]])/g, '\\$1' );
                },
                isDomElement: function ( el ) {
                        return !!el && !!el.nodeType;
                },
                isEmpty: function ( v ) {
                        var key;
-                       if ( v === '' || v === 0 || v === '0' || v === null
-                               || v === false || v === undefined )
-                       {
+                       if (
+                               v === '' || v === 0 || v === '0' || v === null || v === false || v === undefined
+                       {
                                return true;
                        }
                        // the for-loop could potentially contain prototypes
index d458019..d50422e 100644 (file)
@@ -13,7 +13,7 @@
  * @version 2.1.0
  * @license MIT
  */
-(function ($) {
+( function ($) {
 
        var isInputSupported = 'placeholder' in document.createElement('input'),
                isTextareaSupported = 'placeholder' in document.createElement('textarea'),
@@ -49,7 +49,7 @@
 
                        $this
                                .filter((isInputSupported ? 'textarea' : ':input') + '[placeholder]')
-                               .filter(function () {
+                               .filter( function () {
                                        return !$(this).data('placeholder-enabled');
                                })
                                .bind({
                        propHooks.value = hooks;
                }
 
-               $(function () {
+               $( function () {
                        // Look for forms
                        $(document).delegate('form', 'submit.placeholder', function () {
                                // Clear the placeholder values so they don't get submitted
                                var $inputs = $('.placeholder', this).each(clearPlaceholder);
-                               setTimeout(function () {
+                               setTimeout( function () {
                                        $inputs.each(setPlaceholder);
                                }, 10);
                        });
 
                // Clear placeholder values upon page reload
                $(window).bind('beforeunload.placeholder', function () {
-                       $('.placeholder').each(function () {
+                       $('.placeholder').each( function () {
                                this.value = '';
                        });
                });
index bd6518d..e8fc8e4 100644 (file)
                                                        endPos = this.selectionEnd;
                                                        scrollTop = this.scrollTop;
                                                        checkSelectedText();
-                                                       if ( options.selectionStart !== undefined
-                                                                       && endPos - startPos !== options.selectionEnd - options.selectionStart )
-                                                       {
+                                                       if (
+                                                               options.selectionStart !== undefined &&
+                                                               endPos - startPos !== options.selectionEnd - options.selectionStart
+                                                       ) {
                                                                // This means there is a difference in the selection range returned by browser and what we passed.
                                                                // This happens for Chrome in the case of composite characters. Ref bug #30130
                                                                // Set the startPos to the correct position.
index f6fab70..68fbe33 100644 (file)
                                                response.parse.modulemessages ) );
                                }
                                if ( response.parse.displaytitle ) {
-                                       $( '#firstHeading' ).html( '<span dir="auto">' + response.parse.displaytitle + '</span>' );
+                                       $( '#firstHeading' ).html( response.parse.displaytitle );
                                }
                                if ( response.parse.categorieshtml ) {
                                        $( '#catlinks' ).replaceWith( response.parse.categorieshtml['*'] );
index 2c8d2e6..9f786ec 100644 (file)
@@ -4,3 +4,13 @@
 table.collapsed tr.collapsable {
        display: none;
 }
+
+/*
+ * Exclude user interface elements from selection.
+ */
+.mw-metadata-show-hide-extended {
+       -moz-user-select: none;
+       -webkit-user-select: none;
+       -ms-user-select: none;
+       user-select: none;
+}
index 95ef62c..c008dfd 100644 (file)
@@ -76,4 +76,4 @@
                mw.cookie.set( cookieKey, null );
        }
 
-} ( mediaWiki, jQuery ) );
+}( mediaWiki, jQuery ) );
index ccbae06..2525792 100644 (file)
@@ -14,8 +14,7 @@
                 * @return {jQuery.Promise} See mw.Api#post
                 */
                login: function ( username, password ) {
-                       var params, request,
-                               deferred = $.Deferred(),
+                       var params, apiPromise, innerPromise,
                                api = this;
 
                        params = {
                                lgpassword: password
                        };
 
-                       request = api.post( params );
-                       request.fail( deferred.reject );
-                       request.done( function ( data ) {
-                               params.lgtoken = data.login.token;
-                               api.post( params )
-                                       .fail( deferred.reject )
-                                       .done( function ( data ) {
-                                               var code;
-                                               if ( data.login && data.login.result === 'Success' ) {
-                                                       deferred.resolve( data );
-                                               } else {
-                                                       // Set proper error code whenever possible
-                                                       code = data.error && data.error.code || 'unknown';
-                                                       deferred.reject( code, data );
-                                               }
-                                       } );
-                       } );
+                       apiPromise = api.post( params );
 
-                       return deferred.promise( { abort: request.abort } );
+                       return apiPromise
+                               .then( function ( data ) {
+                                       params.lgtoken = data.login.token;
+                                       innerPromise = api.post( params )
+                                               .then( function ( data ) {
+                                                       var code;
+                                                       if ( data.login.result !== 'Success' ) {
+                                                               // Set proper error code whenever possible
+                                                               code = data.error && data.error.code || 'unknown';
+                                                               return $.Deferred().reject( code, data );
+                                                       }
+                                                       return data;
+                                               } );
+                                       return innerPromise;
+                               } )
+                               .promise( {
+                                       abort: function () {
+                                               apiPromise.abort();
+                                               if ( innerPromise ) {
+                                                       innerPromise.abort();
+                                               }
+                                       }
+                               } );
                }
        } );
 
index df95d75..b3765c8 100644 (file)
@@ -54,6 +54,7 @@
                 */
                getData: function ( langCode, dataKey ) {
                        var langData = mw.language.data;
+                       langCode = langCode.toLowerCase();
                        if ( langData && langData[langCode] instanceof mw.Map ) {
                                return langData[langCode].get( dataKey );
                        }
@@ -71,6 +72,7 @@
                 */
                setData: function ( langCode, dataKey, value ) {
                        var langData = mw.language.data;
+                       langCode = langCode.toLowerCase();
                        if ( !( langData[langCode] instanceof mw.Map ) ) {
                                langData[langCode] = new mw.Map();
                        }
index cf54cf9..49186e5 100644 (file)
@@ -1124,6 +1124,7 @@ table.floatleft {
 
 .mw-editsection,
 .toctoggle,
+.tochidden,
 #jump-to-nav {
        -moz-user-select: none;
        -webkit-user-select: none;
index 3658ed8..9514070 100644 (file)
@@ -3,11 +3,18 @@
  * Also Dynamically resize images to justify them.
  */
 ( function ( mw, $ ) {
-       // Is there a better way to detect a touchscreen? Current check taken from stack overflow.
-       var isTouchScreen = !!( window.ontouchstart !== undefined || window.DocumentTouch !== undefined && document instanceof window.DocumentTouch ),
-               $galleries = $();
+       var $galleries,
+               bound = false,
+               // Is there a better way to detect a touchscreen? Current check taken from stack overflow.
+               isTouchScreen = !!( window.ontouchstart !== undefined ||
+                       window.DocumentTouch !== undefined && document instanceof window.DocumentTouch
+               );
 
-       // Now on to justification.
+       /**
+        * Perform the layout justification.
+        * @ignore
+        * @context {HTMLElement} A `ul.mw-gallery-*` element
+        */
        function justify() {
                var lastTop,
                        $img,
                }() );
        }
 
+       function handleResizeStart() {
+               $galleries.children( 'li' ).each( function () {
+                       var imgWidth = $( this ).data( 'imgWidth' ),
+                               imgHeight = $( this ).data( 'imgHeight' ),
+                               width = $( this ).data( 'width' ),
+                               captionWidth = $( this ).data( 'captionWidth' ),
+                               $innerDiv = $( this ).children( 'div' ).first(),
+                               $imageDiv = $innerDiv.children( 'div.thumb' ),
+                               $imageElm, imageElm;
+
+                       // Restore original sizes so we can arrange the elements as on freshly loaded page
+                       $( this ).width( width );
+                       $innerDiv.width( width );
+                       $imageDiv.width( imgWidth );
+                       $( this ).find( 'div.gallerytextwrapper' ).width( captionWidth );
+
+                       $imageElm = $( this ).find( 'img' ).first();
+                       imageElm = $imageElm.length ? $imageElm[0] : null;
+                       if ( imageElm ) {
+                               imageElm.width = imgWidth;
+                               imageElm.height = imgHeight;
+                       } else {
+                               $imageDiv.height( imgHeight );
+                       }
+               } );
+       }
+
+       function handleResizeEnd() {
+               $galleries.each( justify );
+       }
+
        mw.hook( 'wikipage.content' ).add( function ( $content ) {
                if ( isTouchScreen ) {
                        // Always show the caption for a touch screen.
                // Call the justification asynchronous because live preview fires the hook with detached $content.
                setTimeout( function () {
                        $galleries.each( justify );
-               } );
-       } );
 
-       $( function () {
-               $( window ).resize( $.debounce( 300, true, function () {
-                       $galleries.children( 'li' ).each( function () {
-                               var imgWidth = $( this ).data( 'imgWidth' ),
-                                       imgHeight = $( this ).data( 'imgHeight' ),
-                                       width = $( this ).data( 'width' ),
-                                       captionWidth = $( this ).data( 'captionWidth' ),
-                                       $innerDiv = $( this ).children( 'div' ).first(),
-                                       $imageDiv = $innerDiv.children( 'div.thumb' ),
-                                       $imageElm, imageElm;
-
-                               // Restore original sizes so we can arrange the elements as on freshly loaded page
-                               $( this ).width( width );
-                               $innerDiv.width( width );
-                               $imageDiv.width( imgWidth );
-                               $( this ).find( 'div.gallerytextwrapper' ).width( captionWidth );
-
-                               $imageElm = $( this ).find( 'img' ).first();
-                               imageElm = $imageElm.length ? $imageElm[0] : null;
-                               if ( imageElm ) {
-                                       imageElm.width = imgWidth;
-                                       imageElm.height = imgHeight;
-                               } else {
-                                       $imageDiv.height( imgHeight );
-                               }
-                       } );
-               } ) );
-               $( window ).resize( $.debounce( 300, function () {
-                       $galleries.each( justify );
-               } ) );
+                       // Bind here instead of in the top scope as the callbacks use $galleries.
+                       if ( !bound ) {
+                               bound = true;
+                               $( window )
+                                       .resize( $.debounce( 300, true, handleResizeStart ) )
+                                       .resize( $.debounce( 300, handleResizeEnd ) );
+                       }
+               } );
        } );
 }( mediaWiki, jQuery ) );
index ba7f734..7c2269f 100644 (file)
@@ -6,4 +6,4 @@
                        $( '#mw-pl-options-2' ).prop( 'checked', true );
                } );
        } );
-} ( jQuery ) );
+}( jQuery ) );
index 85f4ffa..73e7f6e 100644 (file)
                }
        };
 
-} ( mediaWiki, jQuery ) );
+}( mediaWiki, jQuery ) );
index bed5cb5..98a2f6a 100644 (file)
 
        // Attach to window and globally alias
        window.mw = window.mediaWiki = mw;
-
-       // Auto-register from pre-loaded startup scripts
-       if ( $.isFunction( window.startUp ) ) {
-               window.startUp();
-               window.startUp = undefined;
-       }
-
 }( jQuery ) );
diff --git a/resources/src/mediawiki/mediawiki.startUp.js b/resources/src/mediawiki/mediawiki.startUp.js
new file mode 100644 (file)
index 0000000..028784c
--- /dev/null
@@ -0,0 +1,11 @@
+/*!
+ * Auto-register from pre-loaded startup scripts
+ */
+( function ( $ ) {
+       'use strict';
+
+       if ( $.isFunction( window.startUp ) ) {
+               window.startUp();
+               window.startUp = undefined;
+       }
+}( jQuery ) );
index 809a65e..5e0cfcc 100644 (file)
                        var registration = mw.config.get( 'wgUserRegistration' );
                        if ( user.isAnon() ) {
                                return false;
-                       } else if ( registration === null ) {
+                       }
+                       if ( registration === null ) {
                                // Information may not be available if they signed up before
                                // MW began storing this.
                                return null;
-                       } else {
-                               return new Date( registration );
                        }
+                       return new Date( registration );
                },
 
                /**
index 0dde873..d202270 100644 (file)
@@ -88,7 +88,7 @@
                /**
                 * Get the link to a page name (relative to `wgServer`),
                 *
-                * @param {string} str Page name
+                * @param {string|null} [str=wgPageName] Page name
                 * @param {Object} [params] A mapping of query parameter names to values,
                 *  e.g. `{ action: 'edit' }`
                 * @return {string} Url of the page with name of `str`
index 18aeabb..0d632c5 100644 (file)
@@ -1191,28 +1191,49 @@ Ruby markup (W3C-style)
 </p>
 !! end
 
-# There is a tidy bug here: http://sourceforge.net/p/tidy/bugs/946/
+# The next two test different paths in the sanitizer.
 !! test
 Non-word characters don't terminate tag names (bug 17663, 40670, 52022)
 !! wikitext
-<b→> doesn't work! </b→>
+<b→> doesn't terminate </b→>
 
-<bä> doesn't work! </bä>
+<bä> doesn't terminate </bä>
 
-<boo> works fine </boo>
+<boo> doesn't terminate </boo>
 
-<s.foo>s.foo</s.foo>
+<s.foo> doesn't terminate </s.foo>
 
 <sub-ID#1>
 !! html
-<p>&lt;b→&gt; doesn't work! &lt;/b→&gt;
-</p><p>&lt;bä&gt; doesn't work! &lt;/bä&gt;
-</p><p>&lt;boo&gt; works fine &lt;/boo&gt;
-</p><p>&lt;s.foo&gt;s.foo&lt;/s.foo&gt;
+<p>&lt;b→&gt; doesn't terminate &lt;/b→&gt;
+</p><p>&lt;bä&gt; doesn't terminate &lt;/bä&gt;
+</p><p>&lt;boo&gt; doesn't terminate &lt;/boo&gt;
+</p><p>&lt;s.foo&gt; doesn't terminate &lt;/s.foo&gt;
 </p><p>&lt;sub-ID#1&gt;
 </p>
 !! end
 
+# There is a tidy bug here: http://sourceforge.net/p/tidy/bugs/946/
+!! test
+Non-word characters don't terminate tag names + tidy
+!! wikitext
+<b→> doesn't terminate </b→>
+
+<bä> doesn't terminate </bä>
+
+<boo> doesn't terminate </boo>
+
+<s.foo> doesn't terminate </s.foo>
+
+<sub-ID#1>
+!! html+tidy
+<p>&lt;b→&gt; doesn't terminate &lt;/b→&gt;</p>
+<p>&lt;bä&gt; doesn't terminate &lt;/bä&gt;</p>
+<p>&lt;boo&gt; doesn't terminate &lt;/boo&gt;</p>
+<p>&lt;s.foo&gt; doesn't terminate &lt;/s.foo&gt;</p>
+<p>&lt;sub-ID#1&gt;</p>
+!! end
+
 !! test
 Isolated close tags should be treated as literal text (bug 52760)
 !! wikitext
@@ -3911,7 +3932,7 @@ Definition Lists: Weird Ones: Test 1
 <dl>
 <dt>
 <dl>
-<dt> foo<span typeof="mw:Placeholder" data-parsoid='{"src":" "}'>&nbsp;</span></dt>
+<dt> foo<span typeof="mw:Placeholder">&nbsp;</span></dt>
 <dd data-parsoid='{"stx":"row"}'> bar (who uses this?)</dd>
 </dl></dt>
 </dl></dd>
@@ -5548,7 +5569,6 @@ Invalid attributes in table cell (bug 1830)
 
 !! end
 
-
 # The "|}" to close the table is missing from the input, so parsoid's
 # *2wt modes will fail.
 !! test
@@ -5573,6 +5593,25 @@ parsoid=wt2html,html2html
 <td><a rel="mw:ExtLink" href="ftp://|x||"></a>" onmouseover="alert(document.cookie)">test</td></tr></tbody></table>
 !! end
 
+# FIXME: The php output is broken.
+!! test
+! and || in td attributes should not be parsed as <th>/<td>
+!! wikitext
+{|
+| style="color: red !important;" data-contrived="put this here ||" | foo
+|}
+!! html/php
+<table>
+<tr>
+<td> style="color: red !important;" data-contrived="put this here </td>
+<td> foo
+</td></tr></table>
+
+!! html/parsoid
+<table>
+<tbody><tr><td style="color: red !important;" data-contrived="put this here ||" data-parsoid='{"autoInsertedEnd":true}'> foo</td></tr>
+</tbody></table>
+!! end
 
 !! test
 Indented table markup mixed with indented pre content (proposed in bug 6200)
@@ -8787,6 +8826,17 @@ Aoeu
 </p>
 !! end
 
+# From plwiki:PLOS_ONE
+!! test
+Parsoid: Page property magic word with magic word contents
+!! options
+parsoid
+!! wikitext
+{{DISPLAYTITLE:''{{PAGENAME}}''}}
+!! html
+<meta property="mw:PageProp/displaytitle" content="Main Page" about="#mwt2" typeof="mw:ExpandedAttrs" data-mw='{"attribs":[[{"txt":"content"},{"html":"&lt;i data-parsoid=\"{&amp;quot;dsr&amp;quot;:[15,31,2,2]}\">&lt;span about=\"#mwt1\" typeof=\"mw:Transclusion\" data-parsoid=\"{&amp;quot;pi&amp;quot;:[[]],&amp;quot;dsr&amp;quot;:[17,29,null,null]}\" data-mw=\"{&amp;quot;parts&amp;quot;:[{&amp;quot;template&amp;quot;:{&amp;quot;target&amp;quot;:{&amp;quot;wt&amp;quot;:&amp;quot;PAGENAME&amp;quot;,&amp;quot;function&amp;quot;:&amp;quot;pagename&amp;quot;},&amp;quot;params&amp;quot;:{},&amp;quot;i&amp;quot;:0}}]}\">Main Page&lt;/span>&lt;/i>"}]]}'/>
+!! end
+
 !! test
 Namespace 1 {{ns:1}}
 !! wikitext
@@ -8918,7 +8968,7 @@ Magic Word: prioritize type info over data-parsoid
 !! options
 parsoid=html2wt
 !! html
-<meta property="mw:PageProp/forcetoc" data-parsoid='{"src":"__NOTOC__","magicSrc":"__NOTOC__"}'/>
+<meta property="mw:PageProp/forcetoc" data-parsoid='{"magicSrc":"__NOTOC__"}'/>
 !! wikitext
 __FORCETOC__
 !! end
@@ -8943,7 +8993,7 @@ language=de
 !! wikitext
 __NOEDITSECTION__
 !! html
-<meta property="mw:PageProp/noeditsection" data-parsoid='{"src":"__NOEDITSECTION__","magicSrc":"__NOEDITSECTION__"}'/>
+<meta property="mw:PageProp/noeditsection" data-parsoid='{"magicSrc":"__NOEDITSECTION__"}'/>
 !! end
 
 ###
@@ -9898,7 +9948,7 @@ parsoid=wt2html,wt2wt
 |c
 |}
 !!html/parsoid
-<meta typeof="mw:Includes/IncludeOnly" data-parsoid='{"src":"&lt;includeonly>a&lt;/includeonly>"'/><meta typeof="mw:Includes/IncludeOnly/End" data-parsoid='{"src":""}'/><table about="#mwt2" typeof="mw:ExpandedAttrs" data-mw='{"attribs":[[{"txt":"{{{b}}}","html":"&lt;span about=\"#mwt1\" typeof=\"mw:Param\" data-parsoid=\"{&amp;quot;dsr&amp;quot;:[31,38,null,null],&amp;quot;src&amp;quot;:&amp;quot;{{{b}}}&amp;quot;}\">{{{b}}}&lt;/span>"},{"html":""}]]}' data-parsoid='{"a":{"{{{b}}}":null},"sa":{"{{{b}}}":""}}'>
+<meta typeof="mw:Includes/IncludeOnly"/><meta typeof="mw:Includes/IncludeOnly/End"/><table about="#mwt2" typeof="mw:ExpandedAttrs" data-mw='{"attribs":[[{"txt":"{{{b}}}","html":"&lt;span about=\"#mwt1\" typeof=\"mw:Param\" data-parsoid=\"{&amp;quot;dsr&amp;quot;:[31,38,null,null],&amp;quot;src&amp;quot;:&amp;quot;{{{b}}}&amp;quot;}\">{{{b}}}&lt;/span>"},{"html":""}]]}' data-parsoid='{"a":{"{{{b}}}":null},"sa":{"{{{b}}}":""}}'>
 <tbody><tr><td>c</td></tr>
 </tbody></table>
 
@@ -14973,7 +15023,6 @@ Punctuation: CSS ! important (bug 11874; with space after)
 
 !!end
 
-
 !! test
 HTML bullet list, closed tags (bug 5497)
 !! wikitext
@@ -18797,10 +18846,10 @@ Play a bit with r67090 and bug 3158
 <div style="border&#160;: solid;">&#160;</div>
 
 !! html/parsoid
-<div style="width:50% !important" data-parsoid='{"stx":"html"}'><span typeof="mw:Entity" data-parsoid='{"src":"&amp;nbsp;","srcContent":" "}'> </span></div>
-<div style="width:50% !important" data-parsoid='{"stx":"html","a":{"style":"width:50% !important"},"sa":{"style":"width:50%&amp;nbsp;!important"}}'><span typeof="mw:Entity" data-parsoid='{"src":"&amp;nbsp;","srcContent":" "}'> </span></div>
-<div style="width:50% !important" data-parsoid='{"stx":"html","a":{"style":"width:50% !important"},"sa":{"style":"width:50%&amp;#160;!important"}}'><span typeof="mw:Entity" data-parsoid='{"src":"&amp;nbsp;","srcContent":" "}'> </span></div>
-<div style="border : solid;" data-parsoid='{"stx":"html"}'><span typeof="mw:Entity" data-parsoid='{"src":"&amp;nbsp;","srcContent":" "}'> </span></div>
+<div style="width:50% !important" data-parsoid='{"stx":"html"}'><span typeof="mw:Entity" data-parsoid='{"srcContent":" "}'> </span></div>
+<div style="width:50% !important" data-parsoid='{"stx":"html","a":{"style":"width:50% !important"},"sa":{"style":"width:50%&amp;nbsp;!important"}}'><span typeof="mw:Entity" data-parsoid='{"srcContent":" "}'> </span></div>
+<div style="width:50% !important" data-parsoid='{"stx":"html","a":{"style":"width:50% !important"},"sa":{"style":"width:50%&amp;#160;!important"}}'><span typeof="mw:Entity" data-parsoid='{"srcContent":" "}'> </span></div>
+<div style="border : solid;" data-parsoid='{"stx":"html"}'><span typeof="mw:Entity" data-parsoid='{"srcContent":" "}'> </span></div>
 
 !! end
 
@@ -20031,7 +20080,7 @@ parsoid
 !! wikitext
 <ref name="test &amp; me">hi</ref>
 !! html
-<p><span about="#mwt2" class="reference" id="cite_ref-test_.26_me_1-0" rel="dc:references" typeof="mw:Extension/ref" data-parsoid='{"src":"&lt;ref name=\"test &amp;amp; me\">hi&lt;/ref>"}' data-mw='{"name":"ref","body":{"html":"hi"},"attrs":{"name":"test &amp;amp; me"}}'><a href="#cite_note-test_.26_me-1">[1]</a></span></p>
+<p><span about="#mwt2" class="reference" id="cite_ref-test_.26_me_1-0" rel="dc:references" typeof="mw:Extension/ref" data-mw='{"name":"ref","body":{"html":"hi"},"attrs":{"name":"test &amp;amp; me"}}'><a href="#cite_note-test_.26_me-1">[1]</a></span></p>
 !! end
 
 # This test is wt2html only because we're permitting the serializer to produce
@@ -22275,7 +22324,7 @@ Properly encapsulate empty-content transclusions in fosterable positions
 }}
 </table>
 !! html/parsoid
-<table about="#mwt1" typeof="mw:Transclusion" data-mw='{"parts":["&lt;table>\n",{"template":{"target":{"wt":"#if:","function":"#if"},"params":{"1":{"wt":"\n&lt;td>foo&lt;/td>\n"}},"i":0}},"\n&lt;/table>"]}' data-parsoid='{"stx":"html","pi":[[{"k":"1","spc":["","","",""]}]],"src":"&lt;table>\n{{#if:|\n&lt;td>foo&lt;/td>\n}}\n&lt;/table>"}'>
+<table about="#mwt1" typeof="mw:Transclusion" data-mw='{"parts":["&lt;table>\n",{"template":{"target":{"wt":"#if:","function":"#if"},"params":{"1":{"wt":"\n&lt;td>foo&lt;/td>\n"}},"i":0}},"\n&lt;/table>"]}' data-parsoid='{"stx":"html","pi":[[{"k":"1","spc":["","","",""]}]]}'>
 
 </table>
 !! end
@@ -22748,6 +22797,21 @@ parsoid=html2wt
 == <span> baz</span> ==
 !! end
 
+!! test
+Headings: Force metas to serialize before/after
+!! options
+parsoid=html2wt
+!! html
+<h2>hello there<link href="Category:A1" rel="mw:PageProp/Category" /></h2>
+<h2><link href="Category:A2" rel="mw:PageProp/Category" />hi pal</h2>
+!! wikitext
+== hello there ==
+[[Category:A1]]
+
+[[Category:A2]]
+== hi pal ==
+!! end
+
 !! test
 Parsoid: Serialize positional parameters with = in them as named parameter
 !! options
@@ -23085,7 +23149,7 @@ Edited Redirect link should emit a non-piped wikitext link
 !! options
 parsoid=html2wt
 !! html
-<link rel="mw:PageProp/redirect" href="Bar" data-parsoid='{"src":"#REDIRECT ","a":{"href":"./Foo"},"sa":{"href":"Foo"}}'>
+<link rel="mw:PageProp/redirect" href="Bar" data-parsoid='{"a":{"href":"./Foo"},"sa":{"href":"Foo"}}'>
 !! wikitext
 #REDIRECT [[Bar]]
 !! end
index 7e07823..e49c391 100644 (file)
@@ -117,34 +117,22 @@ abstract class MediaWikiTestCase extends PHPUnit_Framework_TestCase {
                        $this->checkDbIsSupported();
 
                        if ( !self::$dbSetup ) {
-                               wfProfileIn( $logName . ' (clone-db)' );
-
                                // switch to a temporary clone of the database
                                self::setupTestDB( $this->db, $this->dbPrefix() );
 
                                if ( ( $this->db->getType() == 'oracle' || !self::$useTemporaryTables ) && self::$reuseDB ) {
                                        $this->resetDB();
                                }
-
-                               wfProfileOut( $logName . ' (clone-db)' );
                        }
-
-                       wfProfileIn( $logName . ' (prepare-db)' );
                        $this->addCoreDBData();
                        $this->addDBData();
-                       wfProfileOut( $logName . ' (prepare-db)' );
-
                        $needsResetDB = true;
                }
 
-               wfProfileIn( $logName );
                parent::run( $result );
-               wfProfileOut( $logName );
 
                if ( $needsResetDB ) {
-                       wfProfileIn( $logName . ' (reset-db)' );
                        $this->resetDB();
-                       wfProfileOut( $logName . ' (reset-db)' );
                }
        }
 
@@ -226,8 +214,11 @@ abstract class MediaWikiTestCase extends PHPUnit_Framework_TestCase {
 
        }
 
-       protected function tearDown() {
+       protected function addTmpFiles( $files ) {
+               $this->tmpFiles = array_merge( $this->tmpFiles, (array)$files );
+       }
 
+       protected function tearDown() {
                $this->called['tearDown'] = true;
                // Cleaning up temporary files
                foreach ( $this->tmpFiles as $fileName ) {
index 121aade..a5c8ef6 100644 (file)
@@ -15,14 +15,7 @@ EOF;
 }
 
 class MediaWikiPHPUnitBootstrap {
-
-       public function __construct() {
-               wfProfileIn( __CLASS__ );
-       }
-
        public function __destruct() {
-               wfProfileOut( __CLASS__ );
-
                // Return to real wiki db, so profiling data is preserved
                MediaWikiTestCase::teardownTestDB();
 
index 2bfabe4..331fb3b 100644 (file)
@@ -7,7 +7,7 @@ class GlobalTest extends MediaWikiTestCase {
        protected function setUp() {
                parent::setUp();
 
-               $readOnlyFile = tempnam( wfTempDir(), "mwtest_readonly" );
+               $readOnlyFile = $this->getNewTempFile();
                unlink( $readOnlyFile );
 
                $this->setMwGlobals( array(
@@ -22,16 +22,6 @@ class GlobalTest extends MediaWikiTestCase {
                ) );
        }
 
-       protected function tearDown() {
-               global $wgReadOnlyFile;
-
-               if ( file_exists( $wgReadOnlyFile ) ) {
-                       unlink( $wgReadOnlyFile );
-               }
-
-               parent::tearDown();
-       }
-
        /**
         * @dataProvider provideForWfArrayDiff2
         * @covers ::wfArrayDiff2
@@ -312,46 +302,42 @@ class GlobalTest extends MediaWikiTestCase {
         * @covers ::wfDebugMem
         */
        public function testDebugFunctionTest() {
+               $debugLogFile = $this->getNewTempFile();
 
-               global $wgDebugLogFile, $wgDebugTimestamps;
-
-               $old_log_file = $wgDebugLogFile;
-               $wgDebugLogFile = tempnam( wfTempDir(), 'mw-' );
-               # @todo FIXME: $wgDebugTimestamps should be tested
-               $old_wgDebugTimestamps = $wgDebugTimestamps;
-               $wgDebugTimestamps = false;
+               $this->setMwGlobals( array(
+                       'wgDebugLogFile' => $debugLogFile,
+                       # @todo FIXME: $wgDebugTimestamps should be tested
+                       'wgDebugTimestamps' => false
+               ) );
 
                wfDebug( "This is a normal string" );
-               $this->assertEquals( "This is a normal string\n", file_get_contents( $wgDebugLogFile ) );
-               unlink( $wgDebugLogFile );
+               $this->assertEquals( "This is a normal string\n", file_get_contents( $debugLogFile ) );
+               unlink( $debugLogFile );
 
                wfDebug( "This is nöt an ASCII string" );
-               $this->assertEquals( "This is nöt an ASCII string\n", file_get_contents( $wgDebugLogFile ) );
-               unlink( $wgDebugLogFile );
+               $this->assertEquals( "This is nöt an ASCII string\n", file_get_contents( $debugLogFile ) );
+               unlink( $debugLogFile );
 
                wfDebug( "\00305This has böth UTF and control chars\003" );
                $this->assertEquals(
                        " 05This has böth UTF and control chars \n",
-                       file_get_contents( $wgDebugLogFile )
+                       file_get_contents( $debugLogFile )
                );
-               unlink( $wgDebugLogFile );
+               unlink( $debugLogFile );
 
                wfDebugMem();
                $this->assertGreaterThan(
                        1000,
-                       preg_replace( '/\D/', '', file_get_contents( $wgDebugLogFile ) )
+                       preg_replace( '/\D/', '', file_get_contents( $debugLogFile ) )
                );
-               unlink( $wgDebugLogFile );
+               unlink( $debugLogFile );
 
                wfDebugMem( true );
                $this->assertGreaterThan(
                        1000000,
-                       preg_replace( '/\D/', '', file_get_contents( $wgDebugLogFile ) )
+                       preg_replace( '/\D/', '', file_get_contents( $debugLogFile ) )
                );
-               unlink( $wgDebugLogFile );
-
-               $wgDebugLogFile = $old_log_file;
-               $wgDebugTimestamps = $old_wgDebugTimestamps;
+               unlink( $debugLogFile );
        }
 
        /**
diff --git a/tests/phpunit/includes/GlobalFunctions/wfThumbIsStandardTest.php b/tests/phpunit/includes/GlobalFunctions/wfThumbIsStandardTest.php
new file mode 100644 (file)
index 0000000..448250a
--- /dev/null
@@ -0,0 +1,104 @@
+<?php
+
+/**
+ * @group GlobalFunctions
+ * @covers ::wfThumbIsStandard
+ */
+class WfThumbIsStandardTest extends MediaWikiTestCase {
+
+       protected function setUp() {
+               parent::setUp();
+
+               $this->setMwGlobals( array(
+                       'wgThumbLimits' => array(
+                               100,
+                               401
+                       ),
+                       'wgImageLimits' => array(
+                               array( 300, 225 ),
+                               array( 800, 600 ),
+                       ),
+                       'wgMediaHandlers' => array(
+                               'unknown/unknown' => 'MockBitmapHandler',
+                       ),
+               ) );
+       }
+
+       public static function provideThumbParams() {
+               return array(
+                       // Thumb limits
+                       array(
+                               'Standard thumb width',
+                               true,
+                               array( 'width' => 100 ),
+                       ),
+                       array(
+                               'Standard thumb width',
+                               true,
+                               array( 'width' => 401 ),
+                       ),
+                       // wfThumbIsStandard should match Linker::processResponsiveImages
+                       // in its rounding behaviour.
+                       array(
+                               'Standard thumb width (HiDPI 1.5x) - incorrect rounding',
+                               false,
+                               array( 'width' => 601 ),
+                       ),
+                       array(
+                               'Standard thumb width (HiDPI 1.5x)',
+                               true,
+                               array( 'width' => 602 ),
+                       ),
+                       array(
+                               'Standard thumb width (HiDPI 2x)',
+                               true,
+                               array( 'width' => 802 ),
+                       ),
+                       array(
+                               'Non-standard thumb width',
+                               false,
+                               array( 'width' => 300 ),
+                       ),
+                       // Image limits
+                       // Note: Image limits are measured as pairs. Individual values
+                       // may be non-standard based on the aspect ratio.
+                       array(
+                               'Standard image width/height pair',
+                               true,
+                               array( 'width' => 250, 'height' => 225 ),
+                       ),
+                       array(
+                               'Standard image width/height pair',
+                               true,
+                               array( 'width' => 667, 'height' => 600 ),
+                       ),
+                       array(
+                               'Standard image width where image does not fit aspect ratio',
+                               false,
+                               array( 'width' => 300 ),
+                       ),
+                       array(
+                               'Implicit width from image width/height pair aspect ratio fit',
+                               true,
+                               // 2000x1800 fit inside 300x225 makes w=250
+                               array( 'width' => 250 ),
+                       ),
+                       array(
+                               'Height-only is always non-standard',
+                               false,
+                               array( 'height' => 225 ),
+                       ),
+               );
+       }
+
+       /**
+        * @dataProvider provideThumbParams
+        */
+       public function testIsStandard( $message, $expected, $params ) {
+               $this->assertSame(
+                       $expected,
+                       wfThumbIsStandard( new FakeDimensionFile( array( 2000, 1800 ) ), $params ),
+                       $message
+               );
+       }
+}
index 6341bf0..823c933 100644 (file)
@@ -231,6 +231,11 @@ class LinkerTest extends MediaWikiLangTestCase {
                                'foo bar [[Special:BlankPage]]',
                                null,
                        ),
+                       array(
+                               '<a class="external" rel="nofollow" href="//en.example.org/w/Foo%27bar">Foo\'bar</a>',
+                               "[[Foo'bar]]",
+                               'enwiki',
+                       ),
                        array(
                                'foo bar <a class="external" rel="nofollow" href="//en.example.org/w/Special:BlankPage">Special:BlankPage</a>',
                                'foo bar [[Special:BlankPage]]',
index 027b877..9501e45 100644 (file)
@@ -1,5 +1,8 @@
 <?php
 
+/**
+ * @group Database
+ */
 class MovePageTest extends MediaWikiTestCase {
 
        /**
@@ -36,4 +39,25 @@ class MovePageTest extends MediaWikiTestCase {
                        array( 'File:Test.jpg', 'Page', 'imagenocrossnamespace' ),
                );
        }
+
+       /**
+        * Integration test to catch regressions like T74870. Taken and modified
+        * from SemanticMediaWiki
+        */
+       public function testTitleMoveCompleteIntegrationTest() {
+               $oldTitle = Title::newFromText( 'Help:Some title' );
+               WikiPage::factory( $oldTitle )->doEditContent( new WikitextContent( 'foo' ), 'bar' );
+               $newTitle = Title::newFromText( 'Help:Some other title' );
+               $this->assertNull(
+                       WikiPage::factory( $newTitle )->getRevision()
+               );
+
+               $this->assertTrue( $oldTitle->moveTo( $newTitle, false, 'test1', true ) );
+               $this->assertNotNull(
+                       WikiPage::factory( $oldTitle )->getRevision()
+               );
+               $this->assertNotNull(
+                       WikiPage::factory( $newTitle)->getRevision()
+               );
+       }
 }
index 628c59b..44463cf 100644 (file)
@@ -109,7 +109,9 @@ class StatusTest extends MediaWikiLangTestCase {
        public function testIsGood( $ok, $errors, $expected ) {
                $status = new Status();
                $status->ok = $ok;
-               $status->errors = $errors;
+               foreach ( $errors as $error ) {
+                       $status->warning( $error );
+               }
                $this->assertEquals( $expected, $status->isGood() );
        }
 
index 7e51339..d4d9651 100644 (file)
@@ -21,12 +21,6 @@ abstract class ApiTestCaseUpload extends ApiTestCase {
                $this->clearFakeUploads();
        }
 
-       protected function tearDown() {
-               $this->clearTempUpload();
-
-               parent::tearDown();
-       }
-
        /**
         * Helper function -- remove files and associated articles by Title
         *
@@ -105,7 +99,7 @@ abstract class ApiTestCaseUpload extends ApiTestCase {
         * @return bool
         */
        function fakeUploadFile( $fieldName, $fileName, $type, $filePath ) {
-               $tmpName = tempnam( wfTempDir(), "" );
+               $tmpName = $this->getNewTempFile();
                if ( !file_exists( $filePath ) ) {
                        throw new Exception( "$filePath doesn't exist!" );
                }
@@ -132,7 +126,7 @@ abstract class ApiTestCaseUpload extends ApiTestCase {
        }
 
        function fakeUploadChunk( $fieldName, $fileName, $type, & $chunkData ) {
-               $tmpName = tempnam( wfTempDir(), "" );
+               $tmpName = $this->getNewTempFile();
                // copy the chunk data to temp location:
                if ( !file_put_contents( $tmpName, $chunkData ) ) {
                        throw new Exception( "couldn't copy chunk data to $tmpName" );
@@ -153,15 +147,6 @@ abstract class ApiTestCaseUpload extends ApiTestCase {
                );
        }
 
-       function clearTempUpload() {
-               if ( isset( $_FILES['file']['tmp_name'] ) ) {
-                       $tmp = $_FILES['file']['tmp_name'];
-                       if ( file_exists( $tmp ) ) {
-                               unlink( $tmp );
-                       }
-               }
-       }
-
        /**
         * Remove traces of previous fake uploads
         */
index 7fdefb6..b4b1bf3 100644 (file)
@@ -103,7 +103,7 @@ class ApiUploadTest extends ApiTestCaseUpload {
 
                try {
                        $randomImageGenerator = new RandomImageGenerator();
-                       $filePaths = $randomImageGenerator->writeImages( 1, $extension, wfTempDir() );
+                       $filePaths = $randomImageGenerator->writeImages( 1, $extension, $this->getNewTempDirectory() );
                } catch ( Exception $e ) {
                        $this->markTestIncomplete( $e->getMessage() );
                }
@@ -143,7 +143,6 @@ class ApiUploadTest extends ApiTestCaseUpload {
 
                // clean up
                $this->deleteFileByFilename( $fileName );
-               unlink( $filePath );
        }
 
        /**
@@ -152,7 +151,7 @@ class ApiUploadTest extends ApiTestCaseUpload {
        public function testUploadZeroLength( $session ) {
                $mimeType = 'image/png';
 
-               $filePath = tempnam( wfTempDir(), "" );
+               $filePath = $this->getNewTempFile();
                $fileName = "apiTestUploadZeroLength.png";
 
                $this->deleteFileByFileName( $fileName );
@@ -180,7 +179,6 @@ class ApiUploadTest extends ApiTestCaseUpload {
 
                // clean up
                $this->deleteFileByFilename( $fileName );
-               unlink( $filePath );
        }
 
        /**
@@ -192,7 +190,7 @@ class ApiUploadTest extends ApiTestCaseUpload {
 
                try {
                        $randomImageGenerator = new RandomImageGenerator();
-                       $filePaths = $randomImageGenerator->writeImages( 2, $extension, wfTempDir() );
+                       $filePaths = $randomImageGenerator->writeImages( 2, $extension, $this->getNewTempDirectory() );
                } catch ( Exception $e ) {
                        $this->markTestIncomplete( $e->getMessage() );
                }
@@ -251,8 +249,6 @@ class ApiUploadTest extends ApiTestCaseUpload {
 
                // clean up
                $this->deleteFileByFilename( $fileName );
-               unlink( $filePaths[0] );
-               unlink( $filePaths[1] );
        }
 
        /**
@@ -264,7 +260,7 @@ class ApiUploadTest extends ApiTestCaseUpload {
 
                try {
                        $randomImageGenerator = new RandomImageGenerator();
-                       $filePaths = $randomImageGenerator->writeImages( 1, $extension, wfTempDir() );
+                       $filePaths = $randomImageGenerator->writeImages( 1, $extension, $this->getNewTempDirectory() );
                } catch ( Exception $e ) {
                        $this->markTestIncomplete( $e->getMessage() );
                }
@@ -333,7 +329,6 @@ class ApiUploadTest extends ApiTestCaseUpload {
                // clean up
                $this->deleteFileByFilename( $fileNames[0] );
                $this->deleteFileByFilename( $fileNames[1] );
-               unlink( $filePaths[0] );
        }
 
        /**
@@ -349,7 +344,7 @@ class ApiUploadTest extends ApiTestCaseUpload {
 
                try {
                        $randomImageGenerator = new RandomImageGenerator();
-                       $filePaths = $randomImageGenerator->writeImages( 1, $extension, wfTempDir() );
+                       $filePaths = $randomImageGenerator->writeImages( 1, $extension, $this->getNewTempDirectory() );
                } catch ( Exception $e ) {
                        $this->markTestIncomplete( $e->getMessage() );
                }
@@ -417,7 +412,6 @@ class ApiUploadTest extends ApiTestCaseUpload {
 
                // clean up
                $this->deleteFileByFilename( $fileName );
-               unlink( $filePath );
        }
 
        /**
@@ -431,16 +425,14 @@ class ApiUploadTest extends ApiTestCaseUpload {
 
                $chunkSize = 1048576;
                // Download a large image file
-               // ( using RandomImageGenerator for large files is not stable )
+               // (using RandomImageGenerator for large files is not stable)
+               // @todo Don't download files from wikimedia.org
                $mimeType = 'image/jpeg';
                $url = 'http://upload.wikimedia.org/wikipedia/commons/'
                        . 'e/ed/Oberaargletscher_from_Oberaar%2C_2010_07.JPG';
-               $filePath = wfTempDir() . '/Oberaargletscher_from_Oberaar.jpg';
+               $filePath = $this->getNewTempDirectory() . '/Oberaargletscher_from_Oberaar.jpg';
                try {
-                       // Only download if the file is not avaliable in the temp location:
-                       if ( !is_file( $filePath ) ) {
-                               copy( $url, $filePath );
-                       }
+                       copy( $url, $filePath );
                } catch ( Exception $e ) {
                        $this->markTestIncomplete( $e->getMessage() );
                }
@@ -564,7 +556,5 @@ class ApiUploadTest extends ApiTestCaseUpload {
 
                // clean up
                $this->deleteFileByFilename( $fileName );
-               // don't remove downloaded temporary file for fast subquent tests.
-               //unlink( $filePath );
        }
 }
index 9558cc7..b40d2d2 100644 (file)
@@ -13,14 +13,13 @@ class FileBackendTest extends MediaWikiTestCase {
        private $multiBackend;
        /** @var FSFileBackend */
        public $singleBackend;
-       private $filesToPrune = array();
        private static $backendToUse;
 
        protected function setUp() {
                global $wgFileBackends;
                parent::setUp();
                $uniqueId = time() . '-' . mt_rand();
-               $tmpPrefix = wfTempDir() . '/filebackend-unittest-' . $uniqueId;
+               $tmpDir = $this->getNewTempDirectory();
                if ( $this->getCliArg( 'use-filebackend' ) ) {
                        if ( self::$backendToUse ) {
                                $this->singleBackend = self::$backendToUse;
@@ -51,8 +50,8 @@ class FileBackendTest extends MediaWikiTestCase {
                                'lockManager' => LockManagerGroup::singleton()->get( 'fsLockManager' ),
                                'wikiId' => wfWikiID(),
                                'containerPaths' => array(
-                                       'unittest-cont1' => "{$tmpPrefix}-localtesting-cont1",
-                                       'unittest-cont2' => "{$tmpPrefix}-localtesting-cont2" )
+                                       'unittest-cont1' => "{$tmpDir}/localtesting-cont1",
+                                       'unittest-cont2' => "{$tmpDir}/localtesting-cont2" )
                        ) );
                }
                $this->multiBackend = new FileBackendMultiWrite( array(
@@ -65,21 +64,20 @@ class FileBackendTest extends MediaWikiTestCase {
                                        'name' => 'localmultitesting1',
                                        'class' => 'FSFileBackend',
                                        'containerPaths' => array(
-                                               'unittest-cont1' => "{$tmpPrefix}-localtestingmulti1-cont1",
-                                               'unittest-cont2' => "{$tmpPrefix}-localtestingmulti1-cont2" ),
+                                               'unittest-cont1' => "{$tmpDir}/localtestingmulti1-cont1",
+                                               'unittest-cont2' => "{$tmpDir}/localtestingmulti1-cont2" ),
                                        'isMultiMaster' => false
                                ),
                                array(
                                        'name' => 'localmultitesting2',
                                        'class' => 'FSFileBackend',
                                        'containerPaths' => array(
-                                               'unittest-cont1' => "{$tmpPrefix}-localtestingmulti2-cont1",
-                                               'unittest-cont2' => "{$tmpPrefix}-localtestingmulti2-cont2" ),
+                                               'unittest-cont1' => "{$tmpDir}/localtestingmulti2-cont1",
+                                               'unittest-cont2' => "{$tmpDir}/localtestingmulti2-cont2" ),
                                        'isMultiMaster' => true
                                )
                        )
                ) );
-               $this->filesToPrune = array();
        }
 
        private static function baseStorePath() {
@@ -214,7 +212,7 @@ class FileBackendTest extends MediaWikiTestCase {
         * @dataProvider provider_testStore
         */
        public function testStore( $op ) {
-               $this->filesToPrune[] = $op['src'];
+               $this->addTmpFiles( $op['src'] );
 
                $this->backend = $this->singleBackend;
                $this->tearDownFiles();
@@ -224,7 +222,6 @@ class FileBackendTest extends MediaWikiTestCase {
                $this->backend = $this->multiBackend;
                $this->tearDownFiles();
                $this->doTestStore( $op );
-               $this->filesToPrune[] = $op['src']; # avoid file leaking
                $this->tearDownFiles();
        }
 
@@ -275,27 +272,15 @@ class FileBackendTest extends MediaWikiTestCase {
                $tmpName = TempFSFile::factory( "unittests_", 'txt' )->getPath();
                $toPath = self::baseStorePath() . '/unittest-cont1/e/fun/obj1.txt';
                $op = array( 'op' => 'store', 'src' => $tmpName, 'dst' => $toPath );
-               $cases[] = array(
-                       $op, // operation
-                       $tmpName, // source
-                       $toPath, // dest
-               );
+               $cases[] = array( $op );
 
                $op2 = $op;
                $op2['overwrite'] = true;
-               $cases[] = array(
-                       $op2, // operation
-                       $tmpName, // source
-                       $toPath, // dest
-               );
+               $cases[] = array( $op2 );
 
-               $op2 = $op;
-               $op2['overwriteSame'] = true;
-               $cases[] = array(
-                       $op2, // operation
-                       $tmpName, // source
-                       $toPath, // dest
-               );
+               $op3 = $op;
+               $op3['overwriteSame'] = true;
+               $cases[] = array( $op3 );
 
                return $cases;
        }
@@ -948,18 +933,14 @@ class FileBackendTest extends MediaWikiTestCase {
         * @dataProvider provider_testConcatenate
         */
        public function testConcatenate( $op, $srcs, $srcsContent, $alreadyExists, $okStatus ) {
-               $this->filesToPrune[] = $op['dst'];
-
                $this->backend = $this->singleBackend;
                $this->tearDownFiles();
                $this->doTestConcatenate( $op, $srcs, $srcsContent, $alreadyExists, $okStatus );
-               $this->filesToPrune[] = $op['dst']; # avoid file leaking
                $this->tearDownFiles();
 
                $this->backend = $this->multiBackend;
                $this->tearDownFiles();
                $this->doTestConcatenate( $op, $srcs, $srcsContent, $alreadyExists, $okStatus );
-               $this->filesToPrune[] = $op['dst']; # avoid file leaking
                $this->tearDownFiles();
        }
 
@@ -983,7 +964,7 @@ class FileBackendTest extends MediaWikiTestCase {
                $this->assertGoodStatus( $status,
                        "Creation of source files succeeded ($backendName)." );
 
-               $dest = $params['dst'];
+               $dest = $params['dst'] = $this->getNewTempFile();
                if ( $alreadyExists ) {
                        $ok = file_put_contents( $dest, 'blah...blah...waahwaah' ) !== false;
                        $this->assertEquals( true, $ok,
@@ -1029,8 +1010,6 @@ class FileBackendTest extends MediaWikiTestCase {
        public static function provider_testConcatenate() {
                $cases = array();
 
-               $rand = mt_rand( 0, 2000000000 ) . time();
-               $dest = wfTempDir() . "/randomfile!$rand.txt";
                $srcs = array(
                        self::baseStorePath() . '/unittest-cont1/e/file1.txt',
                        self::baseStorePath() . '/unittest-cont1/e/file2.txt',
@@ -1055,7 +1034,7 @@ class FileBackendTest extends MediaWikiTestCase {
                        'lkaem;a',
                        'legma'
                );
-               $params = array( 'srcs' => $srcs, 'dst' => $dest );
+               $params = array( 'srcs' => $srcs );
 
                $cases[] = array(
                        $params, // operation
@@ -1761,16 +1740,13 @@ class FileBackendTest extends MediaWikiTestCase {
                $fileCContents = 'eigna[ogmewt 3qt g3qg flew[ag';
 
                $tmpNameA = TempFSFile::factory( "unittests_", 'txt' )->getPath();
-               file_put_contents( $tmpNameA, $fileAContents );
                $tmpNameB = TempFSFile::factory( "unittests_", 'txt' )->getPath();
-               file_put_contents( $tmpNameB, $fileBContents );
                $tmpNameC = TempFSFile::factory( "unittests_", 'txt' )->getPath();
+               $this->addTmpFiles( array( $tmpNameA, $tmpNameB, $tmpNameC ) );
+               file_put_contents( $tmpNameA, $fileAContents );
+               file_put_contents( $tmpNameB, $fileBContents );
                file_put_contents( $tmpNameC, $fileCContents );
 
-               $this->filesToPrune[] = $tmpNameA; # avoid file leaking
-               $this->filesToPrune[] = $tmpNameB; # avoid file leaking
-               $this->filesToPrune[] = $tmpNameC; # avoid file leaking
-
                $fileA = "$base/unittest-cont1/e/a/b/fileA.txt";
                $fileB = "$base/unittest-cont1/e/a/b/fileB.txt";
                $fileC = "$base/unittest-cont1/e/a/b/fileC.txt";
@@ -2434,16 +2410,10 @@ class FileBackendTest extends MediaWikiTestCase {
        }
 
        function tearDownFiles() {
-               foreach ( $this->filesToPrune as $file ) {
-                       if ( is_file( $file ) ) {
-                               unlink( $file );
-                       }
-               }
                $containers = array( 'unittest-cont1', 'unittest-cont2', 'unittest-cont-bad' );
                foreach ( $containers as $container ) {
                        $this->deleteFiles( $container );
                }
-               $this->filesToPrune = array();
        }
 
        private function deleteFiles( $container ) {
index 9cc2efb..86bfe12 100644 (file)
@@ -16,7 +16,7 @@ class StoreBatchTest extends MediaWikiTestCase {
                parent::setUp();
 
                # Forge a FSRepo object to not have to rely on local wiki settings
-               $tmpPrefix = wfTempDir() . '/storebatch-test-' . time() . '-' . mt_rand();
+               $tmpPrefix = $this->getNewTempDirectory();
                if ( $this->getCliArg( 'use-filebackend' ) ) {
                        $name = $this->getCliArg( 'use-filebackend' );
                        $useConfig = array();
@@ -35,10 +35,10 @@ class StoreBatchTest extends MediaWikiTestCase {
                                'name' => 'local-testing',
                                'wikiId' => wfWikiID(),
                                'containerPaths' => array(
-                                       'unittests-public' => "{$tmpPrefix}-public",
-                                       'unittests-thumb' => "{$tmpPrefix}-thumb",
-                                       'unittests-temp' => "{$tmpPrefix}-temp",
-                                       'unittests-deleted' => "{$tmpPrefix}-deleted",
+                                       'unittests-public' => "{$tmpPrefix}/public",
+                                       'unittests-thumb' => "{$tmpPrefix}/thumb",
+                                       'unittests-temp' => "{$tmpPrefix}/temp",
+                                       'unittests-deleted' => "{$tmpPrefix}/deleted",
                                )
                        ) );
                }
@@ -52,13 +52,8 @@ class StoreBatchTest extends MediaWikiTestCase {
        }
 
        protected function tearDown() {
-               $this->repo->cleanupBatch( $this->createdFiles ); // delete files
-               foreach ( $this->createdFiles as $tmp ) { // delete dirs
-                       $tmp = $this->repo->resolveVirtualUrl( $tmp );
-                       while ( $tmp = FileBackend::parentStoragePath( $tmp ) ) {
-                               $this->repo->getBackend()->clean( array( 'dir' => $tmp ) );
-                       }
-               }
+               // Delete files
+               $this->repo->cleanupBatch( $this->createdFiles );
                parent::tearDown();
        }
 
index 010ae66..3ce3e1f 100644 (file)
@@ -124,7 +124,7 @@ class NewParserTest extends MediaWikiTestCase {
                $tmpGlobals['wgFileExtensions'][] = 'svg';
                $tmpGlobals['wgSVGConverter'] = 'rsvg';
                $tmpGlobals['wgSVGConverters']['rsvg'] =
-                       '$path/rsvg-convert -w $width -h $height $input -o $output';
+                       '$path/rsvg-convert -w $width -h $height -o $output $input';
 
                if ( $GLOBALS['wgStyleDirectory'] === false ) {
                        $tmpGlobals['wgStyleDirectory'] = "$IP/skins";
@@ -480,16 +480,16 @@ class NewParserTest extends MediaWikiTestCase {
         */
        protected function getUploadDir() {
                if ( $this->keepUploads ) {
+                       // Don't use getNewTempDirectory() as this is meant to persist
                        $dir = wfTempDir() . '/mwParser-images';
 
                        if ( is_dir( $dir ) ) {
                                return $dir;
                        }
                } else {
-                       $dir = wfTempDir() . "/mwParser-" . mt_rand() . "-images";
+                       $dir = $this->getNewTempDirectory();
                }
 
-               // wfDebug( "Creating upload directory $dir\n" );
                if ( file_exists( $dir ) ) {
                        wfDebug( "Already exists!\n" );
 
index 96df354..b4c225c 100644 (file)
@@ -97,6 +97,173 @@ class ExtensionProcessorTest extends MediaWikiTestCase {
                $this->assertArrayNotHasKey( 'wg@IGNORED', $extracted['globals'] );
        }
 
+       public static function provideExtracttExtensionMessagesFiles() {
+               $dir = __DIR__ . '/FooBar/';
+               return array(
+                       array(
+                               array( 'ExtensionMessagesFiles' => array( 'FooBarAlias' => 'FooBar.alias.php' ) ),
+                               array( 'wgExtensionMessagesFiles' => array( 'FooBarAlias' => $dir . 'FooBar.alias.php' ) )
+                       ),
+                       array(
+                               array(
+                                       'ExtensionMessagesFiles' => array(
+                                               'FooBarAlias' => 'FooBar.alias.php',
+                                               'FooBarMagic' => 'FooBar.magic.i18n.php',
+                                       ),
+                               ),
+                               array(
+                                       'wgExtensionMessagesFiles' => array(
+                                               'FooBarAlias' => $dir . 'FooBar.alias.php',
+                                               'FooBarMagic' => $dir . 'FooBar.magic.i18n.php',
+                                       ),
+                               ),
+                       ),
+               );
+       }
+
+       /**
+        * @covers ExtensionProcessor::extracttExtensionMessagesFiles
+        * @dataProvider provideExtracttExtensionMessagesFiles
+        */
+       public function testExtracttExtensionMessagesFiles( $input, $expected ) {
+               $processor = new ExtensionProcessor();
+               $processor->extractInfo( $this->dir, $input + self::$default );
+               $out = $processor->getExtractedInfo();
+               foreach ( $expected as $key => $value ) {
+                       $this->assertEquals( $value, $out['globals'][$key] );
+               }
+       }
+
+
+       public static function provideExtractMessagesDirs() {
+               $dir = __DIR__ . '/FooBar/';
+               return array(
+                       array(
+                               array( 'MessagesDirs' => array( 'VisualEditor' => 'i18n' ) ),
+                               array( 'wgMessagesDirs' => array( 'VisualEditor' => array( $dir . 'i18n' ) ) )
+                       ),
+                       array(
+                               array( 'MessagesDirs' => array( 'VisualEditor' => array( 'i18n', 'foobar' ) ) ),
+                               array( 'wgMessagesDirs' => array( 'VisualEditor' => array( $dir . 'i18n', $dir . 'foobar' ) ) )
+                       ),
+               );
+       }
+
+       /**
+        * @covers ExtensionProcessor::extractMessagesDirs
+        * @dataProvider provideExtractMessagesDirs
+        */
+       public function testExtractMessagesDirs( $input, $expected ) {
+               $processor = new ExtensionProcessor();
+               $processor->extractInfo( $this->dir, $input + self::$default );
+               $out = $processor->getExtractedInfo();
+               foreach ( $expected as $key => $value ) {
+                       $this->assertEquals( $value, $out['globals'][$key] );
+               }
+       }
+
+       /**
+        * @covers ExtensionProcessor::extractResourceLoaderModules
+        * @dataProvider provideExtractResourceLoaderModules
+        */
+       public function testExtractResourceLoaderModules( $input, $expected ) {
+               $processor = new ExtensionProcessor();
+               $processor->extractInfo( $this->dir, $input + self::$default );
+               $out = $processor->getExtractedInfo();
+               foreach ( $expected as $key => $value ) {
+                       $this->assertEquals( $value, $out['globals'][$key] );
+               }
+       }
+
+       public static function provideExtractResourceLoaderModules() {
+               $dir = __DIR__ . '/FooBar/';
+               return array(
+                       // Generic module with localBasePath/remoteExtPath specified
+                       array(
+                               // Input
+                               array(
+                                       'ResourceModules' => array(
+                                               'test.foo' => array(
+                                                       'styles' => 'foobar.js',
+                                                       'localBasePath' => '',
+                                                       'remoteExtPath' => 'FooBar',
+                                               ),
+                                       ),
+                               ),
+                               // Expected
+                               array(
+                                       'wgResourceModules' => array(
+                                               'test.foo' => array(
+                                                       'styles' => 'foobar.js',
+                                                       'localBasePath' => $dir,
+                                                       'remoteExtPath' => 'FooBar',
+                                               ),
+                                       ),
+                               ),
+                       ),
+                       // ResourceFileModulePaths specified:
+                       array(
+                               // Input
+                               array(
+                                       'ResourceFileModulePaths' => array(
+                                               'localBasePath' => '',
+                                               'remoteExtPath' => 'FooBar',
+                                       ),
+                                       'ResourceModules' => array(
+                                               // No paths
+                                               'test.foo' => array(
+                                                       'styles' => 'foo.js',
+                                               ),
+                                               // Different paths set
+                                               'test.bar' => array(
+                                                       'styles' => 'bar.js',
+                                                       'localBasePath' => 'subdir',
+                                                       'remoteExtPath' => 'FooBar/subdir',
+                                               ),
+                                               // Custom class with no paths set
+                                               'test.class' => array(
+                                                       'class' => 'FooBarModule',
+                                                       'extra' => 'argument',
+                                               ),
+                                               // Custom class with a localBasePath
+                                               'test.class.with.path' => array(
+                                                       'class' => 'FooBarPathModule',
+                                                       'extra' => 'argument',
+                                                       'localBasePath' => '',
+                                               )
+                                       ),
+                               ),
+                               // Expected
+                               array(
+                                       'wgResourceModules' => array(
+                                               'test.foo' => array(
+                                                       'styles' => 'foo.js',
+                                                       'localBasePath' => $dir,
+                                                       'remoteExtPath' => 'FooBar',
+                                               ),
+                                               'test.bar' => array(
+                                                       'styles' => 'bar.js',
+                                                       'localBasePath' => $dir . 'subdir',
+                                                       'remoteExtPath' => 'FooBar/subdir',
+                                               ),
+                                               'test.class' => array(
+                                                       'class' => 'FooBarModule',
+                                                       'extra' => 'argument',
+                                                       'localBasePath' => $dir,
+                                                       'remoteExtPath' => 'FooBar',
+                                               ),
+                                               'test.class.with.path' => array(
+                                                       'class' => 'FooBarPathModule',
+                                                       'extra' => 'argument',
+                                                       'localBasePath' => $dir,
+                                                       'remoteExtPath' => 'FooBar',
+                                               )
+                                       ),
+                               ),
+                       ),
+               );
+       }
+
        public static function provideSetToGlobal() {
                return array(
                        array(
index f23b264..63ad8c0 100644 (file)
@@ -93,7 +93,7 @@ class UploadBaseTest extends MediaWikiTestCase {
 
        // Helper used to create an empty file of size $size.
        private function createFileOfSize( $size ) {
-               $filename = tempnam( wfTempDir(), "mwuploadtest" );
+               $filename = $this->getNewTempFile();
 
                $fh = fopen( $filename, 'w' );
                ftruncate( $fh, $size );
@@ -118,7 +118,6 @@ class UploadBaseTest extends MediaWikiTestCase {
                $filename = $this->createFileOfSize( 100 );
                $this->upload->initializePathInfo( basename( $filename ) . '.txt', $filename, 100 );
                $result = $this->upload->verifyUpload();
-               unlink( $filename );
 
                $this->assertEquals(
                        array( 'status' => UploadBase::OK ),
index f6ea1b4..a87721b 100644 (file)
@@ -46,7 +46,7 @@
        } );
 
        QUnit.test( 'updateTooltipAccessKeys - current browser', 2, function ( assert ) {
-               var title = $( makeInput ( 'Title', 'a' ) ).updateTooltipAccessKeys().prop( 'title' ),
+               var title = $( makeInput( 'Title', 'a' ) ).updateTooltipAccessKeys().prop( 'title' ),
                        //The new title should be something like "Title [alt-a]", but the exact label will depend on the browser.
                        //The "a" could be capitalized, and the prefix could be anything, e.g. a simple "^" for ctrl-
                        //(no browser is known using such a short prefix, though) or "Alt+Umschalt+" in German Firefox.
index bbea829..78c185f 100644 (file)
@@ -1,10 +1,10 @@
-(function ($) {
+( function ($) {
 
        QUnit.module('jquery.placeholder', QUnit.newMwEnvironment());
 
        QUnit.test('caches results of feature tests', 2, function (assert) {
-               assert.strictEqual(typeof $.fn.placeholder.input, 'boolean', '$.fn.placeholder.input');
-               assert.strictEqual(typeof $.fn.placeholder.textarea, 'boolean', '$.fn.placeholder.textarea');
+               assert.strictEqual( typeof $.fn.placeholder.input, 'boolean', '$.fn.placeholder.input');
+               assert.strictEqual( typeof $.fn.placeholder.textarea, 'boolean', '$.fn.placeholder.textarea');
        });
 
        if ($.fn.placeholder.input && $.fn.placeholder.textarea) {
index ece5116..1fb1723 100644 (file)
@@ -1,6 +1,7 @@
 ( function ( mw, $ ) {
-       var mwLanguageCache = {}, formatText, formatParse, formatnumTests, specialCharactersPageName,
-               expectedListUsers, expectedEntrypoints;
+       var formatText, formatParse, formatnumTests, specialCharactersPageName, expectedListUsers, expectedEntrypoints,
+               mwLanguageCache = {},
+               hasOwn = Object.hasOwnProperty;
 
        // When the expected result is the same in both modes
        function assertBothModes( assert, parserArguments, expectedResult, assertMessage ) {
                }
        } ) );
 
-       function getMwLanguage( langCode, cb ) {
-               if ( mwLanguageCache[langCode] !== undefined ) {
-                       mwLanguageCache[langCode].add( cb );
-                       return;
-               }
-               mwLanguageCache[langCode] = $.Callbacks( 'once memory' );
-               mwLanguageCache[langCode].add( cb );
-               $.ajax( {
-                       url: mw.util.wikiScript( 'load' ),
-                       data: {
-                               skin: mw.config.get( 'skin' ),
-                               lang: langCode,
-                               debug: mw.config.get( 'debug' ),
-                               modules: [
-                                       'mediawiki.language.data',
-                                       'mediawiki.language'
-                               ].join( '|' ),
-                               only: 'scripts'
-                       },
-                       dataType: 'script'
-               } ).done(function () {
-                               mwLanguageCache[langCode].fire( mw.language );
-                       } ).fail( function () {
-                               mwLanguageCache[langCode].fire( false );
+       /**
+        * Be careful to no run this in parallel as it uses a global identifier (mw.language)
+        * to transport the module back to the test. It musn't be overwritten concurrentely.
+        *
+        * This function caches the mw.language data to avoid having to request the same module
+        * multiple times. There is more than one test case for any given language.
+        */
+       function getMwLanguage( langCode ) {
+               if ( !hasOwn.call( mwLanguageCache, langCode ) ) {
+                       mwLanguageCache[langCode] = $.ajax( {
+                               url: mw.util.wikiScript( 'load' ),
+                               data: {
+                                       skin: mw.config.get( 'skin' ),
+                                       lang: langCode,
+                                       debug: mw.config.get( 'debug' ),
+                                       modules: [
+                                               'mediawiki.language.data',
+                                               'mediawiki.language'
+                                       ].join( '|' ),
+                                       only: 'scripts'
+                               },
+                               dataType: 'script',
+                               cache: true
+                       } ).then( function () {
+                               return mw.language;
                        } );
+               }
+               return mwLanguageCache[langCode];
+       }
+
+       /**
+        * @param {Function[]} tasks List of functions that perform tasks
+        *  that may be asynchronous. Invoke the callback parameter when done.
+        * @param {Function} done When all tasks are done.
+        * @return
+        */
+       function process( tasks, done ) {
+               function run() {
+                       var task = tasks.shift();
+                       if ( task ) {
+                               task( run );
+                       } else {
+                               done();
+                       }
+               }
+               run();
        }
 
        QUnit.test( 'Replace', 16, function ( assert ) {
 
        QUnit.test( 'Match PHP parser', mw.libs.phpParserData.tests.length, function ( assert ) {
                mw.messages.set( mw.libs.phpParserData.messages );
-               $.each( mw.libs.phpParserData.tests, function ( i, test ) {
-                       QUnit.stop();
-                       getMwLanguage( test.lang, function ( langClass ) {
-                               QUnit.start();
-                               if ( !langClass ) {
-                                       assert.ok( false, 'Language "' + test.lang + '" failed to load' );
-                                       return;
-                               }
-                               mw.config.set( 'wgUserLanguage', test.lang );
-                               var parser = new mw.jqueryMsg.parser( { language: langClass } );
-                               assert.equal(
-                                       parser.parse( test.key, test.args ).html(),
-                                       test.result,
-                                       test.name
-                               );
-                       } );
+               var tasks = $.map( mw.libs.phpParserData.tests, function ( test ) {
+                       return function ( next ) {
+                               getMwLanguage( test.lang )
+                                       .done( function ( langClass ) {
+                                               mw.config.set( 'wgUserLanguage', test.lang );
+                                               var parser = new mw.jqueryMsg.parser( { language: langClass } );
+                                               assert.equal(
+                                                       parser.parse( test.key, test.args ).html(),
+                                                       test.result,
+                                                       test.name
+                                               );
+                                       } )
+                                       .fail( function () {
+                                               assert.ok( false, 'Language "' + test.lang + '" failed to load.' );
+                                       } )
+                                       .always( next );
+                       };
                } );
+
+               QUnit.stop();
+               process( tasks, QUnit.start );
        } );
 
        QUnit.test( 'Links', 6, function ( assert ) {
                );
        } );
 
-// Tests that getMessageFunction is used for non-plain messages with curly braces or
-// square brackets, but not otherwise.
+       // Tests that getMessageFunction is used for non-plain messages with curly braces or
+       // square brackets, but not otherwise.
        QUnit.test( 'mw.Message.prototype.parser monkey-patch', 22, function ( assert ) {
                var oldGMF, outerCalled, innerCalled;
 
@@ -618,25 +644,27 @@ formatnumTests = [
 QUnit.test( 'formatnum', formatnumTests.length, function ( assert ) {
        mw.messages.set( 'formatnum-msg', '{{formatnum:$1}}' );
        mw.messages.set( 'formatnum-msg-int', '{{formatnum:$1|R}}' );
-       $.each( formatnumTests, function ( i, test ) {
-               QUnit.stop();
-               getMwLanguage( test.lang, function ( langClass ) {
-                       QUnit.start();
-                       if ( !langClass ) {
-                               assert.ok( false, 'Language "' + test.lang + '" failed to load' );
-                               return;
-                       }
-                       mw.messages.set(test.message );
-                       mw.config.set( 'wgUserLanguage', test.lang );
-                       var parser = new mw.jqueryMsg.parser( { language: langClass } );
-                       assert.equal(
-                               parser.parse( test.integer ? 'formatnum-msg-int' : 'formatnum-msg',
-                                       [ test.number ] ).html(),
-                               test.result,
-                               test.description
-                       );
-               } );
+       var queue = $.map( formatnumTests, function ( test ) {
+               return function ( next ) {
+                       getMwLanguage( test.lang )
+                               .done( function ( langClass ) {
+                                       mw.config.set( 'wgUserLanguage', test.lang );
+                                       var parser = new mw.jqueryMsg.parser( { language: langClass } );
+                                       assert.equal(
+                                               parser.parse( test.integer ? 'formatnum-msg-int' : 'formatnum-msg',
+                                                       [ test.number ] ).html(),
+                                               test.result,
+                                               test.description
+                                       );
+                               } )
+                               .fail( function () {
+                                       assert.ok( false, 'Language "' + test.lang + '" failed to load' );
+                               } )
+                               .always( next );
+               };
        } );
+       QUnit.stop();
+       process( queue, QUnit.start );
 } );
 
 // HTML in wikitext
index 16f90df..a068846 100644 (file)
                }
        } ) );
 
-       QUnit.test( 'mw.language getData and setData', 2, function ( assert ) {
+       QUnit.test( 'mw.language getData and setData', 3, function ( assert ) {
                mw.language.setData( 'en', 'testkey', 'testvalue' );
                assert.equal( mw.language.getData( 'en', 'testkey' ), 'testvalue', 'Getter setter test for mw.language' );
                assert.equal( mw.language.getData( 'en', 'invalidkey' ), undefined, 'Getter setter test for mw.language with invalid key' );
+               mw.language.setData( 'en-us', 'testkey', 'testvalue' );
+               assert.equal( mw.language.getData( 'en-US', 'testkey' ), 'testvalue', 'Case insensitive test for mw.language' );
        } );
 
        QUnit.test( 'mw.language.commafy test', 9, function ( assert ) {
index 7aa9133..3f19a64 100644 (file)
                } );
        } );
 
-       QUnit.test( 'getUrl', 4, function ( assert ) {
+       QUnit.test( 'getUrl', 5, function ( assert ) {
                // Not part of startUp module
                mw.config.set( 'wgArticlePath', '/wiki/$1' );
                mw.config.set( 'wgPageName', 'Foobar' );
 
                var href = mw.util.getUrl( 'Sandbox' );
-               assert.equal( href, '/wiki/Sandbox', 'Simple title; Get link for "Sandbox"' );
+               assert.equal( href, '/wiki/Sandbox', 'simple title' );
 
-               href = mw.util.getUrl( 'Foo:Sandbox ? 5+5=10 ! (test)/subpage' );
-               assert.equal( href, '/wiki/Foo:Sandbox_%3F_5%2B5%3D10_!_(test)/subpage',
-                       'Advanced title; Get link for "Foo:Sandbox ? 5+5=10 ! (test)/subpage"' );
+               href = mw.util.getUrl( 'Foo:Sandbox? 5+5=10! (test)/sub ' );
+               assert.equal( href, '/wiki/Foo:Sandbox%3F_5%2B5%3D10!_(test)/sub_', 'advanced title' );
 
                href = mw.util.getUrl();
-               assert.equal( href, '/wiki/Foobar', 'Default title; Get link for current page ("Foobar")' );
+               assert.equal( href, '/wiki/Foobar', 'default title' );
+
+               href = mw.util.getUrl( null, { action: 'edit' } );
+               assert.equal( href, '/wiki/Foobar?action=edit', 'default title with query string' );
 
                href = mw.util.getUrl( 'Sandbox', { action: 'edit' } );
-               assert.equal( href, '/wiki/Sandbox?action=edit',
-                       'Simple title with query string; Get link for "Sandbox" with action=edit' );
+               assert.equal( href, '/wiki/Sandbox?action=edit', 'simple title with query string' );
        } );
 
        QUnit.test( 'wikiScript', 4, function ( assert ) {
index 7352dc4..70cd1e6 100644 (file)
--- a/thumb.php
+++ b/thumb.php
@@ -252,10 +252,12 @@ function wfStreamThumb( array $params ) {
        try {
                $thumbName = $img->thumbName( $params );
                if ( !strlen( $thumbName ) ) { // invalid params?
-                       wfThumbError( 400, 'The specified thumbnail parameters are not valid.' );
-                       return;
+                       throw new MediaTransformInvalidParametersException( 'Empty return from File::thumbName' );
                }
                $thumbName2 = $img->thumbName( $params, File::THUMB_FULL_NAME ); // b/c; "long" style
+       } catch ( MediaTransformInvalidParametersException $e ) {
+               wfThumbError( 400, 'The specified thumbnail parameters are not valid: ' . $e->getMessage() );
+               return;
        } catch ( MWException $e ) {
                wfThumbError( 500, $e->getHTML() );
                return;
@@ -321,6 +323,7 @@ function wfStreamThumb( array $params ) {
 
        // Check for thumbnail generation errors...
        $msg = wfMessage( 'thumbnail_error' );
+       $errorCode = 500;
        if ( !$thumb ) {
                $errorMsg = $errorMsg ?: $msg->rawParams( 'File::transform() returned false' )->escaped();
        } elseif ( $thumb->isError() ) {
@@ -330,10 +333,11 @@ function wfStreamThumb( array $params ) {
        } elseif ( $thumb->fileIsSource() ) {
                $errorMsg = $msg->
                        rawParams( 'Image was not scaled, is the requested width bigger than the source?' )->escaped();
+               $errorCode = 400;
        }
 
        if ( $errorMsg !== false ) {
-               wfThumbError( 500, $errorMsg );
+               wfThumbError( $errorCode, $errorMsg );
        } else {
                // Stream the file if there were no errors
                $thumb->streamFile( $headers );
@@ -424,66 +428,6 @@ function wfGenerateThumbnail( File $file, array $params, $thumbName, $thumbPath
        return array( $thumb, $errorHtml );
 }
 
-/**
- * Returns true if this thumbnail is one that MediaWiki generates
- * links to on file description pages and possibly parser output.
- *
- * $params is considered non-standard if they involve a non-standard
- * width or any non-default parameters aside from width and page number.
- * The number of possible files with standard parameters is far less than
- * that of all combinations; rate-limiting for them can thus be more generious.
- *
- * @param File $file
- * @param array $params
- * @return bool
- */
-function wfThumbIsStandard( File $file, array $params ) {
-       global $wgThumbLimits, $wgImageLimits;
-
-       $handler = $file->getHandler();
-       if ( !$handler || !isset( $params['width'] ) ) {
-               return false;
-       }
-
-       $basicParams = array();
-       if ( isset( $params['page'] ) ) {
-               $basicParams['page'] = $params['page'];
-       }
-
-       // Check if the width matches one of $wgThumbLimits
-       if ( in_array( $params['width'], $wgThumbLimits ) ) {
-               $normalParams = $basicParams + array( 'width' => $params['width'] );
-               // Append any default values to the map (e.g. "lossy", "lossless", ...)
-               $handler->normaliseParams( $file, $normalParams );
-       } else {
-               // If not, then check if the width matchs one of $wgImageLimits
-               $match = false;
-               foreach ( $wgImageLimits as $pair ) {
-                       $normalParams = $basicParams + array( 'width' => $pair[0], 'height' => $pair[1] );
-                       // Decide whether the thumbnail should be scaled on width or height.
-                       // Also append any default values to the map (e.g. "lossy", "lossless", ...)
-                       $handler->normaliseParams( $file, $normalParams );
-                       // Check if this standard thumbnail size maps to the given width
-                       if ( $normalParams['width'] == $params['width'] ) {
-                               $match = true;
-                               break;
-                       }
-               }
-               if ( !$match ) {
-                       return false; // not standard for description pages
-               }
-       }
-
-       // Check that the given values for non-page, non-width, params are just defaults
-       foreach ( $params as $key => $value ) {
-               if ( !isset( $normalParams[$key] ) || $normalParams[$key] != $value ) {
-                       return false;
-               }
-       }
-
-       return true;
-}
-
 /**
  * Convert pathinfo type parameter, into normal request parameters
  *
@@ -605,7 +549,9 @@ function wfThumbError( $status, $msg ) {
 
        header( 'Cache-Control: no-cache' );
        header( 'Content-Type: text/html; charset=utf-8' );
-       if ( $status == 404 ) {
+       if ( $status == 400 ) {
+               header( 'HTTP/1.1 400 Bad request' );
+       } elseif ( $status == 404 ) {
                header( 'HTTP/1.1 404 Not found' );
        } elseif ( $status == 403 ) {
                header( 'HTTP/1.1 403 Forbidden' );
@@ -622,7 +568,11 @@ function wfThumbError( $status, $msg ) {
                $debug = '';
        }
        echo <<<EOT
-<html><head><title>Error generating thumbnail</title></head>
+<!DOCTYPE html>
+<html><head>
+<meta charset="UTF-8" />
+<title>Error generating thumbnail</title>
+</head>
 <body>
 <h1>Error generating thumbnail</h1>
 <p>