Merge "Fix positioning error with draggable, revert and grid"
authorjenkins-bot <jenkins-bot@gerrit.wikimedia.org>
Mon, 30 Jan 2017 13:32:49 +0000 (13:32 +0000)
committerGerrit Code Review <gerrit@wikimedia.org>
Mon, 30 Jan 2017 13:32:50 +0000 (13:32 +0000)
251 files changed:
.mailmap
README
RELEASE-NOTES-1.29
autoload.php
docs/extension.schema.v2.json
docs/hooks.txt
includes/CategoryViewer.php
includes/DefaultSettings.php
includes/EditPage.php
includes/FileDeleteForm.php
includes/MWGrants.php
includes/OutputPage.php
includes/Preferences.php
includes/ProtectionForm.php
includes/RevisionList.php
includes/Sanitizer.php
includes/Setup.php
includes/SiteStats.php
includes/Title.php
includes/TrackingCategories.php [new file with mode: 0644]
includes/api/ApiBase.php
includes/api/ApiErrorFormatter.php
includes/api/ApiMain.php
includes/api/ApiQueryAllImages.php
includes/api/ApiQueryAllUsers.php
includes/api/ApiQueryContributors.php
includes/api/ApiQueryUserInfo.php
includes/api/ApiQueryUsers.php
includes/api/ApiUpload.php
includes/api/ApiUserrights.php
includes/api/i18n/de.json
includes/api/i18n/en.json
includes/api/i18n/es.json
includes/api/i18n/fr.json
includes/api/i18n/it.json
includes/api/i18n/ko.json
includes/api/i18n/lt.json
includes/api/i18n/nl.json
includes/api/i18n/qqq.json
includes/api/i18n/ru.json
includes/api/i18n/zh-hans.json
includes/cache/HTMLFileCache.php
includes/cache/LinkCache.php
includes/cache/MessageCache.php
includes/changes/RecentChange.php
includes/content/ContentHandler.php
includes/db/DatabaseMssql.php
includes/deferred/WANCacheReapUpdate.php [new file with mode: 0644]
includes/exception/PermissionsError.php
includes/filerepo/file/ArchivedFile.php
includes/filerepo/file/LocalFile.php
includes/installer/Installer.php
includes/installer/MysqlUpdater.php
includes/installer/OracleUpdater.php
includes/installer/PostgresUpdater.php
includes/installer/SqliteUpdater.php
includes/installer/i18n/ast.json
includes/installer/i18n/be-tarask.json
includes/installer/i18n/bn.json
includes/installer/i18n/ca.json
includes/installer/i18n/cs.json
includes/installer/i18n/de.json
includes/installer/i18n/el.json
includes/installer/i18n/en.json
includes/installer/i18n/es.json
includes/installer/i18n/fr.json
includes/installer/i18n/gl.json
includes/installer/i18n/it.json
includes/installer/i18n/ko.json
includes/installer/i18n/lb.json
includes/installer/i18n/mk.json
includes/installer/i18n/nb.json
includes/installer/i18n/nl.json
includes/installer/i18n/pl.json
includes/installer/i18n/qqq.json
includes/installer/i18n/ru.json
includes/installer/i18n/sr-ec.json
includes/installer/i18n/sv.json
includes/installer/i18n/tl.json
includes/installer/i18n/war.json
includes/installer/i18n/zh-hans.json
includes/libs/objectcache/WANObjectCache.php
includes/libs/objectcache/WANObjectCacheReaper.php [new file with mode: 0644]
includes/logging/BlockLogFormatter.php
includes/logging/LogFormatter.php
includes/logging/RightsLogFormatter.php
includes/page/Article.php
includes/page/WikiPage.php
includes/parser/Parser.php
includes/parser/ParserOutput.php
includes/search/SearchEngine.php
includes/skins/SkinTemplate.php
includes/specialpage/ChangesListSpecialPage.php
includes/specials/SpecialActiveusers.php
includes/specials/SpecialBlock.php
includes/specials/SpecialListgrouprights.php
includes/specials/SpecialMIMEsearch.php
includes/specials/SpecialTrackingCategories.php
includes/specials/SpecialUnusedimages.php
includes/specials/SpecialUpload.php
includes/specials/SpecialUserrights.php
includes/specials/pagers/ActiveUsersPager.php
includes/specials/pagers/CategoryPager.php
includes/specials/pagers/ContribsPager.php
includes/specials/pagers/NewFilesPager.php
includes/specials/pagers/UsersPager.php
includes/tidy/Balancer.php
includes/upload/UploadBase.php
includes/user/User.php
includes/user/UserGroupMembership.php [new file with mode: 0644]
includes/user/UserRightsProxy.php
includes/widget/search/FullSearchResultWidget.php
languages/Language.php
languages/classes/LanguageFi.php
languages/i18n/ar.json
languages/i18n/ast.json
languages/i18n/ba.json
languages/i18n/be-tarask.json
languages/i18n/bn.json
languages/i18n/br.json
languages/i18n/bs.json
languages/i18n/ca.json
languages/i18n/cs.json
languages/i18n/da.json
languages/i18n/de.json
languages/i18n/diq.json
languages/i18n/el.json
languages/i18n/en.json
languages/i18n/eo.json
languages/i18n/es.json
languages/i18n/et.json
languages/i18n/eu.json
languages/i18n/ext.json
languages/i18n/fi.json
languages/i18n/fr.json
languages/i18n/frp.json
languages/i18n/gl.json
languages/i18n/glk.json
languages/i18n/gom-latn.json
languages/i18n/gor.json
languages/i18n/he.json
languages/i18n/hif-latn.json
languages/i18n/hr.json
languages/i18n/hsb.json
languages/i18n/hu.json
languages/i18n/ia.json
languages/i18n/io.json
languages/i18n/it.json
languages/i18n/ja.json
languages/i18n/ko.json
languages/i18n/ku-latn.json
languages/i18n/lb.json
languages/i18n/lfn.json
languages/i18n/lij.json
languages/i18n/lki.json
languages/i18n/lt.json
languages/i18n/lv.json
languages/i18n/mk.json
languages/i18n/ml.json
languages/i18n/mr.json
languages/i18n/my.json
languages/i18n/nah.json
languages/i18n/nb.json
languages/i18n/nl.json
languages/i18n/nn.json
languages/i18n/oc.json
languages/i18n/pcd.json
languages/i18n/pl.json
languages/i18n/pt-br.json
languages/i18n/pt.json
languages/i18n/qqq.json
languages/i18n/ru.json
languages/i18n/sah.json
languages/i18n/sd.json
languages/i18n/sh.json
languages/i18n/shn.json
languages/i18n/sl.json
languages/i18n/sr-ec.json
languages/i18n/sr-el.json
languages/i18n/sv.json
languages/i18n/ta.json
languages/i18n/te.json
languages/i18n/tet.json
languages/i18n/th.json
languages/i18n/tl.json
languages/i18n/udm.json
languages/i18n/uk.json
languages/i18n/war.json
languages/i18n/zh-hans.json
languages/i18n/zh-hant.json
languages/messages/MessagesCa.php
languages/messages/MessagesOc.php
languages/messages/MessagesSh.php
maintenance/archives/patch-user_groups-ug_expiry.sql [new file with mode: 0644]
maintenance/manageJobs.php [new file with mode: 0644]
maintenance/mssql/archives/patch-user_groups-ug_expiry.sql [new file with mode: 0644]
maintenance/mssql/tables.sql
maintenance/oracle/archives/patch-user_groups-ug_expiry.sql [new file with mode: 0644]
maintenance/oracle/tables.sql
maintenance/postgres/tables.sql
maintenance/refreshLinks.php
maintenance/sqlite/archives/patch-user_groups-ug_expiry.sql [new file with mode: 0644]
maintenance/tables.sql
resources/Resources.php
resources/src/mediawiki.rcfilters/dm/mw.rcfilters.dm.FilterItem.js
resources/src/mediawiki.rcfilters/dm/mw.rcfilters.dm.FiltersViewModel.js
resources/src/mediawiki.rcfilters/mw.rcfilters.Controller.js
resources/src/mediawiki.rcfilters/mw.rcfilters.init.js
resources/src/mediawiki.rcfilters/styles/mw.rcfilters.less [deleted file]
resources/src/mediawiki.rcfilters/styles/mw.rcfilters.ui.FilterCapsuleMultiselectWidget.less
resources/src/mediawiki.rcfilters/styles/mw.rcfilters.ui.FilterGroupWidget.less
resources/src/mediawiki.rcfilters/styles/mw.rcfilters.ui.FilterItemWidget.less
resources/src/mediawiki.rcfilters/styles/mw.rcfilters.ui.FilterWrapperWidget.less
resources/src/mediawiki.rcfilters/ui/mw.rcfilters.ui.FilterCapsuleMultiselectWidget.js
resources/src/mediawiki.rcfilters/ui/mw.rcfilters.ui.FilterGroupWidget.js
resources/src/mediawiki.rcfilters/ui/mw.rcfilters.ui.FilterItemWidget.js
resources/src/mediawiki.rcfilters/ui/mw.rcfilters.ui.FilterWrapperWidget.js
resources/src/mediawiki.skinning/content.css
resources/src/mediawiki.special/mediawiki.special.apisandbox.css
resources/src/mediawiki.special/mediawiki.special.apisandbox.js
resources/src/mediawiki.special/mediawiki.special.userrights.css [new file with mode: 0644]
resources/src/mediawiki.special/mediawiki.special.userrights.js
resources/src/mediawiki/api/options.js
resources/src/mediawiki/mediawiki.notification.js
resources/src/mediawiki/mediawiki.reasonSuggest.js [deleted file]
tests/browser/features/login.feature
tests/browser/features/step_definitions/login_steps.rb
tests/browser/features/support/pages/create_account_page.rb
tests/browser/features/support/pages/login_page.rb
tests/parser/ParserTestRunner.php
tests/parser/parserTests.txt
tests/phan/config.php
tests/phan/stubs/mail.php
tests/phpunit/includes/OutputPageTest.php
tests/phpunit/includes/api/ApiErrorFormatterTest.php
tests/phpunit/includes/api/ApiMainTest.php
tests/phpunit/includes/cache/MessageCacheTest.php
tests/phpunit/includes/changes/RCCacheEntryFactoryTest.php
tests/phpunit/includes/content/ContentHandlerTest.php
tests/phpunit/includes/libs/objectcache/WANObjectCacheTest.php
tests/phpunit/includes/logging/RightsLogFormatterTest.php
tests/phpunit/includes/page/WikiPageTest.php
tests/phpunit/includes/password/UserPasswordPolicyTest.php
tests/phpunit/includes/rcfeed/RCFeedIntegrationTest.php [new file with mode: 0644]
tests/phpunit/includes/skins/SkinTemplateTest.php
tests/phpunit/includes/tidy/BalancerTest.php
tests/phpunit/includes/tidy/html5lib-tests.json
tests/phpunit/includes/user/UserGroupMembershipTest.php [new file with mode: 0644]
tests/phpunit/includes/user/UserTest.php
tests/phpunit/languages/LanguageTest.php
tests/qunit/suites/resources/mediawiki.rcfilters/dm.FiltersViewModel.test.js

index 7aa3257..232824d 100644 (file)
--- a/.mailmap
+++ b/.mailmap
@@ -209,6 +209,7 @@ Jeff Hall <jeffreyehall@gmail.com>
 Jeff Hall <jeffreyehall@gmail.com> <jhall@wikimedia.org>
 Jeff Hobson <jhobson@wikimedia.org>
 Jeff Janes <jeff.janes@gmail.com>
+Jeremy Baron <jeremy@tuxmachine.com>
 Jeremy Postlethwaite <jpostlethwaite@wikimedia.org> <jpostlethwaite@users.mediawiki.org>
 Jeroen De Dauw <jeroendedauw@gmail.com>
 Jeroen De Dauw <jeroendedauw@gmail.com> <jeroendedauw@users.mediawiki.org>
@@ -217,6 +218,7 @@ Jiabao <jiabao.foss@gmail.com>
 Jimmy Collins <jimmy.collins@web.de> <collinj@users.mediawiki.org>
 Joel Sahleen <jsahleen@wikimedia.org>
 John Du Hart <john@compwhizii.net> <johnduhart@users.mediawiki.org>
+John Erling Blad <john.blad@wikimedia.de>
 Jon Harald Søby <jhsoby@gmail.com> <jhsoby@users.mediawiki.org>
 Jon Robson <jrobson@wikimedia.org>
 Jon Robson <jrobson@wikimedia.org> <jdlrobson@gmail.com>
@@ -272,6 +274,7 @@ Markus Glaser <glaser@hallowelt.biz> <mglaser@users.mediawiki.org>
 Matt Johnston <mattj@emazestudios.com> <mattj@users.mediawiki.org>
 Matthew Britton <hugglegurch@gmail.com> <gurch@users.mediawiki.org>
 Matthew Flaschen <mflaschen@wikimedia.org>
+Matthew Walker <mwalker@wikimedia.org>
 Matthias Mullie <git@mullie.eu>
 Matthias Mullie <git@mullie.eu> <mmullie@wikimedia.org>
 Matěj Grabovský <mgrabovsky@yahoo.com> <mgrabovsky@users.mediawiki.org>
@@ -288,7 +291,6 @@ Mormegil <mormegil@centrum.cz>
 MrBlueSky <mrbluesky@wikipedia.be>
 MrBlueSky <mrbluesky@wikipedia.be> <mrbluesky@localhost>
 Mukunda Modell <mmodell@wikimedia.org>
-Mwalker <mwalker@wikimedia.org>
 MZMcBride <g@mzmcbride.com>
 nadeesha <nadeesha@calcey.com> <nadeesha@users.mediawiki.org>
 Namit <namit.ohri@gmail.com>
@@ -311,10 +313,12 @@ OverlordQ <wikipedia@thedarkcitadel.com> <overlordq@users.mediawiki.org>
 Owen Davis <owen@wikia-inc.com>
 Owen Davis <owen@wikia-inc.com> <owen@users.mediawiki.org>
 paladox <thomasmulhall410@yahoo.com>
+Patricio Molina <patriciomolina@gmail.com>
 Patrick Reilly <preilly@wikimedia.org>
 Patrick Reilly <preilly@wikimedia.org> <preilly@users.mediawiki.org>
 Patrick Westerhoff <PatrickWesterhoff@gmail.com>
 Paul Copperman <paul.copperman@gmail.com> <pcopp@users.mediawiki.org>
+Peter Coombe <pcoombe@wikimedia.org>
 Peter Coti <petercoti@gmail.com>
 Peter Potrowl <peter017@gmail.com> <peter17@users.mediawiki.org>
 Petr Kadlec <mormegil@centrum.cz>
@@ -399,10 +403,10 @@ Stephane Bisson <sbisson@wikimedia.org>
 Stephen Liang <github@stephenliang.pw>
 Steve Sanbeg <ffnaort@jro.qr> <sanbeg@users.mediawiki.org>
 Steven Roddis <StevenRoddis@users.noreply.github.com>
+Steven Walling <swalling@wikimedia.org>
 Subramanya Sastry <ssastry@wikimedia.org>
 Sucheta Ghoshal <sghoshal@wikimedia.org>
 Sumit Asthana <asthana.sumit23@gmail.com>
-Swalling <swalling@wikimedia.org>
 Thalia Chan <thalia@cantorion.org>
 Thiemo Mättig (WMDE) <thiemo.maettig@wikimedia.de>
 Thiemo Mättig (WMDE) <thiemo.maettig@wikimedia.de> <mr.heat@gmx.de>
@@ -420,7 +424,6 @@ Timo Tijhof <krinklemail@gmail.com> <krinkle@users.mediawiki.org>
 Timo Tijhof <krinklemail@gmail.com> <timo@wikimedia.org>
 Timo Tijhof <krinklemail@gmail.com> <ttijhof@wikimedia.org>
 Tina Johnson <tinajohnson.1234@gmail.com>
-Tjones <tjones@wikimedia.org>
 Tom Maaswinkel <tom.maaswinkel@12wiki.eu> <thedevilonline@users.mediawiki.org>
 Tomasz Finc <tfinc@wikimedia.org> <tomasz@users.mediawiki.org>
 Tomasz W. Kozlowski <tomasz@twkozlowski.com>
@@ -431,9 +434,11 @@ Tpt <thomaspt@hotmail.fr>
 Trevor Parscal <trevorparscal@gmail.com>
 Trevor Parscal <trevorparscal@gmail.com> <tparscal@users.mediawiki.org>
 Trevor Parscal <trevorparscal@gmail.com> <tparscal@wikimedia.org>
+Trey Jones <tjones@wikimedia.org>
 Tyler Cipriani <tcipriani@wikimedia.org>
 Tyler Romeo <tylerromeo@gmail.com>
 Umherirrender <umherirrender_de.wp@web.de>
+Victor Barbu <victorbarbu08@gmail.com>
 Victor Vasiliev <vasilvv@mit.edu>
 Victor Vasiliev <vasilvv@mit.edu> <vasilievvv@users.mediawiki.org>
 Victor Vasiliev <vasilvv@mit.edu> <vasilvv@gmail.com>
diff --git a/README b/README
index 6d3ab80..ad9b9d9 100644 (file)
--- a/README
+++ b/README
@@ -19,7 +19,7 @@ RELEASE-NOTES, INSTALL, and UPGRADE.
 * Ready to get started?
 ** https://www.mediawiki.org/wiki/Special:MyLanguage/Download
 * Looking for the technical manual?
-** https://www.mediawiki.org/wiki/Special:MyLangyage/Manual:Contents
+** https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Contents
 * Seeking help from a person?
 ** https://www.mediawiki.org/wiki/Special:MyLanguage/Communication
 * Looking to file a bug report or a feature request?
index 024a6f4..883729b 100644 (file)
@@ -28,6 +28,9 @@ production.
   $wgNamespacesWithSubpages[NS_TEMPLATE] to false to keep the old behavior.
 * $wgRunJobsAsync is now false by default (T142751). This change only affects
   wikis with $wgJobRunRate > 0.
+* A temporary feature flag, $wgDisableUserGroupExpiry, is provided to disable
+  new features that rely on the schema changes to the user_groups table. This
+  feature flag will likely be removed before 1.29 is released.
 
 === New features in 1.29 ===
 * (T5233) A cookie can now be set when a user is autoblocked, to track that user
@@ -44,12 +47,11 @@ production.
   from certain IP ranges (e.g. private IPs).
 * (T59603) Added new magic word {{PAGELANGUAGE}} which returns the language code
   of the page being parsed.
-* Added JavaScript that provides as-you-type suggestions for reason
-  on the block, delete and protect forms.
 * HTML5 form validation attributes will no longer be suppressed. Originally
   browsers had poor support for them, but modern browsers handle them fine.
   This might affect some forms that used them and only worked because the
   attributes were not actually being set.
+* Expiry times can now be specified when users are added to user groups.
 
 === External library changes in 1.29 ===
 
@@ -207,6 +209,27 @@ changes to languages because of Phabricator reports.
 * Parser::replaceUnusualEscapes() (deprecated in 1.24) was removed.
 * Article::doEditContent() was marked as deprecated, to be removed in 1.30
   or later.
+* ContentHandler::runLegacyHooks() was removed.
+* refreshLinks.php now can be limited to a particular category with --category=...
+  or a tracking category with --tracking-category=...
+* User-like objects that are passed to SpecialUserRights and its subclasses are
+  now required to have a getGroupMemberships() method. See UserRightsProxy for
+  an example.
+* User::$mGroups (instance variable) was marked private. Use User::getGroups()
+  instead.
+* User::getGroupName(), User::getGroupMember(), User:getGroupPage(),
+  User::makeGroupLinkHTML(), and User::makeGroupLinkWiki() were deprecated.
+  Use equivalent methods on the UserGroupMembership class.
+* Maintenance scripts and tests that call User::addGroup() must now ensure that
+  User objects have been added to the database prior to calling addGroup().
+* Protected function UsersPager::getGroups() was removed, and protected function
+  UsersPager::buildGroupLink() was changed from a static to an instance method.
+* The third parameter ($cache) to the UsersPagerDoBatchLookups hook was changed;
+  see docs/hooks.txt.
+* User::crypt() (deprecated in 1.24) was removed.
+* User::comparePasswords() (deprecated in 1.24) was removed.
+* ArchivedFile::getUserText() (deprecated in 1.23) was removed.
+* HTMLFileCache::newFromTitle() (deprecated in 1.24) was removed.
 
 == Compatibility ==
 
index 5d0ca0d..2bc110c 100644 (file)
@@ -810,6 +810,7 @@ $wgAutoloadLocalClasses = [
        'MaintenanceFormatInstallDoc' => __DIR__ . '/maintenance/formatInstallDoc.php',
        'MakeTestEdits' => __DIR__ . '/maintenance/makeTestEdits.php',
        'MalformedTitleException' => __DIR__ . '/includes/title/MalformedTitleException.php',
+       'ManageJobs' => __DIR__ . '/maintenance/manageJobs.php',
        'ManualLogEntry' => __DIR__ . '/includes/logging/LogEntry.php',
        'MapCacheLRU' => __DIR__ . '/includes/libs/MapCacheLRU.php',
        'MappedIterator' => __DIR__ . '/includes/libs/MappedIterator.php',
@@ -1458,6 +1459,7 @@ $wgAutoloadLocalClasses = [
        'TitlePrefixSearch' => __DIR__ . '/includes/PrefixSearch.php',
        'TitleValue' => __DIR__ . '/includes/title/TitleValue.php',
        'TrackBlobs' => __DIR__ . '/maintenance/storage/trackBlobs.php',
+       'TrackingCategories' => __DIR__ . '/includes/TrackingCategories.php',
        'TraditionalImageGallery' => __DIR__ . '/includes/gallery/TraditionalImageGallery.php',
        'TransactionProfiler' => __DIR__ . '/includes/libs/rdbms/TransactionProfiler.php',
        'TransformParameterError' => __DIR__ . '/includes/media/MediaTransformOutput.php',
@@ -1522,6 +1524,7 @@ $wgAutoloadLocalClasses = [
        'UserBlockedError' => __DIR__ . '/includes/exception/UserBlockedError.php',
        'UserCache' => __DIR__ . '/includes/cache/UserCache.php',
        'UserDupes' => __DIR__ . '/maintenance/userDupes.inc',
+       'UserGroupMembership' => __DIR__ . '/includes/user/UserGroupMembership.php',
        'UserMailer' => __DIR__ . '/includes/mail/UserMailer.php',
        'UserNamePrefixSearch' => __DIR__ . '/includes/user/UserNamePrefixSearch.php',
        'UserNotLoggedIn' => __DIR__ . '/includes/exception/UserNotLoggedIn.php',
@@ -1539,7 +1542,9 @@ $wgAutoloadLocalClasses = [
        'ViewCLI' => __DIR__ . '/maintenance/view.php',
        'VirtualRESTService' => __DIR__ . '/includes/libs/virtualrest/VirtualRESTService.php',
        'VirtualRESTServiceClient' => __DIR__ . '/includes/libs/virtualrest/VirtualRESTServiceClient.php',
+       'WANCacheReapUpdate' => __DIR__ . '/includes/deferred/WANCacheReapUpdate.php',
        'WANObjectCache' => __DIR__ . '/includes/libs/objectcache/WANObjectCache.php',
+       'WANObjectCacheReaper' => __DIR__ . '/includes/libs/objectcache/WANObjectCacheReaper.php',
        'WantedCategoriesPage' => __DIR__ . '/includes/specials/SpecialWantedcategories.php',
        'WantedFilesPage' => __DIR__ . '/includes/specials/SpecialWantedfiles.php',
        'WantedPagesPage' => __DIR__ . '/includes/specials/SpecialWantedpages.php',
index a5543d1..b7ee1a7 100644 (file)
@@ -56,6 +56,7 @@
                "requires": {
                        "type": "object",
                        "description": "Indicates what versions of MediaWiki core or extensions are required. This syntax may be extended in the future, for example to check dependencies between other services.",
+                       "additionalProperties": false,
                        "properties": {
                                "MediaWiki": {
                                        "type": "string",
index c5b112d..27773f6 100644 (file)
@@ -365,6 +365,11 @@ $user: Current user
  * 1.27+: IApiMessage, or a key or key+parameters in ApiBase::$messageMap.
  * Earlier: A key or key+parameters in ApiBase::$messageMap.
 
+'ApiDeprecationHelp': Add messages to the 'deprecation-help' warning generated
+from ApiBase::addDeprecation().
+&$msgs: Message[] Messages to include in the help. Multiple messages will be
+  joined with spaces.
+
 'APIEditBeforeSave': DEPRECATED! Use EditFilterMergedContent instead.
 Before saving a page with api.php?action=edit, after
 processing request parameters. Return false to let the request fail, returning
@@ -2823,11 +2828,11 @@ $terms: Search terms, for highlighting
 
 'ShowSearchHitTitle': Customise display of search hit title/link.
 &$title: Title to link to
-&$text: Text to use for the link
-$result: The search result
-$terms: The search terms entered
-$page: The SpecialSearch object
-&$query: Query string to be appended to the link
+&$titleSnippet: Label for the link representing the search result. Typically the article title.
+$result: The SearchResult object
+$terms: String of the search terms entered
+$specialSearch: The SpecialSearch object
+&$query: Array of query string parameters for the link representing the search result.
 
 'SidebarBeforeOutput': Allows to edit sidebar just before it is output by skins.
 Warning: This hook is run on each display. You should consider to use
@@ -3452,10 +3457,12 @@ temporary password
 &$ip: IP of the user who sent the message out
 &$u: the account whose new password will be set
 
-'UserAddGroup': Called when adding a group; return false to override
-stock group addition.
+'UserAddGroup': Called when adding a group or changing a group's expiry; return
+false to override stock group addition.
 $user: the user object that is to have a group added
-&$group: the group to add, can be modified
+&$group: the group to add; can be modified
+&$expiry: the expiry time in TS_MW format, or null if the group is not to
+expire; can be modified
 
 'UserArrayFromResult': Called when creating an UserArray object from a database
 result.
@@ -3698,7 +3705,8 @@ their data into the cache array so that things like global user groups are
 displayed correctly in Special:ListUsers.
 $dbr: Read-only database handle
 $userIds: Array of user IDs whose groups we should look up
-&$cache: Array of user ID -> internal user group name (e.g. 'sysop') mappings
+&$cache: Array of user ID -> (array of internal group name (e.g. 'sysop') ->
+UserGroupMembership object)
 &$groups: Array of group name -> bool true mappings for members of a given user
 group
 
index facf847..31369b0 100644 (file)
@@ -632,11 +632,12 @@ class CategoryViewer extends ContextSource {
        private function pagingLinks( $first, $last, $type = '' ) {
                $prevLink = $this->msg( 'prev-page' )->text();
 
+               $linkRenderer = MediaWikiServices::getInstance()->getLinkRenderer();
                if ( $first != '' ) {
                        $prevQuery = $this->query;
                        $prevQuery["{$type}until"] = $first;
                        unset( $prevQuery["{$type}from"] );
-                       $prevLink = Linker::linkKnown(
+                       $prevLink = $linkRenderer->makeKnownLink(
                                $this->addFragmentToTitle( $this->title, $type ),
                                $prevLink,
                                [],
@@ -650,7 +651,7 @@ class CategoryViewer extends ContextSource {
                        $lastQuery = $this->query;
                        $lastQuery["{$type}from"] = $last;
                        unset( $lastQuery["{$type}until"] );
-                       $nextLink = Linker::linkKnown(
+                       $nextLink = $linkRenderer->makeKnownLink(
                                $this->addFragmentToTitle( $this->title, $type ),
                                $nextLink,
                                [],
index 086b615..a7cbd96 100644 (file)
@@ -2342,6 +2342,19 @@ $wgWANObjectCaches = [
        */
 ];
 
+/**
+ * Verify and enforce WAN cache purges using reliable DB sources as streams.
+ *
+ * These secondary cache purges are de-duplicated via simple cache mutexes.
+ * This improves consistency when cache purges are lost, which becomes more likely
+ * as more cache servers are added or if there are multiple datacenters. Only keys
+ * related to important mutable content will be checked.
+ *
+ * @var bool
+ * @since 1.29
+ */
+$wgEnableWANCacheReaper = false;
+
 /**
  * Main object stash type. This should be a fast storage system for storing
  * lightweight data like hit counters and user activity. Sites with multiple
@@ -5870,6 +5883,15 @@ $wgBotPasswordsCluster = false;
  */
 $wgBotPasswordsDatabase = false;
 
+/**
+ * Whether to disable user group expiry. This is a transitional feature flag
+ * in accordance with WMF schema change policy, and will be removed later
+ * (hopefully before MW 1.29 release).
+ *
+ * @since 1.29
+ */
+$wgDisableUserGroupExpiry = false;
+
 /** @} */ # end of user rights settings
 
 /************************************************************************//**
index de08880..e070ca3 100644 (file)
@@ -498,6 +498,9 @@ class EditPage {
                $this->enableApiEditOverride = $enableOverride;
        }
 
+       /**
+        * @deprecated since 1.29, call edit directly
+        */
        function submit() {
                $this->edit();
        }
@@ -3573,6 +3576,7 @@ HTML
         */
        public function getCancelLink() {
                $cancelParams = [];
+               $linkRenderer = MediaWikiServices::getInstance()->getLinkRenderer();
                if ( !$this->isConflict && $this->oldid > 0 ) {
                        $cancelParams['oldid'] = $this->oldid;
                } elseif ( $this->getContextTitle()->isRedirect() ) {
@@ -3580,9 +3584,9 @@ HTML
                }
                $attrs = [ 'id' => 'mw-editform-cancel' ];
 
-               return Linker::linkKnown(
+               return $linkRenderer->makeKnownLink(
                        $this->getContextTitle(),
-                       $this->context->msg( 'cancel' )->parse(),
+                       new HtmlArmor( $this->context->msg( 'cancel' )->parse() ),
                        Html::buttonAttributes( $attrs, [ 'mw-ui-quiet' ] ),
                        $cancelParams
                );
index f850152..82af081 100644 (file)
@@ -21,6 +21,7 @@
  * @author Rob Church <robchur@gmail.com>
  * @ingroup Media
  */
+use MediaWiki\MediaWikiServices;
 
 /**
  * File deletion user interface
@@ -301,9 +302,10 @@ class FileDeleteForm {
 
                        if ( $wgUser->isAllowed( 'editinterface' ) ) {
                                $title = wfMessage( 'filedelete-reason-dropdown' )->inContentLanguage()->getTitle();
-                               $link = Linker::linkKnown(
+                               $linkRenderer = MediaWikiServices::getInstance()->getLinkRenderer();
+                               $link = $linkRenderer->makeKnownLink(
                                        $title,
-                                       wfMessage( 'filedelete-edit-reasonlist' )->escaped(),
+                                       wfMessage( 'filedelete-edit-reasonlist' )->text(),
                                        [],
                                        [ 'action' => 'edit' ]
                                );
index 58efdc7..c7c54fd 100644 (file)
@@ -17,6 +17,7 @@
  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  * http://www.gnu.org/copyleft/gpl.html
  */
+use MediaWiki\MediaWikiServices;
 
 /**
  * A collection of public static functions to deal with grants.
@@ -178,9 +179,10 @@ class MWGrants {
         * @return string (proto-relative) HTML link
         */
        public static function getGrantsLink( $grant, $lang = null ) {
-               return \Linker::linkKnown(
+               $linkRenderer = MediaWikiServices::getInstance()->getLinkRenderer();
+               return $linkRenderer->makeKnownLink(
                        \SpecialPage::getTitleFor( 'Listgrants', false, $grant ),
-                       htmlspecialchars( self::grantName( $grant, $lang ) )
+                       self::grantName( $grant, $lang )
                );
        }
 
index 922960f..91fc75c 100644 (file)
@@ -2515,9 +2515,10 @@ class OutputPage extends ContextSource {
                                        $query['returntoquery'] = wfArrayToCgi( $returntoquery );
                                }
                        }
-                       $loginLink = Linker::linkKnown(
+                       $linkRenderer = MediaWikiServices::getInstance()->getLinkRenderer();
+                       $loginLink = $linkRenderer->makeKnownLink(
                                SpecialPage::getTitleFor( 'Userlogin' ),
-                               $this->msg( 'loginreqlink' )->escaped(),
+                               $this->msg( 'loginreqlink' )->text(),
                                [],
                                $query
                        );
@@ -3258,9 +3259,11 @@ class OutputPage extends ContextSource {
                }
 
                foreach ( $this->mMetatags as $tag ) {
-                       if ( 0 == strcasecmp( 'http:', substr( $tag[0], 0, 5 ) ) ) {
+                       if ( strncasecmp( $tag[0], 'http:', 5 ) === 0 ) {
                                $a = 'http-equiv';
                                $tag[0] = substr( $tag[0], 5 );
+                       } elseif ( strncasecmp( $tag[0], 'og:', 3 ) === 0 ) {
+                               $a = 'property';
                        } else {
                                $a = 'name';
                        }
index 89982a6..6d15c1e 100644 (file)
@@ -222,24 +222,48 @@ class Preferences {
                        'section' => 'personal/info',
                ];
 
+               $lang = $context->getLanguage();
+
                # Get groups to which the user belongs
                $userEffectiveGroups = $user->getEffectiveGroups();
-               $userGroups = $userMembers = [];
+               $userGroupMemberships = $user->getGroupMemberships();
+               $userGroups = $userMembers = $userTempGroups = $userTempMembers = [];
                foreach ( $userEffectiveGroups as $ueg ) {
                        if ( $ueg == '*' ) {
                                // Skip the default * group, seems useless here
                                continue;
                        }
-                       $groupName = User::getGroupName( $ueg );
-                       $userGroups[] = User::makeGroupLinkHTML( $ueg, $groupName );
 
-                       $memberName = User::getGroupMember( $ueg, $userName );
-                       $userMembers[] = User::makeGroupLinkHTML( $ueg, $memberName );
-               }
-               asort( $userGroups );
-               asort( $userMembers );
+                       if ( isset( $userGroupMemberships[$ueg] ) ) {
+                               $groupStringOrObject = $userGroupMemberships[$ueg];
+                       } else {
+                               $groupStringOrObject = $ueg;
+                       }
 
-               $lang = $context->getLanguage();
+                       $userG = UserGroupMembership::getLink( $groupStringOrObject, $context, 'html' );
+                       $userM = UserGroupMembership::getLink( $groupStringOrObject, $context, 'html',
+                               $userName );
+
+                       // Store expiring groups separately, so we can place them before non-expiring
+                       // groups in the list. This is to avoid the ambiguity of something like
+                       // "administrator, bureaucrat (until X date)" -- users might wonder whether the
+                       // expiry date applies to both groups, or just the last one
+                       if ( $groupStringOrObject instanceof UserGroupMembership &&
+                               $groupStringOrObject->getExpiry()
+                       ) {
+                               $userTempGroups[] = $userG;
+                               $userTempMembers[] = $userM;
+                       } else {
+                               $userGroups[] = $userG;
+                               $userMembers[] = $userM;
+                       }
+               }
+               sort( $userGroups );
+               sort( $userMembers );
+               sort( $userTempGroups );
+               sort( $userTempMembers );
+               $userGroups = array_merge( $userTempGroups, $userGroups );
+               $userMembers = array_merge( $userTempMembers, $userMembers );
 
                $defaultPreferences['usergroups'] = [
                        'type' => 'info',
@@ -493,9 +517,9 @@ class Preferences {
                                        } else {
                                                $disableEmailPrefs = true;
                                                $emailauthenticated = $context->msg( 'emailnotauthenticated' )->parse() . '<br />' .
-                                                       Linker::linkKnown(
+                                                       $linkRenderer->makeKnownLink(
                                                                SpecialPage::getTitleFor( 'Confirmemail' ),
-                                                               $context->msg( 'emailconfirmlink' )->escaped()
+                                                               $context->msg( 'emailconfirmlink' )->text()
                                                        ) . '<br />';
                                                $emailauthenticationclass = "mw-email-not-authenticated";
                                        }
@@ -942,11 +966,12 @@ class Preferences {
                                'raw' => [ 'EditWatchlist', 'raw' ],
                                'clear' => [ 'EditWatchlist', 'clear' ],
                        ];
+                       $linkRenderer = MediaWikiServices::getInstance()->getLinkRenderer();
                        foreach ( $editWatchlistModes as $editWatchlistMode => $mode ) {
                                // Messages: prefs-editwatchlist-edit, prefs-editwatchlist-raw, prefs-editwatchlist-clear
-                               $editWatchlistLinks[] = Linker::linkKnown(
+                               $editWatchlistLinks[] = $linkRenderer->makeKnownLink(
                                        SpecialPage::getTitleFor( $mode[0], $mode[1] ),
-                                       $context->msg( "prefs-editwatchlist-{$editWatchlistMode}" )->parse()
+                                       new HtmlArmor( $context->msg( "prefs-editwatchlist-{$editWatchlistMode}" )->parse() )
                                );
                        }
 
index bcf4dda..a68c36f 100644 (file)
@@ -22,6 +22,7 @@
  *
  * @file
  */
+use MediaWiki\MediaWikiServices;
 
 /**
  * Handles the page protection UI and backend
@@ -182,21 +183,10 @@ class ProtectionForm {
                        throw new ErrorPageError( 'protect-badnamespace-title', 'protect-badnamespace-text' );
                }
 
-               $out = $this->mContext->getOutput();
-               if ( !wfMessage( 'protect-dropdown' )->inContentLanguage()->isDisabled() ) {
-                       $reasonsList = Xml::getArrayFromWikiTextList(
-                               wfMessage( 'protect-dropdown' )->inContentLanguage()->text()
-                       );
-                       $out->addModules( 'mediawiki.reasonSuggest' );
-                       $out->addJsConfigVars( [
-                               'reasons' => $reasonsList
-                       ] );
-               }
-
                if ( $this->mContext->getRequest()->wasPosted() ) {
                        if ( $this->save() ) {
                                $q = $this->mArticle->isRedirect() ? 'redirect=no' : '';
-                               $out->redirect( $this->mTitle->getFullURL( $q ) );
+                               $this->mContext->getOutput()->redirect( $this->mTitle->getFullURL( $q ) );
                        }
                } else {
                        $this->show();
@@ -554,9 +544,10 @@ class ProtectionForm {
                $out .= Xml::closeElement( 'fieldset' );
 
                if ( $user->isAllowed( 'editinterface' ) ) {
-                       $link = Linker::linkKnown(
+                       $linkRenderer = MediaWikiServices::getInstance()->getLinkRenderer();
+                       $link = $linkRenderer->makeKnownLink(
                                $context->msg( 'protect-dropdown' )->inContentLanguage()->getTitle(),
-                               $context->msg( 'protect-edit-reasonlist' )->escaped(),
+                               $context->msg( 'protect-edit-reasonlist' )->text(),
                                [],
                                [ 'action' => 'edit' ]
                        );
index 052fd16..53cf699 100644 (file)
@@ -363,13 +363,14 @@ class RevisionItem extends RevisionItemBase {
         * @return string
         */
        protected function getRevisionLink() {
-               $date = htmlspecialchars( $this->list->getLanguage()->userTimeAndDate(
-                       $this->revision->getTimestamp(), $this->list->getUser() ) );
+               $date = $this->list->getLanguage()->userTimeAndDate(
+                       $this->revision->getTimestamp(), $this->list->getUser() );
 
                if ( $this->isDeleted() && !$this->canViewContent() ) {
-                       return $date;
+                       return htmlspecialchars( $date );
                }
-               return Linker::linkKnown(
+               $linkRenderer = $this->getLinkRenderer();
+               return $linkRenderer->makeKnownLink(
                        $this->list->title,
                        $date,
                        [],
@@ -391,9 +392,10 @@ class RevisionItem extends RevisionItemBase {
                if ( $this->isDeleted() && !$this->canViewContent() ) {
                        return $this->context->msg( 'diff' )->escaped();
                } else {
-                       return Linker::linkKnown(
+                       $linkRenderer = $this->getLinkRenderer();
+                       return $linkRenderer->makeKnownLink(
                                        $this->list->title,
-                                       $this->list->msg( 'diff' )->escaped(),
+                                       $this->list->msg( 'diff' )->text(),
                                        [],
                                        [
                                                'diff' => $this->revision->getId(),
index 6779189..42b166d 100644 (file)
@@ -1119,6 +1119,7 @@ class Sanitizer {
                        '>'    => '&gt;',   // we've received invalid input
                        '"'    => '&quot;', // which should have been escaped.
                        '{'    => '&#123;',
+                       '}'    => '&#125;', // prevent unpaired language conversion syntax
                        '['    => '&#91;',
                        "''"   => '&#39;&#39;',
                        'ISBN' => '&#73;SBN',
index ecd164d..01ba1e8 100644 (file)
@@ -244,7 +244,7 @@ if ( $wgUseInstantCommons ) {
                'transformVia404' => true,
                'fetchDescription' => true,
                'descriptionCacheExpiry' => 43200,
-               'apiThumbCacheExpiry' => 86400,
+               'apiThumbCacheExpiry' => 0,
        ];
 }
 /*
index ff7875c..42b080f 100644 (file)
@@ -193,7 +193,10 @@ class SiteStats {
                                return $dbr->selectField(
                                        'user_groups',
                                        'COUNT(*)',
-                                       [ 'ug_group' => $group ],
+                                       [
+                                               'ug_group' => $group,
+                                               'ug_expiry IS NULL OR ug_expiry >= ' . $dbr->addQuotes( $dbr->timestamp() )
+                                       ],
                                        __METHOD__
                                );
                        },
index 5cf911f..3ce775b 100644 (file)
@@ -2417,7 +2417,7 @@ class Title implements LinkTarget {
         *
         * @param string $action The action to check
         * @param bool $short Short circuit on first error
-        * @return array List of errors
+        * @return array Array containing an error message key and any parameters
         */
        private function missingPermissionError( $action, $short ) {
                // We avoid expensive display logic for quickUserCan's and such
@@ -2425,19 +2425,7 @@ class Title implements LinkTarget {
                        return [ 'badaccess-group0' ];
                }
 
-               $groups = array_map( [ 'User', 'makeGroupLinkWiki' ],
-                       User::getGroupsWithPermission( $action ) );
-
-               if ( count( $groups ) ) {
-                       global $wgLang;
-                       return [
-                               'badaccess-groups',
-                               $wgLang->commaList( $groups ),
-                               count( $groups )
-                       ];
-               } else {
-                       return [ 'badaccess-group0' ];
-               }
+               return User::newFatalPermissionDeniedStatus( $action )->getErrorsArray()[0];
        }
 
        /**
diff --git a/includes/TrackingCategories.php b/includes/TrackingCategories.php
new file mode 100644 (file)
index 0000000..825860a
--- /dev/null
@@ -0,0 +1,130 @@
+<?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 Categories
+ */
+
+/**
+ * This class performs some operations related to tracking categories, such as creating
+ * a list of all such categories.
+ */
+class TrackingCategories {
+       /** @var Config */
+       private $config;
+
+       /**
+        * Tracking categories that exist in core
+        *
+        * @var array
+        */
+       private static $coreTrackingCategories = [
+               'index-category',
+               'noindex-category',
+               'duplicate-args-category',
+               'expensive-parserfunction-category',
+               'post-expand-template-argument-category',
+               'post-expand-template-inclusion-category',
+               'hidden-category-category',
+               'broken-file-category',
+               'node-count-exceeded-category',
+               'expansion-depth-exceeded-category',
+               'restricted-displaytitle-ignored',
+               'deprecated-self-close-category',
+       ];
+
+       /**
+        * @param Config $config
+        */
+       public function __construct( Config $config ) {
+               $this->config = $config;
+       }
+
+       /**
+        * Read the global and extract title objects from the corresponding messages
+        * @return array Array( 'msg' => Title, 'cats' => Title[] )
+        */
+       public function getTrackingCategories() {
+               $categories = array_merge(
+                       self::$coreTrackingCategories,
+                       ExtensionRegistry::getInstance()->getAttribute( 'TrackingCategories' ),
+                       $this->config->get( 'TrackingCategories' ) // deprecated
+               );
+
+               // Only show magic link tracking categories if they are enabled
+               $enableMagicLinks = $this->config->get( 'EnableMagicLinks' );
+               if ( $enableMagicLinks['ISBN'] ) {
+                       $categories[] = 'magiclink-tracking-isbn';
+               }
+               if ( $enableMagicLinks['RFC'] ) {
+                       $categories[] = 'magiclink-tracking-rfc';
+               }
+               if ( $enableMagicLinks['PMID'] ) {
+                       $categories[] = 'magiclink-tracking-pmid';
+               }
+
+               $trackingCategories = [];
+               foreach ( $categories as $catMsg ) {
+                       /*
+                        * Check if the tracking category varies by namespace
+                        * Otherwise only pages in the current namespace will be displayed
+                        * If it does vary, show pages considering all namespaces
+                        */
+                       $msgObj = wfMessage( $catMsg )->inContentLanguage();
+                       $allCats = [];
+                       $catMsgTitle = Title::makeTitleSafe( NS_MEDIAWIKI, $catMsg );
+                       if ( !$catMsgTitle ) {
+                               continue;
+                       }
+
+                       // Match things like {{NAMESPACE}} and {{NAMESPACENUMBER}}.
+                       // False positives are ok, this is just an efficiency shortcut
+                       if ( strpos( $msgObj->plain(), '{{' ) !== false ) {
+                               $ns = MWNamespace::getValidNamespaces();
+                               foreach ( $ns as $namesp ) {
+                                       $tempTitle = Title::makeTitleSafe( $namesp, $catMsg );
+                                       if ( !$tempTitle ) {
+                                               continue;
+                                       }
+                                       $catName = $msgObj->title( $tempTitle )->text();
+                                       # Allow tracking categories to be disabled by setting them to "-"
+                                       if ( $catName !== '-' ) {
+                                               $catTitle = Title::makeTitleSafe( NS_CATEGORY, $catName );
+                                               if ( $catTitle ) {
+                                                       $allCats[] = $catTitle;
+                                               }
+                                       }
+                               }
+                       } else {
+                               $catName = $msgObj->text();
+                               # Allow tracking categories to be disabled by setting them to "-"
+                               if ( $catName !== '-' ) {
+                                       $catTitle = Title::makeTitleSafe( NS_CATEGORY, $catName );
+                                       if ( $catTitle ) {
+                                               $allCats[] = $catTitle;
+                                       }
+                               }
+                       }
+                       $trackingCategories[$catMsg] = [
+                               'cats' => $allCats,
+                               'msg' => $catMsgTitle,
+                       ];
+               }
+
+               return $trackingCategories;
+       }
+}
index b8dd464..e249810 100644 (file)
@@ -1718,6 +1718,18 @@ abstract class ApiBase extends ContextSource {
                        $this->logFeatureUsage( $feature );
                }
                $this->addWarning( $msg, 'deprecation', $data );
+
+               // No real need to deduplicate here, ApiErrorFormatter does that for
+               // us (assuming the hook is deterministic).
+               $msgs = [ $this->msg( 'api-usage-mailinglist-ref' ) ];
+               Hooks::run( 'ApiDeprecationHelp', [ &$msgs ] );
+               if ( count( $msgs ) > 1 ) {
+                       $key = '$' . join( ' $', range( 1, count( $msgs ) ) );
+                       $msg = ( new RawMessage( $key ) )->params( $msgs );
+               } else {
+                       $msg = reset( $msgs );
+               }
+               $this->getMain()->addWarning( $msg, 'deprecation-help' );
        }
 
        /**
index 814004a..c52b731 100644 (file)
@@ -414,12 +414,17 @@ class ApiErrorFormatter_BackCompat extends ApiErrorFormatter {
 
                if ( $tag === 'error' ) {
                        // In BC mode, only one error
-                       $value = [
-                               'code' => $msg->getApiCode(),
-                               'info' => $value,
-                       ] + $msg->getApiData();
-                       $this->result->addValue( null, 'error', $value,
-                               ApiResult::OVERRIDE | ApiResult::ADD_ON_TOP | ApiResult::NO_SIZE_CHECK );
+                       $existingError = $this->result->getResultData( [ 'error' ] );
+                       if ( !is_array( $existingError ) ||
+                               !isset( $existingError['code'] ) || !isset( $existingError['info'] )
+                       ) {
+                               $value = [
+                                       'code' => $msg->getApiCode(),
+                                       'info' => $value,
+                               ] + $msg->getApiData();
+                               $this->result->addValue( null, 'error', $value,
+                                       ApiResult::OVERRIDE | ApiResult::ADD_ON_TOP | ApiResult::NO_SIZE_CHECK );
+                       }
                } else {
                        if ( $modulePath === null ) {
                                $moduleName = 'unknown';
index 52f1d95..59227d9 100644 (file)
@@ -1109,7 +1109,11 @@ class ApiMain extends ApiBase {
                        $result->addContentValue(
                                $path,
                                'docref',
-                               $this->msg( 'api-usage-docref', $link )->inLanguage( $formatter->getLanguage() )->text()
+                               trim(
+                                       $this->msg( 'api-usage-docref', $link )->inLanguage( $formatter->getLanguage() )->text()
+                                       . ' '
+                                       . $this->msg( 'api-usage-mailinglist-ref' )->inLanguage( $formatter->getLanguage() )->text()
+                               )
                        );
                } else {
                        if ( $config->get( 'ShowExceptionDetails' ) ) {
index e3e5ed6..22561a9 100644 (file)
@@ -197,7 +197,8 @@ class ApiQueryAllImages extends ApiQueryGeneratorBase {
                                        'LEFT JOIN',
                                        [
                                                'ug_group' => User::getGroupsWithPermission( 'bot' ),
-                                               'ug_user = img_user'
+                                               'ug_user = img_user',
+                                               'ug_expiry IS NULL OR ug_expiry >=' . $db->addQuotes( $db->timestamp() )
                                        ]
                                ] ] );
                                $groupCond = ( $params['filterbots'] == 'nobots' ? 'NULL' : 'NOT NULL' );
index 2e2ac32..3faccf9 100644 (file)
@@ -116,8 +116,16 @@ class ApiQueryAllUsers extends ApiQueryBase {
                        // Filter only users that belong to a given group. This might
                        // produce as many rows-per-user as there are groups being checked.
                        $this->addTables( 'user_groups', 'ug1' );
-                       $this->addJoinConds( [ 'ug1' => [ 'INNER JOIN', [ 'ug1.ug_user=user_id',
-                               'ug1.ug_group' => $params['group'] ] ] ] );
+                       $this->addJoinConds( [
+                               'ug1' => [
+                                       'INNER JOIN',
+                                       [
+                                               'ug1.ug_user=user_id',
+                                               'ug1.ug_group' => $params['group'],
+                                               'ug1.ug_expiry IS NULL OR ug1.ug_expiry >= ' . $db->addQuotes( $db->timestamp() )
+                                       ]
+                               ]
+                       ] );
                        $maxDuplicateRows *= count( $params['group'] );
                }
 
@@ -135,7 +143,10 @@ class ApiQueryAllUsers extends ApiQueryBase {
                                ) ];
                        }
                        $this->addJoinConds( [ 'ug1' => [ 'LEFT OUTER JOIN',
-                               array_merge( [ 'ug1.ug_user=user_id' ], $exclude )
+                               array_merge( [
+                                       'ug1.ug_user=user_id',
+                                       'ug1.ug_expiry IS NULL OR ug1.ug_expiry >= ' . $db->addQuotes( $db->timestamp() )
+                               ], $exclude )
                        ] ] );
                        $this->addWhere( 'ug1.ug_user IS NULL' );
                }
@@ -148,7 +159,10 @@ class ApiQueryAllUsers extends ApiQueryBase {
 
                if ( $fld_groups || $fld_rights ) {
                        $this->addFields( [ 'groups' =>
-                               $db->buildGroupConcatField( '|', 'user_groups', 'ug_group', 'ug_user=user_id' )
+                               $db->buildGroupConcatField( '|', 'user_groups', 'ug_group', [
+                                       'ug_user=user_id',
+                                       'ug_expiry IS NULL OR ug_expiry >= ' . $db->addQuotes( $db->timestamp() )
+                               ] )
                        ] );
                }
 
index ac5ccca..89fffd6 100644 (file)
@@ -160,7 +160,11 @@ class ApiQueryContributors extends ApiQueryBase {
                        $this->addTables( 'user_groups' );
                        $this->addJoinConds( [ 'user_groups' => [
                                $excludeGroups ? 'LEFT OUTER JOIN' : 'INNER JOIN',
-                               [ 'ug_user=rev_user', 'ug_group' => $limitGroups ]
+                               [
+                                       'ug_user=rev_user',
+                                       'ug_group' => $limitGroups,
+                                       'ug_expiry IS NULL OR ug_expiry >= ' . $db->addQuotes( $db->timestamp() )
+                               ]
                        ] ] );
                        $this->addWhereIf( 'ug_user IS NULL', $excludeGroups );
                }
index 7bc00cb..04b0fac 100644 (file)
@@ -143,6 +143,19 @@ class ApiQueryUserInfo extends ApiQueryBase {
                        ApiResult::setIndexedTagName( $vals['groups'], 'g' ); // even if empty
                }
 
+               if ( isset( $this->prop['groupmemberships'] ) ) {
+                       $ugms = $user->getGroupMemberships();
+                       $vals['groupmemberships'] = [];
+                       foreach ( $ugms as $group => $ugm ) {
+                               $vals['groupmemberships'][] = [
+                                       'group' => $group,
+                                       'expiry' => ApiResult::formatExpiry( $ugm->getExpiry() ),
+                               ];
+                       }
+                       ApiResult::setArrayType( $vals['groupmemberships'], 'array' ); // even if empty
+                       ApiResult::setIndexedTagName( $vals['groupmemberships'], 'groupmembership' ); // even if empty
+               }
+
                if ( isset( $this->prop['implicitgroups'] ) ) {
                        $vals['implicitgroups'] = $user->getAutomaticGroups();
                        ApiResult::setArrayType( $vals['implicitgroups'], 'array' ); // even if empty
@@ -302,6 +315,7 @@ class ApiQueryUserInfo extends ApiQueryBase {
                                        'blockinfo',
                                        'hasmsg',
                                        'groups',
+                                       'groupmemberships',
                                        'implicitgroups',
                                        'rights',
                                        'changeablegroups',
index 2d620a4..01265cc 100644 (file)
@@ -42,6 +42,7 @@ class ApiQueryUsers extends ApiQueryBase {
                // everything except 'blockinfo' which might show hidden records if the user
                // making the request has the appropriate permissions
                'groups',
+               'groupmemberships',
                'implicitgroups',
                'rights',
                'editcount',
@@ -97,6 +98,8 @@ class ApiQueryUsers extends ApiQueryBase {
        }
 
        public function execute() {
+               $db = $this->getDB();
+
                $params = $this->extractRequestParams();
                $this->requireMaxOneParameter( $params, 'userids', 'users' );
 
@@ -167,11 +170,14 @@ class ApiQueryUsers extends ApiQueryBase {
 
                                $this->addTables( 'user_groups' );
                                $this->addJoinConds( [ 'user_groups' => [ 'INNER JOIN', 'ug_user=user_id' ] ] );
-                               $this->addFields( [ 'user_name', 'ug_group' ] );
+                               $this->addFields( [ 'user_name' ] );
+                               $this->addFields( UserGroupMembership::selectFields() );
+                               $this->addWhere( 'ug_expiry IS NULL OR ug_expiry >= ' .
+                                       $db->addQuotes( $db->timestamp() ) );
                                $userGroupsRes = $this->select( __METHOD__ );
 
                                foreach ( $userGroupsRes as $row ) {
-                                       $userGroups[$row->user_name][] = $row->ug_group;
+                                       $userGroups[$row->user_name][] = $row;
                                }
                        }
 
@@ -207,6 +213,15 @@ class ApiQueryUsers extends ApiQueryBase {
                                        $data[$key]['groups'] = $user->getEffectiveGroups();
                                }
 
+                               if ( isset( $this->prop['groupmemberships'] ) ) {
+                                       $data[$key]['groupmemberships'] = array_map( function( $ugm ) {
+                                               return [
+                                                       'group' => $ugm->getGroup(),
+                                                       'expiry' => ApiResult::formatExpiry( $ugm->getExpiry() ),
+                                               ];
+                                       }, $user->getGroupMemberships() );
+                               }
+
                                if ( isset( $this->prop['implicitgroups'] ) ) {
                                        $data[$key]['implicitgroups'] = $user->getAutomaticGroups();
                                }
@@ -303,6 +318,10 @@ class ApiQueryUsers extends ApiQueryBase {
                                        ApiResult::setArrayType( $data[$u]['groups'], 'array' );
                                        ApiResult::setIndexedTagName( $data[$u]['groups'], 'g' );
                                }
+                               if ( isset( $this->prop['groupmemberships'] ) && isset( $data[$u]['groupmemberships'] ) ) {
+                                       ApiResult::setArrayType( $data[$u]['groupmemberships'], 'array' );
+                                       ApiResult::setIndexedTagName( $data[$u]['groupmemberships'], 'groupmembership' );
+                               }
                                if ( isset( $this->prop['implicitgroups'] ) && isset( $data[$u]['implicitgroups'] ) ) {
                                        ApiResult::setArrayType( $data[$u]['implicitgroups'], 'array' );
                                        ApiResult::setIndexedTagName( $data[$u]['implicitgroups'], 'g' );
@@ -347,6 +366,7 @@ class ApiQueryUsers extends ApiQueryBase {
                                ApiBase::PARAM_TYPE => [
                                        'blockinfo',
                                        'groups',
+                                       'groupmemberships',
                                        'implicitgroups',
                                        'rights',
                                        'editcount',
index 6b38302..af3fff6 100644 (file)
@@ -494,6 +494,13 @@ class ApiUpload extends ApiBase {
                                $this->mParams['filekey'], $this->mParams['filename'], !$this->mParams['async']
                        );
                } elseif ( isset( $this->mParams['file'] ) ) {
+                       // Can't async upload directly from a POSTed file, we'd have to
+                       // stash the file and then queue the publish job. The user should
+                       // just submit the two API queries to perform those two steps.
+                       if ( $this->mParams['async'] ) {
+                               $this->dieWithError( 'apierror-cannot-async-upload-file' );
+                       }
+
                        $this->mUpload = new UploadFromFile();
                        $this->mUpload->initialize(
                                $this->mParams['filename'],
index 4ef974c..262f072 100644 (file)
@@ -1,9 +1,7 @@
 <?php
 
 /**
- *
- *
- * Created on Mar 24, 2009
+ * API userrights module
  *
  * Copyright © 2009 Roan Kattouw "<Firstname>.<Lastname>@gmail.com"
  *
@@ -59,6 +57,41 @@ class ApiUserrights extends ApiBase {
 
                $params = $this->extractRequestParams();
 
+               // Figure out expiry times from the input
+               // @todo Remove this isset check when removing $wgDisableUserGroupExpiry
+               if ( isset( $params['expiry'] ) ) {
+                       $expiry = (array)$params['expiry'];
+               } else {
+                       $expiry = [ 'infinity' ];
+               }
+               if ( count( $expiry ) !== count( $params['add'] ) ) {
+                       if ( count( $expiry ) === 1 ) {
+                               $expiry = array_fill( 0, count( $params['add'] ), $expiry[0] );
+                       } else {
+                               $this->dieWithError( [
+                                       'apierror-toofewexpiries',
+                                       count( $expiry ),
+                                       count( $params['add'] )
+                               ] );
+                       }
+               }
+
+               // Validate the expiries
+               $groupExpiries = [];
+               foreach ( $expiry as $index => $expiryValue ) {
+                       $group = $params['add'][$index];
+                       $groupExpiries[$group] = UserrightsPage::expiryToTimestamp( $expiryValue );
+
+                       if ( $groupExpiries[$group] === false ) {
+                               $this->dieWithError( [ 'apierror-invalidexpiry', wfEscapeWikiText( $expiryValue ) ] );
+                       }
+
+                       // not allowed to have things expiring in the past
+                       if ( $groupExpiries[$group] && $groupExpiries[$group] < wfTimestampNow() ) {
+                               $this->dieWithError( [ 'apierror-pastexpiry', wfEscapeWikiText( $expiryValue ) ] );
+                       }
+               }
+
                $user = $this->getUrUser( $params );
 
                $tags = $params['tags'];
@@ -76,8 +109,8 @@ class ApiUserrights extends ApiBase {
                $r['user'] = $user->getName();
                $r['userid'] = $user->getId();
                list( $r['added'], $r['removed'] ) = $form->doSaveUserGroups(
-                       $user, (array)$params['add'],
-                       (array)$params['remove'], $params['reason'], $tags
+                       $user, (array)$params['add'], (array)$params['remove'],
+                       $params['reason'], $tags, $groupExpiries
                );
 
                $result = $this->getResult();
@@ -120,7 +153,7 @@ class ApiUserrights extends ApiBase {
        }
 
        public function getAllowedParams() {
-               return [
+               $a = [
                        'user' => [
                                ApiBase::PARAM_TYPE => 'user',
                        ],
@@ -131,6 +164,11 @@ class ApiUserrights extends ApiBase {
                                ApiBase::PARAM_TYPE => $this->getAllGroups(),
                                ApiBase::PARAM_ISMULTI => true
                        ],
+                       'expiry' => [
+                               ApiBase::PARAM_ISMULTI => true,
+                               ApiBase::PARAM_ALLOW_DUPLICATES => true,
+                               ApiBase::PARAM_DFLT => 'infinite',
+                       ],
                        'remove' => [
                                ApiBase::PARAM_TYPE => $this->getAllGroups(),
                                ApiBase::PARAM_ISMULTI => true
@@ -147,6 +185,10 @@ class ApiUserrights extends ApiBase {
                                ApiBase::PARAM_ISMULTI => true
                        ],
                ];
+               if ( !$this->getUserRightsPage()->canProcessExpiries() ) {
+                       unset( $a['expiry'] );
+               }
+               return $a;
        }
 
        public function needsToken() {
@@ -158,12 +200,17 @@ class ApiUserrights extends ApiBase {
        }
 
        protected function getExamplesMessages() {
-               return [
+               $a = [
                        'action=userrights&user=FooBot&add=bot&remove=sysop|bureaucrat&token=123ABC'
                                => 'apihelp-userrights-example-user',
                        'action=userrights&userid=123&add=bot&remove=sysop|bureaucrat&token=123ABC'
                                => 'apihelp-userrights-example-userid',
                ];
+               if ( $this->getUserRightsPage()->canProcessExpiries() ) {
+                       $a['action=userrights&user=SometimeSysop&add=sysop&expiry=1%20month&token=123ABC']
+                               = 'apihelp-userrights-example-expiry';
+               }
+               return $a;
        }
 
        public function getHelpUrls() {
index 596c35e..1b3a188 100644 (file)
@@ -16,7 +16,8 @@
                        "Ljonka",
                        "FriedhelmW",
                        "Predatorix",
-                       "Luke081515"
+                       "Luke081515",
+                       "Eddie"
                ]
        },
        "apihelp-main-description": "<div class=\"hlist plainlinks api-main-links\">\n* [[mw:API:Main_page|Dokumentation]]\n* [[mw:API:FAQ|Häufig gestellte Fragen]]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-api Mailingliste]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-api-announce API-Ankündigungen]\n* [https://phabricator.wikimedia.org/maniphest/query/GebfyV4uCaLd/#R Fehlerberichte und Anfragen]\n</div>\n<strong>Status:</strong> Alle auf dieser Seite gezeigten Funktionen sollten funktionieren, allerdings ist die API in aktiver Entwicklung und kann sich zu jeder Zeit ändern. Abonniere die [https://lists.wikimedia.org/pipermail/mediawiki-api-announce/ MediaWiki-API-Ankündigungs-Mailingliste], um über Aktualisierungen informiert zu werden.\n\n<strong>Fehlerhafte Anfragen:</strong> Wenn fehlerhafte Anfragen an die API gesendet werden, wird ein HTTP-Header mit dem Schlüssel „MediaWiki-API-Error“ gesendet. Der Wert des Headers und der Fehlercode werden auf den gleichen Wert gesetzt. Für weitere Informationen siehe [[mw:API:Errors_and_warnings|API: Fehler und Warnungen]].\n\n<strong>Testen:</strong> Zum einfachen Testen von API-Anfragen, siehe [[Special:ApiSandbox]].",
@@ -36,6 +37,7 @@
        "apihelp-main-param-errorsuselocal": "Falls angegeben, verwenden Fehlertexte lokalisierte Nachrichten aus dem {{ns:MediaWiki}}-Namensraum.",
        "apihelp-block-description": "Einen Benutzer sperren.",
        "apihelp-block-param-user": "Benutzername, IP-Adresse oder IP-Adressbereich, der gesperrt werden soll. Kann nicht zusammen mit <var>$1userid</var> verwendet werden.",
+       "apihelp-block-param-userid": "Die zu sperrende Benutzerkennung. Kann nicht zusammen mit <var>$1user</var> verwendet werden.",
        "apihelp-block-param-expiry": "Sperrdauer. Kann relativ (z.&nbsp;B. <kbd>5 months</kbd> oder <kbd>2 weeks</kbd>) oder absolut (z.&nbsp;B. <kbd>2014-09-18T12:34:56Z</kbd>) sein. Wenn auf <kbd>infinite</kbd>, <kbd>indefinite</kbd> oder <kbd>never</kbd> gesetzt, ist die Sperre unbegrenzt.",
        "apihelp-block-param-reason": "Sperrbegründung.",
        "apihelp-block-param-anononly": "Nur anonyme Benutzer sperren (z.&nbsp;B. anonyme Bearbeitungen für diese IP deaktivieren).",
@@ -49,6 +51,8 @@
        "apihelp-block-param-tags": "Auf den Eintrag im Sperr-Logbuch anzuwendende Änderungsmarkierungen.",
        "apihelp-block-example-ip-simple": "IP <kbd>192.0.2.5</kbd> für drei Tage mit der Begründung „First strike“ (erste Verwarnung) sperren",
        "apihelp-block-example-user-complex": "Benutzer <kbd>Vandal</kbd> unbeschränkt sperren mit der Begründung „Vandalism“ (Vandalismus), Erstellung neuer Benutzerkonten sowie Versand von E-Mails verhindern.",
+       "apihelp-changeauthenticationdata-description": "Ändert die Authentifizierungsdaten für den aktuellen Benutzer.",
+       "apihelp-changeauthenticationdata-example-password": "Versucht, das Passwort des aktuellen Benutzers in <kbd>ExamplePassword</kbd> zu ändern.",
        "apihelp-checktoken-description": "Überprüft die Gültigkeit eines über <kbd>[[Special:ApiHelp/query+tokens|action=query&meta=tokens]]</kbd> erhaltenen Tokens.",
        "apihelp-checktoken-param-type": "Typ des Tokens, das getestet werden soll.",
        "apihelp-checktoken-param-token": "Token, das getestet werden soll.",
@@ -56,6 +60,7 @@
        "apihelp-checktoken-example-simple": "Überprüft die Gültigkeit des <kbd>csrf</kbd>-Tokens.",
        "apihelp-clearhasmsg-description": "Löschen des <code>hasmsg</code>-Flags („hat Nachrichten“-Flag) für den aktuellen Benutzer.",
        "apihelp-clearhasmsg-example-1": "<code>hasmsg</code>-Flags für den aktuellen Benutzer löschen",
+       "apihelp-clientlogin-example-login": "Startet den Prozess der Anmeldung in dem Wiki als Benutzer <kbd>Example</kbd> mit dem Passwort <kbd>ExamplePassword</kbd>.",
        "apihelp-compare-description": "Abrufen des Unterschieds zwischen zwei Seiten.\n\nDu musst eine Versionsnummer, einen Seitentitel oder eine Seitennummer für „from“ als auch „to“ angeben.",
        "apihelp-compare-param-fromtitle": "Erster zu vergleichender Titel.",
        "apihelp-compare-param-fromid": "Erste zu vergleichende Seitennummer.",
        "apihelp-managetags-example-activate": "Aktiviert eine Markierung namens <kbd>spam</kbd> mit der Begründung <kbd>For use in edit patrolling</kbd> (für die Eingangskontrolle).",
        "apihelp-managetags-example-deactivate": "Deaktiviert eine Markierung namens <kbd>spam</kbd> mit der Begründung <kbd>No longer required</kbd> (nicht mehr benötigt).",
        "apihelp-mergehistory-description": "Führt Versionsgeschichten von Seiten zusammen.",
+       "apihelp-mergehistory-param-reason": "Grund für die Zusammenführung der Versionsgeschichten",
+       "apihelp-mergehistory-example-merge": "Fügt alle Versionen von <kbd>Oldpage</kbd> der Versionsgeschichte von <kbd>Newpage</kbd> hinzu.",
        "apihelp-move-description": "Eine Seite verschieben.",
        "apihelp-move-param-from": "Titel der zu verschiebenden Seite. Kann nicht zusammen mit <var>$1fromid</var> verwendet werden.",
        "apihelp-move-param-fromid": "Seitenkennung der zu verschiebenden Seite. Kann nicht zusammen mit <var>$1from</var> verwendet werden.",
        "apihelp-query+allrevisions-param-generatetitles": "Wenn als Generator verwendet, werden eher Titel als Bearbeitungs-IDs erzeugt.",
        "apihelp-query+allrevisions-example-user": "Liste die letzten 50 Beiträge, sortiert nach Benutzer <kbd>Beispiel</kbd> auf.",
        "apihelp-query+allrevisions-example-ns-main": "Liste die ersten 50 Bearbeitungen im Hauptnamensraum auf.",
+       "apihelp-query+mystashedfiles-param-prop": "Welche Eigenschaften für die Dateien abgerufen werden sollen.",
        "apihelp-query+mystashedfiles-paramvalue-prop-size": "Ruft die Dateigröße und Bildabmessungen ab.",
        "apihelp-query+mystashedfiles-param-limit": "Wie viele Dateien zurückgegeben werden sollen.",
        "apihelp-query+alltransclusions-description": "Liste alle Transklusionen auf (eingebettete Seiten die &#123;&#123;x&#125;&#125; benutzen), einschließlich nicht vorhandener.",
        "apihelp-query+imageinfo-paramvalue-prop-userid": "Füge die ID des Benutzers zu jeder hochgeladenen Dateiversion hinzu.",
        "apihelp-query+imageinfo-paramvalue-prop-comment": "Kommentar zu der Version.",
        "apihelp-query+imageinfo-paramvalue-prop-parsedcomment": "Analysiere den Kommentar zu dieser Version.",
+       "apihelp-query+imageinfo-paramvalue-prop-canonicaltitle": "Ergänzt den kanonischen Titel für die Datei.",
        "apihelp-query+imageinfo-paramvalue-prop-url": "Gibt die URL zur Datei- und Beschreibungsseite zurück.",
        "apihelp-query+imageinfo-paramvalue-prop-size": "Fügt die Größe der Datei in Bytes und (falls zutreffend) in Höhe, Breite und Seitenzahl hinzu.",
        "apihelp-query+imageinfo-paramvalue-prop-dimensions": "Alias für die Größe.",
        "apihelp-query+recentchanges-param-user": "Listet nur Änderungen von diesem Benutzer auf.",
        "apihelp-query+recentchanges-param-excludeuser": "Listet keine Änderungen von diesem Benutzer auf.",
        "apihelp-query+recentchanges-param-tag": "Listet nur Änderungen auf, die mit dieser Markierung markiert sind.",
+       "apihelp-query+recentchanges-paramvalue-prop-comment": "Fügt den Kommentar für die Bearbeitung hinzu.",
        "apihelp-query+recentchanges-paramvalue-prop-flags": "Ergänzt Markierungen für die Bearbeitung.",
        "apihelp-query+recentchanges-paramvalue-prop-timestamp": "Ergänzt den Zeitstempel für die Bearbeitung.",
        "apihelp-query+recentchanges-paramvalue-prop-title": "Ergänzt den Seitentitel der Bearbeitung.",
        "apihelp-query+redirects-param-prop": "Zurückzugebende Eigenschaften:",
        "apihelp-query+redirects-paramvalue-prop-pageid": "Seitenkennung einer jeden Weiterleitung.",
        "apihelp-query+redirects-paramvalue-prop-title": "Titel einer jeden Weiterleitung.",
+       "apihelp-query+redirects-param-namespace": "Schließt nur Seiten in diesen Namensräumen ein.",
        "apihelp-query+redirects-param-limit": "Wie viele Weiterleitungen zurückgegeben werden sollen.",
        "apihelp-query+revisions-param-tag": "Listet nur Versionen auf, die mit dieser Markierung markiert sind.",
        "apihelp-query+revisions+base-param-prop": "Zurückzugebende Eigenschaften jeder Version:",
        "apihelp-query+search-example-simple": "Nach <kbd>meaning</kbd> suchen.",
        "apihelp-query+search-example-text": "Texte nach <kbd>meaning</kbd> durchsuchen.",
        "apihelp-query+siteinfo-example-simple": "Websiteinformationen abrufen",
+       "apihelp-query+stashimageinfo-param-sessionkey": "Alias für $1filekey, für die Rückwärtskompatibilität.",
+       "apihelp-query+stashimageinfo-example-simple": "Gibt Informationen für eine gespeicherte Datei zurück.",
+       "apihelp-query+stashimageinfo-example-params": "Gibt Vorschaubilder für zwei gespeicherte Dateien zurück.",
        "apihelp-query+tags-description": "Änderungs-Tags auflisten.",
        "apihelp-query+tags-param-prop": "Zurückzugebende Eigenschaften:",
        "apihelp-query+tags-paramvalue-prop-name": "Ergänzt den Namen der Markierung.",
        "apihelp-query+tags-paramvalue-prop-displayname": "Ergänzt die Systemnachricht für die Markierung.",
        "apihelp-query+tags-paramvalue-prop-description": "Ergänzt die Beschreibung der Markierung.",
        "apihelp-query+tags-example-simple": "Verfügbare Tags auflisten",
+       "apihelp-query+templates-param-limit": "Wie viele Vorlagen zurückgegeben werden sollen.",
        "apihelp-query+templates-param-dir": "Die Auflistungsrichtung.",
+       "apihelp-query+tokens-param-type": "Typen der Token, die abgerufen werden sollen.",
        "apihelp-query+transcludedin-param-prop": "Zurückzugebende Eigenschaften:",
        "apihelp-query+transcludedin-paramvalue-prop-pageid": "Seitenkennung jeder Seite.",
        "apihelp-query+usercontribs-description": "Alle Bearbeitungen von einem Benutzer abrufen.",
        "apihelp-userrights-description": "Ändert die Gruppenzugehörigkeit eines Benutzers.",
        "apihelp-userrights-param-user": "Benutzername.",
        "apihelp-userrights-param-userid": "Benutzerkennung.",
-       "apihelp-userrights-param-add": "Fügt den Benutzer zu diesen Gruppen hinzu.",
+       "apihelp-userrights-param-add": "Fügt den Benutzer zu diesen Gruppen hinzu oder falls er bereits Mitglied ist, aktualisiert den Ablauf seiner Mitgliedschaft in dieser Gruppe.",
        "apihelp-userrights-param-remove": "Entfernt den Benutzer von diesen Gruppen.",
        "apihelp-userrights-param-reason": "Grund für die Änderung.",
        "apihelp-userrights-param-tags": "Auf den Eintrag im Benutzerrechte-Logbuch anzuwendende Änderungsmarkierungen.",
        "api-help-right-apihighlimits": "Höhere Beschränkungen in API-Anfragen verwenden (langsame Anfragen: $1; schnelle Anfragen: $2). Die Beschränkungen für langsame Anfragen werden auch auf Mehrwertparameter angewandt.",
        "api-help-open-in-apisandbox": "<small>[in Spielwiese öffnen]</small>",
        "api-help-authmanagerhelper-messageformat": "Zu verwendendes Format zur Rückgabe von Nachrichten.",
+       "apierror-cannot-async-upload-file": "Die Parameter <var>async</var> und <var>file</var> können nicht kombiniert werden. Falls du eine asynchrone Verarbeitung deiner hochgeladenen Datei wünschst, lade sie zuerst mithilfe des Parameters <var>stash</var> auf den Speicher hoch. Veröffentliche anschließend die gespeicherte Datei asynchron mithilfe <var>filekey</var> und <var>async</var>.",
        "apierror-invaliduserid": "Die Benutzerkennung <var>$1</var> ist nicht gültig.",
        "apierror-nosuchuserid": "Es gibt keinen Benutzer mit der Kennung $1.",
        "apierror-pagelang-disabled": "Das Ändern der Sprache von Seiten ist auf diesem Wiki nicht erlaubt.",
+       "apierror-protect-invalidaction": "Ungültiger Schutztyp „$1“.",
+       "apierror-readonly": "Das Wiki ist derzeit im schreibgeschützten Modus.",
+       "apierror-revwrongpage": "Die Version $1 ist keine Version von $2.",
+       "apierror-sectionreplacefailed": "Der aktualisierte Abschnitt konnte nicht zusammengeführt werden.",
        "apierror-stashinvalidfile": "Ungültige gespeicherte Datei.",
        "apierror-stashnosuchfilekey": "Kein derartiger Dateischlüssel: $1.",
        "apierror-stashwrongowner": "Falscher Besitzer: $1",
        "apierror-systemblocked": "Du wurdest von MediaWiki automatisch gesperrt.",
        "apierror-unknownerror-nocode": "Unbekannter Fehler.",
        "apierror-unknownerror": "Unbekannter Fehler: „$1“.",
+       "apierror-unknownformat": "Nicht erkanntes Format „$1“.",
        "apiwarn-invalidcategory": "„$1“ ist keine Kategorie.",
        "apiwarn-invalidtitle": "„$1“ ist kein gültiger Titel.",
        "apiwarn-notfile": "„$1“ ist keine Datei.",
+       "apiwarn-validationfailed-badpref": "Keine gültige Einstellung.",
+       "apiwarn-validationfailed-cannotset": "Kann nicht von diesem Modul festgelegt werden.",
+       "apiwarn-validationfailed-keytoolong": "Der Schlüssel ist zu lang. Es sind nicht mehr als $1 Bytes erlaubt.",
+       "apiwarn-validationfailed": "Validierungsfehler für <kbd>$1</kbd>: $2",
        "api-feed-error-title": "Fehler ($1)",
        "api-usage-docref": "Siehe $1 zur Verwendung der API.",
        "api-credits-header": "Danksagungen",
index c1fefd6..d92d78b 100644 (file)
        "apihelp-query+userinfo-paramvalue-prop-blockinfo": "Tags if the current user is blocked, by whom, and for what reason.",
        "apihelp-query+userinfo-paramvalue-prop-hasmsg": "Adds a tag <samp>messages</samp> if the current user has pending messages.",
        "apihelp-query+userinfo-paramvalue-prop-groups": "Lists all the groups the current user belongs to.",
+       "apihelp-query+userinfo-paramvalue-prop-groupmemberships": "Lists groups that the current user has been explicitly assigned to, including the expiry date of each group membership.",
        "apihelp-query+userinfo-paramvalue-prop-implicitgroups": "Lists all the groups the current user is automatically a member of.",
        "apihelp-query+userinfo-paramvalue-prop-rights": "Lists all the rights the current user has.",
        "apihelp-query+userinfo-paramvalue-prop-changeablegroups": "Lists the groups the current user can add to and remove from.",
        "apihelp-query+users-param-prop": "Which pieces of information to include:",
        "apihelp-query+users-paramvalue-prop-blockinfo": "Tags if the user is blocked, by whom, and for what reason.",
        "apihelp-query+users-paramvalue-prop-groups": "Lists all the groups each user belongs to.",
+       "apihelp-query+users-paramvalue-prop-groupmemberships": "Lists groups that each user has been explicitly assigned to, including the expiry date of each group membership.",
        "apihelp-query+users-paramvalue-prop-implicitgroups": "Lists all the groups a user is automatically a member of.",
        "apihelp-query+users-paramvalue-prop-rights": "Lists all the rights each user has.",
        "apihelp-query+users-paramvalue-prop-editcount": "Adds the user's edit count.",
        "apihelp-userrights-description": "Change a user's group membership.",
        "apihelp-userrights-param-user": "User name.",
        "apihelp-userrights-param-userid": "User ID.",
-       "apihelp-userrights-param-add": "Add the user to these groups.",
+       "apihelp-userrights-param-add": "Add the user to these groups, or if they are already a member, update the expiry of their membership in that group.",
+       "apihelp-userrights-param-expiry": "Expiry timestamps. May be relative (e.g. <kbd>5 months</kbd> or <kbd>2 weeks</kbd>) or absolute (e.g. <kbd>2014-09-18T12:34:56Z</kbd>). If only one timestamp is set, it will be used for all groups passed to the <var>$1add</var> parameter. Use <kbd>infinite</kbd>, <kbd>indefinite</kbd>, <kbd>infinity</kbd>, or <kbd>never</kbd> for a never-expiring user group.",
        "apihelp-userrights-param-remove": "Remove the user from these groups.",
        "apihelp-userrights-param-reason": "Reason for the change.",
        "apihelp-userrights-param-tags": "Change tags to apply to the entry in the user rights log.",
        "apihelp-userrights-example-user": "Add user <kbd>FooBot</kbd> to group <kbd>bot</kbd>, and remove from groups <kbd>sysop</kbd> and <kbd>bureaucrat</kbd>.",
        "apihelp-userrights-example-userid": "Add the user with ID <kbd>123</kbd> to group <kbd>bot</kbd>, and remove from groups <kbd>sysop</kbd> and <kbd>bureaucrat</kbd>.",
+       "apihelp-userrights-example-expiry": "Add user <kbd>SometimeSysop</kbd> to group <kbd>sysop</kbd> for 1 month.",
 
        "apihelp-validatepassword-description": "Validate a password against the wiki's password policies.\n\nValidity is reported as <samp>Good</samp> if the password is acceptable, <samp>Change</samp> if the password may be used for login but must be changed, or <samp>Invalid</samp> if the password is not usable.",
        "apihelp-validatepassword-param-password": "Password to validate.",
        "apierror-blockedfrommail": "You have been blocked from sending email.",
        "apierror-blocked": "You have been blocked from editing.",
        "apierror-botsnotsupported": "This interface is not supported for bots.",
+       "apierror-cannot-async-upload-file": "The parameters <var>async</var> and <var>file</var> cannot be combined. If you want asynchronous processing of your uploaded file, first upload it to stash (using the <var>stash</var> parameter) and then publish the stashed file asynchronously (using <var>filekey</var> and <var>async</var>).",
        "apierror-cannotreauthenticate": "This action is not available as your identity cannot be verified.",
        "apierror-cannotviewtitle": "You are not allowed to view $1.",
        "apierror-cantblock-email": "You don't have permission to block users from sending email through the wiki.",
 
        "api-feed-error-title": "Error ($1)",
        "api-usage-docref": "See $1 for API usage.",
+       "api-usage-mailinglist-ref": "Subscribe to the mediawiki-api-announce mailing list at &lt;https://lists.wikimedia.org/mailman/listinfo/mediawiki-api-announce&gt; for notice of API deprecations and breaking changes.",
        "api-exception-trace": "$1 at $2($3)\n$4",
        "api-credits-header": "Credits",
        "api-credits": "API developers:\n* Yuri Astrakhan (creator, lead developer Sep 2006–Sep 2007)\n* Roan Kattouw (lead developer Sep 2007–2009)\n* Victor Vasiliev\n* Bryan Tong Minh\n* Sam Reed\n* Brad Jorsch (lead developer 2013–present)\n\nPlease send your comments, suggestions and questions to mediawiki-api@lists.wikimedia.org\nor file a bug report at https://phabricator.wikimedia.org/."
index f90f743..d411279 100644 (file)
        "apihelp-parse-param-pst": "Guardar previamente los cambios antes de transformar la entrada antes de analizarla. Sólo es válido cuando se utiliza con el texto.",
        "apihelp-parse-param-onlypst": "Guardar previamente los cambios antes de transformar (PST) en la entrada. Devuelve el mismo wikitexto, después de que un PST se ha aplicado. Sólo es válido cuando se utiliza con <var>$1text</var>.",
        "apihelp-parse-param-effectivelanglinks": "Incluye enlaces de idiomas proporcionados por las extensiones (para utilizar con <kbd>$1prop=langlinks</kbd>).",
+       "apihelp-parse-param-section": "Analizar solo el contenido de este número de sección.\n\nSi el valor es <kbd>new</kbd>, analiza <var>$1text</var> y <var>$1sectiontitle</var> como si se añadiera una nueva sección a la página.\n\n<kbd>new</kbd> solo se permite cuando se especifique <var>text</var>.",
+       "apihelp-parse-param-sectiontitle": "Nuevo título de sección cuando <var>section</var> tiene el valor <kbd>new</kbd>.\n\nAl contrario que en la edición de páginas, no se sustituye por <var>summary</var> cuando se omite o su valor es vacío.",
        "apihelp-parse-param-disablelimitreport": "Omitir el informe de límite (\"NewPP limit report\") desde la salida del analizador.",
        "apihelp-parse-param-disablepp": "Usa <var>$1disablelimitreport</var> en su lugar.",
        "apihelp-parse-param-disableeditsection": "Omitir los enlaces de edición de sección de la salida del analizador.",
        "apihelp-parse-param-sectionpreview": "Analizar sección en modo de vista previa (también activa el modo de vista previa).",
        "apihelp-parse-param-disabletoc": "Omitir la tabla de contenidos en la salida.",
        "apihelp-parse-param-contentformat": "Formato de serialización de contenido utilizado para la introducción de texto. Sólo es válido cuando se utiliza con $1text.",
+       "apihelp-parse-param-contentmodel": "Modelo de contenido del texto de entrada. Si se omite, se debe especificar $1title, y el valor por defecto será el modelo del título especificado. Solo es válido cuando se use junto con $1text.",
        "apihelp-parse-example-page": "Analizar una página.",
        "apihelp-parse-example-text": "Analizar wikitexto.",
        "apihelp-parse-example-texttitle": "Analizar wikitexto, especificando el título de la página.",
        "apihelp-query+alldeletedrevisions-param-user": "Listar solo las revisiones de este usuario.",
        "apihelp-query+alldeletedrevisions-param-excludeuser": "No listar las revisiones de este usuario.",
        "apihelp-query+alldeletedrevisions-param-namespace": "Listar solo las páginas en este espacio de nombres.",
+       "apihelp-query+alldeletedrevisions-param-miser-user-namespace": "<strong>Nota:</strong> Debido al [[mw:Manual:$wgMiserMode|modo avaro]], usar juntos <var>$1user</var> y <var>$1namespace</var> puede dar lugar a que se devuelvan menos de <var>$1limit</var> antes de continuar. En casos extremos, podrían devolverse cero resultados.",
        "apihelp-query+alldeletedrevisions-param-generatetitles": "Cuando se utiliza como generador, generar títulos en lugar de identificadores de revisión.",
        "apihelp-query+alldeletedrevisions-example-user": "Listar las últimas 50 contribuciones borradas del usuario <kbd>Example</kbd>.",
        "apihelp-query+alldeletedrevisions-example-ns-main": "Listar las primeras 50 revisiones borradas en el espacio de nombres principal.",
        "apihelp-query+allmessages-param-prop": "Qué propiedades se obtendrán.",
        "apihelp-query+allmessages-param-enableparser": "Establecer para habilitar el analizador, se preprocesará el wikitexto del mensaje (sustitución de palabras mágicas, uso de plantillas, etc.).",
        "apihelp-query+allmessages-param-nocontent": "Si se establece, no incluya el contenido de los mensajes en la salida.",
+       "apihelp-query+allmessages-param-includelocal": "Incluir también los mensajes locales, es decir, aquellos que no existen en el propio software pero sí en el espacio de nombres {{ns:MediaWiki}}.\nEsto muestra todas las páginas del espacio de nombres {{ns:MediaWiki}}, así que también mostrará las que no son propiamente mensajes, como, por ejemplo, [[MediaWiki:Common.js|Common.js]].",
        "apihelp-query+allmessages-param-args": "Los argumentos que se sustituyen en el mensaje.",
        "apihelp-query+allmessages-param-filter": "Devolver solo mensajes con nombres que contengan esta cadena.",
        "apihelp-query+allmessages-param-customised": "Devolver solo mensajes en este estado de personalización.",
        "apihelp-query+allredirects-param-prefix": "Buscar todas las páginas de destino que empiecen con este valor.",
        "apihelp-query+allredirects-param-unique": "Mostrar solo títulos únicos de páginas de destino. No se puede usar junto con $1prop=ids|fragment|interwiki. Cuando se use como generador, devuelve páginas de destino en vez de páginas de origen.",
        "apihelp-query+allredirects-param-prop": "Qué piezas de información incluir:",
+       "apihelp-query+allredirects-paramvalue-prop-ids": "Añade el identificador de la página de redirección (no se puede usar junto con <var>$1unique</var>).",
        "apihelp-query+allredirects-paramvalue-prop-title": "Añade el título de la redirección.",
+       "apihelp-query+allredirects-paramvalue-prop-fragment": "Añade el fragmento de la redirección, si existe (no se puede usar junto con <var>$1unique</var>).",
+       "apihelp-query+allredirects-paramvalue-prop-interwiki": "Añade el prefijo interwiki de la redirección, si existe (no se puede usar junto con <var>$1unique</var>).",
        "apihelp-query+allredirects-param-namespace": "El espacio de nombres a enumerar.",
        "apihelp-query+allredirects-param-limit": "Cuántos elementos se devolverán.",
        "apihelp-query+allredirects-param-dir": "La dirección en la que se listará.",
+       "apihelp-query+allredirects-example-B": "Enumera las páginas de destino, incluyendo las páginas desaparecidas, con los identificadores de las páginas de las que provienen, empezando por <kbd>B</kbd>.",
        "apihelp-query+allredirects-example-unique": "La lista de páginas de destino.",
        "apihelp-query+allredirects-example-unique-generator": "Obtiene todas las páginas de destino, marcando los que faltan.",
        "apihelp-query+allredirects-example-generator": "Obtiene páginas que contienen las redirecciones.",
        "apihelp-query+alltransclusions-param-namespace": "El espacio de nombres que enumerar.",
        "apihelp-query+alltransclusions-param-limit": "Número de elementos que se desea obtener.",
        "apihelp-query+alltransclusions-param-dir": "La dirección en que ordenar la lista.",
+       "apihelp-query+alltransclusions-example-B": "Enumerar los títulos transcluidos, incluyendo los faltantes, junto con los identificadores de las páginas de las que provienen, empezando por <kbd>B</kbd>.",
        "apihelp-query+alltransclusions-example-unique": "Listar títulos transcluidos de forma única.",
        "apihelp-query+alltransclusions-example-unique-generator": "Obtiene todos los títulos transcluidos, marcando los que faltan.",
        "apihelp-query+alltransclusions-example-generator": "Obtiene las páginas que contienen las transclusiones.",
        "apihelp-query+allusers-param-attachedwiki": "Con <kbd>$1prop=centralids</kbd>, indicar también si el usuario está conectado con el wiki identificado por el ID.",
        "apihelp-query+allusers-example-Y": "Listar usuarios que empiecen por <kbd>Y</kbd>.",
        "apihelp-query+authmanagerinfo-description": "Recuperar información sobre el estado de autenticación actual.",
+       "apihelp-query+authmanagerinfo-param-requestsfor": "Obtener información sobre las peticiones de autentificación requeridas para la acción de autentificación especificada.",
        "apihelp-query+authmanagerinfo-example-login": "Captura de las solicitudes que puede ser utilizadas al comienzo de inicio de sesión.",
+       "apihelp-query+authmanagerinfo-example-login-merged": "Obtener las peticiones que podrían utilizarse al empezar un inicio de sesión, con los campos de formulario integrados.",
        "apihelp-query+authmanagerinfo-example-securitysensitiveoperation": "Comprueba si la autentificación es suficiente para realizar la acción <kbd>foo</kbd>.",
        "apihelp-query+backlinks-description": "Encuentra todas las páginas que enlazan a la página dada.",
        "apihelp-query+backlinks-param-title": "Título que buscar. No se puede usar junto con <var>$1pageid</var>.",
        "apihelp-query+blocks-paramvalue-prop-flags": "Etiquetas la prohibición con (autoblock, anononly, etc.).",
        "apihelp-query+blocks-param-show": "Muestra solamente los elementos que cumplen estos criterios.\nPor ejemplo, para mostrar solamente los bloqueos indefinidos a direcciones IP, introduce <kbd>$1show=ip|!temp</kbd>.",
        "apihelp-query+blocks-example-simple": "Listar bloques.",
+       "apihelp-query+blocks-example-users": "Muestra los bloqueos de los usuarios <kbd>Alice</kbd> y <kbd>Bob</kbd>.",
        "apihelp-query+categories-description": "Enumera todas las categorías a las que pertenecen las páginas.",
        "apihelp-query+categories-param-prop": "Qué propiedades adicionales obtener para cada categoría:",
        "apihelp-query+categories-paramvalue-prop-sortkey": "Añade la clave de ordenación (cadena hexadecimal) y el prefijo de la clave de ordenación (la parte legible) de la categoría.",
        "apihelp-query+categorymembers-param-endsortkey": "Utilizar $1endhexsortkey en su lugar.",
        "apihelp-query+categorymembers-example-simple": "Obtener las primeras 10 páginas en <kbd>Category:Physics</kbd>.",
        "apihelp-query+categorymembers-example-generator": "Obtener información sobre las primeras 10 páginas de la <kbd>Category:Physics</kbd>.",
+       "apihelp-query+contributors-description": "Obtener la lista de contribuidores conectados y el número de contribuidores anónimos de una página.",
+       "apihelp-query+contributors-param-group": "Solo incluir usuarios de los grupos especificados. No incluye grupos implícitos o autopromocionados, como *, usuario o autoconfirmado.",
+       "apihelp-query+contributors-param-excludegroup": "Excluir usuarios de los grupos especificados. No incluye grupos implícitos o autopromocionados, como *, usuario o autoconfirmado.",
+       "apihelp-query+contributors-param-rights": "Solo incluir usuarios con los derechos especificados. No incluye derechos concedidos a grupos implícitos o autopromocionados, como *, usuario o autoconfirmado.",
+       "apihelp-query+contributors-param-excluderights": "Excluir usuarios con los derechos especificados. No incluye derechos concedidos a grupos implícitos o autopromocionados, como *, usuario o autoconfirmado.",
        "apihelp-query+contributors-param-limit": "Cuántos contribuyentes se devolverán.",
        "apihelp-query+contributors-example-simple": "Mostrar los contribuyentes de la página <kbd>Main Page</kbd>.",
        "apihelp-query+deletedrevisions-param-start": "Marca de tiempo por la que empezar la enumeración. Se ignora cuando se esté procesando una lista de ID de revisión.",
        "apihelp-query+fileusage-param-prop": "Qué propiedades se obtendrán:",
        "apihelp-query+fileusage-paramvalue-prop-pageid": "Identificador de cada página.",
        "apihelp-query+fileusage-paramvalue-prop-title": "Título de cada página.",
+       "apihelp-query+fileusage-paramvalue-prop-redirect": "Marcar si la página es una redirección.",
        "apihelp-query+fileusage-param-namespace": "Incluir solo páginas de estos espacios de nombres.",
        "apihelp-query+fileusage-param-limit": "Cuántos se devolverán.",
        "apihelp-query+fileusage-param-show": "Muestra solo los elementos que cumplen estos criterios:\n;redirect: Muestra solamente redirecciones.\n;!redirect: Muestra solamente páginas que no son redirecciones.",
        "apihelp-query+imageinfo-paramvalue-prop-comment": "Comentarios sobre la versión.",
        "apihelp-query+imageinfo-paramvalue-prop-parsedcomment": "Analizar el comentario de la versión.",
        "apihelp-query+imageinfo-paramvalue-prop-canonicaltitle": "Agrega el título canónico del archivo.",
+       "apihelp-query+imageinfo-paramvalue-prop-url": "Devuelve la URL para el archivo y la página de descripción.",
        "apihelp-query+imageinfo-paramvalue-prop-dimensions": "Alias para el tamaño.",
        "apihelp-query+imageinfo-paramvalue-prop-sha1": "Añade el hash SHA-1 para la imagen.",
        "apihelp-query+imageinfo-paramvalue-prop-mime": "Añade el tipo MIME del archivo.",
        "apihelp-query+imageinfo-example-dated": "Obtener información sobre las versiones de [[:File:Test.jpg]] a partir de 2008.",
        "apihelp-query+images-description": "Devuelve todos los archivos contenidos en las páginas dadas.",
        "apihelp-query+images-param-limit": "Cuántos archivos se devolverán.",
+       "apihelp-query+images-param-images": "Mostrar solo estos archivos. Útil para comprobar si una determinada página tiene un determinado archivo.",
        "apihelp-query+images-param-dir": "La dirección en que ordenar la lista.",
        "apihelp-query+images-example-simple": "Obtener una lista de los archivos usados en la [[Main Page|Portada]].",
        "apihelp-query+images-example-generator": "Obtener información sobre todos los archivos empleados en [[Main Page]].",
        "apihelp-query+info-paramvalue-prop-readable": "Si el usuario puede leer esta página.",
        "apihelp-query+info-paramvalue-prop-preload": "Muestra el texto devuelto por EditFormPreloadText.",
        "apihelp-query+info-paramvalue-prop-displaytitle": "Proporciona la manera en que se muestra realmente el título de la página",
+       "apihelp-query+info-param-testactions": "Comprobar su el usuario actual puede realizar determinadas acciones en la página.",
        "apihelp-query+info-param-token": "Usa [[Special:ApiHelp/query+tokens|action=query&meta=tokens]] en su lugar.",
        "apihelp-query+info-example-simple": "Obtener información acerca de la página <kbd>Main Page</kbd>.",
        "apihelp-query+info-example-protection": "Obtén información general y protección acerca de la página <kbd>Main Page</kbd>.",
+       "apihelp-query+iwbacklinks-description": "Encontrar todas las páginas que enlazan al enlace interwiki dado.\n\nPuede utilizarse para encontrar todos los enlaces con un prefijo, o todos los enlaces a un título (con un determinado prefijo). Si no se introduce ninguno de los parámetros, se entiende como «todos los enlaces interwiki».",
        "apihelp-query+iwbacklinks-param-prefix": "Prefijo para el interwiki.",
        "apihelp-query+iwbacklinks-param-title": "Enlace interlingüístico que buscar. Se debe usar junto con <var>$1blprefix</var>.",
        "apihelp-query+iwbacklinks-param-limit": "Cuántas páginas se devolverán.",
        "apihelp-query+links-param-titles": "Devolver solo los enlaces a estos títulos. Útil para comprobar si una determinada página enlaza a un determinado título.",
        "apihelp-query+links-param-dir": "La dirección en que ordenar la lista.",
        "apihelp-query+links-example-simple": "Obtener los enlaces de la página <kbd>Main Page</kbd>",
+       "apihelp-query+links-example-namespaces": "Obtener enlaces de la página <kbd>Main Page</kbd> de los espacios de nombres {{ns:user}} and {{ns:template}}.",
        "apihelp-query+linkshere-description": "Buscar todas las páginas que enlazan a las páginas dadas.",
        "apihelp-query+linkshere-param-prop": "Qué propiedades se obtendrán:",
        "apihelp-query+linkshere-paramvalue-prop-pageid": "Identificador de cada página.",
        "apihelp-query+protectedtitles-param-namespace": "Listar solo los títulos en estos espacios de nombres.",
        "apihelp-query+protectedtitles-param-level": "Listar solo títulos con estos niveles de protección.",
        "apihelp-query+protectedtitles-param-limit": "Cuántas páginas se devolverán.",
+       "apihelp-query+protectedtitles-param-start": "Empezar la enumeración en esta marca de tiempo de protección.",
+       "apihelp-query+protectedtitles-param-end": "Terminar la enumeración en esta marca de tiempo de protección.",
        "apihelp-query+protectedtitles-param-prop": "Qué propiedades se obtendrán:",
        "apihelp-query+protectedtitles-paramvalue-prop-timestamp": "Añade la marca de tiempo de cuando se añadió la protección.",
        "apihelp-query+protectedtitles-paramvalue-prop-user": "Agrega el usuario que agregó la protección.",
        "apihelp-query+querypage-param-page": "El nombre de la página especial. Recuerda, es sensible a mayúsculas y minúsculas.",
        "apihelp-query+querypage-param-limit": "Número de resultados que se devolverán.",
        "apihelp-query+querypage-example-ancientpages": "Devolver resultados de [[Special:Ancientpages]].",
+       "apihelp-query+random-description": "Obtener un conjunto de páginas aleatorias.\n\nLas páginas aparecen enumeradas en una secuencia fija, solo que el punto de partida es aleatorio. Esto quiere decir que, si, por ejemplo, <samp>Portada</samp> es la primera página aleatoria de la lista, <samp>Lista de monos ficticios</samp> <em>siempre</em> será la segunda, <samp>Lista de personas en sellos de Vanuatu</samp> la tercera, etc.",
        "apihelp-query+random-param-namespace": "Devolver solo las páginas de estos espacios de nombres.",
        "apihelp-query+random-param-limit": "Limita el número de páginas aleatorias que se devolverán.",
        "apihelp-query+random-param-redirect": "Usa <kbd>$1filterredir=redirects</kbd> en su lugar.",
        "apihelp-query+recentchanges-param-excludeuser": "No listar cambios de este usuario.",
        "apihelp-query+recentchanges-param-tag": "Listar solo los cambios con esta etiqueta.",
        "apihelp-query+recentchanges-param-prop": "Incluir piezas adicionales de información:",
+       "apihelp-query+recentchanges-paramvalue-prop-user": "Añade el usuario responsable de la edición y añade una etiqueta si se trata de una IP.",
        "apihelp-query+recentchanges-paramvalue-prop-userid": "Añade el identificador del usuario responsable de la edición.",
        "apihelp-query+recentchanges-paramvalue-prop-comment": "Añade el comentario de la edición.",
        "apihelp-query+recentchanges-paramvalue-prop-parsedcomment": "Añade el comentario analizado para la edición.",
        "apihelp-query+recentchanges-paramvalue-prop-loginfo": "Añade información de registro (identificador de registro, tipo de registro, etc.) a las entradas de registro.",
        "apihelp-query+recentchanges-paramvalue-prop-tags": "Muestra las etiquetas de la entrada.",
        "apihelp-query+recentchanges-param-token": "Usa <kbd>[[Special:ApiHelp/query+tokens|action=query&meta=tokens]]</kbd> en su lugar.",
+       "apihelp-query+recentchanges-param-show": "Muestra solo los elementos que cumplan estos criterios. Por ejemplo, para ver solo ediciones menores realizadas por usuarios conectados, introduce $1show=minor|!anon.",
        "apihelp-query+recentchanges-param-limit": "Cuántos cambios en total se devolverán.",
        "apihelp-query+recentchanges-param-type": "Cuántos tipos de cambios se mostrarán.",
+       "apihelp-query+recentchanges-param-toponly": "Enumerar solo las modificaciones que sean las últimas revisiones.",
        "apihelp-query+recentchanges-example-simple": "Lista de cambios recientes.",
+       "apihelp-query+recentchanges-example-generator": "Obtener información de página de cambios recientes no patrullados.",
        "apihelp-query+redirects-description": "Devuelve todas las redirecciones a las páginas dadas.",
        "apihelp-query+redirects-param-prop": "Qué propiedades se obtendrán:",
        "apihelp-query+redirects-paramvalue-prop-pageid": "Identificador de página de cada redirección.",
        "apihelp-query+redirects-example-simple": "Mostrar una lista de las redirecciones a la [[Main Page|Portada]]",
        "apihelp-query+redirects-example-generator": "Obtener información sobre todas las redirecciones a la [[Main Page|Portada]].",
        "apihelp-query+revisions-paraminfo-singlepageonly": "Solo se puede usar con una sola página (modo n.º 2).",
+       "apihelp-query+revisions-param-startid": "Identificador de revisión a partir del cual empezar la enumeración.",
+       "apihelp-query+revisions-param-endid": "Identificador de revisión en el que detener la enumeración.",
+       "apihelp-query+revisions-param-start": "Marca de tiempo a partir de la cual empezar la enumeración.",
        "apihelp-query+revisions-param-end": "Enumerar hasta esta marca de tiempo.",
        "apihelp-query+revisions-param-user": "Incluir solo las revisiones realizadas por el usuario.",
        "apihelp-query+revisions-param-excludeuser": "Excluir las revisiones realizadas por el usuario.",
        "apihelp-query+revisions-param-tag": "Mostrar solo revisiones marcadas con esta etiqueta.",
+       "apihelp-query+revisions-example-content": "Obtener datos con el contenido de la última revisión de los títulos <kbd>API</kbd> y <kbd>Main Page</kbd>.",
        "apihelp-query+revisions-example-last5": "Mostrar las últimas 5 revisiones de la <kbd>Main Page</kbd>.",
+       "apihelp-query+revisions-example-first5": "Obtener las primeras 5 revisiones de <kbd>Main Page</kbd>.",
+       "apihelp-query+revisions-example-first5-after": "Obtener las primeras 5 revisiones de <kbd>Main Page</kbd> realizadas después de 2006-05-01.",
+       "apihelp-query+revisions-example-first5-not-localhost": "Obtener las primeras 5 revisiones de <kbd>Main Page</kbd> que no fueron realizadas por el usuario anónimo <kbd>127.0.0.1</kbd>.",
+       "apihelp-query+revisions-example-first5-user": "Obtener las primeras 5 revisiones de <kbd>Main Page</kbd> que fueron realizadas por el usuario <kbd>MediaWiki default</kbd>.",
        "apihelp-query+revisions+base-param-prop": "Las propiedades que se obtendrán para cada revisión:",
        "apihelp-query+revisions+base-paramvalue-prop-ids": "El identificador de la revisión.",
        "apihelp-query+revisions+base-paramvalue-prop-flags": "Marcas de revisión (menor).",
        "apihelp-query+revisions+base-param-generatexml": "Generar el árbol de análisis sintáctico XML para el contenido de la revisión (requiere $1prop=content; reemplazado por <kbd>$1prop=parsetree</kbd>).",
        "apihelp-query+revisions+base-param-parse": "Analizar el contenido de la revisión (requiere $1prop=content). Por motivos de rendimiento, si se utiliza esta opción, el valor de $1limit es forzado a 1.",
        "apihelp-query+revisions+base-param-section": "Recuperar solamente el contenido de este número de sección.",
+       "apihelp-query+revisions+base-param-contentformat": "Formato de serialización utilizado para <var>$1difftotext</var> y esperado para la salida de contenido.",
        "apihelp-query+search-description": "Realizar una búsqueda de texto completa.",
        "apihelp-query+search-param-namespace": "Buscar sólo en estos espacios de nombres.",
        "apihelp-query+search-param-what": "Tipo de búsqueda que realizar.",
        "apihelp-query+siteinfo-paramvalue-prop-variables": "Devuelve una lista de identificadores variables.",
        "apihelp-query+siteinfo-paramvalue-prop-protocols": "Devuelve una lista de los protocolos que se permiten en los enlaces externos.",
        "apihelp-query+siteinfo-paramvalue-prop-defaultoptions": "Devuelve los valores predeterminados de las preferencias del usuario.",
+       "apihelp-query+siteinfo-param-filteriw": "Devuelve solo entradas locales o solo entradas no locales del mapa interwiki.",
        "apihelp-query+siteinfo-param-numberingroup": "Muestra el número de usuarios en los grupos de usuarios.",
        "apihelp-query+siteinfo-example-simple": "Obtener información del sitio.",
+       "apihelp-query+siteinfo-example-interwiki": "Obtener una lista de prefijos interwiki locales.",
        "apihelp-query+stashimageinfo-description": "Devuelve información del archivo para archivos escondidos.",
        "apihelp-query+stashimageinfo-param-sessionkey": "Alias de $1filekey, para retrocompatibilidad.",
        "apihelp-query+stashimageinfo-example-simple": "Devuelve información para un archivo escondido.",
        "apihelp-query+stashimageinfo-example-params": "Devuelve las miniaturas de dos archivos escondidos.",
+       "apihelp-query+tags-description": "Enumerar las etiquetas de modificación.",
        "apihelp-query+tags-param-limit": "El número máximo de etiquetas para enumerar.",
        "apihelp-query+tags-param-prop": "Qué propiedades se obtendrán:",
        "apihelp-query+tags-paramvalue-prop-name": "Añade el nombre de la etiqueta.",
        "apihelp-query+templates-param-namespace": "Mostrar plantillas solamente en estos espacios de nombres.",
        "apihelp-query+templates-param-limit": "Cuántas plantillas se devolverán.",
        "apihelp-query+templates-param-dir": "La dirección en que ordenar la lista.",
+       "apihelp-query+templates-example-generator": "Obtener información sobre las páginas de las plantillas utilizadas en <kbd>Main Page</kbd>.",
+       "apihelp-query+templates-example-namespaces": "Obtener las páginas de los espacios de nombres {{ns:user}} y {{ns:template}} que están transcluidas en la página <kbd>Main Page</kbd>.",
        "apihelp-query+transcludedin-description": "Encuentra todas las páginas que transcluyan las páginas dadas.",
        "apihelp-query+transcludedin-param-prop": "Qué propiedades se obtendrán:",
        "apihelp-query+transcludedin-paramvalue-prop-pageid": "Identificador de cada página.",
        "apihelp-query+transcludedin-paramvalue-prop-title": "Título de cada página.",
+       "apihelp-query+transcludedin-paramvalue-prop-redirect": "Marcar si la página es una redirección.",
        "apihelp-query+transcludedin-param-namespace": "Incluir solo las páginas en estos espacios de nombres.",
        "apihelp-query+transcludedin-param-limit": "Cuántos se devolverán.",
+       "apihelp-query+transcludedin-param-show": "Muestra solo los elementos que cumplen estos criterios:\n;redirect: Muestra solamente redirecciones.\n;!redirect: Muestra solamente páginas que no son redirecciones.",
        "apihelp-query+transcludedin-example-simple": "Obtener una lista de páginas transcluyendo <kbd>Main Page</kbd>.",
        "apihelp-query+transcludedin-example-generator": "Obtener información sobre las páginas que transcluyen <kbd>Main Page</kbd>.",
        "apihelp-query+usercontribs-description": "Obtener todas las ediciones realizadas por un usuario.",
        "apihelp-query+usercontribs-param-limit": "Número máximo de contribuciones que se devolverán.",
+       "apihelp-query+usercontribs-param-namespace": "Enumerar solo las contribuciones en estos espacios de nombres.",
        "apihelp-query+usercontribs-param-prop": "Incluir piezas adicionales de información:",
        "apihelp-query+usercontribs-paramvalue-prop-ids": "Añade el identificador de página y el de revisión.",
        "apihelp-query+usercontribs-paramvalue-prop-title": "Agrega el título y el identificador del espacio de nombres de la página.",
        "apihelp-query+usercontribs-paramvalue-prop-parsedcomment": "Añade el comentario analizado de la edición.",
        "apihelp-query+usercontribs-paramvalue-prop-size": "Añade el nuevo tamaño de la edición.",
        "apihelp-query+usercontribs-paramvalue-prop-sizediff": "Añade la diferencia de tamaño de la edición respecto de su progenitora.",
+       "apihelp-query+usercontribs-paramvalue-prop-flags": "Añade las marcas de la edición.",
        "apihelp-query+usercontribs-paramvalue-prop-patrolled": "Etiqueta ediciones verificadas.",
        "apihelp-query+usercontribs-paramvalue-prop-tags": "Lista las etiquetas para la edición.",
        "apihelp-query+usercontribs-param-show": "Mostrar solo los elementos que coinciden con estos criterios. Por ejemplo, solo ediciones no menores: <kbd>$2show=!minor</kbd>.\n\nSi se establece <kbd>$2show=patrolled</kbd> o <kbd>$2show=!patrolled</kbd>, las revisiones más antiguas que <var>[[mw:Manual:$wgRCMaxAge|$wgRCMaxAge]]</var> ($1 {{PLURAL:$1|segundo|segundos}}) no se mostrarán.",
+       "apihelp-query+usercontribs-param-tag": "Enumerar solo las revisiones con esta etiqueta.",
+       "apihelp-query+usercontribs-param-toponly": "Enumerar solo las modificaciones que sean las últimas revisiones.",
        "apihelp-query+usercontribs-example-user": "Mostrar contribuciones del usuario <kbd>Example</kbd>.",
        "apihelp-query+usercontribs-example-ipprefix": "Mostrar las contribuciones de todas las direcciones IP con el prefijo <kbd>192.0.2.</kbd>.",
        "apihelp-query+userinfo-description": "Obtener información sobre el usuario actual.",
        "apihelp-query+userinfo-param-prop": "Qué piezas de información incluir:",
+       "apihelp-query+userinfo-paramvalue-prop-blockinfo": "Etiqueta si el usuario está bloqueado, por quién y por qué motivo.",
+       "apihelp-query+userinfo-paramvalue-prop-hasmsg": "Añade una etiqueta <samp>messages</samp> si el usuario actual tiene mensajes pendientes.",
        "apihelp-query+userinfo-paramvalue-prop-groups": "Lista todos los grupos al que pertenece el usuario actual.",
+       "apihelp-query+userinfo-paramvalue-prop-implicitgroups": "Enumera todos los grupos a los que pertenece automáticamente el usuario actual.",
        "apihelp-query+userinfo-paramvalue-prop-rights": "Lista todos los permisos que tiene el usuario actual.",
+       "apihelp-query+userinfo-paramvalue-prop-changeablegroups": "Enumera los grupos a los que el usuario actual se puede unir o retirar.",
        "apihelp-query+userinfo-paramvalue-prop-options": "Lista todas las preferencias que haya establecido el usuario actual.",
        "apihelp-query+userinfo-paramvalue-prop-editcount": "Añade el número de ediciones del usuario actual.",
        "apihelp-query+userinfo-paramvalue-prop-ratelimits": "Lista todos los límites de velocidad aplicados al usuario actual.",
        "apihelp-query+userinfo-paramvalue-prop-email": "Añade la dirección de correo electrónico del usuario y la fecha de autenticación por correo.",
        "apihelp-query+userinfo-paramvalue-prop-acceptlang": "Reenvía la cabecera <code>Accept-Language</code> enviada por el cliente en un formato estructurado.",
        "apihelp-query+userinfo-paramvalue-prop-registrationdate": "Añade la fecha de registro del usuario.",
+       "apihelp-query+userinfo-paramvalue-prop-unreadcount": "Añade el recuento de páginas no leídas de la lista de seguimiento del usuario (máximo $1, devuelve <samp>$2</samp> si el número es mayor).",
        "apihelp-query+userinfo-example-simple": "Obtener información sobre el usuario actual.",
        "apihelp-query+userinfo-example-data": "Obtener información adicional sobre el usuario actual.",
        "apihelp-query+users-description": "Obtener información sobre una lista de usuarios.",
        "apihelp-query+users-paramvalue-prop-rights": "Enumera todos los permisos que tiene cada usuario.",
        "apihelp-query+users-paramvalue-prop-editcount": "Añade el número de ediciones del usuario.",
        "apihelp-query+users-paramvalue-prop-registration": "Añade la marca de tiempo del registro del usuario.",
+       "apihelp-query+users-paramvalue-prop-emailable": "Marca si el usuario puede y quiere recibir correo electrónico a través de [[Special:Emailuser]].",
        "apihelp-query+users-paramvalue-prop-gender": "Etiqueta el género del usuario. Devuelve \"masculino\", \"femenino\" o \"desconocido\".",
+       "apihelp-query+users-paramvalue-prop-cancreate": "Indica si se puede crear una cuenta para nombres de usuario válidos pero no registrados.",
+       "apihelp-query+users-param-users": "Una lista de usuarios de los que obtener información.",
+       "apihelp-query+users-param-userids": "Una lista de identificadores de usuarios de los que obtener información.",
+       "apihelp-query+users-param-token": "Usa <kbd>[[Special:ApiHelp/query+tokens|action=query&meta=tokens]]</kbd> en su lugar.",
        "apihelp-query+users-example-simple": "Devolver información del usuario <kbd>Example</kbd>.",
+       "apihelp-query+watchlist-description": "Obtener los cambios recientes de las páginas de la lista de seguimiento del usuario actual.",
        "apihelp-query+watchlist-param-start": "El sello de tiempo para comenzar la enumeración",
        "apihelp-query+watchlist-param-end": "El sello de tiempo para finalizar la enumeración.",
        "apihelp-query+watchlist-param-namespace": "Filtrar cambios solamente a los espacios de nombres dados.",
        "apihelp-query+watchlist-paramvalue-prop-sizes": "Añade la longitud vieja y la nueva de la página.",
        "apihelp-query+watchlist-paramvalue-prop-notificationtimestamp": "Añade fecha y hora de cuando el usuario fue notificado por última vez acerca de la edición.",
        "apihelp-query+watchlist-paramvalue-prop-loginfo": "Añade información del registro cuando corresponda.",
+       "apihelp-query+watchlist-param-show": "Muestra solo los elementos que cumplan estos criterios. Por ejemplo, para ver solo ediciones menores realizadas por usuarios conectados, introduce $1show=minor|!anon.",
        "apihelp-query+watchlist-param-type": "Qué tipos de cambios mostrar:",
        "apihelp-query+watchlist-paramvalue-type-edit": "Ediciones comunes a páginas",
        "apihelp-query+watchlist-paramvalue-type-external": "Cambios externos.",
        "apihelp-query+watchlist-paramvalue-type-new": "Creaciones de páginas.",
        "apihelp-query+watchlist-paramvalue-type-log": "Entradas del registro.",
+       "apihelp-query+watchlist-paramvalue-type-categorize": "Cambios de pertenencia a categorías.",
        "apihelp-query+watchlist-param-owner": "Utilizado junto con $1token para acceder a la lista de seguimiento de otro usuario.",
+       "apihelp-query+watchlist-example-simple": "Enumera la última revisión de las páginas con cambios recientes de la lista de seguimiento del usuario actual.",
+       "apihelp-query+watchlist-example-props": "Obtener información adicional sobre la última revisión de páginas con cambios recientes en la lista de seguimiento del usuario actual.",
+       "apihelp-query+watchlist-example-allrev": "Obtener información sobre todos los cambios recientes de páginas de la lista de seguimiento del usuario actual.",
+       "apihelp-query+watchlist-example-generator": "Obtener información de página de las páginas con cambios recientes de la lista de seguimiento del usuario actual.",
+       "apihelp-query+watchlist-example-generator-rev": "Obtener información de revisión de los cambios recientes de páginas de la lista de seguimiento del usuario actual.",
+       "apihelp-query+watchlist-example-wlowner": "Enumerar la última revisión de páginas con cambios recientes de la lista de seguimiento del usuario <kbd>Example</kbd>.",
        "apihelp-query+watchlistraw-description": "Obtener todas las páginas de la lista de seguimiento del usuario actual.",
        "apihelp-query+watchlistraw-param-namespace": "Mostrar solamente las páginas de los espacios de nombres dados.",
        "apihelp-query+watchlistraw-param-limit": "Número de resultados que devolver en cada petición.",
        "apihelp-query+watchlistraw-param-prop": "Qué propiedades adicionales se obtendrán:",
+       "apihelp-query+watchlistraw-paramvalue-prop-changed": "Añade la marca de tiempo de la última notificación al usuario sobre la edición.",
        "apihelp-query+watchlistraw-param-show": "Sólo listar los elementos que cumplen estos criterios.",
        "apihelp-query+watchlistraw-param-owner": "Utilizado junto con $1token para acceder a la lista de seguimiento de otro usuario.",
        "apihelp-query+watchlistraw-param-dir": "La dirección en la que se listará.",
        "apihelp-query+watchlistraw-param-fromtitle": "Título (con el prefijo de espacio de nombres) desde el que se empezará a enumerar.",
        "apihelp-query+watchlistraw-param-totitle": "Título (con el prefijo de espacio de nombres) desde el que se dejará de enumerar.",
        "apihelp-query+watchlistraw-example-simple": "Listar las páginas de la lista de seguimiento del usuario actual.",
+       "apihelp-query+watchlistraw-example-generator": "Obtener información de las páginas de la lista de seguimiento del usuario actual.",
        "apihelp-removeauthenticationdata-description": "Elimina los datos de autentificación del usuario actual.",
+       "apihelp-removeauthenticationdata-example-simple": "Trata de eliminar los datos del usuario actual para <kbd>FooAuthenticationRequest</kbd>.",
        "apihelp-resetpassword-description": "Enviar un email de reinicialización de la contraseña a un usuario.",
        "apihelp-revisiondelete-description": "Eliminar y restaurar revisiones",
+       "apihelp-revisiondelete-param-target": "Título de la página para el borrado de la revisión, en caso de ser necesario para ese tipo.",
+       "apihelp-revisiondelete-param-ids": "Identificadores de las revisiones para borrar.",
        "apihelp-revisiondelete-param-hide": "Qué ocultar en cada revisión.",
        "apihelp-revisiondelete-param-show": "Qué mostrar en cada revisión.",
        "apihelp-revisiondelete-param-reason": "Motivo de la eliminación o restauración.",
+       "apihelp-revisiondelete-param-tags": "Etiquetas que aplicar a la entrada en el registro de borrados.",
        "apihelp-revisiondelete-example-revision": "Ocultar el contenido de la revisión <kbd>12345</kbd> de la página <kbd>Main Page</kbd>.",
        "apihelp-revisiondelete-example-log": "Ocultar todos los datos de la entrada de registro <kbd>67890</kbd> con el motivo <kbd>BLP violation</kbd>.",
        "apihelp-rollback-description": "Deshacer la última edición de la página.\n\nSi el último usuario que editó la página hizo varias ediciones consecutivas, todas ellas serán revertidas.",
+       "apihelp-rollback-param-title": "Título de la página que revertir. No se puede usar junto con <var>$1pageid</var>.",
+       "apihelp-rollback-param-pageid": "Identificador de la página que revertir. No se puede usar junto con <var>$1title</var>.",
+       "apihelp-rollback-param-tags": "Etiquetas que aplicar a la reversión.",
+       "apihelp-rollback-param-user": "Nombre del usuario cuyas ediciones se van a revertir.",
        "apihelp-rollback-param-summary": "Resumen de edición personalizado. Si se deja vacío se utilizará el predeterminado.",
        "apihelp-rollback-param-markbot": "Marcar las acciones revertidas y la reversión como ediciones por bots.",
+       "apihelp-rollback-param-watchlist": "Añadir o borrar incondicionalmente la página de la lista de seguimiento del usuario actual, usar preferencias o no cambiar seguimiento.",
+       "apihelp-rollback-example-simple": "Revertir las últimas ediciones de la página <kbd>Main Page</kbd> por el usuario <kbd>Example</kbd>.",
+       "apihelp-rollback-example-summary": "Revertir las últimas ediciones de la página <kbd>Main Page</kbd> por el usuario de IP <kbd>192.0.2.5</kbd> con resumen <kbd>Reverting vandalism</kbd>, y marcar esas ediciones y la reversión como ediciones realizadas por bots.",
        "apihelp-rsd-description": "Exportar un esquema RSD (Really Simple Discovery; Descubrimiento Muy Simple).",
        "apihelp-rsd-example-simple": "Exportar el esquema RSD.",
+       "apihelp-setnotificationtimestamp-description": "Actualizar la marca de tiempo de notificación de las páginas en la lista de seguimiento.\n\nEsto afecta a la función de resaltado de las páginas modificadas en la lista de seguimiento y al envío de correo electrónico cuando la preferencia \"{{int:tog-enotifwatchlistpages}}\" está habilitada.",
+       "apihelp-setnotificationtimestamp-param-timestamp": "Marca de tiempo en la que fijar la marca de tiempo de notificación.",
+       "apihelp-setnotificationtimestamp-param-torevid": "Revisión a la que fijar la marca de tiempo de notificación (una sola página).",
+       "apihelp-setnotificationtimestamp-param-newerthanrevid": "Revisión a la que fijar la marca de tiempo de notificación más reciente (una sola página).",
+       "apihelp-setnotificationtimestamp-example-all": "Restablecer el estado de notificación para la totalidad de la lista de seguimiento.",
+       "apihelp-setnotificationtimestamp-example-page": "Restablecer el estado de notificación de <kbd>Main page</kbd>.",
+       "apihelp-setnotificationtimestamp-example-pagetimestamp": "Fijar la marca de tiempo de notificación de <kbd>Main page</kbd> para que todas las ediciones posteriores al 1 de enero de 2012 estén consideradas como no vistas.",
+       "apihelp-setnotificationtimestamp-example-allpages": "Restablecer el estado de notificación de las páginas del espacio de nombres <kbd>{{ns:user}}</kbd>.",
        "apihelp-setpagelanguage-description": "Cambiar el idioma de una página.",
        "apihelp-setpagelanguage-description-disabled": "En este wiki no se permite modificar el idioma de las páginas.\n\nActiva <var>[[mw:Manual:$wgPageLanguageUseDB|$wgPageLanguageUseDB]]</var> para utilizar esta acción.",
        "apihelp-setpagelanguage-param-title": "Título de la página cuyo idioma deseas cambiar. No se puede usar junto con <var>$1pageid</var>.",
        "apihelp-setpagelanguage-param-pageid": "Identificador de la página cuyo idioma deseas cambiar. No se puede usar junto con <var>$1title</var>.",
        "apihelp-setpagelanguage-param-lang": "Código del idioma al que se desea cambiar la página. Usa <kbd>default</kbd> para restablecer la página al idioma predeterminado para el contenido del wiki.",
        "apihelp-setpagelanguage-param-reason": "Motivo del cambio.",
+       "apihelp-setpagelanguage-param-tags": "Cambiar las etiquetas que aplicar a la entrada de registro resultante de esta acción.",
        "apihelp-setpagelanguage-example-language": "Cambiar el idioma de <kbd>Main Page</kbd> al euskera.",
        "apihelp-setpagelanguage-example-default": "Cambiar el idioma de la página con identificador 123 al idioma predeterminado para el contenido del wiki.",
        "apihelp-stashedit-param-title": "Título de la página que se está editando.",
        "apihelp-stashedit-param-contentformat": "Formato de serialización de contenido utilizado para el texto de entrada.",
        "apihelp-stashedit-param-baserevid": "Identificador de la revisión de base.",
        "apihelp-stashedit-param-summary": "Resumen de cambios.",
+       "apihelp-tag-description": "Añadir o borrar etiquetas de modificación de revisiones individuales o entradas de registro.",
+       "apihelp-tag-param-rcid": "Uno o más identificadores de cambios recientes a los que añadir o borrar la etiqueta.",
+       "apihelp-tag-param-revid": "Uno o más identificadores de revisión a los que añadir o borrar la etiqueta.",
        "apihelp-tag-param-logid": "Uno o más identificadores de entradas del registro a los que agregar o eliminar la etiqueta.",
+       "apihelp-tag-param-add": "Etiquetas que añadir. Solo se pueden añadir etiquetas definidas manualmente.",
+       "apihelp-tag-param-remove": "Etiquetas que borrar. Solo se pueden borrar etiquetas definidas manualmente o completamente indefinidas.",
        "apihelp-tag-param-reason": "Motivo del cambio.",
+       "apihelp-tag-param-tags": "Etiquetas que aplicar a la entrada de registro que se generará como resultado de esta acción.",
        "apihelp-tag-example-rev": "Añadir la etiqueta <kbd>vandalism</kbd> al identificador de revisión 123 sin especificar un motivo",
        "apihelp-tag-example-log": "Eliminar la etiqueta <kbd>spam</kbd> de la entrada del registro con identificador 123 con el motivo <kbd>Wrongly applied</kbd>",
        "apihelp-unblock-description": "Desbloquear un usuario.",
        "apihelp-undelete-param-title": "Título de la página que restaurar.",
        "apihelp-undelete-param-reason": "Motivo de la restauración.",
        "apihelp-undelete-param-tags": "Cambiar las etiquetas para aplicar a la entrada en el registro de borrados.",
+       "apihelp-undelete-example-page": "Restaurar la página <kbd>Main page</kbd>.",
        "apihelp-undelete-example-revisions": "Restaurar dos revisiones de la página <kbd>Main Page</kbd>.",
        "apihelp-upload-param-filename": "Nombre del archivo de destino.",
        "apihelp-upload-param-tags": "Cambiar etiquetas para aplicar a la entrada del registro de subidas y a la revisión de página de archivo.",
+       "apihelp-upload-param-text": "Texto de página inicial para archivos nuevos.",
        "apihelp-upload-param-watch": "Vigilar la página.",
+       "apihelp-upload-param-watchlist": "Añadir o borrar incondicionalmente la página de la lista de seguimiento del usuario actual, utilizar las preferencias o no cambiar el estado de seguimiento.",
        "apihelp-upload-param-ignorewarnings": "Ignorar las advertencias.",
        "apihelp-upload-param-file": "Contenido del archivo.",
        "apihelp-upload-param-url": "URL de la que obtener el archivo.",
        "apihelp-validatepassword-example-1": "Validar la contraseña <kbd>foobar</kbd> para el usuario actual.",
        "apihelp-validatepassword-example-2": "Validar la contraseña <kbd>qwerty</kbd> para la creación del usuario <kbd>Example</kbd>.",
        "apihelp-watch-description": "Añadir o borrar páginas de la lista de seguimiento del usuario actual.",
+       "apihelp-watch-param-title": "La página que seguir o dejar de seguir. Usa <var>$1titles</var> en su lugar.",
+       "apihelp-watch-param-unwatch": "Si se define, en vez de seguir la página, se dejará de seguir.",
        "apihelp-watch-example-watch": "Vigilar la página <kbd>Main Page</kbd>.",
        "apihelp-watch-example-unwatch": "Dejar de vigilar la <kbd>Main Page</kbd>.",
+       "apihelp-watch-example-generator": "Seguir las primeras páginas del espacio de nombres principal.",
        "apihelp-format-example-generic": "Devolver el resultado de la consulta en formato $1.",
        "apihelp-json-description": "Extraer los datos de salida en formato JSON.",
        "apihelp-json-param-callback": "Si se especifica, envuelve la salida dentro de una llamada a una función dada. Por motivos de seguridad, cualquier dato específico del usuario estará restringido.",
        "api-help-param-multi-all": "Para especificar todos los valores, utiliza <kbd>$1</kbd>.",
        "api-help-param-default": "Predeterminado: $1",
        "api-help-param-default-empty": "Predeterminado: <span class=\"apihelp-empty\">(vacío)</span>",
+       "api-help-param-disabled-in-miser-mode": "Deshabilitado debido al [[mw:Manual:$wgMiserMode|modo avaro]].",
+       "api-help-param-limited-in-miser-mode": "<strong>Nota:</strong> Debido al [[mw:Manual:$wgMiserMode|modo avaro]], usar esto puede dar lugar a que se devuelvan menos de <var>$1limit</var> antes de continuar. En casos extremos, podrían devolverse cero resultados.",
        "api-help-param-continue": "Cuando haya más resultados disponibles, utiliza esto para continuar.",
        "api-help-param-no-description": "<span class=\"apihelp-empty\">(sin descripción)</span>",
        "api-help-examples": "{{PLURAL:$1|Ejemplo|Ejemplos}}:",
        "api-help-permissions": "{{PLURAL:$1|Permiso|Permisos}}:",
        "api-help-permissions-granted-to": "{{PLURAL:$1|Concedido a|Concedidos a}}: $2",
+       "api-help-open-in-apisandbox": "<small>[abrir en la zona de pruebas]</small>",
        "api-help-authmanagerhelper-messageformat": "Formato utilizado para los mensajes devueltos.",
        "api-help-authmanagerhelper-preservestate": "Preservar el estado de un intento fallido anterior de inicio de sesión, si es posible.",
+       "apierror-articleexists": "El artículo que intentaste crear ya estaba creado.",
        "apierror-assertbotfailed": "La aserción de que el usuario tiene el derecho <code>bot</code> falló.",
        "apierror-assertnameduserfailed": "La aserción de que el usuario es «$1» falló.",
        "apierror-assertuserfailed": "La aserción de que el usuario está conectado falló.",
        "apierror-autoblocked": "Tu dirección IP ha sido bloqueada automáticamente porque fue utilizada por un usuario bloqueado.",
        "apierror-badconfig-resulttoosmall": "El valor de <code>$wgAPIMaxResultSize</code> en este wiki es demasiado pequeño como para contener información básica de resultados.",
        "apierror-baddiff": "La comparación no puede recuperarse. Una o ambas revisiones no existen o no tienes permiso para verlas.",
+       "apierror-badformat-generic": "El formato solicitado $1 no es compatible con el modelo de contenido $2.",
+       "apierror-badformat": "El formato solicitado $1 no es compatible con el modelo de contenido $2 utilizado por $3.",
        "apierror-badgenerator-notgenerator": "El módulo <kbd>$1</kbd> no puede utilizarse como un generador.",
        "apierror-badgenerator-unknown": "<kbd>generator=$1</kbd> desconocido.",
        "apierror-badip": "El parámetro IP no es válido.",
        "apierror-cantundelete": "No se ha podido restaurar: puede que las revisiones solicitadas no existan o que ya se hayan restaurado.",
        "apierror-changeauth-norequest": "No se ha podido crear la petición de modificación.",
        "apierror-contentserializationexception": "La serialización de contenido falló: $1",
+       "apierror-create-titleexists": "Los títulos existentes no se pueden proteger con <kbd>create</kbd>.",
        "apierror-databaseerror": "[$1] Error en la consulta de la base de datos.",
        "apierror-deletedrevs-param-not-1-2": "El parámetro <var>$1</var> no se puede utilizar en los modos 1 o 2.",
        "apierror-deletedrevs-param-not-3": "El parámetro <var>$1</var> no se puede usar en modo 3.",
        "apierror-fileexists-sharedrepo-perm": "El archivo objetivo existe en un repositorio compartido. Usa el parámetro <var>ignorewarnings</var> para reemplazarlo.",
        "apierror-filenopath": "No se pudo obtener la ruta local del archivo.",
        "apierror-filetypecannotberotated": "El tipo de archivo no se puede girar.",
+       "apierror-formatphp": "Esta respuesta no se puede representar con <kbd>format=php</kbd>. Véase https://phabricator.wikimedia.org/T68776.",
        "apierror-imageusage-badtitle": "El título de <kbd>$1</kbd> debe ser un archivo.",
        "apierror-import-unknownerror": "Error desconocido en la importación: $1.",
+       "apierror-integeroutofrange-abovebotmax": "<var>$1</var> no puede ser mayor que $2 (fijado a $3) para bots o administradores de sistema.",
+       "apierror-integeroutofrange-abovemax": "<var>$1</var> no puede ser mayor que $2 (fijado a $3) para usuarios.",
+       "apierror-integeroutofrange-belowminimum": "<var>$1</var> no puede ser menor que $2 (fijado a $3).",
        "apierror-invalidcategory": "El nombre de la categoría que has introducido no es válida.",
        "apierror-invalidexpiry": "Tiempo de expiración \"$1\" no válido.",
+       "apierror-invalidlang": "Código de idioma no válido para el parámetro <var>$1</var>.",
        "apierror-invalidparammix-cannotusewith": "El parámetro <kbd>$1</kbd> no se puede utilizar junto con <kbd>$2</kbd>.",
        "apierror-invalidparammix-mustusewith": "El parámetro <kbd>$1</kbd> solo se puede utilizar junto con <kbd>$2</kbd>.",
        "apierror-invalidparammix-parse-new-section": "<kbd>section=new</kbd> no se puede combinar con los parámetros <var>oldid</var>, <var>pageid</var> y <var>page</var>. Por favor, utiliza <var>title</var> y <var>text</var>.",
        "apierror-invalidsha1base36hash": "El hash SHA1Base36 proporcionado no es válido.",
        "apierror-invalidsha1hash": "El hash SHA1 proporcionado no es válido.",
        "apierror-invalidtitle": "Título incorrecto \"$1\".",
+       "apierror-invalidurlparam": "Valor no válido para <var>$1urlparam</var> (<kbd>$2=$3</kbd>).",
        "apierror-invaliduser": "Nombre de usuario «$1» no válido.",
        "apierror-invaliduserid": "El identificador de usuario <var>$1</var> no es válido.",
+       "apierror-mimesearchdisabled": "La búsqueda MIME está deshabilitada en el modo avaro.",
+       "apierror-missingcontent-pageid": "Contenido faltante para la página con identificador $1.",
        "apierror-missingparam-at-least-one-of": "{{PLURAL:$2|El parámetro|Al menos uno de los parámetros}} $1 es necesario.",
        "apierror-missingparam-one-of": "{{PLURAL:$2|El parámetro|Uno de los parámetros}} $1 es necesario.",
        "apierror-missingparam": "Se debe establecer el parámetro <var>$1</var>.",
        "apierror-missingrev-pageid": "No hay ninguna revisión actual de la página con ID $1.",
+       "apierror-missingtitle-createonly": "Los títulos faltantes solo se pueden proteger con <kbd>create</kbd>.",
        "apierror-missingtitle": "El título especificado no existe.",
        "apierror-missingtitle-byname": "La página $1 no existe.",
        "apierror-moduledisabled": "El módulo <kbd>$1</kbd> ha sido deshabilitado.",
        "apierror-mustbeloggedin-removeauth": "Debes estar conectado para borrar datos de autentificación.",
        "apierror-mustbeloggedin": "Debes estar conectado para $1.",
        "apierror-mustbeposted": "El módulo <kbd>$1</kbd> requiere una petición POST.",
+       "apierror-nochanges": "No se solicitó ningún cambio.",
        "apierror-noedit-anon": "Los usuarios anónimos no pueden editar páginas.",
        "apierror-noedit": "No tienes permiso para editar páginas.",
        "apierror-noimageredirect-anon": "Los usuarios anónimos no pueden crear redirecciones de imágenes.",
        "apierror-nosuchsection": "No hay ninguna sección $1.",
        "apierror-nosuchsection-what": "No hay ninguna sección $1 en $2.",
        "apierror-nosuchuserid": "No hay ningún usuario con ID $1.",
+       "apierror-notarget": "No has especificado un destino válido para esta acción.",
+       "apierror-notpatrollable": "La revisión r$1 no se puede patrullar por ser demasiado antigua.",
+       "apierror-opensearch-json-warnings": "No se pueden representar los avisos en formato JSON de OpenSearch.",
+       "apierror-pagecannotexist": "En este espacio de nombres no se permiten páginas reales.",
+       "apierror-pagedeleted": "La página ha sido borrada en algún momento desde que obtuviste su marca de tiempo.",
        "apierror-pagelang-disabled": "En este wiki no se puede cambiar el idioma de una página.",
        "apierror-paramempty": "El parámetro <var>$1</var> no puede estar vacío.",
+       "apierror-parsetree-notwikitext-title": "<kbd>prop=parsetree</kbd> solo es compatible con el contenido en wikitexto. $1 usa el modelo de contenido $2.",
        "apierror-permissiondenied": "No tienes permiso para $1.",
        "apierror-permissiondenied-generic": "Permiso denegado.",
        "apierror-permissiondenied-unblock": "No tienes permiso para desbloquear usuarios.",
+       "apierror-promised-nonwrite-api": "La cabecera HTTP <code>Promise-Non-Write-API-Action</code> no se puede enviar a módulos de la API en modo escritura.",
        "apierror-protect-invalidaction": "Tipo de protección «$1» no válido.",
        "apierror-protect-invalidlevel": "Nivel de protección «$1» no válido.",
        "apierror-readapidenied": "Necesitas permiso de lectura para utilizar este módulo.",
        "apierror-readonly": "El wiki está actualmente en modo de solo lectura.",
+       "apierror-reauthenticate": "No te has autentificado recientemente en esta sesión. Por favor, vuelve a autentificarte.",
        "apierror-revdel-paramneeded": "Se requiere al menos un valor para <var>hide</var> y/o <var>show</var>.",
        "apierror-revwrongpage": "r$1 no es una revisión de $2.",
+       "apierror-sectionsnotsupported": "Las secciones no son compatibles con el modelo de contenido $1.",
+       "apierror-sectionsnotsupported-what": "Las secciones no son compatibles con $1.",
        "apierror-show": "Parámetro incorrecto: no se pueden proporcionar valores mutuamente excluyentes.",
+       "apierror-sizediffdisabled": "La diferencia de tamaño está deshabilitada en el modo avaro.",
+       "apierror-spamdetected": "Tu edición fue rechazada por contener un fragmento de spam: <code>$1</code>.",
        "apierror-specialpage-cantexecute": "No tienes permiso para ver los resultados de esta página especial.",
        "apierror-stashwrongowner": "Propietario incorrecto: $1",
        "apierror-systemblocked": "Has sido bloqueado automáticamente por el software MediaWiki.",
+       "apierror-templateexpansion-notwikitext": "La expansión de plantillas solo es compatible con el contenido en wikitexto. $1 usa el modelo de contenido $2.",
        "apierror-unknownaction": "La acción especificada, <kbd>$1</kbd>, no está reconocida.",
        "apierror-unknownerror-nocode": "Error desconocido.",
        "apierror-unknownerror": "Error desconocido: «$1»",
        "apierror-unknownformat": "Formato no reconocido «$1».",
        "apierror-unrecognizedparams": "{{PLURAL:$2|Parámetro no reconocido|Parámetros no reconocidos}}: $1.",
        "apierror-unrecognizedvalue": "Valor no reconocido para el parámetro <var>$1</var>: $2.",
+       "apierror-urlparamnormal": "No se pudieron normalizar los parámetros de imagen de $1.",
        "apierror-writeapidenied": "No tienes permiso para editar este wiki a través de la API.",
+       "apiwarn-alldeletedrevisions-performance": "Para conseguir un mejor rendimiento a la hora de generar títulos, establece <kbd>$1dir=newer</kbd>.",
+       "apiwarn-badurlparam": "No se pudo analizar <var>$1urlparam</var> para $2. Se utilizarán solamente la anchura y altura.",
+       "apiwarn-badutf8": "El valor pasado para <var>$1</var> contiene datos no válidos o no normalizados. Los datos textuales deberían estar en Unicode válido, normalizado en NFC y sin caracteres de control C0 excepto HT (\\t), LF (\\n) y CR (\\r).",
+       "apiwarn-deprecation-deletedrevs": "<kbd>list=deletedrevs</kbd> ha quedado obsoleto. En su lugar, utiliza <kbd>prop=deletedrevisions</kbd> o <kbd>list=alldeletedrevisions</kbd>.",
        "apiwarn-deprecation-httpsexpected": "Se ha utilizado HTTP cuando se esperaba HTTPS.",
+       "apiwarn-deprecation-parameter": "El parámetro <var>$1</var> ha quedado obsoleto.",
+       "apiwarn-deprecation-purge-get": "El uso de <kbd>action=purge</kbd> mediante GET está obsoleto. Usa POST en su lugar.",
+       "apiwarn-deprecation-withreplacement": "<kbd>$1</kbd> ha quedado obsoleto. En su lugar, utiliza <kbd>$2</kbd>.",
        "apiwarn-invalidcategory": "\"$1\" no es una categoría.",
        "apiwarn-invalidtitle": "«$1» no es un título válido.",
        "apiwarn-invalidxmlstylesheetext": "Las hojas de estilo deben tener la extensión <code>.xsl</code>.",
        "apiwarn-invalidxmlstylesheet": "La hoja de estilos especificada no es válida o no existe.",
        "apiwarn-invalidxmlstylesheetns": "La hoja de estilos debería estar en el espacio de nombres {{ns:MediaWiki}}.",
        "apiwarn-notfile": "\"$1\" no es un archivo.",
+       "apiwarn-parse-nocontentmodel": "No se proporcionó <var>title</var> ni <var>contentmodel</var>. Se asume $1.",
+       "apiwarn-tokennotallowed": "La acción «$1» no está permitida para el usuario actual.",
+       "apiwarn-truncatedresult": "Se ha truncado este resultado porque de otra manera sobrepasaría el límite de $1 bytes.",
        "apiwarn-unclearnowtimestamp": "El paso de «$2» para el parámetro <var>$1</var> de la marca de tiempo ha quedado obsoleto. Si por alguna razón necesitas especificar de forma explícita la hora actual sin calcularla desde el lado del cliente, utiliza <kbd>now</kbd> («ahora»).",
        "apiwarn-unrecognizedvalues": "{{PLURAL:$3|Valor no reconocido|Valores no reconocidos}} para el parámetro <var>$1</var>: $2.",
        "apiwarn-validationfailed-badchars": "caracteres no válidos en la clave (solamente se admiten los caracteres <code>a-z</code>, <code>A-Z</code>, <code>0-9</code>, <code>_</code> y <code>-</code>).",
index e3a70f5..52a526d 100644 (file)
        "apihelp-feedrecentchanges-description": "Renvoie un fil de modifications récentes.",
        "apihelp-feedrecentchanges-param-feedformat": "Le format du flux.",
        "apihelp-feedrecentchanges-param-namespace": "Espace de noms auquel limiter les résultats.",
-       "apihelp-feedrecentchanges-param-invert": "Tous les espaces de nom sauf le sélectionné.",
+       "apihelp-feedrecentchanges-param-invert": "Tous les espaces de noms sauf celui sélectionné.",
        "apihelp-feedrecentchanges-param-associated": "Inclure l’espace de noms associé (discussion ou principal).",
        "apihelp-feedrecentchanges-param-days": "Jours auxquels limiter le résultat.",
        "apihelp-feedrecentchanges-param-limit": "Nombre maximal de résultats à renvoyer.",
index 8c76914..727ce02 100644 (file)
        "apihelp-upload-example-url": "Carica da un URL.",
        "apihelp-userrights-param-user": "Nome utente.",
        "apihelp-userrights-param-userid": "ID utente.",
-       "apihelp-userrights-param-add": "Aggiungi l'utente a questi gruppi.",
+       "apihelp-userrights-param-add": "Aggiungere l'utente a questi gruppi, o se sono già membri, aggiornare la scadenza della loro appartenenza a quel gruppo.",
        "apihelp-userrights-param-remove": "Rimuovi l'utente da questi gruppi.",
        "apihelp-userrights-param-reason": "Motivo del cambiamento.",
        "apihelp-validatepassword-description": "Convalida una password seguendo le politiche del wiki sulle password.\n\nLa validità è riportata come <samp>Good</samp> se la password è accettabile, <samp>Change</samp> se la password può essere utilizzata per l'accesso ma deve essere modificata, o <samp>Invalid</samp> se la password non è utilizzabile.",
index dfe77e3..b91b806 100644 (file)
@@ -48,6 +48,7 @@
        "apihelp-block-param-allowusertalk": "자신의 토론 문서를 편집할 수 있도록 허용합니다. (<var>[[mw:Manual:$wgBlockAllowsUTEdit|$wgBlockAllowsUTEdit]]</var> 값에 따라 다름)",
        "apihelp-block-param-reblock": "사용자가 이미 차단된 경우, 기존 차단 설정을 바꿉니다.",
        "apihelp-block-param-watchuser": "해당 사용자 또는 IP 주소의 사용자 문서 및 토론 문서를 주시합니다.",
+       "apihelp-block-param-tags": "차단 기록의 항목에 적용할 태그를 변경합니다.",
        "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-changeauthenticationdata-description": "현재 사용자의 인증 데이터를 변경합니다.",
        "apihelp-imagerotate-description": "하나 이상의 그림을 회전합니다.",
        "apihelp-imagerotate-param-rotation": "시계 방향으로 회전할 그림의 각도.",
        "apihelp-import-param-xml": "업로드한 XML 파일.",
-       "apihelp-login-param-name": "계정 이름.",
+       "apihelp-login-param-name": "사용자 이름.",
        "apihelp-login-param-password": "비밀번호.",
        "apihelp-login-param-domain": "도메인 (선택).",
        "apihelp-login-param-token": "처음 요청에서 로그인 토큰을 취득했습니다.",
        "apihelp-move-param-watch": "현재 사용자의 주시 문서에 이 문서와 넘겨주기 문서를 추가하기",
        "apihelp-move-param-unwatch": "현재 사용자의 주시 문서에 이 문서와 넘겨주기 문서를 제거하기",
        "apihelp-move-param-ignorewarnings": "모든 경고 무시하기",
+       "apihelp-move-example-move": "<kbd>기존 제목</kbd>에서 <kbd>대상 제목</kbd>으로 넘겨주기를 만들지 않고 이동하기.",
        "apihelp-opensearch-description": "OpenSearch 프로토콜을 이용하여 위키 검색하기",
        "apihelp-opensearch-param-search": "문자열 검색",
        "apihelp-opensearch-param-limit": "반환할 결과의 최대 수",
        "apihelp-parse-example-page": "페이지의 구문을 분석합니다.",
        "apihelp-parse-example-text": "위키텍스트의 구문을 분석합니다.",
        "apihelp-parse-example-summary": "요약을 구문 분석합니다.",
+       "apihelp-patrol-example-revid": "판을 점검합니다.",
        "apihelp-protect-description": "문서의 보호 수준을 변경합니다.",
        "apihelp-protect-param-reason": "보호 또는 보호 해제의 이유.",
        "apihelp-protect-example-protect": "문서 보호",
        "apihelp-unblock-param-user": "차단을 해제할 사용자 이름, IP 주소, IP 주소 대역입니다. <var>$1id</var> 또는 <var>$1userid</var>와(과) 함께 사용할 수 없습니다.",
        "apihelp-unblock-param-userid": "차단을 해제할 사용자 ID입니다. <var>$1id</var> 또는 <var>$1user</var>와(과) 함께 사용할 수 없습니다.",
        "apihelp-unblock-param-reason": "차단 해제 이유.",
+       "apihelp-unblock-param-tags": "차단 기록의 항목에 적용할 태그를 변경합니다.",
        "apihelp-upload-param-ignorewarnings": "모든 경고를 무시합니다.",
        "apihelp-userrights-param-user": "사용자 이름.",
        "apihelp-userrights-param-userid": "사용자 ID.",
        "api-help-permissions-granted-to": "{{PLURAL:$1|다음 그룹에 부여됨}}: $2",
        "api-help-right-apihighlimits": "API 쿼리에서 더 높은 제한 사용 (느린 쿼리: $1, 빠른 쿼리: $2) 느린 쿼리에 대한 제한은 다중값 매개변수에도 적용됩니다.",
        "api-help-open-in-apisandbox": "<small>[연습장에서 열기]</small>",
+       "api-help-authmanager-general-usage": "이 모듈을 사용하는 일반적인 절차는 다음과 같습니다:\n# <kbd>amirequestsfor=$4</kbd>와 함께 <kbd>[[Special:ApiHelp/query+authmanagerinfo|action=query&meta=authmanagerinfo]]</kbd>에서 사용할 수 있는 필드와 <kbd>[[Special:ApiHelp/query+tokens|action=query&meta=tokens]]</kbd>의 토큰을 가져옵니다.\n# 사용자에게 필드를 제시하고 사용자의 제출 사항을 취득합니다.\n# <var>$1returnurl</var> 및 관련된 모든 필드를 제공, 이 모듈에 전달합니다.\n# 응답 시 <samp>status</samp>를 확인합니다.\n#* <samp>PASS</samp> 또는 <samp>FAIL</samp>을 수신한 경우 작업은 끝난 것입니다. 동작은 성공하였거나 그렇지 않은 경우입니다.\n#* <samp>UI</samp>를 수신한 경우 사용자에게 새로운 필드를 제시하고 사용자의 제출 사항을 취득합니다. 그 뒤 <var>$1continue</var> 및 관련된 모든 필드 집합과 함께 이 모듈에 전달하고 단계 4를 반복합니다.\n#* <samp>REDIRECT</samp>를 수신한 경우, 사용자를 <samp>redirecttarget</samp>으로 넘겨준 다음 <var>$1returnurl</var>로 반환될 때까지 기다립니다. 그 뒤 <var>$1continue</var> 및 반환 URL에 전달되는, 모든 관련 필드와 함께 이 모듈에 전달하고 단계 4를 반복합니다.\n#* <samp>RESTART</samp>를 수실한 경우 인증은 동작했으나 연결된 사용자 계정이 없다는 것을 의미합니다. <samp>UI</samp>나 <samp>FAIL</samp>로 간주할 수 있습니다.",
+       "api-help-authmanagerhelper-requests": "<kbd>amirequestsfor=$1</kbd>와(과) 함께 <kbd>[[Special:ApiHelp/query+authmanagerinfo|action=query&meta=authmanagerinfo]]</kbd>에서 반환된 <samp>id</samp>를 통해, 또는 이 모듈의 과거 응답으로부터 이 인증 요청만을 사용합니다.",
        "api-help-authmanagerhelper-request": "<kbd>amirequestsfor=$1</kbd>을(를) 지정하여 <kbd>[[Special:ApiHelp/query+authmanagerinfo|action=query&meta=authmanagerinfo]]</kbd>가 반환한 <samp>id</samp>를 통해 이 인증 요청을 사용합니다.",
        "api-help-authmanagerhelper-messageformat": "반환 메시지에 사용할 형식.",
+       "api-help-authmanagerhelper-mergerequestfields": "모든 인증 요청에 대한 필드 정보를 하나의 배열로 합칩니다.",
+       "api-help-authmanagerhelper-preservestate": "가능하면 과거에 실패한 로그인 시도의 상태를 보존합니다.",
+       "api-help-authmanagerhelper-continue": "이 요청은 초기 <samp>UI</samp> 또는 <samp>REDIRECT</samp> 응답 이후에 계속됩니다. 이것 또는 <var>$1returnurl</var> 중 하나가 필요합니다.",
        "api-help-authmanagerhelper-additional-params": "이 모듈은 사용 가능한 인증 요청에 따라 추가 변수를 허용합니다. 사용 가능한 요청 및 사용되는 필드를 결정하려면 <kbd>amirequestsfor=$1</kbd>(또는 해당되는 경우 이 모듈의 과거 응답)과 함께 <kbd>[[Special:ApiHelp/query+authmanagerinfo|action=query&meta=authmanagerinfo]]</kbd>을(를) 사용하십시오.",
        "apierror-articleexists": "작성하려는 문서가 이미 만들어져 있습니다.",
        "apierror-autoblocked": "사용자의 IP 주소는 차단된 사용자에 의해 사용되었으므로 자동으로 차단된 상태입니다.",
index 79c3e63..0935c59 100644 (file)
        "apihelp-query+watchlist-paramvalue-type-log": "Žurnalo įrašai.",
        "apihelp-resetpassword-param-user": "Iš naujo nustatomas vartotojas.",
        "apihelp-resetpassword-param-email": "Iš naujo nustatomo vartotojo el. pašto adresas.",
+       "apihelp-setpagelanguage-description": "Keisti puslapio kalbą.",
+       "apihelp-setpagelanguage-param-reason": "Keitimo priežastis.",
        "apihelp-stashedit-param-title": "Puslapio pavadinimas buvo redaguotas.",
        "apihelp-stashedit-param-sectiontitle": "Naujo skyriaus pavadinimas.",
        "apihelp-stashedit-param-text": "Puslapio turinys.",
        "apierror-invalidparammix": "{{PLURAL:$2|parametrai}} $1 negali būti naudojami kartu.",
        "apierror-invalidtitle": "Blogas pavadinimas „$1“.",
        "apierror-invaliduser": "Negalimas vartotojo vardas „$1“.",
+       "apierror-invaliduserid": "Vartotojo ID <var>$1</var> nėra galimas.",
        "apierror-missingtitle": "Puslapis, kurį nurodėte, neegzistuoja.",
        "apierror-missingtitle-byname": "Puslapis $1 neegzistuoja",
        "apierror-multpages": "<var>$1</var> gali būti naudojamas tik su vienu puslapiu.",
        "apierror-nosuchsection": "Nėra skyriaus $1.",
        "apierror-nosuchsection-what": "$2 nėra sekcijos $1.",
        "apierror-nosuchuserid": "Nėra vartotojo su ID $1.",
+       "apierror-pagelang-disabled": "Puslapio kalbos keitimas nėra leidžiamas šioje viki.",
        "apierror-paramempty": "Parametras <var>$1</var> negali būti tusčiau.",
        "apierror-permissiondenied": "Neturite leidimo $1.",
        "apierror-permissiondenied-generic": "Teisė nesuteikta.",
index 750a233..decd400 100644 (file)
        "apihelp-main-param-requestid": "Elke waarde die hier gegeven wordt, wordt aan het antwoord toegevoegd. Dit kan gebruikt worden om verzoeken te onderscheiden.",
        "apihelp-main-param-servedby": "Voeg de hostnaam van de server die de aanvraag heeft afgehandeld toe aan het antwoord.",
        "apihelp-main-param-curtimestamp": "Huidige tijd aan het antwoord toevoegen.",
+       "apihelp-main-param-responselanginfo": "Toon de talen gebruikt voor <var>uselang</var> en <var>errorlang</var> in het resultaat.",
+       "apihelp-main-param-errorlang": "De taal om te gebruiken voor waarschuwingen en fouten. <kbd>[[Special:ApiHelp/query+siteinfo|action=query&meta=siteinfo]]</kbd> met <kbd>siprop=languages</kbd> toont een lijst van taalcodes, of stel <kbd>inhoud</kbd> in om gebruik te maken van de inhoudstaal van deze wiki, of stel <kbd>uselang</kbd> in om gebruik te maken van dezelfde waarde als de <var>uselang</var> parameter.",
+       "apihelp-main-param-errorsuselocal": "Indien ingesteld maken foutmeldingen gebruik van lokaal-aangepaste berichten in de {{ns:MediaWiki}} naamruimte.",
        "apihelp-block-description": "Gebruiker blokkeren.",
        "apihelp-block-param-user": "Gebruikersnaam, IP-adres of IP-range om te blokkeren. Kan niet samen worden gebruikt me <var>$1userid</var>",
        "apihelp-block-param-userid": "Gebruikers-ID om te blokkeren. Kan niet worden gebruikt in combinatie met <var>$1user</var>.",
+       "apihelp-block-param-expiry": "Vervaldatum. Kan relatief zijn (bijv. <kbd>5 months</kbd> of <kbd>2 weeks</kbd>) of absoluut (<kbd>2014-09-18T12:34:56Z</kbd>). Indien ingesteld op <kbd>infinite</kbd>, <kbd>indefinite</kbd>, of <kbd>never</kbd> verloopt de blokkade nooit.",
        "apihelp-block-param-reason": "Reden voor blokkade.",
        "apihelp-block-param-anononly": "Alleen anonieme gebruikers blokkeren (uitschakelen van anonieme bewerkingen via dit IP-adres)",
        "apihelp-block-param-nocreate": "Voorkom registeren van accounts.",
        "apihelp-block-param-autoblock": "Blokkeer automatisch het laatst gebruikte IP-adres en ieder volgend IP-adres van waaruit ze proberen aan te melden.",
+       "apihelp-block-param-noemail": "Gebruiker weerhouden van het sturen van e-mail. (Vereist het <code>blockemail</code> recht).",
        "apihelp-block-param-hidename": "Verberg de gebruikersnaam uit het blokkeerlogboek. (Vereist het <code>hideuser</code> recht).",
        "apihelp-block-param-reblock": "De huidige blokkade aanpassen als de gebruiker al geblokkeerd is.",
        "apihelp-block-param-watchuser": "De gebruikerspagina en overlegpagina van de gebruiker of het IP-adres volgen.",
+       "apihelp-block-param-tags": "Wijzigingslabels om toe te passen op de regel in het blokkeerlogboek.",
        "apihelp-block-example-ip-simple": "Het IP-adres <kbd>192.0.2.5</kbd> voor drie dagen blokkeren met <kbd>First strike</kbd> als opgegeven reden.",
+       "apihelp-block-example-user-complex": "Blokkeer gebruiker<kbd>Vandal</kbd> voor altijd met reden <kbd>Vandalism</kbd> en voorkom het aanmaken van nieuwe accounts en het versturen van email",
+       "apihelp-changeauthenticationdata-example-password": "Poging tot het wachtwoord van de huidige gebruiker te veranderen naar <kbd>ExamplePassword</kbd>.",
+       "apihelp-checktoken-description": "Controleer de geldigheid van een token van <kbd>[[Special:ApiHelp/query+tokens|action=query&meta=tokens]]</kbd>.",
        "apihelp-checktoken-param-type": "Tokentype wordt getest.",
+       "apihelp-checktoken-param-token": "Token om te controleren.",
+       "apihelp-checktoken-param-maxtokenage": "Maximum levensduur van de token, in seconden.",
+       "apihelp-checktoken-example-simple": "Test de geldigheid van een <kbd>csrf</kbd> token.",
+       "apihelp-clearhasmsg-description": "Wist de <code>hasmsg</code> vlag voor de huidige gebruiker.",
+       "apihelp-clearhasmsg-example-1": "Wis de <code>hasmsg</code> vlag voor de huidige gebruiker.",
+       "apihelp-clientlogin-description": "Log in op de wiki met behulp van de interactieve flow.",
+       "apihelp-clientlogin-example-login": "Start het inlogproces op de wiki als gebruiker <kbd>Example</kbd> met wachtwoord <kbd>ExamplePassword</kbd>.",
        "apihelp-compare-param-fromtitle": "Eerste paginanaam om te vergelijken.",
        "apihelp-compare-param-fromid": "Eerste pagina-ID om te vergelijken.",
        "apihelp-compare-param-fromrev": "Eerste versie om te vergelijken.",
        "apihelp-compare-param-torev": "Tweede versie om te vergelijken.",
        "apihelp-createaccount-description": "Nieuwe gebruikersaccount aanmaken.",
        "apihelp-createaccount-param-name": "Gebruikersnaam.",
+       "apihelp-createaccount-param-password": "Wachtwoord (genegeerd als <var>$1mailpassword</var> is ingesteld).",
+       "apihelp-createaccount-param-domain": "Domein voor externe authentificatie (optioneel).",
        "apihelp-createaccount-param-email": "E-mailadres van de gebruiker (optioneel).",
        "apihelp-createaccount-param-realname": "Echte naam van de gebruiker (optioneel).",
+       "apihelp-createaccount-param-reason": "Optionele reden voor het aanmaken van het account voor in het logboek.",
        "apihelp-createaccount-param-language": "Taalcode om als standaard in te stellen voor de gebruiker (optioneel, standaard de inhoudstaal).",
        "apihelp-createaccount-example-pass": "Maak gebruiker <kbd>testuser</kbd> aan met wachtwoord <kbd>test123</kbd>.",
        "apihelp-createaccount-example-mail": "Maak gebruiker <kbd>testmailuser</kbd> aan en e-mail een willekeurig gegenereerd wachtwoord.",
        "apihelp-edit-param-nocreate": "Een foutmelding geven als de pagina niet bestaat.",
        "apihelp-edit-param-watch": "Voeg de pagina toe aan de volglijst van de huidige gebruiker.",
        "apihelp-edit-param-unwatch": "Verwijder de pagina van de volglijst van de huidige gebruiker.",
+       "apihelp-edit-param-md5": "De MD5-hash van de $1text parameter, of de $1prependtext en $1appendtext parameters samengevoegd. Indien ingesteld, wordt de bewerking niet gemaakt, tenzij de hash juist is.",
+       "apihelp-edit-param-prependtext": "Voeg deze tekst toe aan het begin van de pagina. Overschrijft $1text.",
+       "apihelp-edit-param-appendtext": "Voeg deze tekst toe aan het begin van de pagina. Overschrijft $1text.\n\nGebruik $1section=new in plaats van deze parameter om een nieuw kopje toe te voegen.",
+       "apihelp-edit-param-undo": "Maak deze versie ongedaan. Overschrijft $1text, $1prependtext en $1appendtext.",
+       "apihelp-edit-param-undoafter": "Maak alle versies vanaf $1undo to deze ongedaan maken. Indien niet ingesteld wordt slechts één versie ongedaan gemaakt.",
        "apihelp-edit-param-redirect": "Doorverwijzingen automatisch oplossen.",
+       "apihelp-edit-param-contentmodel": "Inhoudsmodel van de nieuwe inhoud.",
+       "apihelp-edit-param-token": "Het token moet altijd worden verzonden als de laatste parameter, of tenminste na de $1text parameter.",
        "apihelp-edit-example-edit": "Een pagina bewerken.",
+       "apihelp-edit-example-prepend": "Voeg <kbd>__NOTOC__</kbd> toe aan het begin van een pagina.",
        "apihelp-edit-example-undo": "Versies 13579 tot 13585 ongedaan maken met automatische beschrijving.",
        "apihelp-emailuser-description": "Gebruiker e-mailen.",
        "apihelp-emailuser-param-target": "Gebruiker naar wie de e-mail moet worden gestuurd.",
        "apihelp-emailuser-param-subject": "Onderwerpkoptekst.",
        "apihelp-emailuser-param-text": "E-mailtekst.",
        "apihelp-emailuser-param-ccme": "Mij een kopie sturen van deze e-mail.",
+       "apihelp-emailuser-example-email": "Stuur een e-mail naar de gebruiker <kbd>WikiSysop</kbd> met de tekst <kbd>Inhoud</kbd>.",
        "apihelp-expandtemplates-param-title": "Paginanaam.",
        "apihelp-expandtemplates-param-text": "Wikitekst om om te zetten.",
        "apihelp-expandtemplates-paramvalue-prop-wikitext": "De uitgevulde wikitekst.",
        "apihelp-feedcontributions-param-year": "Van jaar (en eerder).",
        "apihelp-feedcontributions-param-month": "Van maand (en eerder).",
        "apihelp-feedcontributions-param-deletedonly": "Alleen verwijderde bijdragen weergeven.",
+       "apihelp-feedcontributions-param-toponly": "Alleen bewerkingen die de nieuwste versies zijn weergeven.",
+       "apihelp-feedcontributions-param-newonly": "Alleen bewerkingen die nieuwe pagina's aanmaken weergeven.",
        "apihelp-feedcontributions-param-hideminor": "Verberg kleine bewerkingen.",
+       "apihelp-feedcontributions-param-showsizediff": "Toon het verschil in grootte tussen versies.",
+       "apihelp-feedcontributions-example-simple": "Toon bijdragen voor gebruiker <kbd>Example</kbd>.",
+       "apihelp-feedrecentchanges-param-feedformat": "De indeling van de feed.",
+       "apihelp-feedrecentchanges-param-namespace": "Naamruimte om de resultaten tot te beperken.",
        "apihelp-feedrecentchanges-param-invert": "Alle naamruimten behalve de geselecteerde.",
        "apihelp-feedrecentchanges-param-limit": "Het maximaal aantal weer te geven resultaten.",
        "apihelp-feedrecentchanges-param-hideminor": "Kleine wijzigingen verbergen.",
        "apihelp-feedrecentchanges-param-tagfilter": "Filteren op label.",
        "apihelp-feedrecentchanges-example-simple": "Recente wijzigingen weergeven.",
        "apihelp-feedrecentchanges-example-30days": "Recente wijzigingen van de afgelopen 30 dagen weergeven.",
+       "apihelp-feedwatchlist-param-feedformat": "De indeling van de feed.",
        "apihelp-filerevert-description": "Een oude versie van een bestand terugplaatsen.",
+       "apihelp-filerevert-param-filename": "Doel bestandsnaam, zonder het Bestand: voorvoegsel.",
+       "apihelp-filerevert-param-comment": "Opmerking voor het uploaden.",
+       "apihelp-filerevert-example-revert": "Zet <kbd>Wiki.png</kbd> terug naar de versie van <kbd>2011-03-05T15:27:40Z</kbd>.",
+       "apihelp-help-description": "Toon help voor de opgegeven modules.",
+       "apihelp-help-param-helpformat": "Indeling van de help uitvoer.",
+       "apihelp-help-example-main": "Hulp voor de hoofdmodule.",
+       "apihelp-help-example-submodules": "Hulp voor <kbd>action=query</kbd> en alle submodules.",
        "apihelp-help-example-recursive": "Alle hulp op een pagina.",
        "apihelp-help-example-help": "Help voor de help-module zelf.",
        "apihelp-imagerotate-description": "Een of meerdere afbeeldingen draaien.",
+       "apihelp-imagerotate-param-tags": "Labels om toe te voegen aan de regel in het uploadlogboek.",
+       "apihelp-imagerotate-example-simple": "Roteer <kbd>File:Example.png</kbd> met <kbd>90</kbd> graden.",
+       "apihelp-imagerotate-example-generator": "Roteer alle afbeeldingen in <kbd>Category:Flip</kbd> met <kbd>180</kbd> graden.",
+       "apihelp-import-description": "Importeer een pagina van een andere wiki, of van een XML bestand.\n\nMerk op dat de HTTP POST moet worden uitgevoerd als bestandsupload (bijv. door middel van multipart/form-data) wanneer een bestand wordt verstuurd voor de <var>xml</var> parameter.",
+       "apihelp-import-param-summary": "Importsamenvatting voor het logboek.",
        "apihelp-import-param-xml": "Geüpload XML-bestand.",
+       "apihelp-import-param-interwikisource": "Voor interwiki imports: wiki om van te importeren.",
        "apihelp-import-param-namespace": "Importeren in deze naamruimte. Can niet samen gebruikt worden met <var>$1rootpage</var>.",
        "apihelp-import-param-rootpage": "Importeren als subpagina van deze pagina. Kan niet samen met <var>$1namespace</var> gebruikt worden.",
        "apihelp-login-param-name": "Gebruikersnaam.",
        "apihelp-logout-description": "Afmelden en sessiegegevens wissen.",
        "apihelp-logout-example-logout": "Meldt de huidige gebruiker af.",
        "apihelp-managetags-param-tag": "Label om aan te maken, te activeren of te deactiveren. Voor het aanmaken van een label, mag het niet bestaan. Voor het verwijderen van een label, moet het bestaan. Voor het activeren van een label, moet het bestaan en mag het niet gebruikt worden door een uitbreiding. Voor het deactiveren van een label, moet het gebruikt worden en handmatig gedefinieerd zijn.",
+       "apihelp-managetags-example-create": "Maak een label met de naam <kbd>spam</kbd> aan met als reden <kbd>For use in edit patrolling</kbd>",
        "apihelp-move-description": "Pagina hernoemen.",
        "apihelp-move-param-to": "Nieuwe paginanaam.",
        "apihelp-move-param-reason": "Reden voor de naamswijziging.",
+       "apihelp-move-param-movetalk": "Hernoem de overlegpagina, indien deze bestaat.",
        "apihelp-move-param-noredirect": "Geen doorverwijzing achterlaten.",
        "apihelp-move-param-watch": "Pagina en de omleiding toevoegen aan de volglijst van de huidige gebruiker.",
        "apihelp-move-param-unwatch": "Verwijder de pagina en de doorverwijzing van de volglijst van de huidige gebruiker.",
        "apihelp-patrol-example-revid": "Een versie markeren als gecontroleerd.",
        "apihelp-protect-param-reason": "Reden voor opheffen van de beveiliging.",
        "apihelp-protect-example-protect": "Een pagina beveiligen",
+       "apihelp-query+allcategories-param-dir": "Richting om in te sorteren.",
+       "apihelp-query+allcategories-paramvalue-prop-size": "Voegt het aantal pagina's in de categorie toe.",
+       "apihelp-query+allcategories-paramvalue-prop-hidden": "Markeert categorieën die verborgen zijn met <code>_&#95;HIDDENCAT_&#95;</code>",
        "apihelp-query+alldeletedrevisions-param-tag": "Alleen versies weergeven met dit label.",
+       "apihelp-query+alldeletedrevisions-param-excludeuser": "Toon geen versies door deze gebruiker.",
+       "apihelp-query+alldeletedrevisions-param-namespace": "Toon alleen pagina's in deze naamruimte.",
+       "apihelp-query+alllinks-param-namespace": "De naamruimte om door te lopen.",
+       "apihelp-query+alllinks-param-limit": "Hoeveel items er in totaal moeten worden getoond.",
        "apihelp-query+allmessages-param-enableparser": "Stel in om de parser in te schakelen, zorgt voor het voorverwerken van de wikitekst van een bericht (vervangen van magische woorden, de afhandeling van sjablonen, enzovoort).",
+       "apihelp-query+allredirects-description": "Toon alle doorverwijzingen naar een naamruimte.",
        "apihelp-query+mystashedfiles-paramvalue-prop-type": "Vraag het MIME- en mediatype van het bestand op.",
+       "apihelp-query+mystashedfiles-param-limit": "Hoeveel bestanden te tonen.",
+       "apihelp-query+allusers-param-excludegroup": "Sluit gebruikers in de gegeven groepen uit.",
+       "apihelp-query+allusers-paramvalue-prop-blockinfo": "Voegt informatie over een actuale blokkade van de gebruiker toe.",
+       "apihelp-query+allusers-paramvalue-prop-groups": "Toont de groepen waar de gebruiker in zit. Dit gebruikt meer serverbronnen en kan minder resultaten teruggeven dat de opgegeven limiet.",
+       "apihelp-query+allusers-paramvalue-prop-implicitgroups": "Toon alle groepen de gebruiker automatisch in zit.",
+       "apihelp-query+allusers-paramvalue-prop-rights": "Toon de rechten die de gebruiker heeft.",
+       "apihelp-query+allusers-paramvalue-prop-editcount": "Voegt het aantal bewerkingen van de gebruiker toe.",
+       "apihelp-query+allusers-paramvalue-prop-registration": "Voegt de registratiedatum van de gebruiker toe, indien beschikbaar (kan leeg zijn).",
+       "apihelp-query+allusers-param-witheditsonly": "Toon alleen gebruikers die bewerkingen hebben gemaakt.",
+       "apihelp-query+allusers-param-activeusers": "Toon alleen gebruikers die actief zijn geweest in de laatste $1 {{PLURAL:$1|dag|dagen}}.",
+       "apihelp-query+allusers-example-Y": "Toon gebruikers vanaf <kbd>Y</kbd>.",
+       "apihelp-query+authmanagerinfo-description": "Haal informatie op over de huidige authentificatie status.",
+       "apihelp-query+backlinks-description": "Vind alle pagina's die verwijzen naar de gegeven pagina.",
+       "apihelp-query+backlinks-param-title": "Titel om op te zoeken. Kan niet worden gebruikt in combinatie met<var>$1pageid</var>.",
+       "apihelp-query+backlinks-param-pageid": "Pagina ID om op te zoeken. Kan niet worden gebruikt in combinatie met <var>$1title</var>.",
+       "apihelp-query+backlinks-param-namespace": "De naamruimte om door te lopen.",
+       "apihelp-query+backlinks-example-simple": "Toon verwijzingen naar de <kbd>Hoofdpagina</kbd>.",
+       "apihelp-query+blocks-description": "Toon alle geblokkeerde gebruikers en IP-adressen.",
+       "apihelp-query+blocks-param-limit": "Het maximum aantal blokkades te tonen.",
+       "apihelp-query+blocks-paramvalue-prop-id": "Voegt de blokkade ID toe.",
+       "apihelp-query+blocks-paramvalue-prop-user": "Voegt de gebruikernaam van de geblokeerde gebruiker toe.",
+       "apihelp-query+blocks-paramvalue-prop-userid": "Voegt de gebruiker-ID van de geblokkeerde gebruiker toe.",
        "apihelp-query+blocks-paramvalue-prop-flags": "Labelt de blokkade met (automatische blokkade, alleen anoniem, enzovoort).",
+       "apihelp-query+blocks-example-simple": "Toon blokkades.",
+       "apihelp-query+blocks-example-users": "Toon blokkades van gebruikers <kbd>Alice</kbd> en <kbd>Bob</kbd>.",
+       "apihelp-query+categories-description": "Toon alle categorieën waar de pagina in zit.",
+       "apihelp-query+categories-paramvalue-prop-hidden": "Markeert categorieën die verborgen zijn met <code>_&#95;HIDDENCAT_&#95;</code>",
+       "apihelp-query+categories-param-show": "Welke soort categorieën te tonen.",
+       "apihelp-query+categories-param-limit": "Hoeveel categorieën te tonen.",
+       "apihelp-query+categorymembers-paramvalue-prop-ids": "Voegt de pagina-ID toe.",
+       "apihelp-query+categorymembers-paramvalue-prop-title": "Voegt de titel en de naamruimte-ID van de pagina toe.",
+       "apihelp-query+categorymembers-param-dir": "Richting om in te sorteren.",
        "apihelp-query+deletedrevisions-param-tag": "Alleen versies weergeven met dit label.",
        "apihelp-query+deletedrevs-param-tag": "Alleen versies weergeven met dit label.",
+       "apihelp-query+embeddedin-param-namespace": "De naamruimte om door te lopen.",
+       "apihelp-query+fileusage-paramvalue-prop-pageid": "Pagina ID van elke pagina.",
+       "apihelp-query+fileusage-paramvalue-prop-title": "Titel van elke pagina.",
+       "apihelp-query+imageusage-param-namespace": "De naamruimte om door te lopen.",
+       "apihelp-query+imageusage-example-simple": "Toon pagina's die gebruik maken van [[:File:Albert Einstein Head.jpg]].",
+       "apihelp-query+imageusage-example-generator": "Toon informatie over pagina's die gebruik maken van [[:File:Albert Einstein Head.jpg]].",
+       "apihelp-query+iwbacklinks-param-prefix": "Voorvoegsel voor de interwiki.",
        "apihelp-query+logevents-param-type": "Logboekregels alleen voor dit type filteren.",
        "apihelp-query+logevents-param-tag": "Alleen logboekregels weergeven met dit label.",
        "apihelp-query+logevents-example-simple": "Recente logboekregels weergeven.",
+       "apihelp-query+protectedtitles-paramvalue-prop-level": "Voegt het beveiligingsniveau toe.",
+       "apihelp-query+protectedtitles-example-simple": "Toon beveiligde titels.",
+       "apihelp-query+querypage-param-limit": "Aantal resultaten om te tonen.",
+       "apihelp-query+querypage-example-ancientpages": "Toon resultaten van [[Special:Ancientpages]].",
+       "apihelp-query+random-param-namespace": "Toon alleen pagina's in deze naamruimten.",
+       "apihelp-query+random-param-limit": "Beperk het aantal aan willekeurige pagina's dat wordt getoond.",
+       "apihelp-query+random-example-simple": "Toon twee willekeurige pagina's uit de hoofdnaamruimte.",
+       "apihelp-query+random-example-generator": "Toon pagina informatie over twee willekeurige pagina's uit de hoofdnaamruimte.",
+       "apihelp-query+recentchanges-param-user": "Toon alleen wijzigingen door deze gebruiker.",
+       "apihelp-query+recentchanges-param-excludeuser": "Toon geen wijzigingen door deze gebruiker",
        "apihelp-query+recentchanges-param-tag": "Alleen versies weergeven met dit label.",
+       "apihelp-query+recentchanges-paramvalue-prop-comment": "Voegt de bewerkingssamenvatting voor de bewerking toe.",
        "apihelp-query+recentchanges-paramvalue-prop-loginfo": "Voegt logboekgegevens toe aan logboekregels (logboek-ID, logboektype, enzovoort).",
+       "apihelp-query+recentchanges-example-simple": "Toon recente wijzigingen.",
+       "apihelp-query+redirects-paramvalue-prop-pageid": "Pagina ID van elke doorverwijzing.",
+       "apihelp-query+redirects-paramvalue-prop-title": "Titel van elke doorverwijzing.",
+       "apihelp-query+redirects-param-namespace": "Toon alleen pagina's in deze naamruimten.",
+       "apihelp-query+redirects-param-limit": "Hoeveel doorverwijzingen te tonen.",
+       "apihelp-query+redirects-example-simple": "Toon een lijst van doorverwijzingen naar [[Main Page]].",
+       "apihelp-query+redirects-example-generator": "Toon informatie over alle doorverwijzingen naar [[Main Page]].",
        "apihelp-query+revisions-param-tag": "Alleen versies weergeven met dit label.",
+       "apihelp-query+revisions+base-paramvalue-prop-content": "Versietekst.",
        "apihelp-query+revisions+base-paramvalue-prop-tags": "Labels voor de versie.",
        "apihelp-query+revisions+base-param-difftotextpst": "\"pre-save\"-transformatie uitvoeren op de tekst alvorens de verschillen te bepalen. Alleen geldig als dit wordt gebruikt met <var>$1difftotext</var>.",
+       "apihelp-query+search-description": "Voer een volledige tekst zoekopdracht uit.",
+       "apihelp-query+search-param-limit": "Hoeveel pagina's te tonen.",
+       "apihelp-query+search-example-simple": "Zoeken naar <kbd>betekenis</kbd>.",
+       "apihelp-query+siteinfo-paramvalue-prop-namespacealiases": "Toon geregistreerde naamruimte aliassen.",
+       "apihelp-query+siteinfo-paramvalue-prop-specialpagealiases": "Toon speciale pagina aliassen.",
+       "apihelp-query+siteinfo-paramvalue-prop-magicwords": "Toon magische woorden en hun aliassen.",
+       "apihelp-query+siteinfo-paramvalue-prop-statistics": "Toon site statistieken.",
+       "apihelp-query+siteinfo-paramvalue-prop-libraries": "Toont bibliotheken die op de wiki zijn geïnstalleerd.",
+       "apihelp-query+siteinfo-paramvalue-prop-extensions": "Toont uitbreidingen die op de wiki zijn geïnstalleerd.",
        "apihelp-query+siteinfo-paramvalue-prop-fileextensions": "Geeft een lijst met bestandsextensies (bestandstypen) die geüpload mogen worden.",
+       "apihelp-query+siteinfo-paramvalue-prop-rightsinfo": "Toont wiki rechten (licentie) informatie als deze beschikbaar is.",
        "apihelp-query+tags-description": "Wijzigingslabels weergeven.",
        "apihelp-query+tags-paramvalue-prop-name": "Voegt de naam van het label toe.",
        "apihelp-query+tags-paramvalue-prop-displayname": "Voegt het systeembericht toe voor het label.",
        "apihelp-query+tags-paramvalue-prop-description": "Voegt beschrijving van het label toe.",
        "apihelp-query+tags-paramvalue-prop-defined": "Geeft aan of het label is gedefinieerd.",
        "apihelp-query+tags-paramvalue-prop-active": "Of het label nog steeds wordt toegepast.",
+       "apihelp-query+tags-example-simple": "Toon beschikbare labels.",
+       "apihelp-query+templates-description": "Toon alle pagina's ingesloten op de gegeven pagina's.",
+       "apihelp-query+templates-param-limit": "Het aantal sjablonen om te tonen.",
+       "apihelp-query+transcludedin-paramvalue-prop-pageid": "Pagina ID van elke pagina.",
+       "apihelp-query+transcludedin-paramvalue-prop-title": "Titel van elke pagina.",
+       "apihelp-query+usercontribs-description": "Toon alle bewerkingen door een gebruiker.",
+       "apihelp-query+usercontribs-param-limit": "Het maximum aantal bewerkingen om te tonen.",
+       "apihelp-query+usercontribs-param-namespace": "Toon alleen bijdragen in deze naamruimten.",
        "apihelp-query+usercontribs-param-tag": "Alleen versies weergeven met dit label.",
+       "apihelp-query+usercontribs-example-ipprefix": "Toon bijdragen van alle IP-adressen met het voorvoegsel <kbd>192.0.2.</kbd>.",
+       "apihelp-query+userinfo-description": "Toon informatie over de huidige gebruiker.",
+       "apihelp-query+userinfo-paramvalue-prop-realname": "Toon de gebruikers echte naam.",
        "apihelp-query+watchlist-paramvalue-prop-loginfo": "Voegt logboekgegevens toe waar van toepassing.",
        "apihelp-query+watchlist-param-type": "Welke typen wijzigingen weer te geven:",
        "apihelp-query+watchlist-paramvalue-type-edit": "Gewone paginabewerkingen.",
index ef2ba8f..297f7ed 100644 (file)
        "apihelp-query+deletedrevs-param-excludeuser": "{{doc-apihelp-param|query+deletedrevs|excludeuser}}",
        "apihelp-query+deletedrevs-param-namespace": "{{doc-apihelp-param|query+deletedrevs|namespace}}",
        "apihelp-query+deletedrevs-param-limit": "{{doc-apihelp-param|query+deletedrevs|limit}}",
-       "apihelp-query+deletedrevs-param-prop": "{{doc-apihelp-param|query+deletedrevs|prop}}",
+       "apihelp-query+deletedrevs-param-prop": "{{doc-apihelp-param|query+deletedrevs|prop}}\n{{doc-important|You can translate the word \"Deprecated\", but please do not alter the <code><nowiki>class=\"apihelp-deprecated\"</nowiki></code> attribute}}",
        "apihelp-query+deletedrevs-example-mode1": "{{doc-apihelp-example|query+deletedrevs}}",
        "apihelp-query+deletedrevs-example-mode2": "{{doc-apihelp-example|query+deletedrevs}}",
        "apihelp-query+deletedrevs-example-mode3-main": "{{doc-apihelp-example|query+deletedrevs}}",
        "apihelp-query+search-paramvalue-prop-sectiontitle": "{{doc-apihelp-paramvalue|query+search|prop|sectiontitle}}",
        "apihelp-query+search-paramvalue-prop-categorysnippet": "{{doc-apihelp-paramvalue|query+search|prop|categorysnippet}}",
        "apihelp-query+search-paramvalue-prop-isfilematch": "{{doc-apihelp-paramvalue|query+search|prop|isfilematch}}",
-       "apihelp-query+search-paramvalue-prop-score": "{{doc-apihelp-paramvalue|query+search|prop|score}}",
-       "apihelp-query+search-paramvalue-prop-hasrelated": "{{doc-apihelp-paramvalue|query+search|prop|hasrelated}}",
+       "apihelp-query+search-paramvalue-prop-score": "{{doc-apihelp-paramvalue|query+search|prop|score}}\n{{doc-important|Please do not alter the <code><nowiki>class=\"apihelp-deprecated\"</nowiki></code> attribute}}",
+       "apihelp-query+search-paramvalue-prop-hasrelated": "{{doc-apihelp-paramvalue|query+search|prop|hasrelated}}\n{{doc-important|Please do not alter the <code><nowiki>class=\"apihelp-deprecated\"</nowiki></code> attribute}}",
        "apihelp-query+search-param-limit": "{{doc-apihelp-param|query+search|limit}}",
        "apihelp-query+search-param-interwiki": "{{doc-apihelp-param|query+search|interwiki}}",
        "apihelp-query+search-param-backend": "{{doc-apihelp-param|query+search|backend}}",
        "apihelp-query+userinfo-paramvalue-prop-blockinfo": "{{doc-apihelp-paramvalue|query+userinfo|prop|blockinfo}}",
        "apihelp-query+userinfo-paramvalue-prop-hasmsg": "{{doc-apihelp-paramvalue|query+userinfo|prop|hasmsg}}",
        "apihelp-query+userinfo-paramvalue-prop-groups": "{{doc-apihelp-paramvalue|query+userinfo|prop|groups}}",
+       "apihelp-query+userinfo-paramvalue-prop-groupmemberships": "{{doc-apihelp-paramvalue|query+userinfo|prop|groupmemberships}}",
        "apihelp-query+userinfo-paramvalue-prop-implicitgroups": "{{doc-apihelp-paramvalue|query+userinfo|prop|implicitgroups}}",
        "apihelp-query+userinfo-paramvalue-prop-rights": "{{doc-apihelp-paramvalue|query+userinfo|prop|rights}}",
        "apihelp-query+userinfo-paramvalue-prop-changeablegroups": "{{doc-apihelp-paramvalue|query+userinfo|prop|changeablegroups}}",
        "apihelp-query+userinfo-paramvalue-prop-options": "{{doc-apihelp-paramvalue|query+userinfo|prop|options}}",
-       "apihelp-query+userinfo-paramvalue-prop-preferencestoken": "{{doc-apihelp-paramvalue|query+userinfo|prop|preferencestoken}}",
+       "apihelp-query+userinfo-paramvalue-prop-preferencestoken": "{{doc-apihelp-paramvalue|query+userinfo|prop|preferencestoken}}\n{{doc-important|You can translate the word \"Deprecated\", but please do not alter the <code><nowiki>class=\"apihelp-deprecated\"</nowiki></code> attribute}}",
        "apihelp-query+userinfo-paramvalue-prop-editcount": "{{doc-apihelp-paramvalue|query+userinfo|prop|editcount}}",
        "apihelp-query+userinfo-paramvalue-prop-ratelimits": "{{doc-apihelp-paramvalue|query+userinfo|prop|ratelimits}}",
        "apihelp-query+userinfo-paramvalue-prop-realname": "{{doc-apihelp-paramvalue|query+userinfo|prop|realname}}",
        "apihelp-query+users-param-prop": "{{doc-apihelp-param|query+users|prop|paramvalues=1}}",
        "apihelp-query+users-paramvalue-prop-blockinfo": "{{doc-apihelp-paramvalue|query+users|prop|blockinfo}}",
        "apihelp-query+users-paramvalue-prop-groups": "{{doc-apihelp-paramvalue|query+users|prop|groups}}",
+       "apihelp-query+users-paramvalue-prop-groupmemberships": "{{doc-apihelp-paramvalue|query+users|prop|groupmemberships}}",
        "apihelp-query+users-paramvalue-prop-implicitgroups": "{{doc-apihelp-paramvalue|query+users|prop|implicitgroups}}",
        "apihelp-query+users-paramvalue-prop-rights": "{{doc-apihelp-paramvalue|query+users|prop|rights}}",
        "apihelp-query+users-paramvalue-prop-editcount": "{{doc-apihelp-paramvalue|query+users|prop|editcount}}",
        "apihelp-userrights-param-user": "{{doc-apihelp-param|userrights|user}}\n{{Identical|Username}}",
        "apihelp-userrights-param-userid": "{{doc-apihelp-param|userrights|userid}}\n{{Identical|User ID}}",
        "apihelp-userrights-param-add": "{{doc-apihelp-param|userrights|add}}",
+       "apihelp-userrights-param-expiry": "{{doc-apihelp-param|userrights|expiry}}",
        "apihelp-userrights-param-remove": "{{doc-apihelp-param|userrights|remove}}",
        "apihelp-userrights-param-reason": "{{doc-apihelp-param|userrights|reason}}",
        "apihelp-userrights-param-tags": "{{doc-apihelp-param|userrights|tags}}",
        "apihelp-userrights-example-user": "{{doc-apihelp-example|userrights}}",
        "apihelp-userrights-example-userid": "{{doc-apihelp-example|userrights}}",
+       "apihelp-userrights-example-expiry": "{{doc-apihelp-example|userrights}}",
        "apihelp-validatepassword-description": "{{doc-apihelp-description|validatepassword}}",
        "apihelp-validatepassword-param-password": "{{doc-apihelp-param|validatepassword|password}}",
        "apihelp-validatepassword-param-user": "{{doc-apihelp-param|validatepassword|user}}",
        "apierror-blockedfrommail": "{{doc-apierror}}",
        "apierror-blocked": "{{doc-apierror}}",
        "apierror-botsnotsupported": "{{doc-apierror}}",
+       "apierror-cannot-async-upload-file": "{{doc-apierror}}",
        "apierror-cannotreauthenticate": "{{doc-apierror}}",
        "apierror-cannotviewtitle": "{{doc-apierror}}\n\nParameters:\n* $1 - Title.",
        "apierror-cantblock-email": "{{doc-apierror}}",
        "apiwarn-wgDebugAPI": "{{doc-apierror}}",
        "api-feed-error-title": "Used as a feed item title when an error occurs in <kbd>action=feedwatchlist</kbd>.\n\nParameters:\n* $1 - API error code\n{{Identical|Error}}",
        "api-usage-docref": "\n\nParameters:\n* $1 - URL of the API auto-generated documentation.",
+       "api-usage-mailinglist-ref": "{{doc-apierror}} Also used in the error response.",
        "api-exception-trace": "\n\nParameters:\n* $1 - Exception class.\n* $2 - File from which the exception was thrown.\n* $3 - Line number from which the exception was thrown.\n* $4 - Exception backtrace.",
        "api-credits-header": "Header for the API credits section in the API help output\n{{Identical|Credit}}",
        "api-credits": "API credits text, displayed in the API help output"
index 9eb4a2e..2b9fc8a 100644 (file)
@@ -22,7 +22,8 @@
                        "MaxBioHazard",
                        "Kareyac",
                        "Mailman",
-                       "Ping08"
+                       "Ping08",
+                       "Ivan-r"
                ]
        },
        "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 с ключом «MediaWiki-API-Error», после чего значение заголовка и код ошибки будут отправлены обратно и установлены в то же значение. Более подробную информацию см. [[mw:API:Errors_and_warnings|API: Ошибки и предупреждения]].\n\n<strong>Тестирование:</strong> для удобства тестирования API-запросов, см. [[Special:ApiSandbox]].",
        "apihelp-protect-example-unprotect": "Снять защиту страницы, установив ограничения <kbd>all</kbd> (т. е. любой желающий может принять меры).",
        "apihelp-protect-example-unprotect2": "Бер ниндәй сикләүҙәр ҡуймай биттән һаҡлауҙы алырға.",
        "apihelp-purge-param-forcelinkupdate": "Обновление связей таблиц.",
-       "apihelp-purge-param-forcerecursivelinkupdate": "Һылтанманы һәм таблицаны яңыртығыҙ һәм был битте шаблон итеп ҡулланған башҡа биттәр өсөн һылтанмаларҙы ла яңыртығыҙ.",
+       "apihelp-purge-param-forcerecursivelinkupdate": "Обновить таблицу ссылок для данной страницы, а также всех страниц, использующих данную как шаблон.",
        "apihelp-purge-example-generator": "Продувка первые 10 страниц в основном пространстве имен.",
        "apihelp-query-param-list": "Какие списки использовать",
        "apihelp-query-param-meta": "Какие метаданные использовать",
index ffcb0c9..ff478a4 100644 (file)
        "apihelp-userrights-description": "更改一位用户的组成员。",
        "apihelp-userrights-param-user": "用户名。",
        "apihelp-userrights-param-userid": "用户ID。",
-       "apihelp-userrights-param-add": "将用户加入至这些组中。",
+       "apihelp-userrights-param-add": "将用户加入至这些组中,或如果其已作为成员,更新其所在用户组成员资格的终止时间。",
        "apihelp-userrights-param-remove": "将用户从这些组中移除。",
        "apihelp-userrights-param-reason": "更改原因。",
        "apihelp-userrights-param-tags": "要在用户权限日志中应用到实体的更改标签。",
        "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-userrights-example-expiry": "添加用户<kbd>SometimeSysop</kbd>至用户组<kbd>sysop</kbd>,为期1个月。",
        "apihelp-validatepassword-description": "验证密码是否符合wiki的密码方针。\n\n如果密码可以接受,就报告有效性为<samp>Good</samp>,如果密码可用于登录但必须更改,则报告为<samp>Change</samp>,或如果密码不可使用,则报告为<samp>Invalid</samp>。",
        "apihelp-validatepassword-param-password": "要验证的密码。",
        "apihelp-validatepassword-param-user": "用户名,供测试账户创建时使用。命名的用户必须不存在。",
        "apierror-blockedfrommail": "您已被封禁,不能发送电子邮件。",
        "apierror-blocked": "您已被封禁,不能编辑。",
        "apierror-botsnotsupported": "此界面不支持机器人。",
+       "apierror-cannot-async-upload-file": "参数<var>async</var>和<var>file</var>不能结合。如果您希望对您上传的文件进行不同处理,请将其首先上传至暂存处(使用<var>stash</var>参数),然后异步发布暂存文件(使用<var>filekey</var>和<var>async</var>)。",
        "apierror-cannotreauthenticate": "由于您的身份不能被验证,此操作不可用。",
        "apierror-cannotviewtitle": "您不被允许查看$1。",
        "apierror-cantblock-email": "您没有权限封禁用户通过wiki发送电子邮件。",
        "apierror-show": "不正确的参数——不可提供互斥值。",
        "apierror-siteinfo-includealldenied": "除非<var>$wgShowHostNames</var>为真,否则不能查看所有服务器的信息。",
        "apierror-sizediffdisabled": "大小差异在Miser模式中被禁用。",
-       "apierror-spamdetected": "您的编辑被拒绝,因为它包含破坏性碎片:<code>$1</code>。",
+       "apierror-spamdetected": "您的编辑被拒绝,因为它包含垃圾部分:<code>$1</code>。",
        "apierror-specialpage-cantexecute": "您没有权限查看此特殊页面的结果。",
        "apierror-stashedfilenotfound": "无法在暂存处找到文件:$1。",
+       "apierror-stashedit-missingtext": "提供的哈希中找不到暂存文本。",
        "apierror-stashfailed-complete": "大块上传已经完成,检查状态以获取详情。",
        "apierror-stashfailed-nosession": "没有带此关键词的大块上传会话。",
        "apierror-stashfilestorage": "不能在暂存处存储上传:$1",
        "apiwarn-badurlparam": "不能为$2解析<var>$1urlparam</var>。请只使用宽和高。",
        "apiwarn-badutf8": "<var>$1</var>通过的值包含无效或非标准化数据。正文数据应为有效的NFC标准化Unicode,没有除HT(\\t)、LF(\\n)和CR(\\r)以外的C0控制字符。",
        "apiwarn-deprecation-deletedrevs": "<kbd>list=deletedrevs</kbd>已被弃用。请改用<kbd>prop=deletedrevisions</kbd>或<kbd>list=alldeletedrevisions</kbd>。",
+       "apiwarn-deprecation-expandtemplates-prop": "因为没有为<var>prop</var>参数指定值,所以在输出上使用了遗留格式。这种格式已弃用,并且将来会为<var>prop</var>参数设置默认值,这会导致新格式总会被使用。",
        "apiwarn-deprecation-httpsexpected": "当应为HTTPS时,HTTP被使用。",
        "apiwarn-deprecation-login-botpw": "通过<kbd>action=login</kbd>的主账户登录已被弃用,并可能在未事先警告的情况下停止工作。要继续通过<kbd>action=login</kbd>登录,请参见[[Special:BotPasswords]]。要安全继续使用主账户登录,请参见<kbd>action=clientlogin</kbd>。",
        "apiwarn-deprecation-login-nobotpw": "通过<kbd>action=login</kbd>的主账户登录已被弃用,并可能在未事先警告的情况下停止工作。要安全登录,请参见<kbd>action=clientlogin</kbd>。",
        "apiwarn-parse-titlewithouttext": "<var>title</var>在没有<var>text</var>的情况下被使用,并且请求了已解析页面的属性。您是想用<var>page</var>而不是<var>title</var>么?",
        "apiwarn-tokennotallowed": "操作“$1”不允许当前用户使用。",
        "apiwarn-toomanyvalues": "参数<var>$1</var>指定了太多的值:上限为$2。",
+       "apiwarn-truncatedresult": "此结果被缩短,否则其将大于$1字节的限制。",
        "apiwarn-unclearnowtimestamp": "为时间戳参数<var>$1</var>传递“$2”已被弃用。如因某些原因您需要明确指定当前时间而不计算客户端,请使用<kbd>now<kbd>。",
        "apiwarn-unrecognizedvalues": "参数<var>$1</var>有无法识别的{{PLURAL:$3|值}}:$2。",
        "apiwarn-unsupportedarray": "参数<var>$1</var>使用未受支持的PHP数组语法。",
index ae8efa9..b0a3a1c 100644 (file)
@@ -35,19 +35,6 @@ class HTMLFileCache extends FileCacheBase {
        const MODE_OUTAGE = 1; // fallback cache for DB outages
        const MODE_REBUILD = 2; // background cache rebuild mode
 
-       /**
-        * Construct an HTMLFileCache object from a Title and an action
-        *
-        * @deprecated since 1.24, instantiate this class directly
-        * @param Title|string $title Title object or prefixed DB key string
-        * @param string $action
-        * @throws MWException
-        * @return HTMLFileCache
-        */
-       public static function newFromTitle( $title, $action ) {
-               return new self( $title, $action );
-       }
-
        /**
         * @param Title|string $title Title object or prefixed DB key string
         * @param string $action
index 23cc26d..b720dec 100644 (file)
@@ -278,6 +278,20 @@ class LinkCache {
                return $id;
        }
 
+       /**
+        * @param WANObjectCache $cache
+        * @param TitleValue $t
+        * @return string[]
+        * @since 1.28
+        */
+       public function getMutableCacheKeys( WANObjectCache $cache, TitleValue $t ) {
+               if ( $this->isCacheable( $t ) ) {
+                       return [ $cache->makeKey( 'page', $t->getNamespace(), sha1( $t->getDBkey() ) ) ];
+               }
+
+               return [];
+       }
+
        private function isCacheable( LinkTarget $title ) {
                return ( $title->inNamespace( NS_TEMPLATE ) || $title->inNamespace( NS_FILE ) );
        }
index 352a94c..9bf0840 100644 (file)
@@ -89,10 +89,12 @@ class MessageCache {
         */
        protected $mInParser = false;
 
-       /** @var BagOStuff */
-       protected $mMemc;
        /** @var WANObjectCache */
        protected $wanCache;
+       /** @var BagOStuff */
+       protected $clusterCache;
+       /** @var BagOStuff */
+       protected $srvCache;
 
        /**
         * Singleton instance
@@ -109,9 +111,13 @@ class MessageCache {
         */
        public static function singleton() {
                if ( self::$instance === null ) {
-                       global $wgUseDatabaseMessages, $wgMsgCacheExpiry;
+                       global $wgUseDatabaseMessages, $wgMsgCacheExpiry, $wgUseLocalMessageCache;
                        self::$instance = new self(
+                               MediaWikiServices::getInstance()->getMainWANObjectCache(),
                                wfGetMessageCacheStorage(),
+                               $wgUseLocalMessageCache
+                                       ? MediaWikiServices::getInstance()->getLocalServerObjectCache()
+                                       : new EmptyBagOStuff(),
                                $wgUseDatabaseMessages,
                                $wgMsgCacheExpiry
                        );
@@ -149,24 +155,25 @@ class MessageCache {
        }
 
        /**
-        * @param BagOStuff $memCached A cache instance. If none, fall back to CACHE_NONE.
-        * @param bool $useDB
+        * @param WANObjectCache $wanCache WAN cache instance
+        * @param BagOStuff $clusterCache Cluster cache instance
+        * @param BagOStuff $srvCache Server cache instance
+        * @param bool $useDB Whether to look for message overrides (e.g. MediaWiki: pages)
         * @param int $expiry Lifetime for cache. @see $mExpiry.
         */
-       function __construct( BagOStuff $memCached, $useDB, $expiry ) {
-               global $wgUseLocalMessageCache;
+       public function __construct(
+               WANObjectCache $wanCache,
+               BagOStuff $clusterCache,
+               BagOStuff $srvCache,
+               $useDB,
+               $expiry
+       ) {
+               $this->wanCache = $wanCache;
+               $this->clusterCache = $clusterCache;
+               $this->srvCache = $srvCache;
 
-               $this->mMemc = $memCached;
                $this->mDisable = !$useDB;
                $this->mExpiry = $expiry;
-
-               if ( $wgUseLocalMessageCache ) {
-                       $this->localCache = MediaWikiServices::getInstance()->getLocalServerObjectCache();
-               } else {
-                       $this->localCache = new EmptyBagOStuff();
-               }
-
-               $this->wanCache = ObjectCache::getMainWANInstance();
        }
 
        /**
@@ -203,7 +210,7 @@ class MessageCache {
        protected function getLocalCache( $code ) {
                $cacheKey = wfMemcKey( __CLASS__, $code );
 
-               return $this->localCache->get( $cacheKey );
+               return $this->srvCache->get( $cacheKey );
        }
 
        /**
@@ -214,7 +221,7 @@ class MessageCache {
         */
        protected function saveToLocalCache( $code, $cache ) {
                $cacheKey = wfMemcKey( __CLASS__, $code );
-               $this->localCache->set( $cacheKey, $cache );
+               $this->srvCache->set( $cacheKey, $cache );
        }
 
        /**
@@ -300,7 +307,7 @@ class MessageCache {
                                        # below, and use the local stale value if it was not acquired.
                                        $where[] = 'global cache is presumed expired';
                                } else {
-                                       $cache = $this->mMemc->get( $cacheKey );
+                                       $cache = $this->clusterCache->get( $cacheKey );
                                        if ( !$cache ) {
                                                $where[] = 'global cache is empty';
                                        } elseif ( $this->isCacheExpired( $cache ) ) {
@@ -381,12 +388,10 @@ class MessageCache {
         * @return bool|string True on success or one of ("cantacquire", "disabled")
         */
        protected function loadFromDBWithLock( $code, array &$where, $mode = null ) {
-               global $wgUseLocalMessageCache;
-
                # If cache updates on all levels fail, give up on message overrides.
                # This is to avoid easy site outages; see $saveSuccess comments below.
                $statusKey = wfMemcKey( 'messages', $code, 'status' );
-               $status = $this->mMemc->get( $statusKey );
+               $status = $this->clusterCache->get( $statusKey );
                if ( $status === 'error' ) {
                        $where[] = "could not load; method is still globally disabled";
                        return 'disabled';
@@ -424,8 +429,8 @@ class MessageCache {
                         * incurring a loadFromDB() overhead on every request, and thus saves the
                         * wiki from complete downtime under moderate traffic conditions.
                         */
-                       if ( !$wgUseLocalMessageCache ) {
-                               $this->mMemc->set( $statusKey, 'error', 60 * 5 );
+                       if ( $this->srvCache instanceof EmptyBagOStuff ) {
+                               $this->clusterCache->set( $statusKey, 'error', 60 * 5 );
                                $where[] = 'could not save cache, disabled globally for 5 minutes';
                        } else {
                                $where[] = "could not save global cache";
@@ -444,7 +449,7 @@ class MessageCache {
         * @param integer $mode Use MessageCache::FOR_UPDATE to skip process cache
         * @return array Loaded messages for storing in caches
         */
-       function loadFromDB( $code, $mode = null ) {
+       protected function loadFromDB( $code, $mode = null ) {
                global $wgMaxMsgCacheEntrySize, $wgLanguageCode, $wgAdaptiveMessageCache;
 
                $dbr = wfGetDB( ( $mode == self::FOR_UPDATE ) ? DB_MASTER : DB_REPLICA );
@@ -518,7 +523,7 @@ class MessageCache {
                                wfDebugLog(
                                        'MessageCache',
                                        __METHOD__
-                                               . ": failed to load message page text for {$row->page_title} ($code)"
+                                       . ": failed to load message page text for {$row->page_title} ($code)"
                                );
                        } else {
                                $entry = ' ' . $text;
@@ -541,11 +546,11 @@ class MessageCache {
        /**
         * Updates cache as necessary when message page is changed
         *
-        * @param string|bool $title Name of the page changed (false if deleted)
+        * @param string $title Message cache key with initial uppercase letter.
         * @param string|bool $text New contents of the page (false if deleted)
         */
        public function replace( $title, $text ) {
-               global $wgMaxMsgCacheEntrySize, $wgContLang, $wgLanguageCode;
+               global $wgLanguageCode;
 
                if ( $this->mDisable ) {
                        return;
@@ -557,63 +562,75 @@ class MessageCache {
                        return;
                }
 
-               // Note that if the cache is volatile, load() may trigger a DB fetch.
-               // In that case we reenter/reuse the existing cache key lock to avoid
-               // a self-deadlock. This is safe as no reads happen *directly* in this
-               // method between getReentrantScopedLock() and load() below. There is
-               // no risk of data "changing under our feet" for replace().
-               $scopedLock = $this->getReentrantScopedLock( wfMemcKey( 'messages', $code ) );
-               // Load the messages from the master DB to avoid race conditions
-               $this->load( $code, self::FOR_UPDATE );
-
-               // Load the new value into the process cache...
+               // (a) Update the process cache with the new message text
                if ( $text === false ) {
+                       // Page deleted
                        $this->mCache[$code][$title] = '!NONEXISTENT';
-               } elseif ( strlen( $text ) > $wgMaxMsgCacheEntrySize ) {
-                       $this->mCache[$code][$title] = '!TOO BIG';
-                       // Pre-fill the individual key cache with the known latest message text
-                       $key = $this->wanCache->makeKey( 'messages-big', $this->mCache[$code]['HASH'], $title );
-                       $this->wanCache->set( $key, " $text", $this->mExpiry );
                } else {
+                       // Ignore $wgMaxMsgCacheEntrySize so the process cache is up to date
                        $this->mCache[$code][$title] = ' ' . $text;
                }
-               // Mark this cache as definitely being "latest" (non-volatile) so
-               // load() calls do not try to refresh the cache with replica DB data
-               $this->mCache[$code]['LATEST'] = time();
 
-               // Update caches if the lock was acquired
-               if ( $scopedLock ) {
-                       $this->saveToCaches( $this->mCache[$code], 'all', $code );
-               } else {
-                       LoggerFactory::getInstance( 'MessageCache' )->error(
-                               __METHOD__ . ': could not acquire lock to update {title} ({code})',
-                               [ 'title' => $title, 'code' => $code ] );
-               }
-
-               ScopedCallback::consume( $scopedLock );
-               // Relay the purge. Touching this check key expires cache contents
-               // and local cache (APC) validation hash across all datacenters.
-               $this->wanCache->touchCheckKey( wfMemcKey( 'messages', $code ) );
-
-               // Also delete cached sidebar... just in case it is affected
-               $codes = [ $code ];
-               if ( $code === 'en' ) {
-                       // Delete all sidebars, like for example on action=purge on the
-                       // sidebar messages
-                       $codes = array_keys( Language::fetchLanguageNames() );
-               }
-
-               foreach ( $codes as $code ) {
-                       $sidebarKey = wfMemcKey( 'sidebar', $code );
-                       $this->wanCache->delete( $sidebarKey );
-               }
+               // (b) Update the shared caches in a deferred update with a fresh DB snapshot
+               DeferredUpdates::addCallableUpdate(
+                       function () use ( $title, $msg, $code ) {
+                               global $wgContLang, $wgMaxMsgCacheEntrySize;
+                               // Allow one caller at a time to avoid race conditions
+                               $scopedLock = $this->getReentrantScopedLock( wfMemcKey( 'messages', $code ) );
+                               if ( !$scopedLock ) {
+                                       LoggerFactory::getInstance( 'MessageCache' )->error(
+                                               __METHOD__ . ': could not acquire lock to update {title} ({code})',
+                                               [ 'title' => $title, 'code' => $code ] );
+                                       return;
+                               }
+                               // Load the messages from the master DB to avoid race conditions
+                               $this->loadFromDB( $code, self::FOR_UPDATE );
+                               // Load the process cache values and set the per-title cache keys
+                               $page = WikiPage::factory( Title::makeTitle( NS_MEDIAWIKI, $title ) );
+                               $page->loadPageData( $page::READ_LATEST );
+                               $text = $this->getMessageTextFromContent( $page->getContent() );
+                               // Check if an individual cache key should exist and update cache accordingly
+                               $titleKey = $this->wanCache->makeKey(
+                                       'messages-big', $this->mCache[$code]['HASH'], $title );
+                               if ( is_string( $text ) && strlen( $text ) > $wgMaxMsgCacheEntrySize ) {
+                                       $this->wanCache->set( $titleKey, ' ' . $text, $this->mExpiry );
+                               }
+                               // Mark this cache as definitely being "latest" (non-volatile) so
+                               // load() calls do try to refresh the cache with replica DB data
+                               $this->mCache[$code]['LATEST'] = time();
+                               // Pre-emptively update the local datacenter cache so things like edit filter and
+                               // blacklist changes are reflect immediately, as these often use MediaWiki: pages.
+                               // The datacenter handling replace() calls should be the same one handling edits
+                               // as they require HTTP POST.
+                               $this->saveToCaches( $this->mCache[$code], 'all', $code );
+                               // Release the lock now that the cache is saved
+                               ScopedCallback::consume( $scopedLock );
+
+                               // Relay the purge. Touching this check key expires cache contents
+                               // and local cache (APC) validation hash across all datacenters.
+                               $this->wanCache->touchCheckKey( wfMemcKey( 'messages', $code ) );
+                               // Also delete cached sidebar... just in case it is affected
+                               // @TODO: shouldn't this be $code === $wgLanguageCode?
+                               if ( $code === 'en' ) {
+                                       // Purge all language sidebars, e.g. on ?action=purge to the sidebar messages
+                                       $codes = array_keys( Language::fetchLanguageNames() );
+                               } else {
+                                       // Purge only the sidebar for this language
+                                       $codes = [ $code ];
+                               }
+                               foreach ( $codes as $code ) {
+                                       $this->wanCache->delete( wfMemcKey( 'sidebar', $code ) );
+                               }
 
-               // Update the message in the message blob store
-               $resourceloader = RequestContext::getMain()->getOutput()->getResourceLoader();
-               $blobStore = $resourceloader->getMessageBlobStore();
-               $blobStore->updateMessage( $wgContLang->lcfirst( $msg ) );
+                               // Purge the message in the message blob store
+                               $resourceloader = RequestContext::getMain()->getOutput()->getResourceLoader();
+                               $blobStore = $resourceloader->getMessageBlobStore();
+                               $blobStore->updateMessage( $wgContLang->lcfirst( $msg ) );
 
-               Hooks::run( 'MessageCacheReplace', [ $title, $text ] );
+                               Hooks::run( 'MessageCacheReplace', [ $title, $text ] );
+                       },
+                       DeferredUpdates::PRESEND
+               );
        }
 
        /**
@@ -648,7 +665,7 @@ class MessageCache {
        protected function saveToCaches( array $cache, $dest, $code = false ) {
                if ( $dest === 'all' ) {
                        $cacheKey = wfMemcKey( 'messages', $code );
-                       $success = $this->mMemc->set( $cacheKey, $cache );
+                       $success = $this->clusterCache->set( $cacheKey, $cache );
                        $this->setValidationHash( $code, $cache );
                } else {
                        $success = true;
@@ -720,7 +737,7 @@ class MessageCache {
         * @return null|ScopedCallback
         */
        protected function getReentrantScopedLock( $key, $timeout = self::WAIT_SEC ) {
-               return $this->mMemc->getScopedLock( $key, $timeout, self::LOCK_TTL, __METHOD__ );
+               return $this->clusterCache->getScopedLock( $key, $timeout, self::LOCK_TTL, __METHOD__ );
        }
 
        /**
@@ -845,7 +862,7 @@ class MessageCache {
 
                $alreadyTried = [];
 
-                // First try the requested language.
+               // First try the requested language.
                $message = $this->getMessageForLang( $lang, $lckey, $useDB, $alreadyTried );
                if ( $message !== false ) {
                        return $message;
@@ -950,6 +967,7 @@ class MessageCache {
         */
        public function getMsgFromNamespace( $title, $code ) {
                $this->load( $code );
+
                if ( isset( $this->mCache[$code][$title] ) ) {
                        $entry = $this->mCache[$code][$title];
                        if ( substr( $entry, 0, 1 ) === ' ' ) {
index 81f64a8..13a5fc7 100644 (file)
@@ -451,6 +451,9 @@ class RecentChange {
                        throw new MWException( __FUNCTION__ . ": Unknown stream logger URI scheme: $scheme" );
                }
 
+               if ( defined( 'MW_PHPUNIT_TEST' ) && is_object( $wgRCEngines[$scheme] ) ) {
+                       return $wgRCEngines[$scheme];
+               }
                return new $wgRCEngines[$scheme];
        }
 
index 5862bf1..119144a 100644 (file)
@@ -1104,7 +1104,6 @@ abstract class ContentHandler {
                        'category',
                        SearchIndexField::INDEX_TYPE_TEXT
                );
-
                $fields['category']->setFlag( SearchIndexField::FLAG_CASEFOLD );
 
                $fields['external_link'] = $engine->makeSearchFieldMapping(
@@ -1121,9 +1120,13 @@ abstract class ContentHandler {
                        'template',
                        SearchIndexField::INDEX_TYPE_KEYWORD
                );
-
                $fields['template']->setFlag( SearchIndexField::FLAG_CASEFOLD );
 
+               $fields['content_model'] = $engine->makeSearchFieldMapping(
+                       'content_model',
+                       SearchIndexField::INDEX_TYPE_KEYWORD
+               );
+
                return $fields;
        }
 
@@ -1170,6 +1173,7 @@ abstract class ContentHandler {
                        $fieldData['text'] = $text;
                        $fieldData['source_text'] = $text;
                        $fieldData['text_bytes'] = $content->getSize();
+                       $fieldData['content_model'] = $content->getModel();
                }
 
                Hooks::run( 'SearchDataForIndex', [ &$fieldData, $this, $page, $output, $engine ] );
index 7c4bb3b..d567d8b 100644 (file)
@@ -94,7 +94,7 @@ class DatabaseMssql extends Database {
                }
 
                // Decide which auth scenerio to use
-               // if we are using Windows auth, don't add credentials to $connectionInfo
+               // if we are using Windows auth, then don't add credentials to $connectionInfo
                if ( !$wgDBWindowsAuthentication ) {
                        $connectionInfo['UID'] = $user;
                        $connectionInfo['PWD'] = $password;
@@ -151,10 +151,10 @@ class DatabaseMssql extends Database {
                $this->offset = 0;
 
                // several extensions seem to think that all databases support limits
-               // via LIMIT N after the WHERE clause well, MSSQL uses SELECT TOP N,
+               // via LIMIT N after the WHERE clause, but  MSSQL uses SELECT TOP N,
                // so to catch any of those extensions we'll do a quick check for a
                // LIMIT clause and pass $sql through $this->LimitToTopN() which parses
-               // the limit clause and passes the result to $this->limitResult();
+               // the LIMIT clause and passes the result to $this->limitResult();
                if ( preg_match( '/\bLIMIT\s*/i', $sql ) ) {
                        // massage LIMIT -> TopN
                        $sql = $this->LimitToTopN( $sql );
@@ -187,7 +187,7 @@ class DatabaseMssql extends Database {
                        $success = (bool)$stmt;
                }
 
-               // make a copy so that anything we add below does not get reflected in future queries
+               // Make a copy to ensure what we add below does not get reflected in future queries
                $ignoreErrors = $this->mIgnoreErrors;
 
                if ( $this->mIgnoreDupKeyErrors ) {
@@ -520,7 +520,7 @@ class DatabaseMssql extends Database {
        public function indexInfo( $table, $index, $fname = __METHOD__ ) {
                # This does not return the same info as MYSQL would, but that's OK
                # because MediaWiki never uses the returned value except to check for
-               # the existance of indexes.
+               # the existence of indexes.
                $sql = "sp_helpindex '" . $this->tableName( $table ) . "'";
                $res = $this->query( $sql, $fname );
 
@@ -609,7 +609,7 @@ class DatabaseMssql extends Database {
 
                foreach ( $arrToInsert as $a ) {
                        // start out with empty identity column, this is so we can return
-                       // it as a result of the insert logic
+                       // it as a result of the INSERT logic
                        $sqlPre = '';
                        $sqlPost = '';
                        $identityClause = '';
diff --git a/includes/deferred/WANCacheReapUpdate.php b/includes/deferred/WANCacheReapUpdate.php
new file mode 100644 (file)
index 0000000..33ddc59
--- /dev/null
@@ -0,0 +1,126 @@
+<?php
+
+use Psr\Log\LoggerInterface;
+
+/**
+ * Class for fixing stale WANObjectCache keys using a purge event source
+ *
+ * This is useful for expiring keys that missed fire-and-forget purges. This uses the
+ * recentchanges table as a reliable stream to make certain keys reach consistency
+ * as soon as the underlying replica database catches up. These means that critical
+ * keys will not escape getting purged simply due to brief hiccups in the network,
+ * which are more prone to happen accross datacenters.
+ *
+ * ----
+ * "I was trying to cheat death. I was only trying to surmount for a little while the
+ * darkness that all my life I surely knew was going to come rolling in on me some day
+ * and obliterate me. I was only to stay alive a little brief while longer, after I was
+ * already gone. To stay in the light, to be with the living, a little while past my time."
+ *   -- Notes for "Blues of a Lifetime", by [[Cornell Woolrich]]
+ *
+ * @since 1.28
+ */
+class WANCacheReapUpdate implements DeferrableUpdate {
+       /** @var IDatabase */
+       private $db;
+       /** @var LoggerInterface */
+       private $logger;
+
+       /**
+        * @param IDatabase $db
+        * @param LoggerInterface $logger
+        */
+       public function __construct( IDatabase $db, LoggerInterface $logger ) {
+               $this->db = $db;
+               $this->logger = $logger;
+       }
+
+       function doUpdate() {
+               $reaper = new WANObjectCacheReaper(
+                       ObjectCache::getMainWANInstance(),
+                       ObjectCache::getLocalClusterInstance(),
+                       [ $this, 'getTitleChangeEvents' ],
+                       [ $this, 'getEventAffectedKeys' ],
+                       [
+                               'channel' => 'table:recentchanges:' . $this->db->getWikiID(),
+                               'logger' => $this->logger
+                       ]
+               );
+
+               $reaper->invoke( 100 );
+       }
+
+       /**
+        * @see WANObjectCacheRepear
+        *
+        * @param int $start
+        * @param int $id
+        * @param int $end
+        * @param int $limit
+        * @return TitleValue[]
+        */
+       public function getTitleChangeEvents( $start, $id, $end, $limit ) {
+               $db = $this->db;
+               $encStart = $db->addQuotes( $db->timestamp( $start ) );
+               $encEnd = $db->addQuotes( $db->timestamp( $end ) );
+               $id = (int)$id; // cast NULL => 0 since rc_id is an integer
+
+               $res = $db->select(
+                       'recentchanges',
+                       [ 'rc_namespace', 'rc_title', 'rc_timestamp', 'rc_id' ],
+                       [
+                               $db->makeList( [
+                                       "rc_timestamp > $encStart",
+                                       "rc_timestamp = $encStart AND rc_id > " . $db->addQuotes( $id )
+                               ], LIST_OR ),
+                               "rc_timestamp < $encEnd"
+                       ],
+                       __METHOD__,
+                       [ 'ORDER BY' => 'rc_timestamp ASC, rc_id ASC', 'LIMIT' => $limit ]
+               );
+
+               $events = [];
+               foreach ( $res as $row ) {
+                       $events[] = [
+                               'id' => (int)$row->rc_id,
+                               'pos' => (int)wfTimestamp( TS_UNIX, $row->rc_timestamp ),
+                               'item' => new TitleValue( (int)$row->rc_namespace, $row->rc_title )
+                       ];
+               }
+
+               return $events;
+       }
+
+       /**
+        * Gets a list of important cache keys associated with a title
+        *
+        * @see WANObjectCacheRepear
+        * @param WANObjectCache $cache
+        * @param TitleValue $t
+        * @returns string[]
+        */
+       public function getEventAffectedKeys( WANObjectCache $cache, TitleValue $t ) {
+               /** @var WikiPage[]|LocalFile[]|User[] $entities */
+               $entities = [];
+
+               $entities[] = WikiPage::factory( Title::newFromTitleValue( $t ) );
+               if ( $t->inNamespace( NS_FILE ) ) {
+                       $entities[] = wfLocalFile( $t->getText() );
+               }
+               if ( $t->inNamespace( NS_USER ) ) {
+                       $entities[] = User::newFromName( $t->getText(), false );
+               }
+
+               $keys = [];
+               foreach ( $entities as $entity ) {
+                       if ( $entity ) {
+                               $keys = array_merge( $keys, $entity->getMutableCacheKeys( $cache ) );
+                       }
+               }
+               if ( $keys ) {
+                       $this->logger->debug( __CLASS__ . ': got key(s) ' . implode( ', ', $keys ) );
+               }
+
+               return $keys;
+       }
+}
index 5ecd237..cc69a76 100644 (file)
@@ -45,10 +45,10 @@ class PermissionsError extends ErrorPageError {
                $this->permission = $permission;
 
                if ( !count( $errors ) ) {
-                       $groups = array_map(
-                               [ 'User', 'makeGroupLinkWiki' ],
-                               User::getGroupsWithPermission( $this->permission )
-                       );
+                       $groups = [];
+                       foreach ( User::getGroupsWithPermission( $this->permission ) as $group ) {
+                               $groups[] = UserGroupMembership::getLink( $group, RequestContext::getMain(), 'wiki' );
+                       }
 
                        if ( $groups ) {
                                $errors[] = [ 'badaccess-groups', $wgLang->commaList( $groups ), count( $groups ) ];
index 9a7a55b..6984d48 100644 (file)
@@ -492,22 +492,6 @@ class ArchivedFile {
                throw new MWException( "Unknown type '$type'." );
        }
 
-       /**
-        * Return the user name of the uploader.
-        *
-        * @deprecated since 1.23 Use getUser( 'text' ) instead.
-        * @return string|int
-        */
-       public function getUserText() {
-               wfDeprecated( __METHOD__, '1.23' );
-               $this->load();
-               if ( $this->isDeleted( File::DELETED_USER ) ) {
-                       return 0;
-               } else {
-                       return $this->user_text;
-               }
-       }
-
        /**
         * Return upload description.
         *
index 16fe72d..be0751f 100644 (file)
@@ -240,6 +240,15 @@ class LocalFile extends File {
                return $this->repo->getSharedCacheKey( 'file', sha1( $this->getName() ) );
        }
 
+       /**
+        * @param WANObjectCache $cache
+        * @return string[]
+        * @since 1.28
+        */
+       public function getMutableCacheKeys( WANObjectCache $cache ) {
+               return [ $this->getCacheKey() ];
+       }
+
        /**
         * Try to load file metadata from memcached, falling back to the database
         */
index d887a13..9c87cf0 100644 (file)
@@ -1656,8 +1656,13 @@ abstract class Installer {
         */
        protected function createMainpage( DatabaseInstaller $installer ) {
                $status = Status::newGood();
+               $title = Title::newMainPage();
+               if ( $title->exists() ) {
+                       $status->warning( 'config-install-mainpage-exists' );
+                       return $status;
+               }
                try {
-                       $page = WikiPage::factory( Title::newMainPage() );
+                       $page = WikiPage::factory( $title );
                        $content = new WikitextContent(
                                wfMessage( 'mainpagetext' )->inContentLanguage()->text() . "\n\n" .
                                wfMessage( 'mainpagedocfooter' )->inContentLanguage()->text()
index d95222c..7a27f5f 100644 (file)
@@ -294,6 +294,7 @@ class MysqlUpdater extends DatabaseUpdater {
 
                        // 1.29
                        [ 'addField', 'externallinks', 'el_index_60', 'patch-externallinks-el_index_60.sql' ],
+                       [ 'addField', 'user_groups', 'ug_expiry', 'patch-user_groups-ug_expiry.sql' ],
                ];
        }
 
index 1f0e411..79ae175 100644 (file)
@@ -121,6 +121,7 @@ class OracleUpdater extends DatabaseUpdater {
 
                        // 1.29
                        [ 'addField', 'externallinks', 'el_index_60', 'patch-externallinks-el_index_60.sql' ],
+                       [ 'addField', 'user_groups', 'ug_expiry', 'patch-user_groups-ug_expiry.sql' ],
 
                        // KEEP THIS AT THE BOTTOM!!
                        [ 'doRebuildDuplicateFunction' ],
index 1eb3f41..e041fdd 100644 (file)
@@ -448,6 +448,8 @@ class PostgresUpdater extends DatabaseUpdater {
                        [ 'addPgField', 'externallinks', 'el_index_60', "BYTEA NOT NULL DEFAULT ''" ],
                        [ 'addPgIndex', 'externallinks', 'el_index_60', '( el_index_60, el_id )' ],
                        [ 'addPgIndex', 'externallinks', 'el_from_index_60', '( el_from, el_index_60, el_id )' ],
+                       [ 'addPgField', 'user_groups', 'ug_expiry', "TIMESTAMPTZ NULL" ],
+                       [ 'addPgIndex', 'user_groups', 'user_groups_expiry', '( ug_expiry )' ],
                ];
        }
 
index 32068e6..cdbbfd0 100644 (file)
@@ -161,6 +161,7 @@ class SqliteUpdater extends DatabaseUpdater {
 
                        // 1.29
                        [ 'addField', 'externallinks', 'el_index_60', 'patch-externallinks-el_index_60.sql' ],
+                       [ 'addField', 'user_groups', 'ug_expiry', 'patch-user_groups-ug_expiry.sql' ],
                ];
        }
 
index c591f1e..e443635 100644 (file)
        "config-help": "Ayuda",
        "config-nofile": "Nun pudo atopase'l ficheru \"$1\". ¿Desaniciose?",
        "mainpagetext": "<strong>Instalóse MediaWiki.</strong>",
-       "mainpagedocfooter": "Consulta [https://www.mediawiki.org/wiki/Special:MyLanguage/Help:Contents] pa saber cómo usar el software wiki.\n\n== Primeros pasos ==\n\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Configuration_settings Llista de les opciones de configuración]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:FAQ EMF de MediaWiki]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-announce Llista de corréu de llanzamientos de MediaWiki]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Localisation#Translation_resources Llocaliza MediaWiki na to llingua]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Combating_spam Depriende como combatir la puxarra na to wiki]"
+       "mainpagedocfooter": "Consulta la [https://www.mediawiki.org/wiki/Special:MyLanguage/Help:Contents Guía del usuariu] pa saber cómo usar el software wiki.\n\n== Primeros pasos ==\n\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Configuration_settings Llista de les opciones de configuración]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:FAQ EMF de MediaWiki]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-announce Llista de corréu de llanzamientos de MediaWiki]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Localisation#Translation_resources Llocaliza MediaWiki na to llingua]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Combating_spam Depriende como combatir la puxarra na to wiki]"
 }
index c17de3f..1335b9c 100644 (file)
        "config-install-subscribe-fail": "Немагчыма падпісацца на «mediawiki-announce»: $1",
        "config-install-subscribe-notpossible": "cURL не ўсталяваны, <code>allow_url_fopen</code> недаступны.",
        "config-install-mainpage": "Стварэньне галоўнай старонкі са зьместам па змоўчваньні",
+       "config-install-mainpage-exists": "Галоўная старонка ўжо існуе, прапускаем",
        "config-install-extension-tables": "Стварэньне табліцаў для ўключаных пашырэньняў",
        "config-install-mainpage-failed": "Немагчыма ўставіць галоўную старонку: $1",
        "config-install-done": "<strong>Віншуем!</strong>\nВы ўсталявалі MediaWiki.\n\nПраграма ўсталяваньня стварыла файл <code>LocalSettings.php</code>.\nЁн утрымлівае ўсе Вашыя налады.\n\nВам неабходна загрузіць яго і захаваць у карэнную дырэкторыю Вашай вікі (у тую ж самую дырэкторыю, дзе знаходзіцца index.php). Загрузка павінна пачацца аўтаматычна.\n\nКалі загрузка не пачалася, ці Вы яе адмянілі, Вы можаце перазапусьціць яе націснуўшы на спасылку ніжэй:\n\n$3\n\n<strong>Заўвага</strong>: калі Вы гэтага ня зробіце зараз, то створаны файл ня будзе даступны Вам потым, калі Вы выйдзеце з праграмы ўсталяваньня безь яго загрузкі.\n\nКалі Вы гэта зробіце, Вы можаце <strong>[$2 ўвайсьці ў Вашую вікі]</strong>.",
index f9a8da8..b5a146d 100644 (file)
@@ -7,7 +7,8 @@
                        "Tauhid16",
                        "Aftabuzzaman",
                        "Hasive",
-                       "আজিজ"
+                       "আজিজ",
+                       "Elias Ahmmad"
                ]
        },
        "config-desc": "মিডিয়াউইকির জন্য ইন্সটলার",
        "config-install-user-alreadyexists": "ব্যবহারকারী \"$1\" ইতিমধ্যে বিদ্যমান আছে",
        "config-install-tables": "টেবিল তৈরি",
        "config-install-keys": "গোপন কি তৈরি",
+       "config-install-mainpage-exists": "মুখ্য পৃষ্ঠা ইতিমধ্যেই বিদ্যমান, skipping",
        "config-help": "সাহায্য",
        "config-help-tooltip": "প্রসারিত করতে ক্লিক করুন",
        "mainpagetext": "<strong>মিডিয়াউইকি ইনস্টল করা হয়েছে।</strong>",
index 003583d..559e7dd 100644 (file)
@@ -20,7 +20,7 @@
        "config-localsettings-upgrade": "S'ha detectat un fitxer <code>LocalSettings.php</code>. \nPer tal d'actualitzar la instal·lació, introduïu el valor de <code>$wgUpgradeKey</code> en el quadre a continuació. El trobareu a <code>LocalSettings.php</code>.",
        "config-localsettings-cli-upgrade": "S'ha detectat un fitxer <code>LocalSettings.php</code>.\nPer a actualitzar la instal·lació, executeu <code>update.php</code>.",
        "config-localsettings-key": "Clau d'actualització:",
-       "config-localsettings-badkey": "La clau que heu proporcionat no és correcta.",
+       "config-localsettings-badkey": "La clau d'actualització que heu proporcionat no és correcta.",
        "config-upgrade-key-missing": "S'ha detectat una instal·lació ja existent del MediaWiki.\nPer actualitzar-la, poseu la línia següent al final de <code>LocalSettings.php</code>:\n\n$1",
        "config-localsettings-incomplete": "El <code>LocalSettings.php</code> que hi ha sembla incomplet.\nLa variable $1 no està definida.\nCanvieu <code>LocalSettings.php</code> perquè la variable estigui definida i feu clic a «{{int:Config-continue}}».",
        "config-localsettings-connection-error": "S'ha trobat un error en connectar-se amb la base de dades fent servir els paràmetres especificats a <code>LocalSettings.php</code>. Corregiu aquests paràmetres i torneu-ho a provar.\n\n$1",
@@ -52,7 +52,7 @@
        "config-restart": "Sí, torna a començar",
        "config-welcome": "=== Comprovacions de l'entorn ===\nS'efectuaran comprovacions bàsiques per veure si l'entorn és adequat per a la instal·lació del MediaWiki.\nRecordeu d'incloure aquesta informació si heu de demanar ajuda sobre com completar la instal·lació.",
        "config-copyright": "=== Drets d'autor i condicions ===\n\n$1\n\nAquest programa és de programari lliure; podeu redistribuir-lo i/o modificar-lo sota les condicions de la Llicència Pública General GNU com es publicada per la Free Software Foundation; qualsevol versió 2 de la llicència, o (opcionalment) qualsevol versió posterior.\n\nAquest programa és distribueix amb l'esperança que serà útil, però <strong>sense cap garantia</strong>; sense ni tan sols la garantia implícita de <strong>\ncomerciabilitat</strong> o <strong>idoneïtat per a un propòsit particular</strong>.\nConsulteu la Llicència Pública General GNU, per a més detalls.\n\nHauríeu d'haver rebut <doclink href=\"Copying\">una còpia de la Llicència Pública General GNU</doclink> amb aquest programa; si no, escriviu a la Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA o [http://www.gnu.org/copyleft/gpl.html per llegir-lo en línia].",
-       "config-sidebar": "* [https://www.mediawiki.org la Pàgina d'inici]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Help:Contents Guia de l'Usuari]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Contents Guia de l'Administrador]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:FAQ FAQ]\n----\n* <doclink href=Readme>Llegeix-me</doclink>\n* <doclink href=ReleaseNotes>Notes de la versió</doclink>\n* <doclink href=Còpia>Còpia</doclink>\n* <doclink href=UpgradeDoc>Actualització</doclink>",
+       "config-sidebar": "* [https://www.mediawiki.org la Pàgina d'inici]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Help:Contents Guia de l'usuari]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Contents Guia de l'administrador]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:FAQ PMF]\n----\n* <doclink href=Readme>Llegeix-me</doclink>\n* <doclink href=ReleaseNotes>Notes de la versió</doclink>\n* <doclink href=Còpia>Còpia</doclink>\n* <doclink href=UpgradeDoc>Actualització</doclink>",
        "config-env-good": "S'ha comprovat l'entorn.\nPodeu instal·lar el MediaWiki.",
        "config-env-bad": "S'ha comprovat l'entorn.\nNo podeu instal·lar el MediaWiki.",
        "config-env-php": "El PHP $1 està instal·lat.",
        "config-admin-error-user": "S'ha produït un error intern en crear un administrador amb el nom «<nowiki>$1</nowiki>».",
        "config-admin-error-password": "S'ha produït un error intern en definir una contrasenya per a l'administrador «<nowiki>$1</nowiki>»: <pre>$2</pre>",
        "config-admin-error-bademail": "Heu introduït una adreça electrònica no vàlida.",
+       "config-subscribe": "Subscriu a la [https://lists.wikimedia.org/mailman/listinfo/mediawiki-announce llista de correu d'anunci de noves versions].",
+       "config-pingback": "Comparteix dades d'aquesta instal·lació amb els desenvolupadors de MediaWiki.",
        "config-almost-done": "Gairebé ja heu acabat!\nPodeu ometre el que queda de la configuració i procedir amb la instal·lació del wiki.",
        "config-optional-continue": "Fes-me més preguntes.",
        "config-optional-skip": "Ja estic avorrit. Simplement instal·leu el wiki.",
        "config-install-subscribe-fail": "No s'ha pogut subscriure a mediawiki-announce: $1",
        "config-install-subscribe-notpossible": "El cURL no està instal·lat i <code>allow_url_fopen</code> no està disponible.",
        "config-install-mainpage": "S'està creant la pàgina principal amb el contingut per defecte",
+       "config-install-mainpage-exists": "La pàgina principal ja existeix, per tant s'omet",
        "config-install-extension-tables": "S'estan creant taules de les extensions habilitades",
        "config-install-mainpage-failed": "No s'ha pogut inserir la pàgina principal: $1",
+       "config-install-done": "<strong>Enhorabona!</strong>\nHeu instal·lat MediaWiki.\n\nL'instal·lador a generat un fitxer <code>LocalSettings.php</code>.\nConté tota la configuració.\n\nCaldrà que el baixeu i el poseu al directori base on heu instal·lat al wiki (el mateix directori on es troba index.php). La baixada hauria d'haver començat automàticament.\n\nSi la baixada no comença, o si l'heu cancel·lat, podeu reiniciar-la fent clic a l'enllaç de sota:\n\n$3\n\n<strong>Nota:</strong> Si no ho feu ara, no podreu accedir a aquest fitxer de configuració més endavant si no l'heu baixat abans.\n\nUna vegada tot això fet, podeu <strong>[$2 entrar al vostre wiki]</strong>.",
        "config-download-localsettings": "Baixa <code>LocalSettings.php</code>",
        "config-help": "ajuda",
        "config-help-tooltip": "feu clic per ampliar",
        "config-nofile": "No s'ha pogut trobar el fitxer «$1». S'ha suprimit?",
-       "mainpagetext": "'''El MediaWiki s'ha instal·lat correctament.'''",
+       "mainpagetext": "<strong>MediaWiki s'ha instal·lat.</strong>",
        "mainpagedocfooter": "Consulteu la [https://meta.wikimedia.org/wiki/Help:Contents Guia d'Usuari] per a més informació sobre com utilitzar-lo.\n\n== Per a començar ==\n\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Configuration_settings Llista de característiques configurables]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:FAQ PMF del MediaWiki]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-announce Llista de correu (''listserv'') per a anuncis del MediaWiki]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Localisation#Translation_resources Traduïu MediaWiki en la vostra llengua]"
 }
index 9f24ec6..2d2f207 100644 (file)
        "config-install-subscribe-fail": "Nelze se přihlásit k odběru mediawiki-announce: $1",
        "config-install-subscribe-notpossible": "Není nainstalován cURL a není dostupné <code>allow_url_fopen</code>.",
        "config-install-mainpage": "Vytváří se počáteční obsah hlavní strany",
+       "config-install-mainpage-exists": "Hlavní strana již existuje, přeskakuji.",
        "config-install-extension-tables": "Vytvářejí se tabulky pro zapnutá rozšíření",
        "config-install-mainpage-failed": "Nepodařilo se vložit hlavní stranu: $1",
        "config-install-done": "<strong>Gratulujeme!</strong>\nNainstalovali jste MediaWiki.\n\nInstalátor vytvořil soubor <code>LocalSettings.php</code>.\nTen obsahuje veškerou vaši konfiguraci.\n\nBudete si ho muset stáhnout a uložit do základního adresáře vaší instalace wiki (do stejného adresáře jako soubor index.php). Stažení souboru se mělo spustit automaticky.\n\nPokud se vám stažení nenabídlo nebo jste ho zrušili, můžete ho spustit znovu kliknutím na následující odkaz:\n\n$3\n\n<strong>Poznámka</strong>: Pokud to neuděláte hned, tento vygenerovaný konfigurační soubor nebude později dostupný, pokud instalaci opustíte, aniž byste si ho stáhli.\n\nAž to dokončíte, můžete <strong>[$2 vstoupit do své wiki]</strong>.",
index c7690e2..3babc3f 100644 (file)
        "config-install-subscribe-fail": "Abonnieren von „mediawiki-announce“ ist gescheitert: $1",
        "config-install-subscribe-notpossible": "cURL ist nicht installiert und <code>allow_url_fopen</code> ist nicht verfügbar.",
        "config-install-mainpage": "Erstellung der Hauptseite mit Standardinhalten",
+       "config-install-mainpage-exists": "Die Hauptseite ist bereits vorhanden. Überspringe.",
        "config-install-extension-tables": "Erstellung der Tabellen für die aktivierten Erweiterungen",
        "config-install-mainpage-failed": "Die Hauptseite konnte nicht erstellt werden: $1",
        "config-install-done": "'''Herzlichen Glückwunsch!'''\nMediaWiki wurde erfolgreich installiert.\n\nDas Installationsprogramm hat die Datei <code>LocalSettings.php</code> erzeugt.\nSie enthält alle vorgenommenen Konfigurationseinstellungen.\n\nDiese Datei muss nun heruntergeladen und anschließend in das Stammverzeichnis der MediaWiki-Installation hochgeladen werden. Dies ist dasselbe Verzeichnis, in dem sich auch die Datei <code>index.php</code> befindet. Das Herunterladen sollte inzwischen automatisch gestartet worden sein.\n\nSofern dies nicht der Fall war, oder das Herunterladen unterbrochen wurde, kann der Vorgang durch einen Klick auf den folgenden Link erneut gestartet werden:\n\n$3\n\n'''Hinweis:''' Die Konfigurationsdatei sollte jetzt unbedingt heruntergeladen werden. Sie wird nach Beenden des Installationsprogramms, nicht mehr zur Verfügung stehen.\n\nSobald alles erledigt wurde, kann auf das '''[$2 Wiki zugegriffen werden]'''. Wir wünschen viel Spaß und Erfolg mit dem Wiki.",
index a11c301..679c0a8 100644 (file)
        "config-install-subscribe-fail": "Ανίκανος να εγγραφείτε στο mediawiki-ανακοινώση: $1",
        "config-install-subscribe-notpossible": "Το cURL δεν είναι εγκατεστημένο και  το <code>allow_url_fopen</code> δεν είναι διαθέσιμο.",
        "config-install-mainpage": "Γίνεται δημιουργία της αρχικής σελίδας με προεπιλεγμένο περιεχόμενο",
+       "config-install-mainpage-exists": "Κύρια σελίδα ήδη υπάρχει, παρακάμπτεται",
        "config-install-extension-tables": "Γίνεται δημιουργία πινάκων για τις εγκατεστημένες επεκτάσεις",
        "config-install-mainpage-failed": "Δεν ήταν δυνατή η εισαγωγή της αρχικής σελίδας: $1",
        "config-install-done": "<strong>Συγχαρητήρια!</strong>\nΈχετε εγκαταστήσει με επιτυχία το MediaWiki.\n\nΤο πρόγραμμα εγκατάστασης έχει δημιουργήσει το  αρχείο   <code>LocalSettings.php</code>.\nΠεριέχει όλες τις ρυθμίσεις παραμέτρων σας.\n\nΘα πρέπει να το κατεβάσετε και να το βάλετε στη βάση της εγκατάστασης του  wiki σας (στον ίδιο κατάλογο όπως το  index.php). Η λήψη θα αρχίσει αυτόματα.\n\nΑν η λήψη δεν προσφέφθηκε, ή αν την ακυρώσατε, μπορείτε να επανεκκινήσετε τη λήψη κάνοντας κλικ στο παρακάτω link:\n\n$3\n\n<strong>Σημείωση:</strong> Εάν δεν το κάνετε αυτό τώρα, αυτό το  αρχείο ρύθμισης παραμέτρων δεν θα είναι διαθέσιμο για σας αργότερα, αν βγείτε από την εγκατάσταση, χωρίς να το κατεβάσετε!\n\nΌταν γίνει αυτό, μπορείτε να <strong>[$2 μπείτε στο wiki σας]</strong>.",
index 95d2ba3..db92652 100644 (file)
        "config-install-subscribe-fail": "Unable to subscribe to mediawiki-announce: $1",
        "config-install-subscribe-notpossible": "cURL is not installed and <code>allow_url_fopen</code> is not available.",
        "config-install-mainpage": "Creating main page with default content",
+       "config-install-mainpage-exists": "Main page already exists, skipping",
        "config-install-extension-tables": "Creating tables for enabled extensions",
        "config-install-mainpage-failed": "Could not insert main page: $1",
        "config-install-done": "<strong>Congratulations!</strong>\nYou have installed MediaWiki.\n\nThe installer has generated a <code>LocalSettings.php</code> file.\nIt contains all your configuration.\n\nYou will need to download it and put it in the base of your wiki installation (the same directory as index.php). The download should have started automatically.\n\nIf the download was not offered, or if you cancelled it, you can restart the download by clicking the link below:\n\n$3\n\n<strong>Note:</strong> If you do not do this now, this generated configuration file will not be available to you later if you exit the installation without downloading it.\n\nWhen that has been done, you can <strong>[$2 enter your wiki]</strong>.",
index c401832..8c4914c 100644 (file)
        "config-install-subscribe-fail": "No se ha podido suscribir a mediawiki-announce: $1",
        "config-install-subscribe-notpossible": "cURL no está instalado y <code>allow_url_fopen</code> no está disponible.",
        "config-install-mainpage": "Creando página principal con contenido predeterminado",
+       "config-install-mainpage-exists": "La página principal ya existe, se omite",
        "config-install-extension-tables": "Creando las tablas para las extensiones habilitadas",
        "config-install-mainpage-failed": "No se pudo insertar la página principal: $1",
        "config-install-done": "<strong>¡Felicidades!</strong>\nHas instalado MediaWiki.\n\nEl instalador ha generado un archivo <code>LocalSettings.php</code>.\nEste contiene toda su configuración.\n\nDeberás descargarlo y ponerlo en la base de la instalación de wiki (el mismo directorio que index.php). La descarga debería haber comenzado automáticamente.\n\nSi no comenzó la descarga, o si se ha cancelado, puedes reiniciar la descarga haciendo clic en el siguiente enlace:\n\n$3\n\n<strong>Nota</strong>: si no haces esto ahora, este archivo de configuración generado no estará disponible más tarde si sales de la instalación sin descargarlo.\n\nCuando lo hayas hecho, podrás <strong>[$2 entrar en tu wiki]</strong>.",
index 882ab92..953d427 100644 (file)
        "config-install-subscribe-fail": "Impossible de s'abonner à mediawiki-announce : $1",
        "config-install-subscribe-notpossible": "cURL n’est pas installé et <code>allow_url_fopen</code> n’est pas disponible.",
        "config-install-mainpage": "Création de la page principale avec un contenu par défaut",
+       "config-install-mainpage-exists": "La page principale existe déjà, ignoré",
        "config-install-extension-tables": "Création de tables pour les extensions activées",
        "config-install-mainpage-failed": "Impossible d’insérer la page principale : $1",
        "config-install-done": "<strong>Félicitations!</strong>\nVous avez installé MediaWiki.\n\nLe programme d'installation a généré un fichier <code>LocalSettings.php</code>. Il contient tous les paramètres de votre configuration.\n\nVous devrez le télécharger et le mettre à la racine de votre installation wiki (dans le même répertoire que index.php). Le téléchargement devrait démarrer automatiquement.\n\nSi le téléchargement n'a pas été proposé, ou que vous l'avez annulé, vous pouvez redémarrer le téléchargement en cliquant ce lien :\n\n$3\n\n<strong>Note :</strong> Si vous ne le faites pas maintenant, ce fichier de configuration généré ne sera pas disponible plus tard si vous quittez l'installation sans le télécharger.\n\nLorsque c'est fait, vous pouvez <strong>[$2 accéder à votre wiki]</strong> .",
index ab1fd7d..d4ac7e3 100644 (file)
        "config-install-subscribe-fail": "Non se puido subscribir á lista mediawiki-announce: $1",
        "config-install-subscribe-notpossible": "cURL non está instalado e <code>allow_url_fopen</code> non está dispoñible.",
        "config-install-mainpage": "Creando a páxina principal co contido por defecto",
+       "config-install-mainpage-exists": "A páxina principal xa existe, saltando",
        "config-install-extension-tables": "Creando as táboas para as extensións activadas",
        "config-install-mainpage-failed": "Non se puido inserir a páxina principal: $1",
        "config-install-done": "<strong>Parabéns!</strong>\nInstalou MediaWiki.\n\nO programa de instalación xerou un ficheiro <code>LocalSettings.php</code>.\nEste ficheiro contén toda a súa configuración.\n\nTerá que descargalo e poñelo na base da instalación do seu wiki (no mesmo directorio ca index.php). A descarga debería comezar automaticamente.\n\nSe non comezou a descarga ou se a cancelou, pode facer que comece de novo premendo na ligazón que aparece a continuación:\n\n$3\n\n<strong>Nota:</strong> Se non fai iso agora, este ficheiro de configuración xerado non estará dispoñible máis adiante se sae da instalación sen descargalo.\n\nCando faga todo isto, xa poderá <strong>[$2 entrar no seu wiki]</strong>.",
index b3b7850..5453e45 100644 (file)
        "config-install-subscribe-fail": "Impossibile sottoscrivere mediawiki-announce: $1",
        "config-install-subscribe-notpossible": "cURL non è installato e <code>allow_url_fopen</code> non è disponibile.",
        "config-install-mainpage": "Creazione della pagina principale con contenuto predefinito",
+       "config-install-mainpage-exists": "La pagina principale già esiste, saltata",
        "config-install-extension-tables": "Creazione delle tabelle per le estensioni attivate",
        "config-install-mainpage-failed": "Impossibile inserire la pagina principale: $1",
        "config-install-done": "<strong>Complimenti!</strong>\nHai installato MediaWiki.\n\nIl programma di installazione ha generato un file <code>LocalSettings.php</code> che contiene tutte le impostazioni.\n\nDevi scaricarlo ed inserirlo nella directory base del tuo wiki (la stessa dove è presente index.php). Il download dovrebbe partire automaticamente.\n\nSe il download non si avvia, o se è stato annullato, puoi riavviarlo cliccando sul collegamento di seguito:\n\n$3\n\n<strong>Nota:</strong> se esci ora dall'installazione senza scaricare il file di configurazione che è stato generato, questo poi non sarà più disponibile in seguito.\n\nQuando hai fatto, puoi <strong>[$2 entrare nel tuo wiki]</strong>.",
index 18acff0..f029d0a 100644 (file)
@@ -11,7 +11,8 @@
                        "Hwangjy9",
                        "Macofe",
                        "Mooozi",
-                       "Ykhwong"
+                       "Ykhwong",
+                       "Jerrykim306"
                ]
        },
        "config-desc": "미디어위키를 위한 설치 관리자",
        "config-install-subscribe-fail": "미디어위키 알림을 구독할 수 없습니다: $1",
        "config-install-subscribe-notpossible": "cURL이 설치되어 있지 않고 <code>allow_url_fopen</code>을 사용할 수 없습니다.",
        "config-install-mainpage": "기본 내용으로 대문을 만드는 중",
+       "config-install-mainpage-exists": "대문은 이미 존재함, 건너뜀",
        "config-install-extension-tables": "활성화된 확장 기능을 위한 테이블을 만드는 중",
        "config-install-mainpage-failed": "대문을 삽입할 수 없습니다: $1",
        "config-install-done": "<strong>축하합니다!</strong>\n미디어위키를 설치했습니다.\n\n설치 관리자가 <code>LocalSettings.php</code> 파일을 만들었습니다.\n여기에 모든 설정이 포함되어 있습니다.\n\n파일을 다운로드하여 위키 설치의 거점에 넣어야 합니다. (index.php와 같은 디렉터리) 다운로드가 자동으로 시작됩니다.\n\n다운로드가 제공되지 않을 경우나 그것을 취소한 경우에는 아래의 링크를 클릭하여 다운로드를 다시 시작할 수 있습니다:\n\n$3\n\n<strong>참고:</strong> 이 생성한 설정 파일을 다운로드하지 않고 설치를 끝내면 이 파일은 나중에 사용할 수 없습니다.\n\n완료되었으면 <strong>[$2 위키에 들어갈 수 있습니다]</strong>.",
index 10de248..7859d7a 100644 (file)
        "config-install-updates": "Net néideg Aktualiséierungen net maachen",
        "config-install-sysop": "Administrateur Benotzerkont gëtt ugeluecht",
        "config-install-mainpage": "Haaptsäit mat Standard-Inhalt gëtt ugeluecht",
+       "config-install-mainpage-exists": "Haaptsäit gëtt et schonn, iwwersprangen",
        "config-install-extension-tables": "D'Tabelle fir déi aktivéiert Erweiderunge ginn ugeluecht",
        "config-install-mainpage-failed": "D'Haaptsäit konnt net dragesat ginn: $1",
        "config-download-localsettings": "<code>LocalSettings.php</code> eroflueden",
index b0b78db..f34849b 100644 (file)
        "config-install-subscribe-fail": "Не можам да ве претплатам на известувањето mediawiki-announce: $1",
        "config-install-subscribe-notpossible": "cURL не е воспоставен, а <code>allow_url_fopen</code> не е достапно.",
        "config-install-mainpage": "Создавам главна страница со стандардна содржина",
+       "config-install-mainpage-exists": "Главната страница веќе постои. Преоѓам на следно.",
        "config-install-extension-tables": "Изработка на табели за овозможени додатоци",
        "config-install-mainpage-failed": "Не можев да вметнам главна страница: $1",
        "config-install-done": "<strong>Честитаме!</strong>\nУспешно го воспоставивте МедијаВики.\n\nВоспоставувачот создаде податотека <code>LocalSettings.php</code>.\nТаму се содржат сите ваши нагодувања.\n\nЌе треба да ја преземете и да ја ставите во основата на воспоставката (истата папка во која се наоѓа index.php). Преземањето треба да е започнато автоматски.\n\nАко не ви е понудено преземање, или пак ако сте го откажале, можете да го почнете одново стискајќи на следнава врска:\n\n$3\n\n<strong>Напомена</strong>: Ако ова не го направите сега, податотеката со поставки повеќе нема да биде на достапна.\n\nОткога ќе завршите со тоа, можете да <strong>[$2 влезете на вашето вики]</strong>.",
index 46156b9..b7a7289 100644 (file)
        "config-install-subscribe-fail": "Ikke mulig å abonnere på mediawiki-announce: $1",
        "config-install-subscribe-notpossible": "cURL er ikke installert og <code>allow_url_fopen</code> er ikke tilgjengelig.",
        "config-install-mainpage": "Oppretter hovedside med standard innhold",
+       "config-install-mainpage-exists": "Hovedsiden eksisterer allerede, hopper over",
        "config-install-extension-tables": "Oppretter tabeller for aktiviserte utvidelser",
        "config-install-mainpage-failed": "Kunne ikke sette inn hovedside: $1",
        "config-install-done": "<strong>Gratulrerer!</strong>\nDu har lykkes i å installere MediaWiki.\n\nInstallasjonsprogrammet har generert en <code>LocalSettings.php</code>-fil.\nDen inneholder alle dine konfigureringer.\n\nDu må laste den ned og legge den på hovedfolderen for din wiki-installasjon (der index.php ligger). Nedlastingen skulle ha startet automatisk.\n\nHvis ingen nedlasting ble tilbudt, eller du avbrøt den, kan du få den i gang ved å klikke på lenken under:\n\n$3\n\n<strong>OBS:</strong> Hvis du ikke gjør dette nå, vil den genererte konfigurasjonsfilen ikke være tilgjengelig for deg senere.\n\nNår dette er gjort, kan du <strong>[$2 gå inn i wikien]</strong>.",
index ac05471..f6b1d23 100644 (file)
@@ -18,7 +18,8 @@
                        "JaapDeKleine",
                        "Macofe",
                        "Hex",
-                       "Mainframe98"
+                       "Mainframe98",
+                       "Rcdeboer"
                ]
        },
        "config-desc": "Het installatieprogramma voor MediaWiki",
        "config-install-subscribe-fail": "Het is niet mogelijk te abonneren op mediawiki-announce: $1",
        "config-install-subscribe-notpossible": "cURL is niet geïnstalleerd en <code>allow_url_fopen</code> is niet beschikbaar.",
        "config-install-mainpage": "Hoofdpagina aanmaken met standaard inhoud",
+       "config-install-mainpage-exists": "Hoofdpagina bestaat al, overslaan",
        "config-install-extension-tables": "Tabellen voor ingeschakelde uitbreidingen worden aangemaakt",
        "config-install-mainpage-failed": "Het was niet mogelijk de hoofdpagina in te voegen: $1",
        "config-install-done": "<strong>Gefeliciteerd!</strong>\nU hebt MediaWiki geïnstalleerd.\n\nHet installatieprogramma heeft het bestand <code>LocalSettings.php</code> aangemaakt.\nDit bevat al uw instellingen.\n\nU moet het bestand downloaden en in de hoofdmap van uw wiki-installatie plaatsen, in dezelfde map als index.php.\nDe download zou automatisch moeten zijn gestart.\n\nAls de download niet is gestart of als u de download hebt geannuleerd, dan kunt u de download opnieuw starten door op de onderstaande koppeling te klikken:\n\n$3\n\n<strong>Let op:</strong> als u dit niet nu doet, dan is het bestand als u later de installatieprocedure afsluit zonder het bestand te downloaden niet meer beschikbaar.\n\nNa het plaatsen van het bestand met instellingen kunt u <strong>[$2 uw wiki gebruiken]</strong>.",
index f224b5d..d0004c4 100644 (file)
        "config-install-subscribe-fail": "Nie można zapisać na listę „mediawiki-announce” – $1",
        "config-install-subscribe-notpossible": "cURL nie jest zainstalowany, więc <code>allow_url_fopen</code> nie jest dostępne.",
        "config-install-mainpage": "Tworzenie strony głównej z domyślną zawartością",
+       "config-install-mainpage-exists": "Strona główna już istnieje, pomijanie",
        "config-install-extension-tables": "Tworzenie tabel dla aktywnych rozszerzeń",
        "config-install-mainpage-failed": "Nie udało się wstawić strony głównej: $1",
        "config-install-done": "<strong>'''Gratulacje!</strong>\nUdało Ci się zainstalować MediaWiki.\n\nInstalator wygenerował plik konfiguracyjny <code>LocalSettings.php</code>.\n\nMusisz go pobrać i umieścić w katalogu głównym Twojej instalacji wiki (tym samym katalogu co index.php). Pobieranie powinno zacząć się automatycznie.\n\nJeżeli pobieranie nie zostało zaproponowane lub jeśli użytkownik je anulował, można ponownie uruchomić pobranie klikając poniższe łącze:\n\n$3\n\n<strong>Uwaga</strong>: Jeśli nie zrobisz tego teraz, wygenerowany plik konfiguracyjny nie będzie już dostępny po zakończeniu instalacji.\n\nPo załadowaniu pliku konfiguracyjnego możesz <strong>[$2 wejść na wiki]</strong>.",
index 7b60ed0..8d10b51 100644 (file)
        "config-install-subscribe-fail": "{{doc-important|\"[[m:mail:mediawiki-announce|mediawiki-announce]]\" is the name of a mailing list and should not be translated.}}\nA message displayed if the MediaWiki installer encounters an error making a request to lists.wikimedia.org which hosts the mailing list.\n* $1 - the HTTP error encountered, reproduced as is (English string)",
        "config-install-subscribe-notpossible": "Error shown when automatically subscribing to the MediaWiki announcements mailing list fails.",
        "config-install-mainpage": "*{{msg-mw|Config-install-database}}\n*{{msg-mw|Config-install-tables}}\n*{{msg-mw|Config-install-schema}}\n*{{msg-mw|Config-install-user}}\n*{{msg-mw|Config-install-interwiki}}\n*{{msg-mw|Config-install-stats}}\n*{{msg-mw|Config-install-keys}}\n*{{msg-mw|Config-install-sysop}}\n*{{msg-mw|Config-install-mainpage}}",
+       "config-install-mainpage-exists": "Warning shown when installer attempts to create main page but it already exists.",
        "config-install-extension-tables": "Notice shown to the user during the install about progress.",
        "config-install-mainpage-failed": "Used as error message. Parameters:\n* $1 - detailed error message",
        "config-install-done": "Parameters:\n* $1 is the URL to LocalSettings download\n* $2 is a link to the wiki.\n* $3 is a download link with attached download icon. The config-download-localsettings message will be used as the link text.",
index 15d54b7..fc9984e 100644 (file)
        "config-install-subscribe-fail": "Не удаётся подписаться на mediawiki-announce: $1",
        "config-install-subscribe-notpossible": "cURL не установлен и не доступна опция <code>allow_url_fopen</code>.",
        "config-install-mainpage": "Создание главной страницы с содержимым по умолчанию",
+       "config-install-mainpage-exists": "Главная страница уже существует, пропускаем",
        "config-install-extension-tables": "Создание таблиц для включённых расширений",
        "config-install-mainpage-failed": "Не удаётся вставить главную страницу: $1",
        "config-install-done": "<strong>Поздравляем!</strong>\nВы установили MediaWiki.\n\nВо время установки был создан файл <code>LocalSettings.php</code>.\nОн содержит все ваши настройки.\n\nВам необходимо скачать его и положить в корневую директорию вашей вики (ту же директорию, где находится файл index.php). Его загрузка должна начаться автоматически.\n\nЕсли автоматическая загрузка не началась или вы её отменили, вы можете скачать по ссылке ниже:\n\n$3\n\n<strong>Примечание</strong>: Если вы не сделаете этого сейчас, то сгенерированный файл конфигурации не будет доступен вам в дальнейшем, если вы выйдете из установки, не скачивая его.\n\nПо окончании действий, описанных выше, вы сможете <strong>[$2 войти в вашу вики]</strong>.",
index f434356..41884c6 100644 (file)
@@ -5,7 +5,8 @@
                        "Михајло Анђелковић",
                        "Milicevic01",
                        "Aktron",
-                       "Сербијана"
+                       "Сербијана",
+                       "Zoranzoki21"
                ]
        },
        "config-desc": "Инсталација за Медијавики",
@@ -82,6 +83,7 @@
        "config-skins": "Теме",
        "config-install-step-done": "готово",
        "config-install-step-failed": "није успело",
+       "config-install-mainpage-exists": "Главна страна већ постоји, прескакање",
        "config-help": "помоћ",
        "config-help-tooltip": "кликните да проширите",
        "mainpagetext": "<strong>Медијавики је успешно инсталиран.</strong>",
index 45c5a7d..4f52403 100644 (file)
        "config-type-mssql": "Microsoft SQL Server",
        "config-support-info": "MediaWiki stöder följande databassystem:\n\n$1\n\nOm du inte ser det databassystem som du försöker använda nedanstående, följ då instruktionerna länkade ovan för aktivera stöd för det.",
        "config-dbsupport-mysql": "* [{{int:version-db-mysql-url}} MySQL] är det primära målet för MediaWiki och det stöds bäst. MediaWiki fungerar även med [{{int:version-db-mariadb-url}} MariaDB] och [{{int:version-db-percona-url}} Percona Server], som är kompatibla med MySQL. ([http://www.php.net/manual/en/mysqli.installation.php Hur man kompilerar PHP med stöd för MySQL])",
-       "config-dbsupport-postgres": "* [{{int:version-db-postgres-url}} PostgreSQL] är ett populärt databassystem med öppen källkod som ett alternativ till MySQL. Det kan finnas några mindre kvarvarande buggar, och den rekommenderas inte för användning i en produktionsmiljö. ([http://www.php.net/manual/en/pgsql.installation.php Hur man kompilerar PHP med PostgreSQL stöd])",
+       "config-dbsupport-postgres": "* [{{int:version-db-postgres-url}} PostgreSQL] är ett populärt databassystem med öppen källkod som ett alternativ till MySQL. ([http://www.php.net/manual/en/pgsql.installation.php Hur man kompilerar PHP med PostgreSQL stöd])",
        "config-dbsupport-sqlite": "* [{{int:version-db-sqlite-url}} SQLite] är en lättviktsdatabassystem med väldigt bra stöd. ([http://www.php.net/manual/en/pdo.installation.php Hur man kompilerar PHP med SQLite stöd], använder PDO)",
        "config-dbsupport-oracle": "* [{{int:version-db-oracle-url}} Oracle] är en kommersiellt databas för företag. ([http://www.php.net/manual/en/oci8.installation.php Hur man kompilerar PHP med OCI8 stöd])",
        "config-dbsupport-mssql": "* [{{int:version-db-mssql-url}} Microsoft SQL Server] är en kommersiellt databas för företag för Windows. ([http://www.php.net/manual/en/sqlsrv.installation.php Hur man kompilerar PHP med SQLSRV stöd])",
        "config-install-subscribe-fail": "Det gick inte att prenumerera på mediawiki-announce: $1",
        "config-install-subscribe-notpossible": "cURL är inte installerad och <code>allow_url_fopen</code> är inte tillgänglig.",
        "config-install-mainpage": "Skapa huvudsida med standardinnehåll",
+       "config-install-mainpage-exists": "Huvudsidan finns redan, hoppar över",
        "config-install-extension-tables": "Skapar tabeller för aktiverade tillägg",
        "config-install-mainpage-failed": "Kunde inte infoga huvudsidan: $1",
        "config-install-done": "<strong>Grattis!</strong>\nDu har installerat MediaWiki.\n\nInstallationsprogrammet har genererat filen <code>LocalSettings.php</code>.\nDet innehåller alla dina konfigurationer.\n\nDu kommer att behöva ladda ner den och placera den i roten för din wiki-installation (samma katalog som index.php). Nedladdningen borde ha startats automatiskt.\n\nOm ingen nedladdning erbjöds, eller om du har avbrutit det kan du starta om nedladdningen genom att klicka på länken nedan:\n\n$3\n\n<strong>OBS</strong>: Om du inte gör detta nu, kommer denna genererade konfigurationsfil inte vara tillgänglig för dig senare om du avslutar installationen utan att ladda ned den.\n\nNär det är klart, kan du <strong>[$2 gå in på din wiki]</strong>",
        "config-nofile": "Filen \"$1\" kunde inte hittas. Har den raderats?",
        "config-extension-link": "Visste du att din wiki stödjer [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Extensions tillägg]?\n\nDu kan bläddra [https://www.mediawiki.org/wiki/Special:MyLanguage/Category:Extensions_by_category tillägg efter kategori].",
        "mainpagetext": "<strong>MediaWiki har installerats utan problem.</strong>",
-       "mainpagedocfooter": "Information om hur wiki-programvaran används finns i [https://meta.wikimedia.org/wiki/Help:Contents användarguiden].\n\n== Att komma igång ==\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Configuration_settings Lista över konfigurationsinställningar]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:FAQ MediaWiki FAQ]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-announce E-postlista för nya versioner av MediaWiki]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Localisation#Translation_resources Lokalisera MediaWiki för ditt språk]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Combating_spam Läs om hur du bekämpar spam på din wiki]"
+       "mainpagedocfooter": "Information om hur wiki-programvaran används finns i [https://www.mediawiki.org/wiki/Special:MyLanguage/Help:Contents användarguiden].\n\n== Att komma igång ==\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Configuration_settings Lista över konfigurationsinställningar]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:FAQ MediaWiki FAQ]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-announce E-postlista för nya versioner av MediaWiki]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Localisation#Translation_resources Lokalisera MediaWiki för ditt språk]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Combating_spam Läs om hur du bekämpar spam på din wiki]"
 }
index 2ba2c27..e078752 100644 (file)
@@ -6,7 +6,8 @@
                        "아라",
                        "Amire80",
                        "Jojit fb",
-                       "Macofe"
+                       "Macofe",
+                       "Emem.calist"
                ]
        },
        "config-desc": "Ang tagapagluklok para sa MediaWiki",
        "config-install-subscribe-fail": "Hindi nagawang magpasipi mula sa mediawiki-announce: $1",
        "config-install-subscribe-notpossible": "Hindi nakalagak ang cURL at hindi makukuha ang <code>allow_url_fopen</code>",
        "config-install-mainpage": "Nililikha ang pangunahing pahina na may likas na nakatakdang nilalaman",
+       "config-install-mainpage-exists": "Ang pangunahing pahina ay nakasaad na, ipagpatuloy ang paglalathala",
        "config-install-extension-tables": "Nililikha ang mga talahanayan para sa pinagaganang mga dugtong",
        "config-install-mainpage-failed": "Hindi maisingit ang pangunahing pahina: $1",
        "config-install-done": "'''Maligayang bati!'''\nMatagumpay mong nailuklok ang MediaWiki.\n\nAng tagapagluklok ay nakagawa ng isang talaksan ng <code>LocalSettings.php</code>.\nNaglalaman ito ng lahat ng iyong mga pagsasaayos.\n\nKailangan mo itong ikargang paibaba at ilagay ito sa lipon ng iyong pagluluklok ng wiki (katulad ng direktoryo ng index.php).  Ang pagkakargang paibaba ay dapat na kusang magsimula.\n\nKung ang pagkakargang paibaba ay hindi inialok, o kung hindi mo ito itinuloy, maaari mong muling simulan ang pagkakargang paibaba sa pamamagitan ng pagpindot sa kawing na nasa ibaba:\n\n$3\n\n'''Paunawa''': Kapag hindi mo ito ginawa ngayon, ang nagawang talaksang ito ng pagkakaayos ay hindi mo na makukuha mamaya kapag lumabas ka mula sa pagluluklok na hindi ikinakarga itong paibaba.\n\nKapag nagawa na iyan, maaari ka nang '''[$2 pumasok sa wiki mo]'''.",
index a3c3d24..ef7694a 100644 (file)
        "config-information": "Impormasyon",
        "config-localsettings-upgrade": "Mayda <code>LocalSettings.php</code> nga paypay nga nabilngan.  Basi ma-upgrade ini nga pag-installar, alayon pagbutáng han value han <code>$wgUpgradeKey</code> ha kahon ha ubós. Mabibilngan mo ini ha <code>LocalSettings.php</code>.",
        "config-localsettings-cli-upgrade": "Mayda <code>LocalSettings.php</code> nga paypay nga nabilngan. Basi ma-upgrade ini nga pag-installar, alayon pagpadalagan lugod han <code>update.php</code>",
-       "config-localsettings-badkey": "An key nga imo ginhatag in diri asya.",
+       "config-localsettings-key": "Upgrade nga yabi:",
+       "config-localsettings-badkey": "Sayop an upgrade nga yabi nga imo ginhátag",
        "config-upgrade-key-missing": "Mayda daan na ng gin-installar nga MediaWiki nga nabilngan.\nBasi ma-upgrade ini nga pag-instalar, alayon pagbutang han nahasunod nga linya ha ubós han imo <code>LocalSettings.php</code>:\n\n$1",
        "config-localsettings-incomplete": "An yana nga <code>LocalSettings.php</code> in baga diri kompleto.\nAn $1 variable in diri naka-set.\nAlayon igsaliwan an <code>LocalSettings.php</code> para ini nga variable in mai-set, ngan pidlita an \"{{int:Config-continue}}\".",
        "config-localsettings-connection-error": "May-ada pagsayop an nahitabo han pagpapakabit ngada ha database nga gingagamitan hin mga kamumutangan nga dapat unta ginpapatuman han <code>LocalSettings.php</code>. Alayon ayda ini nga mga kamumutangan ngan utrohon nala.\n\n$1",
        "config-session-error": "Pakyas an pagtikang han session: $1",
+       "config-session-expired": "An imo sesyon nga data baga na hin naglahós na hin panahón\nIt mga sesyon gin-configure hin pagkaiha nga $1\nPuyde mo ini paiha-on ha pagset hit <code>session.gc_maxlifetime</code> ha php.ini.\nIgtikang hin utro an pag-instalar nga proseso.",
+       "config-no-session": "¡Nawarâ an imo sesyon nga data!\nKitaa an imo php.ini ngan siguroa nga an  <code>session.save_path</code> ginkadâ hin naangay nga direktory.",
        "config-your-language": "Imo pinulongán",
+       "config-your-language-help": "Pili-a in yinaknan nga gagamiton dida han proseso han pag-instalar.",
        "config-wiki-language": "Pinulongán han wiki",
        "config-wiki-language-help": "Pilía an pinulongán nga kauróg igsúsurat hit wiki",
        "config-back": "Bálik",
        "config-page-language": "Pinulongán",
        "config-page-welcome": "Maupay nga pag-abot ha MediaWiki!",
        "config-page-dbconnect": "Igsumpay ha database",
+       "config-page-upgrade": "Ig-upgrade it aada nga na-instalar",
+       "config-page-dbsettings": "Mga setting ha database",
        "config-page-name": "Ngaran",
+       "config-page-options": "Mga pagpipilian",
+       "config-page-install": "Ig-instalar",
        "config-page-complete": "Nakompleto!",
+       "config-page-restart": "Igbalik hin utro in pag-instalar",
        "config-page-readme": "Basaha ako",
+       "config-page-releasenotes": "Mga nota han ginpagawás",
        "config-page-copying": "Nagkokopya",
+       "config-page-upgradedoc": "Pag-upgrade",
+       "config-page-existingwiki": "Aada nga wiki",
+       "config-help-restart": "¿Karúyag mo ba ighawan an tanan nga gin-save nga data nga imo gin-enter ngan igbalik hin utro an proseso hin pag-instalar?",
        "config-restart": "Oo, utroha patikanga",
        "config-welcome": "=== Mga pagpanginano panlibong ===\nMagkakamay-ada yano nga panginano para masabtan kun ini nga libong in naaangay para hiton pagtataod hiton MediaWiki. Hinumdomi iton paglakip hinin nga impormasyon kun karuyag mo mangaro hin suporta kun paunan-on humanon an pagtataod.",
        "config-env-php": "Gin-install an PHP $1.",
index b6afa04..d0c0026 100644 (file)
        "config-install-subscribe-fail": "无法订阅mediawiki-announce:$1",
        "config-install-subscribe-notpossible": "没有安装cURL,<code>allow_url_fopen</code>也不可用。",
        "config-install-mainpage": "正在创建显示默认内容的首页",
+       "config-install-mainpage-exists": "首页已存在,正在跳过",
        "config-install-extension-tables": "正在创建已启用扩展程序表",
        "config-install-mainpage-failed": "无法插入首页:$1",
        "config-install-done": "<strong>恭喜!</strong>\n您已经安装了MediaWiki。\n\n安装程序已经生成了<code>LocalSettings.php</code>文件,其中包含了您所有的配置。\n\n您需要下载该文件,并将其放在您wiki的根目录(index.php的同级目录)中。稍后下载将自动开始。\n\n如果浏览器没有提示您下载,或者您取消了下载,您可以点击下面的链接重新开始下载:\n\n$3\n\n<strong>注意:</strong>如果您现在不完成本步骤,而是没有下载便退出了安装过程,此后您将无法获得自动生成的配置文件。\n\n当本步骤完成后,您可以<strong>[$2 进入您的wiki]</strong>。",
index 171c291..75c79a9 100644 (file)
@@ -1127,6 +1127,65 @@ class WANObjectCache implements IExpiringStore, LoggerAwareInterface {
                return $values;
        }
 
+       /**
+        * Locally set a key to expire soon if it is stale based on $purgeTimestamp
+        *
+        * This sets stale keys' time-to-live at HOLDOFF_TTL seconds, which both avoids
+        * broadcasting in mcrouter setups and also avoids races with new tombstones.
+        *
+        * @param string $key Cache key
+        * @param int $purgeTimestamp UNIX timestamp of purge
+        * @param bool &$isStale Whether the key is stale
+        * @return bool Success
+        * @since 1.28
+        */
+       public function reap( $key, $purgeTimestamp, &$isStale = false ) {
+               $minAsOf = $purgeTimestamp + self::HOLDOFF_TTL;
+               $wrapped = $this->cache->get( self::VALUE_KEY_PREFIX . $key );
+               if ( is_array( $wrapped ) && $wrapped[self::FLD_TIME] < $minAsOf ) {
+                       $isStale = true;
+                       $this->logger->warning( "Reaping stale value key '$key'." );
+                       $ttlReap = self::HOLDOFF_TTL; // avoids races with tombstone creation
+                       $ok = $this->cache->changeTTL( self::VALUE_KEY_PREFIX . $key, $ttlReap );
+                       if ( !$ok ) {
+                               $this->logger->error( "Could not complete reap of key '$key'." );
+                       }
+
+                       return $ok;
+               }
+
+               $isStale = false;
+
+               return true;
+       }
+
+       /**
+        * Locally set a "check" key to expire soon if it is stale based on $purgeTimestamp
+        *
+        * @param string $key Cache key
+        * @param int $purgeTimestamp UNIX timestamp of purge
+        * @param bool &$isStale Whether the key is stale
+        * @return bool Success
+        * @since 1.28
+        */
+       public function reapCheckKey( $key, $purgeTimestamp, &$isStale = false ) {
+               $purge = $this->parsePurgeValue( $this->cache->get( self::TIME_KEY_PREFIX . $key ) );
+               if ( $purge && $purge[self::FLD_TIME] < $purgeTimestamp ) {
+                       $isStale = true;
+                       $this->logger->warning( "Reaping stale check key '$key'." );
+                       $ok = $this->cache->changeTTL( self::TIME_KEY_PREFIX . $key, 1 );
+                       if ( !$ok ) {
+                               $this->logger->error( "Could not complete reap of check key '$key'." );
+                       }
+
+                       return $ok;
+               }
+
+               $isStale = false;
+
+               return false;
+       }
+
        /**
         * @see BagOStuff::makeKey()
         * @param string ... Key component
diff --git a/includes/libs/objectcache/WANObjectCacheReaper.php b/includes/libs/objectcache/WANObjectCacheReaper.php
new file mode 100644 (file)
index 0000000..62e4536
--- /dev/null
@@ -0,0 +1,204 @@
+<?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 Cache
+ * @author Aaron Schulz
+ */
+
+use Psr\Log\LoggerAwareInterface;
+use Psr\Log\LoggerInterface;
+use Psr\Log\NullLogger;
+
+/**
+ * Class for scanning through chronological, log-structured data or change logs
+ * and locally purging cache keys related to entities that appear in this data.
+ *
+ * This is useful for repairing cache when purges are missed by using a reliable
+ * stream, such as Kafka or a replicated MySQL table. Purge loss between datacenters
+ * is expected to be more common than within them.
+ *
+ * @since 1.28
+ */
+class WANObjectCacheReaper implements LoggerAwareInterface {
+       /** @var WANObjectCache */
+       protected $cache;
+       /** @var BagOStuff */
+       protected $store;
+       /** @var callable */
+       protected $logChunkCallback;
+       /** @var callable */
+       protected $keyListCallback;
+       /** @var LoggerInterface */
+       protected $logger;
+
+       /** @var string */
+       protected $channel;
+       /** @var integer */
+       protected $initialStartWindow;
+
+       /**
+        * @param WANObjectCache $cache Cache to reap bad keys from
+        * @param BagOStuff $store Cache to store positions use for locking
+        * @param callable $logCallback Callback taking arguments:
+        *          - The starting position as a UNIX timestamp
+        *          - The starting unique ID used for breaking timestamp collisions or null
+        *          - The ending position as a UNIX timestamp
+        *          - The maximum number of results to return
+        *        It returns a list of maps of (key: cache key, pos: UNIX timestamp, id: unique ID)
+        *        for each key affected, with the corrosponding event timestamp/ID information.
+        *        The events should be in ascending order, by (timestamp,id).
+        * @param callable $keyCallback Callback taking arguments:
+        *          - The WANObjectCache instance
+        *          - An object from the event log
+        *        It should return a list of WAN cache keys.
+        *        The callback must fully duck-type test the object, since can be any model class.
+        * @param array $params Additional options:
+        *          - channel: the name of the update event stream.
+        *            Default: WANObjectCache::DEFAULT_PURGE_CHANNEL.
+        *          - initialStartWindow: seconds back in time to start if the position is lost.
+        *            Default: 1 hour.
+        *          - logger: an SPL monolog instance [optional]
+        */
+       public function __construct(
+               WANObjectCache $cache,
+               BagOStuff $store,
+               callable $logCallback,
+               callable $keyCallback,
+               array $params
+       ) {
+               $this->cache = $cache;
+               $this->store = $store;
+
+               $this->logChunkCallback = $logCallback;
+               $this->keyListCallback = $keyCallback;
+               if ( isset( $params['channel'] ) ) {
+                       $this->channel = $params['channel'];
+               } else {
+                       throw new UnexpectedValueException( "No channel specified." );
+               }
+
+               $this->initialStartWindow = isset( $params['initialStartWindow'] )
+                       ? $params['initialStartWindow']
+                       : 3600;
+               $this->logger = isset( $params['logger'] )
+                       ? $params['logger']
+                       : new NullLogger();
+       }
+
+       public function setLogger( LoggerInterface $logger ) {
+               $this->logger = $logger;
+       }
+
+       /**
+        * Check and reap stale keys based on a chunk of events
+        *
+        * @param int $n Number of events
+        * @return int Number of keys checked
+        */
+       final public function invoke( $n = 100 ) {
+               $posKey = $this->store->makeGlobalKey( 'WANCache', 'reaper', $this->channel );
+               $scopeLock = $this->store->getScopedLock( "$posKey:busy", 0 );
+               if ( !$scopeLock ) {
+                       return 0;
+               }
+
+               $now = time();
+               $status = $this->store->get( $posKey );
+               if ( !$status ) {
+                       $status = [ 'pos' => $now - $this->initialStartWindow, 'id' => null ];
+               }
+
+               // Get events for entities who's keys tombstones/hold-off should have expired by now
+               $events = call_user_func_array(
+                       $this->logChunkCallback,
+                       [ $status['pos'], $status['id'], $now - WANObjectCache::HOLDOFF_TTL - 1, $n ]
+               );
+
+               $event = null;
+               $keyEvents = [];
+               foreach ( $events as $event ) {
+                       $keys = call_user_func_array(
+                               $this->keyListCallback,
+                               [ $this->cache, $event['item'] ]
+                       );
+                       foreach ( $keys as $key ) {
+                               unset( $keyEvents[$key] ); // use only the latest per key
+                               $keyEvents[$key] = [
+                                       'pos' => $event['pos'],
+                                       'id' => $event['id']
+                               ];
+                       }
+               }
+
+               $purgeCount = 0;
+               $lastOkEvent = null;
+               foreach ( $keyEvents as $key => $keyEvent ) {
+                       if ( !$this->cache->reap( $key, $keyEvent['pos'] ) ) {
+                               break;
+                       }
+                       ++$purgeCount;
+                       $lastOkEvent = $event;
+               }
+
+               if ( $lastOkEvent ) {
+                       $ok = $this->store->merge(
+                               $posKey,
+                               function ( $bag, $key, $curValue ) use ( $lastOkEvent ) {
+                                       if ( !$curValue ) {
+                                               // Use new position
+                                       } else {
+                                               $curCoord = [ $curValue['pos'], $curValue['id'] ];
+                                               $newCoord = [ $lastOkEvent['pos'], $lastOkEvent['id'] ];
+                                               if ( $newCoord < $curCoord ) {
+                                                       // Keep prior position instead of rolling it back
+                                                       return $curValue;
+                                               }
+                                       }
+
+                                       return [
+                                               'pos' => $lastOkEvent['pos'],
+                                               'id' => $lastOkEvent['id'],
+                                               'ctime' => $curValue ? $curValue['ctime'] : date( 'c' )
+                                       ];
+                               },
+                               IExpiringStore::TTL_INDEFINITE
+                       );
+
+                       $pos = $lastOkEvent['pos'];
+                       $id = $lastOkEvent['id'];
+                       if ( $ok ) {
+                               $this->logger->info( "Updated cache reap position ($pos, $id)." );
+                       } else {
+                               $this->logger->error( "Could not update cache reap position ($pos, $id)." );
+                       }
+               }
+
+               ScopedCallback::consume( $scopeLock );
+
+               return $purgeCount;
+       }
+
+       /**
+        * @return array|bool Returns (pos, id) map or false if not set
+        */
+       public function getState() {
+               $posKey = $this->store->makeGlobalKey( 'WANCache', 'reaper', $this->channel );
+
+               return $this->store->get( $posKey );
+       }
+}
index c390232..a0bfb59 100644 (file)
@@ -59,9 +59,15 @@ class BlockLogFormatter extends LogFormatter {
                        // The lrm is needed to make sure that the number
                        // is shown on the correct side of the tooltip text.
                        $durationTooltip = '&lrm;' . htmlspecialchars( $params[4] );
-                       $params[4] = Message::rawParam( "<span class='blockExpiry' title='$durationTooltip'>" .
-                               $this->context->getLanguage()->translateBlockExpiry( $params[4],
-                                       $this->context->getUser() ) . '</span>' );
+                       $params[4] = Message::rawParam(
+                               "<span class='blockExpiry' title='$durationTooltip'>" .
+                               $this->context->getLanguage()->translateBlockExpiry(
+                                       $params[4],
+                                       $this->context->getUser(),
+                                       wfTimestamp( TS_UNIX, $this->entry->getTimestamp() )
+                               ) .
+                               '</span>'
+                       );
                        $params[5] = isset( $params[5] ) ?
                                self::formatBlockFlags( $params[5], $this->context->getLanguage() ) : '';
                }
index a64fee1..b5af783 100644 (file)
@@ -353,7 +353,11 @@ class LogFormatter {
                                                        $rawDuration = $parameters['5::duration'];
                                                        $rawFlags = $parameters['6::flags'];
                                                }
-                                               $duration = $wgContLang->translateBlockExpiry( $rawDuration );
+                                               $duration = $wgContLang->translateBlockExpiry(
+                                                       $rawDuration,
+                                                       null,
+                                                       wfTimestamp( TS_UNIX, $entry->getTimestamp() )
+                                               );
                                                $flags = BlockLogFormatter::formatBlockFlags( $rawFlags, $wgContLang );
                                                $text = wfMessage( 'blocklogentry' )
                                                        ->rawParams( $target, $duration, $flags )->inContentLanguage()->escaped();
@@ -363,7 +367,11 @@ class LogFormatter {
                                                        ->rawParams( $target )->inContentLanguage()->escaped();
                                                break;
                                        case 'reblock':
-                                               $duration = $wgContLang->translateBlockExpiry( $parameters['5::duration'] );
+                                               $duration = $wgContLang->translateBlockExpiry(
+                                                       $parameters['5::duration'],
+                                                       null,
+                                                       wfTimestamp( TS_UNIX, $entry->getTimestamp() )
+                                               );
                                                $flags = BlockLogFormatter::formatBlockFlags( $parameters['6::flags'], $wgContLang );
                                                $text = wfMessage( 'reblock-logentry' )
                                                        ->rawParams( $target, $duration, $flags )->inContentLanguage()->escaped();
index be73c86..791330c 100644 (file)
@@ -70,7 +70,7 @@ class RightsLogFormatter extends LogFormatter {
        protected function getMessageParameters() {
                $params = parent::getMessageParameters();
 
-               // Really old entries
+               // Really old entries that lack old/new groups
                if ( !isset( $params[3] ) && !isset( $params[4] ) ) {
                        return $params;
                }
@@ -81,25 +81,29 @@ class RightsLogFormatter extends LogFormatter {
                $userName = $this->entry->getTarget()->getText();
                if ( !$this->plaintext && count( $oldGroups ) ) {
                        foreach ( $oldGroups as &$group ) {
-                               $group = User::getGroupMember( $group, $userName );
+                               $group = UserGroupMembership::getGroupMemberName( $group, $userName );
                        }
                }
                if ( !$this->plaintext && count( $newGroups ) ) {
                        foreach ( $newGroups as &$group ) {
-                               $group = User::getGroupMember( $group, $userName );
+                               $group = UserGroupMembership::getGroupMemberName( $group, $userName );
                        }
                }
 
-               $lang = $this->context->getLanguage();
+               // fetch the metadata about each group membership
+               $allParams = $this->entry->getParameters();
+
                if ( count( $oldGroups ) ) {
-                       $params[3] = $lang->listToText( $oldGroups );
+                       $params[3] = [ 'raw' => $this->formatRightsList( $oldGroups,
+                               isset( $allParams['oldmetadata'] ) ? $allParams['oldmetadata'] : [] ) ];
                } else {
                        $params[3] = $this->msg( 'rightsnone' )->text();
                }
                if ( count( $newGroups ) ) {
                        // Array_values is used here because of T44211
                        // see use of array_unique in UserrightsPage::doSaveUserGroups on $newGroups.
-                       $params[4] = $lang->listToText( array_values( $newGroups ) );
+                       $params[4] = [ 'raw' => $this->formatRightsList( array_values( $newGroups ),
+                               isset( $allParams['newmetadata'] ) ? $allParams['newmetadata'] : [] ) ];
                } else {
                        $params[4] = $this->msg( 'rightsnone' )->text();
                }
@@ -109,6 +113,42 @@ class RightsLogFormatter extends LogFormatter {
                return $params;
        }
 
+       protected function formatRightsList( $groups, $serializedUGMs = [] ) {
+               $uiLanguage = $this->context->getLanguage();
+               $uiUser = $this->context->getUser();
+               // separate arrays of temporary and permanent memberships
+               $tempList = $permList = [];
+
+               reset( $groups );
+               reset( $serializedUGMs );
+               while ( current( $groups ) ) {
+                       $group = current( $groups );
+
+                       if ( current( $serializedUGMs ) &&
+                               isset( current( $serializedUGMs )['expiry'] ) &&
+                               current( $serializedUGMs )['expiry']
+                       ) {
+                               // there is an expiry date; format the group and expiry into a friendly string
+                               $expiry = current( $serializedUGMs )['expiry'];
+                               $expiryFormatted = $uiLanguage->userTimeAndDate( $expiry, $uiUser );
+                               $expiryFormattedD = $uiLanguage->userDate( $expiry, $uiUser );
+                               $expiryFormattedT = $uiLanguage->userTime( $expiry, $uiUser );
+                               $tempList[] = $this->msg( 'rightslogentry-temporary-group' )->params( $group,
+                                       $expiryFormatted, $expiryFormattedD, $expiryFormattedT )->parse();
+                       } else {
+                               // the right does not expire; just insert the group name
+                               $permList[] = $group;
+                       }
+
+                       next( $groups );
+                       next( $serializedUGMs );
+               }
+
+               // place all temporary memberships first, to avoid the ambiguity of
+               // "adinistrator, bureaucrat and importer (temporary, until X time)"
+               return $uiLanguage->listToText( array_merge( $tempList, $permList ) );
+       }
+
        protected function getParametersForApi() {
                $entry = $this->entry;
                $params = $entry->getParameters();
@@ -126,12 +166,44 @@ class RightsLogFormatter extends LogFormatter {
                        }
                }
 
-               // Really old entries does not have log params
+               // Really old entries do not have log params, so form them from whatever info
+               // we have.
+               // Also walk through the parallel arrays of groups and metadata, combining each
+               // metadata array with the name of the group it pertains to
                if ( isset( $params['4:array:oldgroups'] ) ) {
                        $params['4:array:oldgroups'] = $this->makeGroupArray( $params['4:array:oldgroups'] );
+
+                       $oldmetadata =& $params['oldmetadata'];
+                       // unset old metadata entry to ensure metadata goes at the end of the params array
+                       unset( $params['oldmetadata'] );
+                       $params['oldmetadata'] = array_map( function( $index ) use ( $params, $oldmetadata ) {
+                               $result = [ 'group' => $params['4:array:oldgroups'][$index] ];
+                               if ( isset( $oldmetadata[$index] ) ) {
+                                       $result += $oldmetadata[$index];
+                               }
+                               $result['expiry'] = ApiResult::formatExpiry( isset( $result['expiry'] ) ?
+                                       $result['expiry'] : null );
+
+                               return $result;
+                       }, array_keys( $params['4:array:oldgroups'] ) );
                }
+
                if ( isset( $params['5:array:newgroups'] ) ) {
                        $params['5:array:newgroups'] = $this->makeGroupArray( $params['5:array:newgroups'] );
+
+                       $newmetadata =& $params['newmetadata'];
+                       // unset old metadata entry to ensure metadata goes at the end of the params array
+                       unset( $params['newmetadata'] );
+                       $params['newmetadata'] = array_map( function( $index ) use ( $params, $newmetadata ) {
+                               $result = [ 'group' => $params['5:array:newgroups'][$index] ];
+                               if ( isset( $newmetadata[$index] ) ) {
+                                       $result += $newmetadata[$index];
+                               }
+                               $result['expiry'] = ApiResult::formatExpiry( isset( $result['expiry'] ) ?
+                                       $result['expiry'] : null );
+
+                               return $result;
+                       }, array_keys( $params['5:array:newgroups'] ) );
                }
 
                return $params;
@@ -145,6 +217,14 @@ class RightsLogFormatter extends LogFormatter {
                if ( isset( $ret['newgroups'] ) ) {
                        ApiResult::setIndexedTagName( $ret['newgroups'], 'g' );
                }
+               if ( isset( $ret['oldmetadata'] ) ) {
+                       ApiResult::setArrayType( $ret['oldmetadata'], 'array' );
+                       ApiResult::setIndexedTagName( $ret['oldmetadata'], 'g' );
+               }
+               if ( isset( $ret['newmetadata'] ) ) {
+                       ApiResult::setArrayType( $ret['newmetadata'], 'array' );
+                       ApiResult::setIndexedTagName( $ret['newmetadata'], 'g' );
+               }
                return $ret;
        }
 
index d39da90..34ff63c 100644 (file)
@@ -1654,15 +1654,6 @@ class Article implements Page {
                $title = $this->getTitle();
                $ctx = $this->getContext();
                $outputPage = $ctx->getOutput();
-               if ( !wfMessage( 'deletereason-dropdown' )->inContentLanguage()->isDisabled() ) {
-                       $reasonsList = Xml::getArrayFromWikiTextList(
-                               wfMessage( 'deletereason-dropdown' )->inContentLanguage()->text()
-                       );
-                       $outputPage->addModules( 'mediawiki.reasonSuggest' );
-                       $outputPage->addJsConfigVars( [
-                               'reasons' => $reasonsList
-                       ] );
-               }
                $useMediaWikiUIEverywhere = $ctx->getConfig()->get( 'UseMediaWikiUIEverywhere' );
                $outputPage->setPageTitle( wfMessage( 'delete-confirm', $title->getPrefixedText() ) );
                $outputPage->addBacklinkSubtitle( $title );
index f760cd1..1c1412a 100644 (file)
@@ -2088,8 +2088,12 @@ class WikiPage implements Page, IDBAccessObject {
                                );
                        } else {
                                // Try to avoid a second parse if {{REVISIONID}} is used
-                               $edit->popts->setSpeculativeRevIdCallback( function () {
-                                       return 1 + (int)wfGetDB( DB_MASTER )->selectField(
+                               $dbIndex = ( $this->mDataLoadedFrom & self::READ_LATEST ) === self::READ_LATEST
+                                       ? DB_MASTER // use the best possible guess
+                                       : DB_REPLICA; // T154554
+
+                               $edit->popts->setSpeculativeRevIdCallback( function () use ( $dbIndex ) {
+                                       return 1 + (int)wfGetDB( $dbIndex )->selectField(
                                                'revision',
                                                'MAX(rev_id)',
                                                [],
@@ -3648,4 +3652,15 @@ class WikiPage implements Page, IDBAccessObject {
        public function getSourceURL() {
                return $this->getTitle()->getCanonicalURL();
        }
+
+       /*
+        * @param WANObjectCache $cache
+        * @return string[]
+        * @since 1.28
+        */
+       public function getMutableCacheKeys( WANObjectCache $cache ) {
+               $linkCache = MediaWikiServices::getInstance()->getLinkCache();
+
+               return $linkCache->getMutableCacheKeys( $cache, $this->getTitle()->getTitleValue() );
+       }
 }
index 702a479..3ec0596 100644 (file)
@@ -2201,7 +2201,7 @@ class Parser {
                                continue;
                        }
 
-                       $origLink = $m[1];
+                       $origLink = ltrim( $m[1], ' ' );
 
                        # Don't allow internal links to pages containing
                        # PROTO: where PROTO is a valid URL protocol; these
index 7bf848f..0c162b4 100644 (file)
@@ -696,6 +696,8 @@ class ParserOutput extends CacheTime {
         * to SpecialTrackingCategories::$coreTrackingCategories, and extensions
         * should add to "TrackingCategories" in their extension.json.
         *
+        * @todo Migrate some code to TrackingCategories
+        *
         * @param string $msg Message key
         * @param Title $title title of the page which is being tracked
         * @return bool Whether the addition was successful
index 0bcb07a..206067f 100644 (file)
@@ -109,6 +109,20 @@ abstract class SearchEngine {
                $this->features[$feature] = $data;
        }
 
+       /**
+        * Way to retrieve custom data set by setFeatureData
+        * or by the engine itself.
+        * @since 1.29
+        * @param string $feature feature name
+        * @return mixed the feature value or null if unset
+        */
+       public function getFeatureData( $feature ) {
+               if ( isset ( $this->features[$feature] ) ) {
+                       return $this->features[$feature];
+               }
+               return null;
+       }
+
        /**
         * When overridden in derived class, performs database-specific conversions
         * on text to be used for searching or updating search index.
index 575a9ac..bc6dfca 100644 (file)
@@ -61,7 +61,7 @@ class SkinTemplate extends Skin {
         *
         * @param OutputPage $out
         */
-       function setupSkinUserCss( OutputPage $out ) {
+       public function setupSkinUserCss( OutputPage $out ) {
                $moduleStyles = [
                        'mediawiki.legacy.shared',
                        'mediawiki.legacy.commonPrint',
@@ -1283,7 +1283,7 @@ class SkinTemplate extends Skin {
                                'href' => $this->getTitle()->getLocalURL( "action=info" )
                        ];
 
-                       if ( $this->getTitle()->exists() ) {
+                       if ( $this->getTitle()->exists() || $this->getTitle()->inNamespace( NS_CATEGORY ) ) {
                                $nav_urls['recentchangeslinked'] = [
                                        'href' => SpecialPage::getTitleFor( 'Recentchangeslinked', $this->thispage )->getLocalURL()
                                ];
@@ -1322,11 +1322,11 @@ class SkinTemplate extends Skin {
                        if ( !$user->isAnon() ) {
                                $sur = new UserrightsPage;
                                $sur->setContext( $this->getContext() );
-                               $canChange = $sur->userCanChangeRights( $this->getUser(), false );
+                               $canChange = $sur->userCanChangeRights( $user );
                                $nav_urls['userrights'] = [
                                        'text' => $this->msg(
                                                $canChange ? 'tool-link-userrights' : 'tool-link-userrights-readonly',
-                                               $this->getUser()->getName()
+                                               $rootUser
                                        )->text(),
                                        'href' => self::makeSpecialUrlSubpage( 'Userrights', $rootUser )
                                ];
index 00efeae..00439a1 100644 (file)
@@ -20,6 +20,7 @@
  * @file
  * @ingroup SpecialPage
  */
+use MediaWiki\Logger\LoggerFactory;
 
 /**
  * Special page which uses a ChangesList to show query results.
@@ -77,6 +78,14 @@ abstract class ChangesListSpecialPage extends SpecialPage {
                $this->webOutput( $rows, $opts );
 
                $rows->free();
+
+               if ( $this->getConfig()->get( 'EnableWANCacheReaper' ) ) {
+                       // Clean up any bad page entries for titles showing up in RC
+                       DeferredUpdates::addUpdate( new WANCacheReapUpdate(
+                               $this->getDB(),
+                               LoggerFactory::getInstance( 'objectcache' )
+                       ) );
+               }
        }
 
        /**
index a01e9b2..e7030c5 100644 (file)
@@ -86,7 +86,7 @@ class SpecialActiveUsers extends SpecialPage {
                $groups = User::getAllGroups();
 
                foreach ( $groups as $group ) {
-                       $msg = htmlspecialchars( User::getGroupName( $group ) );
+                       $msg = htmlspecialchars( UserGroupMembership::getGroupName( $group ) );
                        $options[$msg] = $group;
                }
 
index 82f7d08..c18ae0e 100644 (file)
@@ -127,15 +127,7 @@ class SpecialBlock extends FormSpecialPage {
         */
        protected function getFormFields() {
                global $wgBlockAllowsUTEdit;
-               if ( !wfMessage( 'ipbreason-dropdown' )->inContentLanguage()->isDisabled() ) {
-                       $reasonsList = Xml::getArrayFromWikiTextList(
-                               wfMessage( 'ipbreason-dropdown' )->inContentLanguage()->text()
-                       );
-                       $this->getOutput()->addModules( 'mediawiki.reasonSuggest' );
-                       $this->getOutput()->addJsConfigVars( [
-                               'reasons' => $reasonsList
-                       ] );
-               }
+
                $user = $this->getUser();
 
                $suggestedDurations = self::getSuggestedDurations();
@@ -837,7 +829,7 @@ class SpecialBlock extends FormSpecialPage {
                $logEntry->setRelations( [ 'ipb_id' => $blockIds ] );
                $logId = $logEntry->insert();
 
-               if ( count( $data['Tags'] ) ) {
+               if ( !empty( $data['Tags'] ) ) {
                        $logEntry->setTags( $data['Tags'] );
                }
 
index f3d3a77..7a25e55 100644 (file)
@@ -273,12 +273,14 @@ class SpecialListGroupRights extends SpecialPage {
                        } elseif ( is_array( $changeGroup ) ) {
                                $changeGroup = array_intersect( array_values( array_unique( $changeGroup ) ), $allGroups );
                                if ( count( $changeGroup ) ) {
+                                       $groupLinks = [];
+                                       foreach ( $changeGroup as $group ) {
+                                               $groupLinks[] = UserGroupMembership::getLink( $group, $this->getContext(), 'wiki' );
+                                       }
                                        // For grep: listgrouprights-addgroup, listgrouprights-removegroup,
                                        // listgrouprights-addgroup-self, listgrouprights-removegroup-self
                                        $r[] = $this->msg( 'listgrouprights-' . $messageKey,
-                                               $lang->listToText( array_map( [ 'User', 'makeGroupLinkWiki' ], $changeGroup ) ),
-                                               count( $changeGroup )
-                                       )->parse();
+                                               $lang->listToText( $groupLinks ), count( $changeGroup ) )->parse();
                                }
                        }
                }
index 15696bc..52cb30a 100644 (file)
@@ -111,7 +111,8 @@ class MIMEsearchPage extends QueryPage {
        function getPageHeader() {
                $formDescriptor = [
                        'mime' => [
-                               'type' => 'text',
+                               'type' => 'combobox',
+                               'options' => $this->getSuggestionsForTypes(),
                                'name' => 'mime',
                                'label-message' => 'mimetype',
                                'required' => true,
@@ -127,6 +128,33 @@ class MIMEsearchPage extends QueryPage {
                        ->displayForm( false );
        }
 
+       protected function getSuggestionsForTypes() {
+               $dbr = wfGetDB( DB_REPLICA );
+               $lastMajor = null;
+               $suggestions = [];
+               $result = $dbr->select(
+                       [ 'image' ],
+                       // We ignore img_media_type, but using it in the query is needed for MySQL to choose a
+                       // sensible execution plan
+                       [ 'img_media_type', 'img_major_mime', 'img_minor_mime' ],
+                       [],
+                       __METHOD__,
+                       [ 'GROUP BY' => [ 'img_media_type', 'img_major_mime', 'img_minor_mime' ] ]
+               );
+               foreach ( $result as $row ) {
+                       $major = $row->img_major_mime;
+                       $minor = $row->img_minor_mime;
+                       $suggestions[ "$major/$minor" ] = "$major/$minor";
+                       if ( $lastMajor === $major ) {
+                               // If there are at least two with the same major mime type, also include the wildcard
+                               $suggestions[ "$major/*" ] = "$major/*";
+                       }
+                       $lastMajor = $major;
+               }
+               ksort( $suggestions );
+               return $suggestions;
+       }
+
        public function execute( $par ) {
                $this->mime = $par ? $par : $this->getRequest()->getText( 'mime' );
                $this->mime = trim( $this->mime );
index 8ff0527..e503d92 100644 (file)
@@ -36,26 +36,6 @@ class SpecialTrackingCategories extends SpecialPage {
                parent::__construct( 'TrackingCategories' );
        }
 
-       /**
-        * Tracking categories that exist in core
-        *
-        * @var array
-        */
-       private static $coreTrackingCategories = [
-               'index-category',
-               'noindex-category',
-               'duplicate-args-category',
-               'expensive-parserfunction-category',
-               'post-expand-template-argument-category',
-               'post-expand-template-inclusion-category',
-               'hidden-category-category',
-               'broken-file-category',
-               'node-count-exceeded-category',
-               'expansion-depth-exceeded-category',
-               'restricted-displaytitle-ignored',
-               'deprecated-self-close-category',
-       ];
-
        function execute( $par ) {
                $this->setHeaders();
                $this->outputHeader();
@@ -76,10 +56,11 @@ class SpecialTrackingCategories extends SpecialPage {
                        </tr></thead>"
                );
 
-               $trackingCategories = $this->prepareTrackingCategoriesData();
+               $trackingCategories = new TrackingCategories( $this->getConfig() );
+               $categoryList = $trackingCategories->getTrackingCategories();
 
                $batch = new LinkBatch();
-               foreach ( $trackingCategories as $catMsg => $data ) {
+               foreach ( $categoryList as $catMsg => $data ) {
                        $batch->addObj( $data['msg'] );
                        foreach ( $data['cats'] as $catTitle ) {
                                $batch->addObj( $catTitle );
@@ -87,11 +68,11 @@ class SpecialTrackingCategories extends SpecialPage {
                }
                $batch->execute();
 
-               Hooks::run( 'SpecialTrackingCategories::preprocess', [ $this, $trackingCategories ] );
+               Hooks::run( 'SpecialTrackingCategories::preprocess', [ $this, $categoryList ] );
 
                $linkRenderer = $this->getLinkRenderer();
 
-               foreach ( $trackingCategories as $catMsg => $data ) {
+               foreach ( $categoryList as $catMsg => $data ) {
                        $allMsgs = [];
                        $catDesc = $catMsg . '-desc';
 
@@ -143,80 +124,6 @@ class SpecialTrackingCategories extends SpecialPage {
                $this->getOutput()->addHTML( Html::closeElement( 'table' ) );
        }
 
-       /**
-        * Read the global and extract title objects from the corresponding messages
-        * @return array Array( 'msg' => Title, 'cats' => Title[] )
-        */
-       private function prepareTrackingCategoriesData() {
-               $categories = array_merge(
-                       self::$coreTrackingCategories,
-                       ExtensionRegistry::getInstance()->getAttribute( 'TrackingCategories' ),
-                       $this->getConfig()->get( 'TrackingCategories' ) // deprecated
-               );
-
-               // Only show magic link tracking categories if they are enabled
-               $enableMagicLinks = $this->getConfig()->get( 'EnableMagicLinks' );
-               if ( $enableMagicLinks['ISBN'] ) {
-                       $categories[] = 'magiclink-tracking-isbn';
-               }
-               if ( $enableMagicLinks['RFC'] ) {
-                       $categories[] = 'magiclink-tracking-rfc';
-               }
-               if ( $enableMagicLinks['PMID'] ) {
-                       $categories[] = 'magiclink-tracking-pmid';
-               }
-
-               $trackingCategories = [];
-               foreach ( $categories as $catMsg ) {
-                       /*
-                        * Check if the tracking category varies by namespace
-                        * Otherwise only pages in the current namespace will be displayed
-                        * If it does vary, show pages considering all namespaces
-                        */
-                       $msgObj = $this->msg( $catMsg )->inContentLanguage();
-                       $allCats = [];
-                       $catMsgTitle = Title::makeTitleSafe( NS_MEDIAWIKI, $catMsg );
-                       if ( !$catMsgTitle ) {
-                               continue;
-                       }
-
-                       // Match things like {{NAMESPACE}} and {{NAMESPACENUMBER}}.
-                       // False positives are ok, this is just an efficiency shortcut
-                       if ( strpos( $msgObj->plain(), '{{' ) !== false ) {
-                               $ns = MWNamespace::getValidNamespaces();
-                               foreach ( $ns as $namesp ) {
-                                       $tempTitle = Title::makeTitleSafe( $namesp, $catMsg );
-                                       if ( !$tempTitle ) {
-                                               continue;
-                                       }
-                                       $catName = $msgObj->title( $tempTitle )->text();
-                                       # Allow tracking categories to be disabled by setting them to "-"
-                                       if ( $catName !== '-' ) {
-                                               $catTitle = Title::makeTitleSafe( NS_CATEGORY, $catName );
-                                               if ( $catTitle ) {
-                                                       $allCats[] = $catTitle;
-                                               }
-                                       }
-                               }
-                       } else {
-                               $catName = $msgObj->text();
-                               # Allow tracking categories to be disabled by setting them to "-"
-                               if ( $catName !== '-' ) {
-                                       $catTitle = Title::makeTitleSafe( NS_CATEGORY, $catName );
-                                       if ( $catTitle ) {
-                                               $allCats[] = $catTitle;
-                                       }
-                               }
-                       }
-                       $trackingCategories[$catMsg] = [
-                               'cats' => $allCats,
-                               'msg' => $catMsgTitle,
-                       ];
-               }
-
-               return $trackingCategories;
-       }
-
        protected function getGroupName() {
                return 'pages';
        }
index 2cc1a7b..9fcbf15 100644 (file)
@@ -50,8 +50,6 @@ class UnusedimagesPage extends ImageQueryPage {
                                'namespace' => NS_FILE,
                                'title' => 'img_name',
                                'value' => 'img_timestamp',
-                               'img_user', 'img_user_text',
-                               'img_description'
                        ],
                        'conds' => [ 'il_to IS NULL' ],
                        'join_conds' => [ 'imagelinks' => [ 'LEFT JOIN', 'il_to = img_name' ] ]
index 8b8e514..c5a1f27 100644 (file)
@@ -1090,12 +1090,14 @@ class UploadForm extends HTMLForm {
                                global $wgContLang;
 
                                $mto = $file->transform( [ 'width' => 120 ] );
-                               $this->addHeaderText(
-                                       '<div class="thumb t' . $wgContLang->alignEnd() . '">' .
-                                       Html::element( 'img', [
-                                               'src' => $mto->getUrl(),
-                                               'class' => 'thumbimage',
-                                       ] ) . '</div>', 'description' );
+                               if ( $mto ) {
+                                       $this->addHeaderText(
+                                               '<div class="thumb t' . $wgContLang->alignEnd() . '">' .
+                                               Html::element( 'img', [
+                                                       'src' => $mto->getUrl(),
+                                                       'class' => 'thumbimage',
+                                               ] ) . '</div>', 'description' );
+                               }
                        }
                }
 
index 4db2198..b0808f6 100644 (file)
@@ -49,19 +49,25 @@ class UserrightsPage extends SpecialPage {
        }
 
        /**
-        * @param User $user
-        * @param bool $checkIfSelf
+        * Check whether the current user (from context) can change the target user's rights.
+        *
+        * @param User $targetUser User whose rights are being changed
+        * @param bool $checkIfSelf If false, assume that the current user can add/remove groups defined
+        *   in $wgGroupsAddToSelf / $wgGroupsRemoveFromSelf, without checking if it's the same as target
+        *   user
         * @return bool
         */
-       public function userCanChangeRights( $user, $checkIfSelf = true ) {
+       public function userCanChangeRights( $targetUser, $checkIfSelf = true ) {
+               $isself = $this->getUser()->equals( $targetUser );
+
                $available = $this->changeableGroups();
-               if ( $user->getId() == 0 ) {
+               if ( $targetUser->getId() == 0 ) {
                        return false;
                }
 
                return !empty( $available['add'] )
                        || !empty( $available['remove'] )
-                       || ( ( $this->isself || !$checkIfSelf ) &&
+                       || ( ( $isself || !$checkIfSelf ) &&
                                ( !empty( $available['add-self'] )
                                        || !empty( $available['remove-self'] ) ) );
        }
@@ -79,6 +85,8 @@ class UserrightsPage extends SpecialPage {
                $session = $request->getSession();
                $out = $this->getOutput();
 
+               $out->addModules( [ 'mediawiki.special.userrights' ] );
+
                if ( $par !== null ) {
                        $this->mTarget = $par;
                } else {
@@ -111,7 +119,6 @@ class UserrightsPage extends SpecialPage {
                        // Remove session data for the success message
                        $session->remove( 'specialUserrightsSaveSuccess' );
 
-                       $out->addModules( [ 'mediawiki.special.userrights' ] );
                        $out->addModuleStyles( 'mediawiki.notification.convertmessagebox.styles' );
                        $out->addHTML(
                                Html::rawElement(
@@ -172,18 +179,22 @@ class UserrightsPage extends SpecialPage {
                        ) {
                                $out->addWikiMsg( 'userrights-conflict' );
                        } else {
-                               $this->saveUserGroups(
+                               $status = $this->saveUserGroups(
                                        $this->mTarget,
                                        $request->getVal( 'user-reason' ),
                                        $targetUser
                                );
 
-                               // Set session data for the success message
-                               $session->set( 'specialUserrightsSaveSuccess', 1 );
+                               if ( $status->isOK() ) {
+                                       // Set session data for the success message
+                                       $session->set( 'specialUserrightsSaveSuccess', 1 );
 
-                               $out->redirect( $this->getSuccessURL() );
-
-                               return;
+                                       $out->redirect( $this->getSuccessURL() );
+                                       return;
+                               } else {
+                                       // Print an error message and redisplay the form
+                                       $out->addWikiText( '<div class="error">' . $status->getWikiText() . '</div>' );
+                               }
                        }
                }
 
@@ -197,6 +208,41 @@ class UserrightsPage extends SpecialPage {
                return $this->getPageTitle( $this->mTarget )->getFullURL();
        }
 
+       /**
+        * Returns true if this user rights form can set and change user group expiries.
+        * Subclasses may wish to override this to return false.
+        *
+        * @return bool
+        */
+       public function canProcessExpiries() {
+               return !$this->getConfig()->get( 'DisableUserGroupExpiry' );
+       }
+
+       /**
+        * Converts a user group membership expiry string into a timestamp. Words like
+        * 'existing' or 'other' should have been filtered out before calling this
+        * function.
+        *
+        * @param string $expiry
+        * @return string|null|false A string containing a valid timestamp, or null
+        *   if the expiry is infinite, or false if the timestamp is not valid
+        */
+       public static function expiryToTimestamp( $expiry ) {
+               if ( wfIsInfinity( $expiry ) ) {
+                       return null;
+               }
+
+               $unix = strtotime( $expiry );
+
+               if ( !$unix || $unix === -1 ) {
+                       return false;
+               }
+
+               // @todo FIXME: Non-qualified absolute times are not in users specified timezone
+               // and there isn't notice about it in the ui (see ProtectionForm::getExpiry)
+               return wfTimestamp( TS_MW, $unix );
+       }
+
        /**
         * Save user groups changes in the database.
         * Data comes from the editUserGroupsForm() form function
@@ -204,11 +250,12 @@ class UserrightsPage extends SpecialPage {
         * @param string $username Username to apply changes to.
         * @param string $reason Reason for group change
         * @param User|UserRightsProxy $user Target user object.
-        * @return null
+        * @return Status
         */
-       function saveUserGroups( $username, $reason, $user ) {
+       protected function saveUserGroups( $username, $reason, $user ) {
                $allgroups = $this->getAllGroups();
                $addgroup = [];
+               $groupExpiries = []; // associative array of (group name => expiry)
                $removegroup = [];
 
                // This could possibly create a highly unlikely race condition if permissions are changed between
@@ -218,12 +265,38 @@ class UserrightsPage extends SpecialPage {
                        // Later on, this gets filtered for what can actually be removed
                        if ( $this->getRequest()->getCheck( "wpGroup-$group" ) ) {
                                $addgroup[] = $group;
+
+                               if ( $this->canProcessExpiries() ) {
+                                       // read the expiry information from the request
+                                       $expiryDropdown = $this->getRequest()->getVal( "wpExpiry-$group" );
+                                       if ( $expiryDropdown === 'other' ) {
+                                               $expiryValue = $this->getRequest()->getVal( "wpExpiry-$group-other" );
+                                       } elseif ( $expiryDropdown !== 'existing' ) {
+                                               $expiryValue = $expiryDropdown;
+                                       } else {
+                                               continue;
+                                       }
+
+                                       // validate the expiry
+                                       $groupExpiries[$group] = self::expiryToTimestamp( $expiryValue );
+
+                                       if ( $groupExpiries[$group] === false ) {
+                                               return Status::newFatal( 'userrights-invalid-expiry', $group );
+                                       }
+
+                                       // not allowed to have things expiring in the past
+                                       if ( $groupExpiries[$group] && $groupExpiries[$group] < wfTimestampNow() ) {
+                                               return Status::newFatal( 'userrights-expiry-in-past', $group );
+                                       }
+                               }
                        } else {
                                $removegroup[] = $group;
                        }
                }
 
-               $this->doSaveUserGroups( $user, $addgroup, $removegroup, $reason );
+               $this->doSaveUserGroups( $user, $addgroup, $removegroup, $reason, [], $groupExpiries );
+
+               return Status::newGood();
        }
 
        /**
@@ -234,9 +307,13 @@ class UserrightsPage extends SpecialPage {
         * @param array $remove Array of groups to remove
         * @param string $reason Reason for group change
         * @param array $tags Array of change tags to add to the log entry
+        * @param array $groupExpiries Associative array of (group name => expiry),
+        *   containing only those groups that are to have new expiry values set
         * @return array Tuple of added, then removed groups
         */
-       function doSaveUserGroups( $user, $add, $remove, $reason = '', $tags = [] ) {
+       function doSaveUserGroups( $user, $add, $remove, $reason = '', $tags = [],
+               $groupExpiries = [] ) {
+
                // Validate input set...
                $isself = $user->getName() == $this->getUser()->getName();
                $groups = $user->getGroups();
@@ -246,17 +323,21 @@ class UserrightsPage extends SpecialPage {
 
                $remove = array_unique(
                        array_intersect( (array)$remove, $removable, $groups ) );
-               $add = array_unique( array_diff(
-                       array_intersect( (array)$add, $addable ),
-                       $groups )
-               );
+               $add = array_intersect( (array)$add, $addable );
+
+               // add only groups that are not already present or that need their expiry updated
+               $add = array_filter( $add,
+                       function( $group ) use ( $groups, $groupExpiries ) {
+                               return !in_array( $group, $groups ) || array_key_exists( $group, $groupExpiries );
+                       } );
 
                Hooks::run( 'ChangeUserGroups', [ $this->getUser(), $user, &$add, &$remove ] );
 
-               $oldGroups = $user->getGroups();
+               $oldGroups = $groups;
+               $oldUGMs = $user->getGroupMemberships();
                $newGroups = $oldGroups;
 
-               // Remove then add groups
+               // Remove groups, then add new ones/update expiries of existing ones
                if ( $remove ) {
                        foreach ( $remove as $index => $group ) {
                                if ( !$user->removeGroup( $group ) ) {
@@ -267,13 +348,15 @@ class UserrightsPage extends SpecialPage {
                }
                if ( $add ) {
                        foreach ( $add as $index => $group ) {
-                               if ( !$user->addGroup( $group ) ) {
+                               $expiry = isset( $groupExpiries[$group] ) ? $groupExpiries[$group] : null;
+                               if ( !$user->addGroup( $group, $expiry ) ) {
                                        unset( $add[$index] );
                                }
                        }
                        $newGroups = array_merge( $newGroups, $add );
                }
                $newGroups = array_unique( $newGroups );
+               $newUGMs = $user->getGroupMemberships();
 
                // Ensure that caches are cleared
                $user->invalidateCache();
@@ -286,25 +369,59 @@ class UserrightsPage extends SpecialPage {
 
                wfDebug( 'oldGroups: ' . print_r( $oldGroups, true ) . "\n" );
                wfDebug( 'newGroups: ' . print_r( $newGroups, true ) . "\n" );
+               wfDebug( 'oldUGMs: ' . print_r( $oldUGMs, true ) . "\n" );
+               wfDebug( 'newUGMs: ' . print_r( $newUGMs, true ) . "\n" );
                // Deprecated in favor of UserGroupsChanged hook
                Hooks::run( 'UserRights', [ &$user, $add, $remove ], '1.26' );
 
-               if ( $newGroups != $oldGroups ) {
-                       $this->addLogEntry( $user, $oldGroups, $newGroups, $reason, $tags );
+               // Only add a log entry if something actually changed
+               if ( $newGroups != $oldGroups || $newUGMs != $oldUGMs ) {
+                       $this->addLogEntry( $user, $oldGroups, $newGroups, $reason, $tags, $oldUGMs, $newUGMs );
                }
 
                return [ $add, $remove ];
        }
 
+       /**
+        * Serialise a UserGroupMembership object for storage in the log_params section
+        * of the logging table. Only keeps essential data, removing redundant fields.
+        *
+        * @param UserGroupMembership|null $ugm May be null if things get borked
+        * @return array
+        */
+       protected static function serialiseUgmForLog( $ugm ) {
+               if ( !$ugm instanceof UserGroupMembership ) {
+                       return null;
+               }
+               return [ 'expiry' => $ugm->getExpiry() ];
+       }
+
        /**
         * Add a rights log entry for an action.
-        * @param User $user
+        * @param User|UserRightsProxy $user
         * @param array $oldGroups
         * @param array $newGroups
         * @param array $reason
-        * @param array $tags
+        * @param array $tags Change tags for the log entry
+        * @param array $oldUGMs Associative array of (group name => UserGroupMembership)
+        * @param array $newUGMs Associative array of (group name => UserGroupMembership)
         */
-       function addLogEntry( $user, $oldGroups, $newGroups, $reason, $tags ) {
+       protected function addLogEntry( $user, $oldGroups, $newGroups, $reason, $tags,
+               $oldUGMs, $newUGMs ) {
+
+               // make sure $oldUGMs and $newUGMs are in the same order, and serialise
+               // each UGM object to a simplified array
+               $oldUGMs = array_map( function( $group ) use ( $oldUGMs ) {
+                       return isset( $oldUGMs[$group] ) ?
+                               self::serialiseUgmForLog( $oldUGMs[$group] ) :
+                               null;
+               }, $oldGroups );
+               $newUGMs = array_map( function( $group ) use ( $newUGMs ) {
+                       return isset( $newUGMs[$group] ) ?
+                               self::serialiseUgmForLog( $newUGMs[$group] ) :
+                               null;
+               }, $newGroups );
+
                $logEntry = new ManualLogEntry( 'rights', 'rights' );
                $logEntry->setPerformer( $this->getUser() );
                $logEntry->setTarget( $user->getUserPage() );
@@ -312,6 +429,8 @@ class UserrightsPage extends SpecialPage {
                $logEntry->setParameters( [
                        '4::oldgroups' => $oldGroups,
                        '5::newgroups' => $newGroups,
+                       'oldmetadata' => $oldUGMs,
+                       'newmetadata' => $newUGMs,
                ] );
                $logid = $logEntry->insert();
                if ( count( $tags ) ) {
@@ -335,8 +454,8 @@ class UserrightsPage extends SpecialPage {
                }
 
                $groups = $user->getGroups();
-
-               $this->showEditUserGroupsForm( $user, $groups );
+               $groupMemberships = $user->getGroupMemberships();
+               $this->showEditUserGroupsForm( $user, $groups, $groupMemberships );
 
                // This isn't really ideal logging behavior, but let's not hide the
                // interwiki logs if we're using them as is.
@@ -465,62 +584,51 @@ class UserrightsPage extends SpecialPage {
                );
        }
 
-       /**
-        * Go through used and available groups and return the ones that this
-        * form will be able to manipulate based on the current user's system
-        * permissions.
-        *
-        * @param array $groups List of groups the given user is in
-        * @return array Tuple of addable, then removable groups
-        */
-       protected function splitGroups( $groups ) {
-               list( $addable, $removable, $addself, $removeself ) = array_values( $this->changeableGroups() );
-
-               $removable = array_intersect(
-                       array_merge( $this->isself ? $removeself : [], $removable ),
-                       $groups
-               ); // Can't remove groups the user doesn't have
-               $addable = array_diff(
-                       array_merge( $this->isself ? $addself : [], $addable ),
-                       $groups
-               ); // Can't add groups the user does have
-
-               return [ $addable, $removable ];
-       }
-
        /**
         * Show the form to edit group memberships.
         *
         * @param User|UserRightsProxy $user User or UserRightsProxy you're editing
-        * @param array $groups Array of groups the user is in
+        * @param array $groups Array of groups the user is in. Not used by this implementation
+        *   anymore, but kept for backward compatibility with subclasses
+        * @param array $groupMemberships Associative array of (group name => UserGroupMembership
+        *   object) containing the groups the user is in
         */
-       protected function showEditUserGroupsForm( $user, $groups ) {
-               $list = [];
-               $membersList = [];
-               foreach ( $groups as $group ) {
-                       $list[] = self::buildGroupLink( $group );
-                       $membersList[] = self::buildGroupMemberLink( $group );
+       protected function showEditUserGroupsForm( $user, $groups, $groupMemberships ) {
+               $list = $membersList = $tempList = $tempMembersList = [];
+               foreach ( $groupMemberships as $ugm ) {
+                       $linkG = UserGroupMembership::getLink( $ugm, $this->getContext(), 'html' );
+                       $linkM = UserGroupMembership::getLink( $ugm, $this->getContext(), 'html',
+                               $user->getName() );
+                       if ( $ugm->getExpiry() ) {
+                               $tempList[] = $linkG;
+                               $tempMembersList[] = $linkM;
+                       } else {
+                               $list[] = $linkG;
+                               $membersList[] = $linkM;
+
+                       }
                }
 
                $autoList = [];
                $autoMembersList = [];
                if ( $user instanceof User ) {
                        foreach ( Autopromote::getAutopromoteGroups( $user ) as $group ) {
-                               $autoList[] = self::buildGroupLink( $group );
-                               $autoMembersList[] = self::buildGroupMemberLink( $group );
+                               $autoList[] = UserGroupMembership::getLink( $group, $this->getContext(), 'html' );
+                               $autoMembersList[] = UserGroupMembership::getLink( $group, $this->getContext(),
+                                       'html', $user->getName() );
                        }
                }
 
                $language = $this->getLanguage();
                $displayedList = $this->msg( 'userrights-groupsmember-type' )
                        ->rawParams(
-                               $language->listToText( $list ),
-                               $language->listToText( $membersList )
+                               $language->commaList( array_merge( $tempList, $list ) ),
+                               $language->commaList( array_merge( $tempMembersList, $membersList ) )
                        )->escaped();
                $displayedAutolist = $this->msg( 'userrights-groupsmember-type' )
                        ->rawParams(
-                               $language->listToText( $autoList ),
-                               $language->listToText( $autoMembersList )
+                               $language->commaList( $autoList ),
+                               $language->commaList( $autoMembersList )
                        )->escaped();
 
                $grouplist = '';
@@ -549,7 +657,8 @@ class UserrightsPage extends SpecialPage {
                        Linker::TOOL_LINKS_EMAIL /* Add "send e-mail" link */
                );
 
-               list( $groupCheckboxes, $canChangeAny ) = $this->groupCheckboxes( $groups, $user );
+               list( $groupCheckboxes, $canChangeAny ) =
+                       $this->groupCheckboxes( $groupMemberships, $user );
                $this->getOutput()->addHTML(
                        Xml::openElement(
                                'form',
@@ -615,26 +724,6 @@ class UserrightsPage extends SpecialPage {
                );
        }
 
-       /**
-        * Format a link to a group description page
-        *
-        * @param string $group
-        * @return string
-        */
-       private static function buildGroupLink( $group ) {
-               return User::makeGroupLinkHTML( $group, User::getGroupName( $group ) );
-       }
-
-       /**
-        * Format a link to a group member description page
-        *
-        * @param string $group
-        * @return string
-        */
-       private static function buildGroupMemberLink( $group ) {
-               return User::makeGroupLinkHTML( $group, User::getGroupMember( $group ) );
-       }
-
        /**
         * Returns an array of all groups that may be edited
         * @return array Array of groups that may be edited.
@@ -646,8 +735,8 @@ class UserrightsPage extends SpecialPage {
        /**
         * Adds a table with checkboxes where you can select what groups to add/remove
         *
-        * @todo Just pass the username string?
-        * @param array $usergroups Groups the user belongs to
+        * @param array $usergroups Associative array of (group name as string =>
+        *   UserGroupMembership object) for groups the user belongs to
         * @param User $user
         * @return Array with 2 elements: the XHTML table element with checkxboes, and
         * whether any groups are changeable
@@ -656,12 +745,18 @@ class UserrightsPage extends SpecialPage {
                $allgroups = $this->getAllGroups();
                $ret = '';
 
+               // Get the list of preset expiry times from the system message
+               $expiryOptionsMsg = $this->msg( 'userrights-expiry-options' )->inContentLanguage();
+               $expiryOptions = $expiryOptionsMsg->isDisabled() ?
+                       [] :
+                       explode( ',', $expiryOptionsMsg->text() );
+
                // Put all column info into an associative array so that extensions can
                // more easily manage it.
                $columns = [ 'unchangeable' => [], 'changeable' => [] ];
 
                foreach ( $allgroups as $group ) {
-                       $set = in_array( $group, $usergroups );
+                       $set = isset( $usergroups[$group] );
                        // Should the checkbox be disabled?
                        $disabled = !(
                                ( $set && $this->canRemove( $group ) ) ||
@@ -708,7 +803,7 @@ class UserrightsPage extends SpecialPage {
                        foreach ( $column as $group => $checkbox ) {
                                $attr = $checkbox['disabled'] ? [ 'disabled' => 'disabled' ] : [];
 
-                               $member = User::getGroupMember( $group, $user->getName() );
+                               $member = UserGroupMembership::getGroupMemberName( $group, $user->getName() );
                                if ( $checkbox['irreversible'] ) {
                                        $text = $this->msg( 'userrights-irreversible-marker', $member )->text();
                                } else {
@@ -717,9 +812,91 @@ class UserrightsPage extends SpecialPage {
                                $checkboxHtml = Xml::checkLabel( $text, "wpGroup-" . $group,
                                        "wpGroup-" . $group, $checkbox['set'], $attr );
                                $ret .= "\t\t" . ( $checkbox['disabled']
-                                       ? Xml::tags( 'span', [ 'class' => 'mw-userrights-disabled' ], $checkboxHtml )
-                                       : $checkboxHtml
-                               ) . "<br />\n";
+                                       ? Xml::tags( 'div', [ 'class' => 'mw-userrights-disabled' ], $checkboxHtml )
+                                       : Xml::tags( 'div', [], $checkboxHtml )
+                               ) . "\n";
+
+                               if ( $this->canProcessExpiries() ) {
+                                       $uiUser = $this->getUser();
+                                       $uiLanguage = $this->getLanguage();
+
+                                       $currentExpiry = isset( $usergroups[$group] ) ?
+                                               $usergroups[$group]->getExpiry() :
+                                               null;
+
+                                       // If the user can't uncheck this checkbox, print the current expiry below
+                                       // it in plain text. Otherwise provide UI to set/change the expiry
+                                       if ( $checkbox['set'] && ( $checkbox['irreversible'] || $checkbox['disabled'] ) ) {
+                                               if ( $currentExpiry ) {
+                                                       $expiryFormatted = $uiLanguage->userTimeAndDate( $currentExpiry, $uiUser );
+                                                       $expiryFormattedD = $uiLanguage->userDate( $currentExpiry, $uiUser );
+                                                       $expiryFormattedT = $uiLanguage->userTime( $currentExpiry, $uiUser );
+                                                       $expiryHtml = $this->msg( 'userrights-expiry-current' )->params(
+                                                               $expiryFormatted, $expiryFormattedD, $expiryFormattedT )->text();
+                                               } else {
+                                                       $expiryHtml = $this->msg( 'userrights-expiry-none' )->text();
+                                               }
+                                               $expiryHtml .= "<br />\n";
+                                       } else {
+                                               $expiryHtml = Xml::element( 'span', null,
+                                                       $this->msg( 'userrights-expiry' )->text() );
+                                               $expiryHtml .= Xml::openElement( 'span' );
+
+                                               // add a form element to set the expiry date
+                                               $expiryFormOptions = new XmlSelect(
+                                                       "wpExpiry-$group",
+                                                       "mw-input-wpExpiry-$group", // forward compatibility with HTMLForm
+                                                       $currentExpiry ? 'existing' : 'infinite'
+                                               );
+                                               if ( $checkbox['disabled'] ) {
+                                                       $expiryFormOptions->setAttribute( 'disabled', 'disabled' );
+                                               }
+
+                                               if ( $currentExpiry ) {
+                                                       $timestamp = $uiLanguage->userTimeAndDate( $currentExpiry, $uiUser );
+                                                       $d = $uiLanguage->userDate( $currentExpiry, $uiUser );
+                                                       $t = $uiLanguage->userTime( $currentExpiry, $uiUser );
+                                                       $existingExpiryMessage = $this->msg( 'userrights-expiry-existing',
+                                                               $timestamp, $d, $t );
+                                                       $expiryFormOptions->addOption( $existingExpiryMessage->text(), 'existing' );
+                                               }
+
+                                               $expiryFormOptions->addOption(
+                                                       $this->msg( 'userrights-expiry-none' )->text(),
+                                                       'infinite'
+                                               );
+                                               $expiryFormOptions->addOption(
+                                                       $this->msg( 'userrights-expiry-othertime' )->text(),
+                                                       'other'
+                                               );
+                                               foreach ( $expiryOptions as $option ) {
+                                                       if ( strpos( $option, ":" ) === false ) {
+                                                               $displayText = $value = $option;
+                                                       } else {
+                                                               list( $displayText, $value ) = explode( ":", $option );
+                                                       }
+                                                       $expiryFormOptions->addOption( $displayText, htmlspecialchars( $value ) );
+                                               }
+
+                                               // Add expiry dropdown
+                                               $expiryHtml .= $expiryFormOptions->getHTML() . '<br />';
+
+                                               // Add custom expiry field
+                                               $attribs = [ 'id' => "mw-input-wpExpiry-$group-other" ];
+                                               if ( $checkbox['disabled'] ) {
+                                                       $attribs['disabled'] = 'disabled';
+                                               }
+                                               $expiryHtml .= Xml::input( "wpExpiry-$group-other", 30, '', $attribs );
+
+                                               $expiryHtml .= Xml::closeElement( 'span' );
+                                       }
+
+                                       $divAttribs = [
+                                               'id' => "mw-userrights-nested-wpGroup-$group",
+                                               'class' => 'mw-userrights-nested',
+                                       ];
+                                       $ret .= "\t\t\t" . Xml::tags( 'div', $divAttribs, $expiryHtml ) . "\n";
+                               }
                        }
                        $ret .= "\t</td>\n";
                }
index 645a115..e2f4d4b 100644 (file)
@@ -101,12 +101,17 @@ class ActiveUsersPager extends UsersPager {
                        $tables[] = 'user_groups';
                        $conds[] = 'ug_user = user_id';
                        $conds['ug_group'] = $this->groups;
+                       $conds[] = 'ug_expiry IS NULL OR ug_expiry >= ' . $dbr->addQuotes( $dbr->timestamp() );
                }
                if ( $this->excludegroups !== [] ) {
                        foreach ( $this->excludegroups as $group ) {
                                $conds[] = 'NOT EXISTS (' . $dbr->selectSQLText(
-                                               'user_groups', '1', [ 'ug_user = user_id', 'ug_group' => $group ]
-                                       ) . ')';
+                                       'user_groups', '1', [
+                                               'ug_user = user_id',
+                                               'ug_group' => $group,
+                                               'ug_expiry IS NULL OR ug_expiry >= ' . $dbr->addQuotes( $dbr->timestamp() )
+                                       ]
+                               ) . ')';
                        }
                }
                if ( !$this->getUser()->isAllowed( 'hideuser' ) ) {
@@ -165,9 +170,9 @@ class ActiveUsersPager extends UsersPager {
                $list = [];
                $user = User::newFromId( $row->user_id );
 
-               $groups_list = self::getGroups( intval( $row->user_id ), $this->userGroupCache );
-               foreach ( $groups_list as $group ) {
-                       $list[] = self::buildGroupLink( $group, $userName );
+               $ugms = self::getGroupMemberships( intval( $row->user_id ), $this->userGroupCache );
+               foreach ( $ugms as $ugm ) {
+                       $list[] = $this->buildGroupLink( $ugm, $userName );
                }
 
                $groups = $lang->commaList( $list );
index 345577d..7db90c1 100644 (file)
@@ -92,21 +92,24 @@ class CategoryPager extends AlphabeticPager {
        }
 
        public function getStartForm( $from ) {
-               return Xml::tags(
-                       'form',
-                       [ 'method' => 'get', 'action' => wfScript() ],
-                       Html::hidden( 'title', $this->getTitle()->getPrefixedText() ) .
-                       Xml::fieldset(
-                               $this->msg( 'categories' )->text(),
-                               Xml::inputLabel(
-                                       $this->msg( 'categoriesfrom' )->text(),
-                                       'from', 'from', 20, $from, [ 'class' => 'mw-ui-input-inline' ] ) .
-                               ' ' .
-                               Html::submitButton(
-                                       $this->msg( 'categories-submit' )->text(),
-                                       [], [ 'mw-ui-progressive' ]
-                               )
-                       )
-               );
+               $formDescriptor = [
+                       'from' => [
+                               'type' => 'title',
+                               'namespace' => NS_CATEGORY,
+                               'relative' => true,
+                               'label-message' => 'categoriesfrom',
+                               'name' => 'from',
+                               'id' => 'from',
+                               'size' => 20,
+                               'default' => $from,
+                       ],
+               ];
+
+               $htmlForm = HTMLForm::factory( 'ooui', $formDescriptor, $this->getContext() )
+                       ->setSubmitTextMsg( 'categories-submit' )
+                       ->setWrapperLegendMsg( 'categories' )
+                       ->setMethod( 'get' );
+               return $htmlForm->prepareForm()->getHTML( false );
        }
+
 }
index 39c55c8..3993f62 100644 (file)
@@ -222,7 +222,8 @@ class ContribsPager extends ReverseChronologicalPager {
                                $join_conds['user_groups'] = [
                                        'LEFT JOIN', [
                                                'ug_user = rev_user',
-                                               'ug_group' => $groupsWithBotPermission
+                                               'ug_group' => $groupsWithBotPermission,
+                                               'ug_expiry IS NULL OR ug_expiry >= ' . $this->mDb->addQuotes( $this->mDb->timestamp() )
                                        ]
                                ];
                        }
index e22b939..76f90bd 100644 (file)
@@ -59,13 +59,15 @@ class NewFilesPager extends ReverseChronologicalPager {
                        $groupsWithBotPermission = User::getGroupsWithPermission( 'bot' );
 
                        if ( count( $groupsWithBotPermission ) ) {
+                               $dbr = wfGetDB( DB_REPLICA );
                                $tables[] = 'user_groups';
                                $conds[] = 'ug_group IS NULL';
                                $jconds['user_groups'] = [
                                        'LEFT JOIN',
                                        [
                                                'ug_group' => $groupsWithBotPermission,
-                                               'ug_user = img_user'
+                                               'ug_user = img_user',
+                                               'ug_expiry IS NULL OR ug_expiry >= ' . $dbr->addQuotes( $dbr->timestamp() )
                                        ]
                                ];
                        }
index 901be38..da3a30b 100644 (file)
@@ -112,6 +112,7 @@ class UsersPager extends AlphabeticPager {
 
                if ( $this->requestedGroup != '' ) {
                        $conds['ug_group'] = $this->requestedGroup;
+                       $conds[] = 'ug_expiry IS NULL OR ug_expiry >= ' . $dbr->addQuotes( $dbr->timestamp() );
                }
 
                if ( $this->requestedUser != '' ) {
@@ -177,12 +178,12 @@ class UsersPager extends AlphabeticPager {
                $lang = $this->getLanguage();
 
                $groups = '';
-               $groups_list = self::getGroups( intval( $row->user_id ), $this->userGroupCache );
+               $ugms = self::getGroupMemberships( intval( $row->user_id ), $this->userGroupCache );
 
-               if ( !$this->including && count( $groups_list ) > 0 ) {
+               if ( !$this->including && count( $ugms ) > 0 ) {
                        $list = [];
-                       foreach ( $groups_list as $group ) {
-                               $list[] = self::buildGroupLink( $group, $userName );
+                       foreach ( $ugms as $ugm ) {
+                               $list[] = $this->buildGroupLink( $ugm, $userName );
                        }
                        $groups = $lang->commaList( $list );
                }
@@ -231,15 +232,18 @@ class UsersPager extends AlphabeticPager {
                $dbr = wfGetDB( DB_REPLICA );
                $groupRes = $dbr->select(
                        'user_groups',
-                       [ 'ug_user', 'ug_group' ],
+                       UserGroupMembership::selectFields(),
                        [ 'ug_user' => $userIds ],
                        __METHOD__
                );
                $cache = [];
                $groups = [];
                foreach ( $groupRes as $row ) {
-                       $cache[intval( $row->ug_user )][] = $row->ug_group;
-                       $groups[$row->ug_group] = true;
+                       $ugm = UserGroupMembership::newFromRow( $row );
+                       if ( !$ugm->isExpired() ) {
+                               $cache[$row->ug_user][$row->ug_group] = $ugm;
+                               $groups[$row->ug_group] = true;
+                       }
                }
 
                // Give extensions a chance to add things like global user group data
@@ -250,7 +254,7 @@ class UsersPager extends AlphabeticPager {
 
                // Add page of groups to link batch
                foreach ( $groups as $group => $unused ) {
-                       $groupPage = User::getGroupPage( $group );
+                       $groupPage = UserGroupMembership::getGroupPage( $group );
                        if ( $groupPage ) {
                                $batch->addObj( $groupPage );
                        }
@@ -340,7 +344,7 @@ class UsersPager extends AlphabeticPager {
        function getAllGroups() {
                $result = [];
                foreach ( User::getAllGroups() as $group ) {
-                       $result[$group] = User::getGroupName( $group );
+                       $result[$group] = UserGroupMembership::getGroupName( $group );
                }
                asort( $result );
 
@@ -365,36 +369,30 @@ class UsersPager extends AlphabeticPager {
        }
 
        /**
-        * Get a list of groups the specified user belongs to
+        * Get an associative array containing groups the specified user belongs to,
+        * and the relevant UserGroupMembership objects
         *
         * @param int $uid User id
         * @param array|null $cache
-        * @return array
+        * @return array (group name => UserGroupMembership object)
         */
-       protected static function getGroups( $uid, $cache = null ) {
+       protected static function getGroupMemberships( $uid, $cache = null ) {
                if ( $cache === null ) {
                        $user = User::newFromId( $uid );
-                       $effectiveGroups = $user->getEffectiveGroups();
+                       return $user->getGroupMemberships();
                } else {
-                       $effectiveGroups = isset( $cache[$uid] ) ? $cache[$uid] : [];
+                       return isset( $cache[$uid] ) ? $cache[$uid] : [];
                }
-               $groups = array_diff( $effectiveGroups, User::getImplicitGroups() );
-
-               return $groups;
        }
 
        /**
         * Format a link to a group description page
         *
-        * @param string $group Group name
+        * @param string|UserGroupMembership $group Group name or UserGroupMembership object
         * @param string $username Username
         * @return string
         */
-       protected static function buildGroupLink( $group, $username ) {
-               return User::makeGroupLinkHTML(
-                       $group,
-                       User::getGroupMember( $group, $username )
-               );
+       protected function buildGroupLink( $group, $username ) {
+               return UserGroupMembership::getLink( $group, $this->getContext(), 'html', $username );
        }
-
 }
index 95cbe09..8da1553 100644 (file)
@@ -75,7 +75,7 @@ class BalanceSets {
                self::HTML_NAMESPACE => [
                        'html' => true, 'head' => true, 'body' => true, 'frameset' => true,
                        'frame' => true,
-                       'plaintext' => true, 'isindex' => true,
+                       'plaintext' => true,
                        'xmp' => true, 'iframe' => true, 'noembed' => true,
                        'noscript' => true, 'script' => true,
                        'title' => true
@@ -119,9 +119,9 @@ class BalanceSets {
                        'h2' => true, 'h3' => true, 'h4' => true, 'h5' => true,
                        'h6' => true, 'head' => true, 'header' => true, 'hgroup' => true,
                        'hr' => true, 'html' => true, 'iframe' => true, 'img' => true,
-                       'input' => true, 'isindex' => true, 'li' => true, 'link' => true,
+                       'input' => true, 'li' => true, 'link' => true,
                        'listing' => true, 'main' => true, 'marquee' => true,
-                       'menu' => true, 'menuitem' => true, 'meta' => true, 'nav' => true,
+                       'menu' => true, 'meta' => true, 'nav' => true,
                        'noembed' => true, 'noframes' => true, 'noscript' => true,
                        'object' => true, 'ol' => true, 'p' => true, 'param' => true,
                        'plaintext' => true, 'pre' => true, 'script' => true,
@@ -156,7 +156,8 @@ class BalanceSets {
 
        public static $impliedEndTagsSet = [
                self::HTML_NAMESPACE => [
-                       'dd' => true, 'dt' => true, 'li' => true, 'optgroup' => true,
+                       'dd' => true, 'dt' => true, 'li' => true,
+                       'menuitem' => true, 'optgroup' => true,
                        'option' => true, 'p' => true, 'rb' => true, 'rp' => true,
                        'rt' => true, 'rtc' => true
                ]
@@ -498,6 +499,16 @@ class BalanceElement {
                                        $this->attribs = [ 'class' => "mw-empty-elt" ];
                                }
                                $blank = false;
+                       } elseif (
+                               $this->isA( BalanceSets::$extraLinefeedSet ) &&
+                               count( $this->children ) > 0 &&
+                               substr( $this->children[0], 0, 1 ) == "\n"
+                       ) {
+                               // Double the linefeed after pre/listing/textarea
+                               // according to the (old) HTML5 fragment serialization
+                               // algorithm (see https://github.com/whatwg/html/issues/944)
+                               // to ensure this will round-trip.
+                               array_unshift( $this->children, "\n" );
                        }
                        $flat = $blank ? '' : "{$this}";
                } else {
@@ -529,15 +540,6 @@ class BalanceElement {
                                $out .= "{$elt}";
                        }
                        $out .= "</{$this->localName}>";
-                       if (
-                               $this->isA( BalanceSets::$extraLinefeedSet ) &&
-                               $out[$len] === "\n"
-                       ) {
-                               // Double the linefeed after pre/listing/textarea
-                               // according to the HTML5 fragment serialization algorithm.
-                               $out = substr( $out, 0, $len + 1 ) .
-                                       substr( $out, $len );
-                       }
                } else {
                        $out = "<{$this->localName}{$encAttribs} />";
                        Assert::invariant(
@@ -1770,7 +1772,7 @@ class BalanceActiveFormattingElements {
  *   and escaped.
  * - All null characters are assumed to have been removed.
  * - The following elements are disallowed: <html>, <head>, <body>, <frameset>,
- *   <frame>, <plaintext>, <isindex>, <xmp>, <iframe>,
+ *   <frame>, <plaintext>, <xmp>, <iframe>,
  *   <noembed>, <noscript>, <script>, <title>.  As a result,
  *   further simplifications can be made:
  *   - `frameset-ok` is not tracked.
@@ -1865,7 +1867,9 @@ class Balancer {
         *         provide historical compatibility with the old "tidy"
         *         program: <p>-wrapping is done to the children of
         *         <body> and <blockquote> elements, and empty elements
-        *         are removed.
+        *         are removed.  The <pre>/<listing>/<textarea> serialization
+        *         is also tweaked to allow lossless round trips.
+        *         (See: https://github.com/whatwg/html/issues/944)
         *     'allowComments': boolean, defaults to true.
         *         When true, allows HTML comments in the input.
         *         The Sanitizer generally strips all comments, so if you
@@ -1997,6 +2001,7 @@ class Balancer {
                // Some hoops we have to jump through
                $adjusted = $this->stack->adjustedCurrentNode( $this->fragmentContext );
 
+               // The spec calls this the "tree construction dispatcher".
                $isForeign = true;
                if (
                        $this->stack->length() === 0 ||
@@ -2037,6 +2042,9 @@ class Balancer {
                if ( $token === 'text' ) {
                        $this->stack->insertText( $value );
                        return true;
+               } elseif ( $token === 'comment' ) {
+                       $this->stack->insertComment( $value );
+                       return true;
                } elseif ( $token === 'tag' ) {
                        switch ( $value ) {
                        case 'font':
@@ -2468,7 +2476,6 @@ class Balancer {
                        case 'header':
                        case 'hgroup':
                        case 'main':
-                       case 'menu':
                        case 'nav':
                        case 'ol':
                        case 'p':
@@ -2481,6 +2488,16 @@ class Balancer {
                                $this->stack->insertHTMLElement( $value, $attribs );
                                return true;
 
+                       case 'menu':
+                               if ( $this->stack->inButtonScope( "p" ) ) {
+                                       $this->inBodyMode( 'endtag', 'p' );
+                               }
+                               if ( $this->stack->currentNode->isHtmlNamed( 'menuitem' ) ) {
+                                       $this->stack->pop();
+                               }
+                               $this->stack->insertHTMLElement( $value, $attribs );
+                               return true;
+
                        case 'h1':
                        case 'h2':
                        case 'h3':
@@ -2656,7 +2673,6 @@ class Balancer {
                                // (hence we don't need to examine the tag's "type" attribute)
                                return true;
 
-                       case 'menuitem':
                        case 'param':
                        case 'source':
                        case 'track':
@@ -2668,6 +2684,9 @@ class Balancer {
                                if ( $this->stack->inButtonScope( 'p' ) ) {
                                        $this->inBodyMode( 'endtag', 'p' );
                                }
+                               if ( $this->stack->currentNode->isHtmlNamed( 'menuitem' ) ) {
+                                       $this->stack->pop();
+                               }
                                $this->stack->insertHTMLElement( $value, $attribs );
                                $this->stack->pop();
                                return true;
@@ -2676,8 +2695,6 @@ class Balancer {
                                // warts!
                                return $this->inBodyMode( $token, 'img', $attribs, $selfClose );
 
-                       // OMITTED: <isindex>
-
                        case 'textarea':
                                $this->stack->insertHTMLElement( $value, $attribs );
                                $this->ignoreLinefeed = true;
@@ -2715,6 +2732,14 @@ class Balancer {
                                $this->stack->insertHTMLElement( $value, $attribs );
                                return true;
 
+                       case 'menuitem':
+                               if ( $this->stack->currentNode->isHtmlNamed( 'menuitem' ) ) {
+                                       $this->stack->pop();
+                               }
+                               $this->afe->reconstruct( $this->stack );
+                               $this->stack->insertHTMLElement( $value, $attribs );
+                               return true;
+
                        case 'rb':
                        case 'rtc':
                                if ( $this->stack->inScope( 'ruby' ) ) {
index 96f8638..79166ef 100644 (file)
@@ -1440,6 +1440,7 @@ abstract class UploadBase {
                        'http://www.w3.org/1999/02/22-rdf-syntax-ns#',
                        'http://www.w3.org/2000/svg',
                        'http://www.w3.org/tr/rec-rdf-syntax/',
+                       'http://www.w3.org/2000/01/rdf-schema#',
                ];
 
                // Inkscape mangles namespace definitions created by Adobe Illustrator.
index fed64c2..6804df2 100644 (file)
@@ -66,7 +66,7 @@ class User implements IDBAccessObject {
        /**
         * @const int Serialized record version.
         */
-       const VERSION = 10;
+       const VERSION = 11;
 
        /**
         * Exclude user options that are set to their default value.
@@ -104,7 +104,7 @@ class User implements IDBAccessObject {
                'mRegistration',
                'mEditCount',
                // user_groups table
-               'mGroups',
+               'mGroupMemberships',
                // user_properties table
                'mOptionOverrides',
        ];
@@ -225,8 +225,13 @@ class User implements IDBAccessObject {
        protected $mRegistration;
        /** @var int */
        protected $mEditCount;
-       /** @var array */
-       public $mGroups;
+       /**
+        * @var array No longer used since 1.29; use User::getGroups() instead
+        * @deprecated since 1.29
+        */
+       private $mGroups;
+       /** @var array Associative array of (group name => UserGroupMembership object) */
+       protected $mGroupMemberships;
        /** @var array */
        protected $mOptionOverrides;
        // @}
@@ -283,9 +288,7 @@ class User implements IDBAccessObject {
        /** @var array */
        public $mOptions;
 
-       /**
-        * @var WebRequest
-        */
+       /** @var WebRequest */
        private $mRequest;
 
        /** @var Block */
@@ -468,6 +471,17 @@ class User implements IDBAccessObject {
                return $cache->makeGlobalKey( 'user', 'id', wfWikiID(), $this->mId );
        }
 
+       /**
+        * @param WANObjectCache $cache
+        * @return string[]
+        * @since 1.28
+        */
+       public function getMutableCacheKeys( WANObjectCache $cache ) {
+               $id = $this->getId();
+
+               return $id ? [ $this->getCacheKey( $cache ) ] : [];
+       }
+
        /**
         * Load user data from shared cache, given mId has already been set.
         *
@@ -1138,7 +1152,7 @@ class User implements IDBAccessObject {
                $this->mEmailToken = '';
                $this->mEmailTokenExpires = null;
                $this->mRegistration = wfTimestamp( TS_MW );
-               $this->mGroups = [];
+               $this->mGroupMemberships = [];
 
                Hooks::run( 'UserLoadDefaults', [ $this, $name ] );
        }
@@ -1250,7 +1264,7 @@ class User implements IDBAccessObject {
                if ( $s !== false ) {
                        // Initialise user table data
                        $this->loadFromRow( $s );
-                       $this->mGroups = null; // deferred
+                       $this->mGroupMemberships = null; // deferred
                        $this->getEditCount(); // revalidation for nulls
                        return true;
                } else {
@@ -1267,13 +1281,16 @@ class User implements IDBAccessObject {
         * @param stdClass $row Row from the user table to load.
         * @param array $data Further user data to load into the object
         *
-        *      user_groups             Array with groups out of the user_groups table
-        *      user_properties         Array with properties out of the user_properties table
+        *  user_groups   Array of arrays or stdClass result rows out of the user_groups
+        *                table. Previously you were supposed to pass an array of strings
+        *                here, but we also need expiry info nowadays, so an array of
+        *                strings is ignored.
+        *  user_properties   Array with properties out of the user_properties table
         */
        protected function loadFromRow( $row, $data = null ) {
                $all = true;
 
-               $this->mGroups = null; // deferred
+               $this->mGroupMemberships = null; // deferred
 
                if ( isset( $row->user_name ) ) {
                        $this->mName = $row->user_name;
@@ -1342,7 +1359,18 @@ class User implements IDBAccessObject {
 
                if ( is_array( $data ) ) {
                        if ( isset( $data['user_groups'] ) && is_array( $data['user_groups'] ) ) {
-                               $this->mGroups = $data['user_groups'];
+                               if ( !count( $data['user_groups'] ) ) {
+                                       $this->mGroupMemberships = [];
+                               } else {
+                                       $firstGroup = reset( $data['user_groups'] );
+                                       if ( is_array( $firstGroup ) || is_object( $firstGroup ) ) {
+                                               $this->mGroupMemberships = [];
+                                               foreach ( $data['user_groups'] as $row ) {
+                                                       $ugm = UserGroupMembership::newFromRow( (object)$row );
+                                                       $this->mGroupMemberships[$ugm->getGroup()] = $ugm;
+                                               }
+                                       }
+                               }
                        }
                        if ( isset( $data['user_properties'] ) && is_array( $data['user_properties'] ) ) {
                                $this->loadOptions( $data['user_properties'] );
@@ -1366,18 +1394,12 @@ class User implements IDBAccessObject {
         * Load the groups from the database if they aren't already loaded.
         */
        private function loadGroups() {
-               if ( is_null( $this->mGroups ) ) {
+               if ( is_null( $this->mGroupMemberships ) ) {
                        $db = ( $this->queryFlagsUsed & self::READ_LATEST )
                                ? wfGetDB( DB_MASTER )
                                : wfGetDB( DB_REPLICA );
-                       $res = $db->select( 'user_groups',
-                               [ 'ug_group' ],
-                               [ 'ug_user' => $this->mId ],
-                               __METHOD__ );
-                       $this->mGroups = [];
-                       foreach ( $res as $row ) {
-                               $this->mGroups[] = $row->ug_group;
-                       }
+                       $this->mGroupMemberships = UserGroupMembership::getMembershipsForUser(
+                               $this->mId, $db );
                }
        }
 
@@ -1509,7 +1531,7 @@ class User implements IDBAccessObject {
                $this->mRights = null;
                $this->mEffectiveGroups = null;
                $this->mImplicitGroups = null;
-               $this->mGroups = null;
+               $this->mGroupMemberships = null;
                $this->mOptions = null;
                $this->mOptionsLoaded = false;
                $this->mEditCount = null;
@@ -3222,7 +3244,20 @@ class User implements IDBAccessObject {
        public function getGroups() {
                $this->load();
                $this->loadGroups();
-               return $this->mGroups;
+               return array_keys( $this->mGroupMemberships );
+       }
+
+       /**
+        * Get the list of explicit group memberships this user has, stored as
+        * UserGroupMembership objects. Implicit groups are not included.
+        *
+        * @return array Associative array of (group name as string => UserGroupMembership object)
+        * @since 1.29
+        */
+       public function getGroupMemberships() {
+               $this->load();
+               $this->loadGroups();
+               return $this->mGroupMemberships;
        }
 
        /**
@@ -3333,34 +3368,35 @@ class User implements IDBAccessObject {
        }
 
        /**
-        * Add the user to the given group.
-        * This takes immediate effect.
+        * Add the user to the given group. This takes immediate effect.
+        * If the user is already in the group, the expiry time will be updated to the new
+        * expiry time. (If $expiry is omitted or null, the membership will be altered to
+        * never expire.)
+        *
         * @param string $group Name of the group to add
+        * @param string $expiry Optional expiry timestamp in any format acceptable to
+        *   wfTimestamp(), or null if the group assignment should not expire
         * @return bool
         */
-       public function addGroup( $group ) {
+       public function addGroup( $group, $expiry = null ) {
                $this->load();
+               $this->loadGroups();
+
+               if ( $expiry ) {
+                       $expiry = wfTimestamp( TS_MW, $expiry );
+               }
 
-               if ( !Hooks::run( 'UserAddGroup', [ $this, &$group ] ) ) {
+               if ( !Hooks::run( 'UserAddGroup', [ $this, &$group, &$expiry ] ) ) {
                        return false;
                }
 
-               $dbw = wfGetDB( DB_MASTER );
-               if ( $this->getId() ) {
-                       $dbw->insert( 'user_groups',
-                               [
-                                       'ug_user' => $this->getId(),
-                                       'ug_group' => $group,
-                               ],
-                               __METHOD__,
-                               [ 'IGNORE' ] );
+               // create the new UserGroupMembership and put it in the DB
+               $ugm = new UserGroupMembership( $this->mId, $group, $expiry );
+               if ( !$ugm->insert( true ) ) {
+                       return false;
                }
 
-               $this->loadGroups();
-               $this->mGroups[] = $group;
-               // In case loadGroups was not called before, we now have the right twice.
-               // Get rid of the duplicate.
-               $this->mGroups = array_unique( $this->mGroups );
+               $this->mGroupMemberships[$group] = $ugm;
 
                // Refresh the groups caches, and clear the rights cache so it will be
                // refreshed on the next call to $this->getRights().
@@ -3380,29 +3416,19 @@ class User implements IDBAccessObject {
         */
        public function removeGroup( $group ) {
                $this->load();
+
                if ( !Hooks::run( 'UserRemoveGroup', [ $this, &$group ] ) ) {
                        return false;
                }
 
-               $dbw = wfGetDB( DB_MASTER );
-               $dbw->delete( 'user_groups',
-                       [
-                               'ug_user' => $this->getId(),
-                               'ug_group' => $group,
-                       ], __METHOD__
-               );
-               // Remember that the user was in this group
-               $dbw->insert( 'user_former_groups',
-                       [
-                               'ufg_user' => $this->getId(),
-                               'ufg_group' => $group,
-                       ],
-                       __METHOD__,
-                       [ 'IGNORE' ]
-               );
+               $ugm = UserGroupMembership::getMembership( $this->mId, $group );
+               // delete the membership entry
+               if ( !$ugm || !$ugm->delete() ) {
+                       return false;
+               }
 
                $this->loadGroups();
-               $this->mGroups = array_diff( $this->mGroups, [ $group ] );
+               unset( $this->mGroupMemberships[$group] );
 
                // Refresh the groups caches, and clear the rights cache so it will be
                // refreshed on the next call to $this->getRights().
@@ -4736,25 +4762,27 @@ class User implements IDBAccessObject {
 
        /**
         * Get the localized descriptive name for a group, if it exists
+        * @deprecated since 1.29 Use UserGroupMembership::getGroupName instead
         *
         * @param string $group Internal group name
         * @return string Localized descriptive group name
         */
        public static function getGroupName( $group ) {
-               $msg = wfMessage( "group-$group" );
-               return $msg->isBlank() ? $group : $msg->text();
+               wfDeprecated( __METHOD__, '1.29' );
+               return UserGroupMembership::getGroupName( $group );
        }
 
        /**
         * Get the localized descriptive name for a member of a group, if it exists
+        * @deprecated since 1.29 Use UserGroupMembership::getGroupMemberName instead
         *
         * @param string $group Internal group name
         * @param string $username Username for gender (since 1.19)
         * @return string Localized name for group member
         */
        public static function getGroupMember( $group, $username = '#' ) {
-               $msg = wfMessage( "group-$group-member", $username );
-               return $msg->isBlank() ? $group : $msg->text();
+               wfDeprecated( __METHOD__, '1.29' );
+               return UserGroupMembership::getGroupMemberName( $group, $username );
        }
 
        /**
@@ -4804,34 +4832,33 @@ class User implements IDBAccessObject {
 
        /**
         * Get the title of a page describing a particular group
+        * @deprecated since 1.29 Use UserGroupMembership::getGroupPage instead
         *
         * @param string $group Internal group name
         * @return Title|bool Title of the page if it exists, false otherwise
         */
        public static function getGroupPage( $group ) {
-               $msg = wfMessage( 'grouppage-' . $group )->inContentLanguage();
-               if ( $msg->exists() ) {
-                       $title = Title::newFromText( $msg->text() );
-                       if ( is_object( $title ) ) {
-                               return $title;
-                       }
-               }
-               return false;
+               wfDeprecated( __METHOD__, '1.29' );
+               return UserGroupMembership::getGroupPage( $group );
        }
 
        /**
         * Create a link to the group in HTML, if available;
         * else return the group name.
+        * @deprecated since 1.29 Use UserGroupMembership::getLink instead, or
+        * make the link yourself if you need custom text
         *
         * @param string $group Internal name of the group
         * @param string $text The text of the link
         * @return string HTML link to the group
         */
        public static function makeGroupLinkHTML( $group, $text = '' ) {
+               wfDeprecated( __METHOD__, '1.29' );
+
                if ( $text == '' ) {
-                       $text = self::getGroupName( $group );
+                       $text = UserGroupMembership::getGroupName( $group );
                }
-               $title = self::getGroupPage( $group );
+               $title = UserGroupMembership::getGroupPage( $group );
                if ( $title ) {
                        return Linker::link( $title, htmlspecialchars( $text ) );
                } else {
@@ -4842,16 +4869,20 @@ class User implements IDBAccessObject {
        /**
         * Create a link to the group in Wikitext, if available;
         * else return the group name.
+        * @deprecated since 1.29 Use UserGroupMembership::getLink instead, or
+        * make the link yourself if you need custom text
         *
         * @param string $group Internal name of the group
         * @param string $text The text of the link
         * @return string Wikilink to the group
         */
        public static function makeGroupLinkWiki( $group, $text = '' ) {
+               wfDeprecated( __METHOD__, '1.29' );
+
                if ( $text == '' ) {
-                       $text = self::getGroupName( $group );
+                       $text = UserGroupMembership::getGroupName( $group );
                }
-               $title = self::getGroupPage( $group );
+               $title = UserGroupMembership::getGroupPage( $group );
                if ( $title ) {
                        $page = $title->getFullText();
                        return "[[$page|$text]]";
@@ -5091,54 +5122,6 @@ class User implements IDBAccessObject {
                return $msg->isDisabled() ? $grant : $msg->text();
        }
 
-       /**
-        * Make a new-style password hash
-        *
-        * @param string $password Plain-text password
-        * @param bool|string $salt Optional salt, may be random or the user ID.
-        *  If unspecified or false, will generate one automatically
-        * @return string Password hash
-        * @deprecated since 1.24, use Password class
-        */
-       public static function crypt( $password, $salt = false ) {
-               wfDeprecated( __METHOD__, '1.24' );
-               $passwordFactory = new PasswordFactory();
-               $passwordFactory->init( RequestContext::getMain()->getConfig() );
-               $hash = $passwordFactory->newFromPlaintext( $password );
-               return $hash->toString();
-       }
-
-       /**
-        * Compare a password hash with a plain-text password. Requires the user
-        * ID if there's a chance that the hash is an old-style hash.
-        *
-        * @param string $hash Password hash
-        * @param string $password Plain-text password to compare
-        * @param string|bool $userId User ID for old-style password salt
-        *
-        * @return bool
-        * @deprecated since 1.24, use Password class
-        */
-       public static function comparePasswords( $hash, $password, $userId = false ) {
-               wfDeprecated( __METHOD__, '1.24' );
-
-               // Check for *really* old password hashes that don't even have a type
-               // The old hash format was just an md5 hex hash, with no type information
-               if ( preg_match( '/^[0-9a-f]{32}$/', $hash ) ) {
-                       global $wgPasswordSalt;
-                       if ( $wgPasswordSalt ) {
-                               $password = ":B:{$userId}:{$hash}";
-                       } else {
-                               $password = ":A:{$hash}";
-                       }
-               }
-
-               $passwordFactory = new PasswordFactory();
-               $passwordFactory->init( RequestContext::getMain()->getConfig() );
-               $hash = $passwordFactory->newFromCiphertext( $hash );
-               return $hash->equals( $password );
-       }
-
        /**
         * Add a newuser log entry for this user.
         * Before 1.19 the return value was always true.
@@ -5411,10 +5394,10 @@ class User implements IDBAccessObject {
        static function newFatalPermissionDeniedStatus( $permission ) {
                global $wgLang;
 
-               $groups = array_map(
-                       [ 'User', 'makeGroupLinkWiki' ],
-                       User::getGroupsWithPermission( $permission )
-               );
+               $groups = [];
+               foreach ( User::getGroupsWithPermission( $permission ) as $group ) {
+                       $groups[] = UserGroupMembership::getLink( $group, RequestContext::getMain(), 'wiki' );
+               }
 
                if ( $groups ) {
                        return Status::newFatal( 'badaccess-groups', $wgLang->commaList( $groups ), count( $groups ) );
diff --git a/includes/user/UserGroupMembership.php b/includes/user/UserGroupMembership.php
new file mode 100644 (file)
index 0000000..bb0b7d2
--- /dev/null
@@ -0,0 +1,475 @@
+<?php
+/**
+ * Represents the membership of a user to a user group.
+ *
+ * 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
+ */
+
+/**
+ * Represents a "user group membership" -- a specific instance of a user belonging
+ * to a group. For example, the fact that user Mary belongs to the sysop group is a
+ * user group membership.
+ *
+ * The class encapsulates rows in the user_groups table. The logic is low-level and
+ * doesn't run any hooks. Often, you will want to call User::addGroup() or
+ * User::removeGroup() instead.
+ *
+ * @since 1.29
+ */
+class UserGroupMembership {
+       /** @var int The ID of the user who belongs to the group */
+       private $userId;
+
+       /** @var string */
+       private $group;
+
+       /** @var string|null Timestamp of expiry in TS_MW format, or null if no expiry */
+       private $expiry;
+
+       /**
+        * @param int $userId The ID of the user who belongs to the group
+        * @param string $group The internal group name
+        * @param string|null $expiry Timestamp of expiry in TS_MW format, or null if no expiry
+        */
+       public function __construct( $userId = 0, $group = null, $expiry = null ) {
+               global $wgDisableUserGroupExpiry;
+               if ( $wgDisableUserGroupExpiry ) {
+                       $expiry = null;
+               }
+
+               $this->userId = (int)$userId;
+               $this->group = $group; // TODO throw on invalid group?
+               $this->expiry = $expiry ?: null;
+       }
+
+       /**
+        * @return int
+        */
+       public function getUserId() {
+               return $this->userId;
+       }
+
+       /**
+        * @return string
+        */
+       public function getGroup() {
+               return $this->group;
+       }
+
+       /**
+        * @return string|null Timestamp of expiry in TS_MW format, or null if no expiry
+        */
+       public function getExpiry() {
+               global $wgDisableUserGroupExpiry;
+               if ( $wgDisableUserGroupExpiry ) {
+                       return null;
+               }
+
+               return $this->expiry;
+       }
+
+       protected function initFromRow( $row ) {
+               global $wgDisableUserGroupExpiry;
+
+               $this->userId = (int)$row->ug_user;
+               $this->group = $row->ug_group;
+               if ( $wgDisableUserGroupExpiry ) {
+                       $this->expiry = null;
+               } else {
+                       $this->expiry = $row->ug_expiry === null ?
+                               null :
+                               wfTimestamp( TS_MW, $row->ug_expiry );
+               }
+       }
+
+       /**
+        * Creates a new UserGroupMembership object from a database row.
+        *
+        * @param stdClass $row The row from the user_groups table
+        * @return UserGroupMembership
+        */
+       public static function newFromRow( $row ) {
+               $ugm = new self;
+               $ugm->initFromRow( $row );
+               return $ugm;
+       }
+
+       /**
+        * Returns the list of user_groups fields that should be selected to create
+        * a new user group membership.
+        * @return array
+        */
+       public static function selectFields() {
+               global $wgDisableUserGroupExpiry;
+               if ( $wgDisableUserGroupExpiry ) {
+                       return [
+                               'ug_user',
+                               'ug_group',
+                       ];
+               } else {
+                       return [
+                               'ug_user',
+                               'ug_group',
+                               'ug_expiry',
+                       ];
+               }
+       }
+
+       /**
+        * Delete the row from the user_groups table.
+        *
+        * @throws MWException
+        * @param IDatabase|null $dbw Optional master database connection to use
+        * @return bool Whether or not anything was deleted
+        */
+       public function delete( IDatabase $dbw = null ) {
+               global $wgDisableUserGroupExpiry;
+               if ( wfReadOnly() ) {
+                       return false;
+               }
+
+               if ( $dbw === null ) {
+                       $dbw = wfGetDB( DB_MASTER );
+               }
+
+               if ( $wgDisableUserGroupExpiry ) {
+                       $dbw->delete( 'user_groups', $this->getDatabaseArray( $dbw ), __METHOD__ );
+               } else {
+                       $dbw->delete(
+                               'user_groups',
+                               [ 'ug_user' => $this->userId, 'ug_group' => $this->group ],
+                               __METHOD__ );
+               }
+               if ( !$dbw->affectedRows() ) {
+                       return false;
+               }
+
+               // Remember that the user was in this group
+               $dbw->insert(
+                       'user_former_groups',
+                       [ 'ufg_user' => $this->userId, 'ufg_group' => $this->group ],
+                       __METHOD__,
+                       [ 'IGNORE' ] );
+
+               return true;
+       }
+
+       /**
+        * Insert a user right membership into the database. When $allowUpdate is false,
+        * the function fails if there is a conflicting membership entry (same user and
+        * group) already in the table.
+        *
+        * @throws MWException
+        * @param bool $allowUpdate Whether to perform "upsert" instead of INSERT
+        * @param IDatabase|null $dbw If you have one available
+        * @return bool Whether or not anything was inserted
+        */
+       public function insert( $allowUpdate = false, IDatabase $dbw = null ) {
+               global $wgDisableUserGroupExpiry;
+               if ( $dbw === null ) {
+                       $dbw = wfGetDB( DB_MASTER );
+               }
+
+               // Purge old, expired memberships from the DB
+               self::purgeExpired( $dbw );
+
+               // Check that the values make sense
+               if ( $this->group === null ) {
+                       throw new UnexpectedValueException(
+                               'Don\'t try inserting an uninitialized UserGroupMembership object' );
+               } elseif ( $this->userId <= 0 ) {
+                       throw new UnexpectedValueException(
+                               'UserGroupMembership::insert() needs a positive user ID. ' .
+                               'Did you forget to add your User object to the database before calling addGroup()?' );
+               }
+
+               $row = $this->getDatabaseArray( $dbw );
+               $dbw->insert( 'user_groups', $row, __METHOD__, [ 'IGNORE' ] );
+               $affected = $dbw->affectedRows();
+
+               // Don't collide with expired user group memberships
+               // Do this after trying to insert, in order to avoid locking
+               if ( !$wgDisableUserGroupExpiry && !$affected ) {
+                       $conds = [
+                               'ug_user' => $row['ug_user'],
+                               'ug_group' => $row['ug_group'],
+                       ];
+                       // if we're unconditionally updating, check that the expiry is not already the
+                       // same as what we are trying to update it to; otherwise, only update if
+                       // the expiry date is in the past
+                       if ( $allowUpdate ) {
+                               if ( $this->expiry ) {
+                                       $conds[] = 'ug_expiry IS NULL OR ug_expiry != ' .
+                                               $dbw->addQuotes( $dbw->timestamp( $this->expiry ) );
+                               } else {
+                                       $conds[] = 'ug_expiry IS NOT NULL';
+                               }
+                       } else {
+                               $conds[] = 'ug_expiry < ' . $dbw->addQuotes( $dbw->timestamp() );
+                       }
+
+                       $row = $dbw->selectRow( 'user_groups', $this::selectFields(), $conds, __METHOD__ );
+                       if ( $row ) {
+                               $dbw->update(
+                                       'user_groups',
+                                       [ 'ug_expiry' => $this->expiry ? $dbw->timestamp( $this->expiry ) : null ],
+                                       [ 'ug_user' => $row->ug_user, 'ug_group' => $row->ug_group ],
+                                       __METHOD__ );
+                               $affected = $dbw->affectedRows();
+                       }
+               }
+
+               return $affected > 0;
+       }
+
+       /**
+        * Get an array suitable for passing to $dbw->insert() or $dbw->update()
+        * @param IDatabase $db
+        * @return array
+        */
+       protected function getDatabaseArray( IDatabase $db ) {
+               global $wgDisableUserGroupExpiry;
+
+               $a = [
+                       'ug_user' => $this->userId,
+                       'ug_group' => $this->group,
+               ];
+               if ( !$wgDisableUserGroupExpiry ) {
+                       $a['ug_expiry'] = $this->expiry ? $db->timestamp( $this->expiry ) : null;
+               }
+               return $a;
+       }
+
+       /**
+        * Has the membership expired?
+        * @return bool
+        */
+       public function isExpired() {
+               global $wgDisableUserGroupExpiry;
+               if ( $wgDisableUserGroupExpiry || !$this->expiry ) {
+                       return false;
+               } else {
+                       return wfTimestampNow() > $this->expiry;
+               }
+       }
+
+       /**
+        * Purge expired memberships from the user_groups table
+        *
+        * @param IDatabase|null $dbw
+        */
+       public static function purgeExpired( IDatabase $dbw = null ) {
+               global $wgDisableUserGroupExpiry;
+               if ( $wgDisableUserGroupExpiry || wfReadOnly() ) {
+                       return;
+               }
+
+               if ( $dbw === null ) {
+                       $dbw = wfGetDB( DB_MASTER );
+               }
+
+               DeferredUpdates::addUpdate( new AtomicSectionUpdate(
+                       $dbw,
+                       __METHOD__,
+                       function ( IDatabase $dbw, $fname ) {
+                               $expiryCond = [ 'ug_expiry < ' . $dbw->addQuotes( $dbw->timestamp() ) ];
+                               $res = $dbw->select( 'user_groups', self::selectFields(), $expiryCond, $fname );
+
+                               // save an array of users/groups to insert to user_former_groups
+                               $usersAndGroups = [];
+                               foreach ( $res as $row ) {
+                                       $usersAndGroups[] = [ 'ufg_user' => $row->ug_user, 'ufg_group' => $row->ug_group ];
+                               }
+
+                               // delete 'em all
+                               $dbw->delete( 'user_groups', $expiryCond, $fname );
+
+                               // and push the groups to user_former_groups
+                               $dbw->insert( 'user_former_groups', $usersAndGroups, __METHOD__, [ 'IGNORE' ] );
+                       }
+               ) );
+       }
+
+       /**
+        * Returns UserGroupMembership objects for all the groups a user currently
+        * belongs to.
+        *
+        * @param int $userId ID of the user to search for
+        * @param IDatabase|null $db Optional database connection
+        * @return array Associative array of (group name => UserGroupMembership object)
+        */
+       public static function getMembershipsForUser( $userId, $db = null ) {
+               if ( !$db ) {
+                       $db = wfGetDB( DB_REPLICA );
+               }
+
+               $res = $db->select( 'user_groups',
+                       self::selectFields(),
+                       [ 'ug_user' => $userId ],
+                       __METHOD__ );
+
+               $ugms = [];
+               foreach ( $res as $row ) {
+                       $ugm = self::newFromRow( $row );
+                       if ( !$ugm->isExpired() ) {
+                               $ugms[$ugm->group] = $ugm;
+                       }
+               }
+
+               return $ugms;
+       }
+
+       /**
+        * Returns a UserGroupMembership object that pertains to the given user and group,
+        * or false if the user does not belong to that group (or the assignment has
+        * expired).
+        *
+        * @param int $userId ID of the user to search for
+        * @param string $group User group name
+        * @param IDatabase|null $db Optional database connection
+        * @return UserGroupMembership|false
+        */
+       public static function getMembership( $userId, $group, IDatabase $db = null ) {
+               if ( !$db ) {
+                       $db = wfGetDB( DB_REPLICA );
+               }
+
+               $row = $db->selectRow( 'user_groups',
+                       self::selectFields(),
+                       [ 'ug_user' => $userId, 'ug_group' => $group ],
+                       __METHOD__ );
+               if ( !$row ) {
+                       return false;
+               }
+
+               $ugm = self::newFromRow( $row );
+               if ( !$ugm->isExpired() ) {
+                       return $ugm;
+               } else {
+                       return false;
+               }
+       }
+
+       /**
+        * Gets a link for a user group, possibly including the expiry date if relevant.
+        *
+        * @param string|UserGroupMembership $ugm Either a group name as a string, or
+        *   a UserGroupMembership object
+        * @param IContextSource $context
+        * @param string $format Either 'wiki' or 'html'
+        * @param string|null $userName If you want to use the group member message
+        *   ("administrator"), pass the name of the user who belongs to the group; it
+        *   is used for GENDER of the group member message. If you instead want the
+        *   group name message ("Administrators"), omit this parameter.
+        * @return string
+        */
+       public static function getLink( $ugm, IContextSource $context, $format,
+               $userName = null ) {
+
+               if ( $format !== 'wiki' && $format !== 'html' ) {
+                       throw new MWException( 'UserGroupMembership::getLink() $format parameter should be ' .
+                               "'wiki' or 'html'" );
+               }
+
+               if ( $ugm instanceof UserGroupMembership ) {
+                       $expiry = $ugm->getExpiry();
+                       $group = $ugm->getGroup();
+               } else {
+                       $expiry = null;
+                       $group = $ugm;
+               }
+
+               if ( $userName !== null ) {
+                       $groupName = self::getGroupMemberName( $group, $userName );
+               } else {
+                       $groupName = self::getGroupName( $group );
+               }
+
+               // link to the group description page, if it exists
+               $linkTitle = self::getGroupPage( $group );
+               if ( $linkTitle ) {
+                       if ( $format === 'wiki' ) {
+                               $linkPage = $linkTitle->getFullText();
+                               $groupLink = "[[$linkPage|$groupName]]";
+                       } else {
+                               $groupLink = Linker::link( $linkTitle, htmlspecialchars( $groupName ) );
+                       }
+               } else {
+                       $groupLink = htmlspecialchars( $groupName );
+               }
+
+               if ( $expiry ) {
+                       // format the expiry to a nice string
+                       $uiLanguage = $context->getLanguage();
+                       $uiUser = $context->getUser();
+                       $expiryDT = $uiLanguage->userTimeAndDate( $expiry, $uiUser );
+                       $expiryD = $uiLanguage->userDate( $expiry, $uiUser );
+                       $expiryT = $uiLanguage->userTime( $expiry, $uiUser );
+                       if ( $format === 'html' ) {
+                               $groupLink = Message::rawParam( $groupLink );
+                       }
+                       return $context->msg( 'group-membership-link-with-expiry' )
+                               ->params( $groupLink, $expiryDT, $expiryD, $expiryT )->text();
+               } else {
+                       return $groupLink;
+               }
+       }
+
+       /**
+        * Gets the localized friendly name for a group, if it exists. For example,
+        * "Administrators" or "Bureaucrats"
+        *
+        * @param string $group Internal group name
+        * @return string Localized friendly group name
+        */
+       public static function getGroupName( $group ) {
+               $msg = wfMessage( "group-$group" );
+               return $msg->isBlank() ? $group : $msg->text();
+       }
+
+       /**
+        * Gets the localized name for a member of a group, if it exists. For example,
+        * "administrator" or "bureaucrat"
+        *
+        * @param string $group Internal group name
+        * @param string $username Username for gender
+        * @return string Localized name for group member
+        */
+       public static function getGroupMemberName( $group, $username ) {
+               $msg = wfMessage( "group-$group-member", $username );
+               return $msg->isBlank() ? $group : $msg->text();
+       }
+
+       /**
+        * Gets the title of a page describing a particular user group. When the name
+        * of the group appears in the UI, it can link to this page.
+        *
+        * @param string $group Internal group name
+        * @return Title|bool Title of the page if it exists, false otherwise
+        */
+       public static function getGroupPage( $group ) {
+               $msg = wfMessage( "grouppage-$group" )->inContentLanguage();
+               if ( $msg->exists() ) {
+                       $title = Title::newFromText( $msg->text() );
+                       if ( is_object( $title ) ) {
+                               return $title;
+                       }
+               }
+               return false;
+       }
+}
index 69bc503..23c2177 100644 (file)
@@ -210,38 +210,51 @@ class UserRightsProxy {
        }
 
        /**
-        * Replaces User::addUserGroup()
-        * @param string $group
+        * Replaces User::getGroupMemberships()
+        *
+        * @return array
+        * @since 1.29
+        */
+       function getGroupMemberships() {
+               $res = $this->db->select( 'user_groups',
+                       UserGroupMembership::selectFields(),
+                       [ 'ug_user' => $this->id ],
+                       __METHOD__ );
+               $ugms = [];
+               foreach ( $res as $row ) {
+                       $ugms[$row->ug_group] = UserGroupMembership::newFromRow( $row );
+               }
+               return $ugms;
+       }
+
+       /**
+        * Replaces User::addGroup()
         *
+        * @param string $group
+        * @param string|null $expiry
         * @return bool
         */
-       function addGroup( $group ) {
-               $this->db->insert( 'user_groups',
-                       [
-                               'ug_user' => $this->id,
-                               'ug_group' => $group,
-                       ],
-                       __METHOD__,
-                       [ 'IGNORE' ] );
+       function addGroup( $group, $expiry = null ) {
+               if ( $expiry ) {
+                       $expiry = wfTimestamp( TS_MW, $expiry );
+               }
 
-               return true;
+               $ugm = new UserGroupMembership( $this->id, $group, $expiry );
+               return $ugm->insert( true, $this->db );
        }
 
        /**
-        * Replaces User::removeUserGroup()
-        * @param string $group
+        * Replaces User::removeGroup()
         *
+        * @param string $group
         * @return bool
         */
        function removeGroup( $group ) {
-               $this->db->delete( 'user_groups',
-                       [
-                               'ug_user' => $this->id,
-                               'ug_group' => $group,
-                       ],
-                       __METHOD__ );
-
-               return true;
+               $ugm = UserGroupMembership::getMembership( $this->id, $group, $this->db );
+               if ( !$ugm ) {
+                       return false;
+               }
+               return $ugm->delete( $this->db );
        }
 
        /**
index 69bfa6d..0d0fa12 100644 (file)
@@ -131,16 +131,16 @@ class FullSearchResultWidget implements SearchResultWidget {
 
                // clone to prevent hook from changing the title stored inside $result
                $title = clone $result->getTitle();
-               $queryString = [];
+               $query = [];
 
                Hooks::run( 'ShowSearchHitTitle',
-                       [ &$title, &$snippet, $result, $terms, $this->specialPage, &$queryString ] );
+                       [ &$title, &$snippet, $result, $terms, $this->specialPage, &$query ] );
 
                $link = $this->linkRenderer->makeLink(
                        $title,
                        $snippet,
                        [ 'data-serp-pos' => $position ],
-                       $queryString
+                       $query
                );
 
                return $link;
index 5bce76b..68727bb 100644 (file)
@@ -3975,10 +3975,11 @@ class Language {
         *
         * @param string $str The validated block duration in English
         * @param User $user User object to use timezone from or null for $wgUser
+        * @param int $now Current timestamp, for formatting relative block durations
         * @return string Somehow translated block duration
         * @see LanguageFi.php for example implementation
         */
-       function translateBlockExpiry( $str, User $user = null ) {
+       function translateBlockExpiry( $str, User $user = null, $now = 0 ) {
                $duration = SpecialBlock::getSuggestedDurations( $this );
                foreach ( $duration as $show => $value ) {
                        if ( strcmp( $str, $value ) == 0 ) {
@@ -3995,12 +3996,13 @@ class Language {
                }
 
                // If all else fails, return a standard duration or timestamp description.
-               $time = strtotime( $str, 0 );
+               $time = strtotime( $str, $now );
                if ( $time === false ) { // Unknown format. Return it as-is in case.
                        return $str;
-               } elseif ( $time !== strtotime( $str, 1 ) ) { // It's a relative timestamp.
-                       // $time is relative to 0 so it's a duration length.
-                       return $this->formatDuration( $time );
+               } elseif ( $time !== strtotime( $str, $now + 1 ) ) { // It's a relative timestamp.
+                       // The result differs based on current time, so the difference
+                       // is a fixed duration length.
+                       return $this->formatDuration( $time - $now );
                } else { // It's an absolute timestamp.
                        if ( $time === 0 ) {
                                // wfTimestamp() handles 0 as current time instead of epoch.
index 3388536..54ff421 100644 (file)
@@ -85,9 +85,10 @@ class LanguageFi extends Language {
        /**
         * @param string $str
         * @param User $user User object to use timezone from or null for $wgUser
+        * @param int $now Current timestamp, for formatting relative block durations
         * @return string
         */
-       function translateBlockExpiry( $str, User $user = null ) {
+       function translateBlockExpiry( $str, User $user = null, $now = 0 ) {
                /*
                        'ago', 'now', 'today', 'this', 'next',
                        'first', 'third', 'fourth', 'fifth', 'sixth', 'seventh', 'eighth', 'ninth',
index 0376f42..c2befb1 100644 (file)
        "youremail": "البريد:",
        "username": "{{GENDER:$1|اسم المستخدم|اسم المستخدمة}}:",
        "prefs-memberingroups": "{{GENDER:$2|عضو|عضوة}} في {{PLURAL:$1|مجموعة|مجموعة|مجموعتي|مجموعات}}:",
+       "group-membership-link-with-expiry": "$1 (حتى $2)",
        "prefs-registration": "وقت التسجيل:",
        "yourrealname": "الاسم الحقيقي:",
        "yourlanguage": "اللغة:",
        "userrights-nodatabase": "قاعدة البيانات $1 غير موجودة أو ليست محلية.",
        "userrights-changeable-col": "المجموعات التي يمكنك تغييرها",
        "userrights-unchangeable-col": "المجموعات التي لا يمكنك تغييرها",
+       "userrights-expiry-current": "تنتهي $1",
+       "userrights-expiry-none": "غير منتهية",
+       "userrights-expiry": "تنتهي:",
+       "userrights-expiry-existing": "وقت الانتهاء الموجود: $3، $2",
+       "userrights-expiry-othertime": "وقت آخر:",
+       "userrights-expiry-options": "1 يوم:1 day,1 أسبوع:1 week,1 شهر:1 month,3 شهور:3 months,6 شهور:6 months,1 سنة:1 year",
+       "userrights-invalid-expiry": "تاريخ انتهاء المجموعة \"$1\" غير صحيح.",
+       "userrights-expiry-in-past": "تاريخ انتهاء المجموعة \"$1\" هو في الماضي.",
        "userrights-conflict": "تضارب في تغيير صلاحيات المستخدم! الرجاء مراجعة تغييراتك مجدّدا وتأكيدها.",
        "group": "المجموعة:",
        "group-user": "مستخدمون",
        "recentchanges-legend-newpage": "{{int:recentchanges-label-newpage}} (راجع أيضا [[Special:NewPages|قائمة الصفحات الجديدة]])",
        "recentchanges-submit": "أظهر",
        "rcfilters-activefilters": "المرشحات النشطة",
+       "rcfilters-restore-default-filters": "استرجاع المرشحات الافتراضية",
+       "rcfilters-clear-all-filters": "مسح كل المرشحات",
        "rcfilters-search-placeholder": "رشح أحدث التغييرات (تصفح أو ابدأ الكتابة)",
        "rcfilters-invalid-filter": "مرشح غير صحيح",
+       "rcfilters-empty-filter": "لا مرشحات فعالة. كل المساهمات معروضة.",
        "rcfilters-filterlist-title": "مرشحات",
        "rcfilters-filterlist-noresults": "لم يتم العثور على مرشحات",
+       "rcfilters-filtergroup-registration": "تسجيل المستخدم",
+       "rcfilters-filter-registered-label": "مسجل",
+       "rcfilters-filter-registered-description": "المحررون مسجلو الدخول.",
+       "rcfilters-filter-unregistered-label": "غير مسجل",
+       "rcfilters-filter-unregistered-description": "المحررون غير مسجلي الدخول.",
        "rcfilters-filtergroup-authorship": "ملكية التعديلات",
        "rcfilters-filter-editsbyself-label": "تعديلاتك الشخصية",
        "rcfilters-filter-editsbyself-description": "التعديلات بواسطتك.",
        "rcfilters-filter-editsbyother-label": "التعديلات بواسطة الآخرين",
-       "rcfilters-filter-editsbyother-description": "التعديلات المنشأة بواسطة المستخدمين الآخرين (ليس أنت.)",
-       "rcfilters-filtergroup-userExpLevel": "Ù\85ستÙ\88Ù\89 Ø®Ø¨Ø±Ø© Ø§Ù\84Ù\85ستخدÙ\85",
+       "rcfilters-filter-editsbyother-description": "التعديلات المنشأة بواسطة المستخدمين الآخرين (ليس أنت).",
+       "rcfilters-filtergroup-userExpLevel": "Ù\85ستÙ\88Ù\89 Ø§Ù\84خبرة (Ù\84Ù\84Ù\85ستخدÙ\85Ù\8aÙ\86 Ø§Ù\84Ù\85سجÙ\84Ù\8aÙ\86 Ù\81Ù\82Ø·)",
        "rcfilters-filter-userExpLevel-newcomer-label": "القادمون الجدد",
-       "rcfilters-filter-userExpLevel-newcomer-description": "اÙ\84Ù\85ستخدÙ\85Ù\88Ù\86 Ø§Ù\84جدد Ø¬Ø¯Ø§: Ø£Ù\82Ù\84 Ù\85Ù\86 10 ØªØ¹Ø¯Ù\8aÙ\84ات Ù\884 Ø£Ù\8aاÙ\85 Ù\85Ù\86 Ø§Ù\84Ù\86شاط.",
+       "rcfilters-filter-userExpLevel-newcomer-description": "أقل من 10 تعديلات و4 أيام من النشاط.",
        "rcfilters-filter-userExpLevel-learner-label": "المتعلمون",
-       "rcfilters-filter-userExpLevel-learner-description": "المزيد من أيام النشاط والتعديلات أكثر من 'القادمين الجدد' ولكن أقل من 'المستخدمين ذوي الخبرة.'",
+       "rcfilters-filter-userExpLevel-learner-description": "المزيد من أيام النشاط والتعديلات أكثر من \"القادمين الجدد\" ولكن أقل من \"المستخدمين ذوي الخبرة\".",
        "rcfilters-filter-userExpLevel-experienced-label": "المستخدمون ذوو الخبرة",
        "rcfilters-filter-userExpLevel-experienced-description": "أكثر من 30 يوما من النشاط و500 تعديل.",
+       "rcfilters-filtergroup-automated": "المساهمات الأوتوماتيكية",
+       "rcfilters-filter-bots-label": "بوت",
+       "rcfilters-filter-bots-description": "التعديلات بواسطة الأدوات الأوتوماتيكية.",
+       "rcfilters-filter-humans-label": "بشري (ليس بوت)",
+       "rcfilters-filter-humans-description": "التعديلات بواسطة المحررين البشريين.",
+       "rcfilters-filtergroup-significance": "الأهمية",
+       "rcfilters-filter-minor-label": "تعديلات طفيفة",
+       "rcfilters-filter-minor-description": "التعديلات التي علم عليها المستخدم كطفيفة.",
+       "rcfilters-filter-major-label": "التعديلات غير الطفيفة",
+       "rcfilters-filter-major-description": "التعديلات غير المعلم عليها كطفيفة.",
+       "rcfilters-filtergroup-changetype": "نوع التغيير",
+       "rcfilters-filter-pageedits-label": "تعديلات الصفحة",
+       "rcfilters-filter-pageedits-description": "التعديلات لمحتوى الويكي، النقاشات، وصوفات التصنيفات....",
+       "rcfilters-filter-newpages-label": "إنشاء الصفحات",
+       "rcfilters-filter-newpages-description": "التعديلات التي تصنع صفحات جديدة.",
+       "rcfilters-filter-categorization-label": "تغييرات التصنيفات",
+       "rcfilters-filter-categorization-description": "سجلات إضافة أو إزالة الصفحات من التصنيفات.",
+       "rcfilters-filter-logactions-label": "الأفعال المسجلة",
+       "rcfilters-filter-logactions-description": "الأفعال الإدارية، إنشاء الحسابات، حذف الصفحات، عمليات الرفع....",
        "rcnotefrom": "بالأسفل {{PLURAL:$5|التغيير|التغييرات}} منذ <strong>$2</strong> (إلى <strong>$1</strong> معروضة).",
        "rclistfrom": "أظهر التغييرات بدء من $3 $2",
        "rcshowhideminor": "$1 التعديلات الطفيفة",
        "apisandbox-sending-request": "إرسال طلب API ...",
        "apisandbox-loading-results": "استقبال طلبات API ...",
        "apisandbox-results-error": "حدث خطأ أثناء تحميل رد استعدلام الAPI: $1.",
-       "apisandbox-request-params-json": "معاملات JSON:",
+       "apisandbox-request-selectformat-label": "عرض بيانات الطلب ك:",
+       "apisandbox-request-format-url-label": "سلسلة حروف استعلام المسار",
        "apisandbox-request-url-label": "مسار الطلب:",
+       "apisandbox-request-json-label": "JSON الطلب:",
        "apisandbox-request-time": "وقت الطلب: {{PLURAL:$1|$1 ms}}",
        "apisandbox-results-fixtoken": "رمز الصحيح وإعادة الموافقة",
        "apisandbox-results-fixtoken-fail": "فشل جلب توكين \"$1\"",
        "emailccsubject": "نسخة من رسالتك إلى $1: $2",
        "emailsent": "أُرسل البريد الإلكتروني",
        "emailsenttext": "أُرسلت رسالتك الإلكترونية.",
-       "emailuserfooter": "هذا البريد الإلكتروني {{GENDER:$1|تم إرساله}} بواسطة $1 إلى {{GENDER:$2|$2}} بواسطة وظيفة \"{{int:emailuser}}\" في {{SITENAME}}. عنوان البريد الخاص {{GENDER:$2|بك}} سيتم إرساله مباشرة {{GENDER:$1|للمرسل الأصلي|للمرسلة الأصلية}}، مما يكشف عنوان البريد الإلكتروني الخاص {{GENDER:$2|بك}} {{GENDER:$1|لهم}}.",
+       "emailuserfooter": "هذا البريد الإلكتروني {{GENDER:$1|تم إرساله}} بواسطة $1 إلى {{GENDER:$2|$2}} بواسطة وظيفة \"{{int:emailuser}}\" في {{SITENAME}}. لو {{GENDER:$2|أنك}} رددت على هذا البريد، فعنوان البريد الخاص {{GENDER:$2|بك}} سيتم إرساله مباشرة {{GENDER:$1|للمرسل الأصلي|للمرسلة الأصلية}}، مما يكشف عنوان البريد الإلكتروني الخاص {{GENDER:$2|بك}} {{GENDER:$1|لهم}}.",
        "usermessage-summary": "ترك رسالة نظام.",
        "usermessage-editor": "مراسل النظام",
        "watchlist": "قائمة مراقبتي",
        "logentry-tag-update-logentry": "$1 {{GENDER:$2|حدث|حدثت}} الوسوم على مدخلة السجل $5 للصفحة $3 ({{PLURAL:$7|أضاف}} $6; {{PLURAL:$9|أزال}} $8)",
        "rightsnone": "(لا شيء)",
        "revdelete-summary": "ملخص التعديل",
+       "rightslogentry-temporary-group": "$1 (مؤقت، حتى $2)",
        "feedback-adding": "إضافة تعليقات إلى الصفحة...",
        "feedback-back": "رجوع",
        "feedback-bugcheck": "رائع! تحقق من أن هذه ليست إحدى [$1 العلل المعروفة].",
        "usercssispublic": "من فضل لاحظ: صفحات الCSS الفرعية لا ينبغي أن تحتوي على بيانات سرية بما أنها يمكن رؤيتها بواسطة المستخدمين الآخرين.",
        "restrictionsfield-badip": "عنوان أيبي أو نطاق غير صحيح: $1",
        "restrictionsfield-label": "نطاقات الأيبي المسموح بها:",
-       "restrictionsfield-help": "عنوان أيبي أو نطاق CIDR واحد لكل سطر. لتفعيل كل شيء، استخدم<br><code>0.0.0.0/0</code><br><code>::/0</code>",
+       "restrictionsfield-help": "عنوان أيبي أو نطاق CIDR واحد لكل سطر. لتفعيل كل شيء، استخدم:\n<pre>0.0.0.0/0\n::/0</pre>",
        "revid": "المراجعة $1",
        "pageid": "معرف الصفحة $1"
 }
index e06c407..46722ee 100644 (file)
        "youremail": "Corréu electrónicu:",
        "username": "Nome d'{{GENDER:$1|usuariu|usuaria}}:",
        "prefs-memberingroups": "{{GENDER:$2|Miembru}} {{PLURAL:$1|del grupu|de los grupos}}:",
+       "group-membership-link-with-expiry": "$1 (ata'l $2)",
        "prefs-registration": "Hora del rexistru:",
        "yourrealname": "Nome real:",
        "yourlanguage": "Llingua:",
        "userrights-nodatabase": "La base de datos $1 nun esiste o nun ye llocal.",
        "userrights-changeable-col": "Grupos que pues camudar",
        "userrights-unchangeable-col": "Grupos que nun pues camudar",
+       "userrights-expiry-current": "Caduca el $1",
+       "userrights-expiry-none": "Nun caduca",
+       "userrights-expiry": "Caduca:",
+       "userrights-expiry-existing": "Hora de caducidá actual: $3 del $2",
+       "userrights-expiry-othertime": "Otru periodu:",
+       "userrights-expiry-options": "1 día:1 day,1 selmana:1 week,1 mes:1 month,3 meses:3 months,6 meses:6 months,1 añu:1 year",
+       "userrights-invalid-expiry": "La hora de caducidá del grupu «$1» nun ye válida.",
+       "userrights-expiry-in-past": "La hora de caducidá del grupu «$1» ta nel pasáu",
        "userrights-conflict": "¡Conflictu de cambiu de permisos d'usuariu! Por favor, revise y confirme los cambios.",
        "group": "Grupu:",
        "group-user": "Usuarios",
        "recentchanges-legend-plusminus": "(''±123'')",
        "recentchanges-submit": "Amosar",
        "rcfilters-activefilters": "Filtros activos",
+       "rcfilters-restore-default-filters": "Restaurar los filtros predeterminaos",
+       "rcfilters-clear-all-filters": "Borrar tolos filtros",
        "rcfilters-search-placeholder": "Filtriar los cambeos recién (restola o empieza a escribir)",
        "rcfilters-invalid-filter": "Filtru inválidu",
+       "rcfilters-empty-filter": "Nun hai filtros activos. Amuésense toles contribuciones.",
        "rcfilters-filterlist-title": "Filtros",
        "rcfilters-filterlist-noresults": "Nun s'alcontraron filtros",
        "rcfilters-filtergroup-registration": "Rexistru del usuariu",
        "apisandbox-sending-request": "Unviando solicitú a la API...",
        "apisandbox-loading-results": "Recibiendo los resultaos de la API...",
        "apisandbox-results-error": "Asocedió un error al cargar la respuesta de la consulta API: $1.",
-       "apisandbox-request-params-json": "Parámetros JSON:",
+       "apisandbox-request-selectformat-label": "Amosar los datos de la solicitú como:",
+       "apisandbox-request-format-url-label": "Cadena de consulta como URL",
        "apisandbox-request-url-label": "URL de la solicitú:",
+       "apisandbox-request-json-label": "JSON de la solicitú:",
        "apisandbox-request-time": "Duración de la solicitú: {{PLURAL:$1|$1 ms}}",
        "apisandbox-results-fixtoken": "Igua'l token y vuelve a unviar",
        "apisandbox-results-fixtoken-fail": "Nun pudo recuperase'l token «$1».",
        "emailccsubject": "Copia del to mensaxe a $1: $2",
        "emailsent": "Corréu unviáu",
        "emailsenttext": "Unviose'l to mensaxe de corréu.",
-       "emailuserfooter": "Esti corréu electrónicu {{GENDER:$1|unviólu}} $1 a {{GENDER:$2|$2}} per aciu de la función «{{int:emailuser}}» de {{SITENAME}}. Unviaráse'l {{GENDER:$2|to}} corréu direutamente {{GENDER:$1|al remitente|a la remitente}} orixinal, {{GENDER:$1|revelando-y}} la {{GENDER:$2|to}} direición de corréu.",
+       "emailuserfooter": "Esti corréu electrónicu {{GENDER:$1|unviólu}} $1 a {{GENDER:$2|$2}} per aciu de la función «{{int:emailuser}}» de {{SITENAME}}. Si {{GENDER:$2|contestes}} a esti corréu, el {{GENDER:$2|to}} corréu unviaráse direutamente {{GENDER:$1|al remitente|a la remitente}} orixinal, {{GENDER:$1|revelando-y}} la {{GENDER:$2|to}} direición de corréu.",
        "usermessage-summary": "Dexar un mensaxe del sistema.",
        "usermessage-editor": "Mensaxería del sistema",
        "watchlist": "Llista de siguimientu",
        "logentry-tag-update-logentry": "$1 {{GENDER:$2|anovó}} etiquetes na entrada del rexistru $5 de la páxina $3 ({{PLURAL:$7|amestó}} $6; {{PLURAL:$9|desanició}} $8)",
        "rightsnone": "(nengún)",
        "revdelete-summary": "editar resume",
+       "rightslogentry-temporary-group": "$1 (temporal, ata $2)",
        "feedback-adding": "Amestando el comentariu a la páxina...",
        "feedback-back": "Anterior",
        "feedback-bugcheck": "¡Perfeuto! Comprueba que nun tea yá ente los [$1 fallos conocíos].",
index e0ef977..03531a6 100644 (file)
        "about": "Тасуирлау",
        "article": "Мәҡәлә",
        "newwindow": "(яңы биттә)",
-       "cancel": "Ð\91Ó©Ñ\82Ó©Ñ\80Ó©Ñ\80гÓ\99",
+       "cancel": "Ð\9aиÑ\80е Ð°Ð»Ñ\8bÑ\80Ò\93а",
        "moredotdotdot": "Дауамы...",
        "morenotlisted": "Был исемлек тулы түгел",
        "mypage": "Бит",
        "views": "Ҡарауҙар",
        "toolbox": "Ҡоралдар",
        "tool-link-userrights": "{{GENDER:$1|Ҡатнашыусы}} төркөмдәрен үҙгәртергә",
-       "tool-link-userrights-readonly": "{{GENDER:$1|ҡаÑ\82наÑ\88Ñ\8bÑ\83Ñ\81Ñ\8bлаÑ\80}} Ñ\82Ó©Ñ\80көмөн ҡарарға",
+       "tool-link-userrights-readonly": "{{GENDER:$1|ҠаÑ\82наÑ\88Ñ\8bÑ\83Ñ\81Ñ\8b|ҠаÑ\82наÑ\88Ñ\8bÑ\83лаÑ\80}} Ñ\82Ó©Ñ\80көмдÓ\99Ñ\80ен ҡарарға",
        "tool-link-emailuser": "{{GENDER:$1|Ҡатнашыусыға}} хат яҙырға",
        "userpage": "Ҡулланыусы битен ҡарарға",
        "projectpage": "Проект битен ҡарарға",
        "title-invalid-too-long": "Һоралған бит исеме бик оҙон. $1 {{PLURAL:$1|байттан}} артмаҫҡа тейеш.",
        "title-invalid-leading-colon": "Һораған бит башында ярамаған ике нөктә бар.",
        "perfcached": "Был мәғлүмәттәр кэштан алынған, уларҙа һуңғы үҙгәртеүҙәр булмаҫҡа мөмкин. Кэшта иң күбе {{PLURAL:$1|язма}} һаҡлана.",
-       "perfcachedts": "Был мәғлүмәттәр кэштан алынған, ул һуңғы тапҡыр $1 яңыртылды.  Кэшта иң күбе  {{PLURAL:$4|язма}} һаҡлана",
+       "perfcachedts": "Был мәғлүмәттәр кэштан алынған, ул һуңғы тапҡыр $1 яңыртылды.  Кэшта иң күбе $4 {{PLURAL:$4|яҙма}} һаҡлана.",
        "querypage-no-updates": "Был битте яңыртыу хәҙер тыйылған.\nБында күрһәтелгән мәғлүмәттәр яңыртылмаясаҡ.",
        "viewsource": "Сығанаҡты ҡарау",
        "viewsource-title": "$1 битенең сығанаҡ текстын ҡарарға",
        "resetpass_submit": "Серһүҙ ҡуйырға һәм танышырға",
        "changepassword-success": "Серһүҙегеҙ уңышлы үҙгәртелде!",
        "changepassword-throttled": "Һеҙ системаға ҡат-ҡат танылырға тырыштығыҙ.\nТағы бер танылырҙан алда, зинһар, $1 көтөгөҙ.",
-       "botpasswords": "Роботтар серһүҙе.",
+       "botpasswords": "Роботтар серһүҙе",
        "botpasswords-summary": "<em>ПРобот пароле</em> API иҫәп яҙмаһына логин һәм паролһыҙ инергә мөмкинлек бирә. Робот пароле менән ингәндә ҡулланыусы хоҡуғы сикләнгән булыуы мөмкин.\n\nНи өсөн икәнен белмәһәгеҙ, быны эшләмәүегеҙ яҡшыраҡ.",
        "botpasswords-disabled": "Роботтар серһүҙе һүндерелгән.",
        "botpasswords-no-central-id": "Робот серһүҙен ҡулланыу өсөн үҙәк иҫәп яҙмаһына инергә кәрәк.",
        "resetpass_forbidden-reason": "Серһүҙҙәр үҙгәртелә алмай: $1",
        "resetpass-no-info": "Был битте туранан ҡарау өсөн һеҙгә системала танылырға кәрәк.",
        "resetpass-submit-loggedin": "Серһүҙҙе үҙгәртергә",
-       "resetpass-submit-cancel": "Ð\91Ó©Ñ\82Ó©Ñ\80Ó©Ñ\80гÓ\99",
+       "resetpass-submit-cancel": "Ð\9aиÑ\80е Ð°Ð»Ñ\8bÑ\80Ò\93а",
        "resetpass-wrong-oldpass": "Хаталы ваҡытлыса йәки ағымдағы серһүҙ.\nҺеҙ, бәлки, серһүҙегеҙҙе алмаштырғанһығыҙ йәки яңы серһүҙ һоратҡанһығыҙ.",
        "resetpass-recycled": "Үҙегеҙҙекенән айырмалы серһүҙ һайлағыҙ.",
        "resetpass-temp-emailed": "Һеҙ электорон почта аша ебәрелгән ваҡытлыса серһүҙ менән индегеҙ. Инеүҙе башҡарыу өсөн яңы серһүҙ яҙығыҙ.",
        "feedback-useragent": "Браузер:",
        "searchsuggest-search": "{{SITENAME}} эсендә эҙләү",
        "searchsuggest-containing": "эстәлегендә...",
-       "api-error-badaccess-groups": "Һеҙгә был викиға файлдар күсереү рөхсәт ителмәй",
        "api-error-badtoken": "Эске хата: дөрөҫ булмаған токен",
-       "api-error-blocked": "Мөхәррирләү һеҙҙең өсөн бикләнде.",
-       "api-error-copyuploaddisabled": "Был серверҙа URL адрес буйынса йөкләү өҙөлгән",
-       "api-error-duplicate": "Бындай эстәлекле {{PLURAL:$1|файл}}  бар.",
-       "api-error-duplicate-archive": "Сайтта бындай эстәлекле {{PLURAL:$1|башҡа файл}} бар ине инде, ләкин {{PLURAL:$1|1=ул юйылды|улар юйылды}}",
-       "api-error-empty-file": "Һеҙ ебәргән файл буш.",
        "api-error-emptypage": "Яңы буш биттәр яһау тыйыла.",
-       "api-error-fetchfileerror": "Эске хата: файлды күсергән ваҡытта хата китте",
-       "api-error-fileexists-forbidden": "«$1» исемле файл бар һәм өҫтөнә яҙып булмай.",
-       "api-error-fileexists-shared-forbidden": "«$1» исемле файл уртаҡ файлдар һаҡлағысында бар һәм өҫтөнә яҙып булмай.",
-       "api-error-file-too-large": "Һеҙ ебәргән файл үтә ҙур.",
-       "api-error-filename-tooshort": "Файл исеме бик ҡыҫҡа.",
-       "api-error-filetype-banned": "Был файл төрө тыйылған.",
-       "api-error-filetype-banned-type": "$1 {{PLURAL:$4|1=тыйылған файл төрө|тыйылған файл төрҙәре}}. Рөхсәт ителгән {{PLURAL:$3|1=файл төрө|файл төрҙәре}} $2.",
-       "api-error-filetype-missing": "Был файлдың ҡушымтаһы юҡ",
-       "api-error-hookaborted": "Һеҙ эшләргә теләгән үҙгәртеүҙәр ҡушымтаны тикшереүсе тарафынан өҙөлдө",
-       "api-error-http": "Эске хата: серверға бәйләнеп булмай.",
-       "api-error-illegal-filename": "Рөхсәт ителмәгән файл исеме.",
-       "api-error-internal-error": "Эске хата: һеҙ викиға йөкләгәнде тикшергән ваҡытта хата китте",
-       "api-error-invalid-file-key": "Эске хата: ваҡытлыса һаҡлағыста файл табылманы",
-       "api-error-missingparam": "Эске хата: мөрәжәғеттең параматрҙары юҡ.",
-       "api-error-missingresult": "Эске хата: күсереү уңышлы булыуын билдәләп булманы.",
-       "api-error-mustbeloggedin": "Файлдарҙы йөкмәтеү өсөн һеҙ сисемаға танышырға тейешһегеҙ.",
-       "api-error-mustbeposted": "Эске хата: мөрәжәғәт HTTP POST адресын талап итә.",
-       "api-error-noimageinfo": "Йөкләү уңышлы тамамланды, әммә сервер файл тураһында бер ниндәйҙә мәғлүмәт бирмәне.",
-       "api-error-nomodule": "Эске хата: тейәү модуле көйләнмәгән.",
-       "api-error-ok-but-empty": "Эске хата: серверҙан яуап юҡ.",
-       "api-error-overwrite": "Булған файлды алыштырыу рөхсәт ителмәй.",
-       "api-error-stashfailed": "Эске хата: сервер ваҡытлыса файлды һаҡлай алманы.",
        "api-error-publishfailed": "Эске хата: сервер ваҡытлыса файлды һаҡлай алманы.",
-       "api-error-stasherror": "Файлы һаҡлағысҡа тейәгән ваҡытта хата китте.",
-       "api-error-stashedfilenotfound": "Ваҡытлыса һаҡлағыстан файлы тейәгән ваҡытта сығанаҡ файл табылманы.",
-       "api-error-stashpathinvalid": "Ваҡытлыса һаҡлағыста урынлашҡан файл юлы дөрөҫ түгел.",
-       "api-error-stashfilestorage": "Файлды һаҡлағысҡа тейәгән ваҡытта хата китте.",
-       "api-error-stashzerolength": "Сервер файлды ваҡытлыса һаҡлағыста һаҡлау алмай, сөнкт оҙонлоғо 0.",
-       "api-error-stashnotloggedin": "Файлды ваҡытлыса һаҡлағысҡа урынлаштырыу өсөн һеҙ системаҡа инергә тейешһегеҙ.",
-       "api-error-stashwrongowner": "Ваҡытлыса һаҡлағыстағы файлда асырға теләнегеҙ, был файл һеҙҙеке түгел",
-       "api-error-stashnosuchfilekey": "Ваҡытлыса һаҡлағыста һеҙ асырға теләгән файлдың асҡысы юҡ.",
-       "api-error-timeout": "Көтөлгән ваҡыт эсендә сервер яуып бирмәне.",
-       "api-error-unclassified": "Билдәһеҙ хата барлыҡҡа килде.",
-       "api-error-unknown-code": "Билдәһеҙ хата: «$1»",
-       "api-error-unknown-error": "Эске хата: файлды йөкләгәндә ниндәйҙер хата китте.",
+       "api-error-stashfailed": "Эске хата: сервер ваҡытлыса файлды һаҡлай алманы.",
        "api-error-unknown-warning": "Билдәһеҙ белдереү: \"$1\".",
        "api-error-unknownerror": "Билдәһеҙ хата: «$1»",
-       "api-error-uploaddisabled": "Был викила файл тейәү мөмкинлеге ябылған.",
-       "api-error-verification-error": "Был файл боҙолған, йәки дөрөҫ булмаған ҡушымтаһы бар.",
        "duration-seconds": "$1 {{PLURAL:$1|1=секунд|секунд}}",
        "duration-minutes": "$1 {{PLURAL:$1|1=минут|минут}}",
        "duration-hours": "$1 {{PLURAL:$1|1=сәғәт|сәғәт}}",
index 0497a0d..c659021 100644 (file)
        "undo-norev": "Рэдагаваньне ня можа быць адмененае, таму што яно не існуе альбо было выдаленае.",
        "undo-nochange": "Выглядае, што праўка ўжо была адмененая.",
        "undo-summary": "Скасаваньне праўкі $1 {{GENDER:$2|удзельніка|удзельніцы}} [[Special:Contributions/$2|$2]] ([[User talk:$2|гутаркі]])",
-       "undo-summary-username-hidden": "Ð\92Ñ\8dÑ\80Ñ\81Ñ\96Ñ\8f $1 Ñ\81каÑ\81аванаÑ\8f Ñ\81Ñ\85аванÑ\8bм Ñ\83дзелÑ\8cнÑ\96кам",
+       "undo-summary-username-hidden": "СкаÑ\81аванÑ\8cне Ð²Ñ\8dÑ\80Ñ\81Ñ\96Ñ\96 $1 Ñ\81Ñ\85аванага Ñ\9eдзелÑ\8cнÑ\96ка",
        "cantcreateaccount-text": "Стварэньне рахункаў з гэтага IP-адрасу ('''$1''') было заблякаванае [[User:$3|$3]].\n\nПрычына блякаваньня пададзеная $3: ''$2''",
        "cantcreateaccount-range-text": "Стварэньне рахункаў з IP-адрасоў у дыяпазоне <strong>$1</strong>, у які ўваходзіць ваш IP-адрас (<strong>$4</strong>), было забароненае {{GENDER:$3|ўдзельнікам|ўдзельніцай}} [[User:$3|$3]].\n\n{{GENDER:$3|Удзельнікам|Удзельніцай}} $3 была пададзеная наступная прычына: <em>$2</em>.",
        "viewpagelogs": "Паказаць журналы падзеяў для гэтай старонкі",
        "youremail": "Адрас электроннай пошты:",
        "username": "Імя {{GENDER:$1|ўдзельніка|ўдзельніцы}}:",
        "prefs-memberingroups": "{{GENDER:$2|Удзельнік|Удзельніца}} {{PLURAL:$1|1=групы|групаў}}:",
+       "group-membership-link-with-expiry": "$1 (да $2)",
        "prefs-registration": "Час рэгістрацыі:",
        "yourrealname": "Сапраўднае імя:",
        "yourlanguage": "Мова інтэрфэйсу:",
        "userrights-nodatabase": "Базы зьвестак $1 не існуе альбо яна не зьяўляецца лякальнай.",
        "userrights-changeable-col": "Групы, якія Вы можаце мяняць",
        "userrights-unchangeable-col": "Групы, якія Вы ня можаце мяняць",
+       "userrights-expiry-current": "Сканчаецца $1",
        "userrights-conflict": "Канфлікт пры зьмене правоў удзельнікаў! Калі ласка, праверце і захавайце вашыя зьмены.",
        "group": "Група:",
        "group-user": "Удзельнікі",
        "recentchanges-legend-newpage": "{{int:recentchanges-label-newpage}} (глядзіце таксама [[Special:NewPages|сьпіс новых старонак]])",
        "recentchanges-submit": "Паказаць",
        "rcfilters-activefilters": "Актыўныя фільтры",
+       "rcfilters-restore-default-filters": "Аднавіць фільтры па змоўчаньні",
+       "rcfilters-clear-all-filters": "Ачысьціць усе фільтры",
        "rcfilters-search-placeholder": "Фільтар апошніх зьменаў (праглядзець або пачніце друкаваць)",
        "rcfilters-invalid-filter": "Няслушны фільтар",
+       "rcfilters-empty-filter": "Няма актыўных фільтраў. Паказаны ўвесь унёсак.",
        "rcfilters-filterlist-title": "Фільтры",
        "rcfilters-filterlist-noresults": "Фільтры ня знойдзеныя",
        "rcfilters-filtergroup-registration": "Рэгістрацыя ўдзельнікаў",
        "rcfilters-filter-registered-label": "Зарэгістраваныя",
+       "rcfilters-filter-registered-description": "Рэдактары, якія ўвайшлі ў сыстэму.",
+       "rcfilters-filter-unregistered-label": "Незарэгістраваныя",
+       "rcfilters-filter-unregistered-description": "Рэдактары, якія не ўвайшлі ў сыстэму",
        "rcfilters-filtergroup-authorship": "Рэдагаваць аўтарства",
        "rcfilters-filter-editsbyself-label": "Вашыя праўкі",
        "rcfilters-filter-editsbyself-description": "Праўкі, зробленыя вамі",
        "rcfilters-filter-editsbyother-label": "Праўкі іншых удзельнікаў",
        "rcfilters-filter-editsbyother-description": "Праўкі, зробленыя іншымі ўдзельнікамі (ня вамі).",
-       "rcfilters-filtergroup-userExpLevel": "Узровень досьведу ўдзельнікаў",
+       "rcfilters-filtergroup-userExpLevel": "Узровень досьведу (толькі для зарэгістраваных удзельнікаў)",
        "rcfilters-filter-userExpLevel-newcomer-label": "Навічкі",
-       "rcfilters-filter-userExpLevel-newcomer-description": "Ð\97Ñ\83Ñ\81Ñ\96м Ð½Ð¾Ð²Ñ\8bÑ\8f Ñ\80Ñ\8dдакÑ\82аÑ\80Ñ\8b: Ð¼енш за 10 правак і 4 дні актыўнасьці.",
+       "rcfilters-filter-userExpLevel-newcomer-description": "Ð\9cенш за 10 правак і 4 дні актыўнасьці.",
        "rcfilters-filter-userExpLevel-learner-label": "Вучні",
        "rcfilters-filter-userExpLevel-learner-description": "Болей дзён актыўнасьці і правак, чым у «навічкоў», але меней чым у «дасьведчаных удзельнікаў».",
        "rcfilters-filter-userExpLevel-experienced-label": "Дасьведчаныя ўдзельнікі",
        "rcfilters-filter-userExpLevel-experienced-description": "Больш за 30 дзён актыўнасьці і 500 правак.",
+       "rcfilters-filtergroup-automated": "Аўтаматычны ўнёсак",
+       "rcfilters-filter-bots-label": "Робат",
+       "rcfilters-filter-bots-description": "Праўкі, зробленыя з дапамогай аўтаматызаваных інструмэнтаў.",
+       "rcfilters-filter-humans-label": "Чалавек (ня робат)",
+       "rcfilters-filter-humans-description": "Праўкі, зробленыя людзьмі.",
+       "rcfilters-filtergroup-significance": "Значэньне",
        "rcnotefrom": "Ніжэй {{PLURAL:$5|знаходзіцца зьмена|знаходзяцца зьмены}} з <strong>$4 $3</strong> (да <strong>$1</strong> на старонку).",
        "rclistfrom": "Паказаць зьмены з $2 $3",
        "rcshowhideminor": "$1 дробныя праўкі",
        "apisandbox-sending-request": "Адпраўка API-запыту…",
        "apisandbox-loading-results": "Атрымліваем API-вынікі…",
        "apisandbox-results-error": "Адбылася памылка пры загрузцы адказу на API-запыт: $1.",
-       "apisandbox-request-params-json": "JSON-парамэтры:",
        "apisandbox-request-url-label": "URL-адрас запыту:",
        "apisandbox-request-time": "Час запыту: {{PLURAL:$1|$1 мс}}",
        "apisandbox-results-fixtoken": "Выпраўце токен і паўтарыце адпраўку",
        "emailccsubject": "Копія Вашага ліста да $1: $2",
        "emailsent": "Ліст адасланы",
        "emailsenttext": "Ваш ліст быў адасланы.",
-       "emailuserfooter": "Гэты ліст быў дасланы {{GENDER:$1|ўдзельнікам|ўдзельніцай}} $1 да {{GENDER:$2|ўдзельніка|ўдзельніцы}} $2 з дапамогай функцыі «{{int:emailuser}}» {{GRAMMAR:родны|{{SITENAME}}}}. {{GENDER:$2|Ваш}} ліст у адказ будзе дасланы {{GENDER:$1|адпраўніку|адпраўніцы}}, і {{GENDER:$1|яму|ёй}} будзе бачны {{GENDER:$2|ваш}} адрас электроннай пошты.",
+       "emailuserfooter": "Гэты ліст быў дасланы {{GENDER:$1|ўдзельнікам|ўдзельніцай}} $1 да {{GENDER:$2|ўдзельніка|ўдзельніцы}} $2 з дапамогай функцыі «{{int:emailuser}}» {{GRAMMAR:родны|{{SITENAME}}}}. Калі вы адкажаце на гэты ліст, {{GENDER:$2|ваш}} ліст у адказ будзе дасланы непасрэдна {{GENDER:$1|адпраўніку|адпраўніцы}}, і {{GENDER:$1|яму|ёй}} будзе бачны {{GENDER:$2|ваш}} адрас электроннай пошты.",
        "usermessage-summary": "Паведамленьне пра выхад з сыстэмы.",
        "usermessage-editor": "Дастаўка сыстэмных паведамленьняў",
        "watchlist": "Сьпіс назіраньня",
index 25ac402..79558c1 100644 (file)
@@ -31,7 +31,8 @@
                        "Matma Rex",
                        "আজিজ",
                        "Kayser Ahmad",
-                       "NahidSultan"
+                       "NahidSultan",
+                       "Elias Ahmmad"
                ]
        },
        "tog-underline": "সংযোগগুলির নিচে দাগ দেখানো হোক:",
        "searcharticle": "চলো",
        "history": "পাতার ইতিহাস",
        "history_short": "ইতিহাস",
+       "history_small": "ইতিহাস",
        "updatedmarker": "আমার শেষ পরিদর্শনের পর থেকে হালনাগাদকৃত",
        "printableversion": "ছাপার যোগ্য সংস্করণ",
        "permalink": "স্থায়ী সংযোগ",
        "recentchanges-legend-newpage": "{{int:recentchanges-label-newpage}} (আরও দেখুন [[Special:NewPages|নতুন পাতার তালিকা]])",
        "recentchanges-legend-plusminus": "(''±১২৩'')",
        "recentchanges-submit": "দেখাও",
+       "rcfilters-activefilters": "সক্রিয় ফিল্টার",
+       "rcfilters-restore-default-filters": "ডিফল্ট ফিল্টার পুনরুদ্ধার",
+       "rcfilters-clear-all-filters": "সমস্ত ফিল্টার অপসারণ",
+       "rcfilters-search-placeholder": "ফিল্টারে সাম্প্রতিক পরিবর্তনসমূহ (ব্রাউজ বা টাইপ করা শুরু করুন)",
+       "rcfilters-invalid-filter": "অকার্যকর ফিল্টার",
+       "rcfilters-empty-filter": "কোনো সক্রিয় ফিল্টার নেই। সমস্ত অবদান দেখানো হয়েছে।",
+       "rcfilters-filterlist-title": "ছাকনী",
+       "rcfilters-filterlist-noresults": "কোনও ফিল্টার পাওয়া যায়নি",
+       "rcfilters-filtergroup-registration": "ব্যবহারকারী রেজিস্ট্রেশন",
+       "rcfilters-filter-registered-label": "নিবন্ধিত",
+       "rcfilters-filter-registered-description": "লগ-ইন সম্পাদকবৃন্দ।",
+       "rcfilters-filter-unregistered-label": "অনিবন্ধিত",
+       "rcfilters-filtergroup-authorship": "কৃতি সম্পাদনা",
        "rcfilters-filter-editsbyself-label": "আপনার নিজস্ব সম্পাদনা",
        "rcfilters-filter-editsbyself-description": "আপনার দ্বারা সম্পাদনা।",
        "rcfilters-filter-editsbyother-label": "অন্যদের দ্বারা সম্পাদনা",
        "rcfilters-filter-editsbyother-description": "অন্য ব্যবহারকারীদের দ্বারা করা সম্পাদনা (আপনার না)।",
-       "rcfilters-filtergroup-userExpLevel": "বà§\8dযবহারà¦\95ারà§\80র à¦\85ভিà¦\9cà§\8dà¦\9eতা à¦¸à§\8dতর",
+       "rcfilters-filtergroup-userExpLevel": "à¦\85ভিà¦\9cà§\8dà¦\9eতার à¦¸à§\8dতর (শà§\81ধà§\81 à¦®à¦¾à¦¤à§\8dর à¦¨à¦¿à¦¬à¦¨à§\8dধিত à¦¬à§\8dযবহারà¦\95ারà§\80র à¦\9cনà§\8dয)",
        "rcfilters-filter-userExpLevel-newcomer-label": "নতুন আগত",
        "rcfilters-filter-userExpLevel-learner-label": "শিক্ষার্থী",
        "rcfilters-filter-userExpLevel-experienced-label": "অভিজ্ঞ ব্যবহারকারী",
+       "rcfilters-filter-bots-label": "বট",
+       "rcfilters-filter-pageedits-label": "পাতার সম্পাদনা",
        "rcnotefrom": "<strong>$2</strong>টা থেকে সংঘটিত পরিবর্তনগুলি (সর্বোচ্চ <strong>$1টি</strong> দেখানো হয়েছে)।",
        "rclistfrom": "$2, $3 তারিখের পর সংঘটিত নতুন পরিবর্তনগুলো দেখাও",
        "rcshowhideminor": "অনুল্লেখ্য পরিবর্তনগুলো $1",
        "apisandbox-results": "ফলাফল",
        "apisandbox-sending-request": "API অনুরোধ পাঠানো হচ্ছে...",
        "apisandbox-loading-results": "API ফলাফল গ্রহণ করা হচ্ছে...",
-       "apisandbox-request-params-json": "JSON প্যারামিটার:",
+       "apisandbox-request-selectformat-label": "অনুরোধ ডেটা দেখান যেভাবে:",
+       "apisandbox-request-format-url-label": "URL কোয়েরি স্ট্রিং",
        "apisandbox-request-url-label": "অনুরোধের URL:",
+       "apisandbox-request-json-label": "অনুরোধ JSON:",
        "apisandbox-request-time": "অনুরোধের সময়: {{PLURAL:$1|$1 মি.সে.}}",
        "apisandbox-results-fixtoken": "টোকেন সংশোধন ও পুনরায় জমা",
        "apisandbox-alert-page": "এই পাতার ঘরগুলো বৈধ নয়।",
        "emailccsubject": "আপনার বার্তার অনুলিপি $1-কে: $2",
        "emailsent": "ই-মেইল প্রেরণ করা হয়েছে",
        "emailsenttext": "আপনার ই-মেইল বার্তা প্রেরণ করা হয়েছে।",
-       "emailuserfooter": "এই ইমেইলটি {{SITENAME}} সাইটের \"{{int:emailuser}}\" সুবিধা ব্যবহার করে $1-এর পক্ষ থেকে {{GENDER:$2|$2}}-এর নিকট {{GENDER:$1|পাঠানো হয়েছে}}। {{GENDER:$2|আপনার}} উত্তরের ইমেইলটি সরাসরি {{GENDER:$1|মূল প্রেরকের}} কাছে পাঠানো হবে, সেই সাথে {{GENDER:$2|আপনার}} ইমেল ঠিকানা {{GENDER:$1|তাঁর}} কাছে প্রকাশ করা হবে।",
+       "emailuserfooter": "এই ইমেইলটি {{SITENAME}} সাইটের \"{{int:emailuser}}\" সুবিধা ব্যবহার করে $1-এর পক্ষ থেকে {{GENDER:$2|$2}}-এর নিকট {{GENDER:$1|পাঠানো হয়েছে}}। যদি {{GENDER:$2|আপনি}} এই ইমেইলটির উত্তর দেন, তাহলে {{GENDER:$2|আপনার}} উত্তরের ইমেইলটি সরাসরি {{GENDER:$1|মূল প্রেরকের}} কাছে পাঠানো হবে, সেই সাথে {{GENDER:$2|আপনার}} ইমেল ঠিকানা {{GENDER:$1|তাঁর}} কাছে প্রকাশ করা হবে।",
        "usermessage-summary": "বাদবাকি সিস্টেম বার্তা",
        "usermessage-editor": "সিস্টেম ম্যাসেঞ্জার",
        "usermessage-template": "MediaWiki:ব্যবহারকারী বার্তা",
        "pagelang-select-lang": "ভাষা নির্বাচন করুন",
        "pagelang-reason": "কারণ",
        "pagelang-submit": "জমা দাও",
+       "pagelang-db-failed": "ডাটাবেস পৃষ্ঠার ভাষা পরিবর্তন করতে ব্যর্থ হয়েছে।",
        "right-pagelang": "পাতার ভাষা পরিবর্তন করুন",
        "action-pagelang": "পাতার ভাষা পরিবর্তন করুন",
        "log-name-pagelang": "ভাষা পরিবর্তন লগ",
        "usercssispublic": "অনুগ্রহ করে লক্ষ্য করুন: সিএসএসের উপপাতাগুলিতে গোপনীয় তথ্য থাকা উচিত নয় যেহেতু অন্যান্য ব্যবহারকারীও এগুলি দেখতে পান।",
        "restrictionsfield-badip": "আইপি ঠিকানা অথবা পরিসীমা অবৈধ: $1",
        "restrictionsfield-label": "অনুমোদিত আইপি পরিসীমা:",
-       "restrictionsfield-help": "লাইন প্রতি একটি আইপি ঠিকানা বা CIDR পরিসীমা। সবকিছু সক্রিয় করতে<br><code>0.0.0.0/0</code><br><code>::/0</code><br>ব্যবহার করুন",
+       "restrictionsfield-help": "লাইন প্রতি একটি আইপি ঠিকানা বা CIDR পরিসীমা। সবকিছু সক্রিয় করতে, <pre>0.0.0.0/0::/0</pre> ব্যবহার করুন",
        "revid": "সংশোধন $1",
        "pageid": "পাতার আইডি $1"
 }
index 352d7e5..cefa4a6 100644 (file)
        "searcharticle": "Mont",
        "history": "Istor ar bajenn",
        "history_short": "Istor",
+       "history_small": "istor",
        "updatedmarker": "kemmet abaoe ma zaol-sell diwezhañ",
        "printableversion": "Stumm da voullañ",
        "permalink": "Chomlec'h ar stumm-mañ",
        "pool-timeout": "Aet eur dreist d'an termen gortoz evit ar stankadenn",
        "pool-queuefull": "Soulgarget eo ar servijerioù",
        "pool-errorunknown": "Fazi dianav",
+       "pool-servererror": "N'eo ket hegerz ar servij kontañ ($1).",
        "poolcounter-usage-error": "Fazi implij : $1",
        "aboutsite": "Diwar-benn {{SITENAME}}",
        "aboutpage": "Project:Diwar-benn",
        "content-model-css": "CSS",
        "content-json-empty-object": "Elfenn goullo",
        "content-json-empty-array": "Taolenn c'houllo",
+       "deprecated-self-close-category": "Pajennoù a ra gant tikedennoù HTML emserriñ direizh",
        "expensive-parserfunction-warning": "Diwallit : Re a c'halvoù koustus e-keñver an arc'hwelioù parser zo gant ar bajenn-mañ.\n\nDleout a rafe bezañ nebeutoc'h eget $2 {{PLURAL:$2|galv|galv}}, ha {{PLURAL:$1|$1 galv|$1 galv}} zo.",
        "expensive-parserfunction-category": "Pagjennoù enno re a c'halvoù koustus e-keñver an arc'hwelioù parser.",
        "post-expand-template-inclusion-warning": "Diwallit : re a batromoù zo war ar bajenn-mañ.\nLod anezho a vo lakaet a-gostez.",
        "mergehistory-empty": "N'haller ket kendeuziñ stumm ebet.",
        "mergehistory-done": "Kendeuzet ez eus bet $3 {{PLURAL:$3|stumm|stumm}} eus $1 e [[:$2]].",
        "mergehistory-fail": "Dibosupl kendeuziñ an istorioù. Gwiriit ar bajenn hag arventennoù an deiziadoù.",
+       "mergehistory-fail-bad-timestamp": "Merk amzer direizh.",
+       "mergehistory-fail-invalid-source": "Pajenn darzh direizh.",
+       "mergehistory-fail-invalid-dest": "Pajenn vuket direizh.",
        "mergehistory-fail-toobig": "Ne c'haller ket kendeuziñ an istorioù o vezañ ma vefe mont en tu all d'ar harzh a $1 reizhadenn da zilec'hiañ.",
        "mergehistory-no-source": "N'eus ket eus ar bajenn orin $1.",
        "mergehistory-no-destination": "N'eus ket eus ar bajenn dal $1.",
        "prefs-rc": "Kemmoù diwezhañ",
        "prefs-watchlist": "Roll evezhiañ",
        "prefs-editwatchlist": "Kemmañ ar roll evezhiañ",
+       "prefs-editwatchlist-edit": "Gwelet ha lemel titloù a-ziwar ho roll evezhiañ",
        "prefs-editwatchlist-raw": "Kemmañ ar roll evezhiañ (mod diginkl)",
        "prefs-editwatchlist-clear": "Diverkañ ho roll evezhiañ",
        "prefs-watchlist-days": "Niver a zevezhioù da ziskouez er rollad evezhiañ :",
        "grouppage-bot": "{{ns:project}}:Botoù",
        "grouppage-sysop": "{{ns:project}}:Merourien",
        "grouppage-bureaucrat": "{{ns:project}}: Burevidi",
-       "grouppage-suppress": "{{ns:project}}: Dindan evezh",
+       "grouppage-suppress": "{{ns:project}}: Diverkerien",
        "right-read": "Lenn ar pajennoù",
        "right-edit": "Kemmañ ar pajennoù",
        "right-createpage": "Krouiñ pajennoù (estreget pajennoù kaozeal)",
        "right-createtalk": "Krouiñ pajennoù kaozeal",
        "right-createaccount": "Krouiñ kontoù implijer nevez",
+       "right-autocreateaccount": "Kevreañ ent emgefre gant ur gont implijer diavaez",
        "right-minoredit": "Merkañ ar c'hemmoù evel kemmoù dister",
        "right-move": "Adenvel pajennoù",
        "right-move-subpages": "Dilec'hiañ ar pajennoù gant o ispajennoù",
        "right-override-export-depth": "Ezporzhiañ ar pajennoù en ur lakaat e-barzh ar pajennoù liammet betek un donder a 5 live",
        "right-sendemail": "Kas ur postel d'an implijerien all",
        "grant-group-email": "Kas ur postel",
+       "grant-group-other": "Obererezh liesseurt",
        "grant-blockusers": "Stankañ ha distankañ implijerien",
        "grant-createaccount": "Krouiñ kontoù",
        "grant-createeditmovepage": "Krouiñ, aozañ ha dilec'hiañ pajennoù",
+       "grant-delete": "Diverkañ ar pajennoù, an adweladennoù hag an enmontoù er marilh",
+       "grant-editinterface": "Kemmañ esaouenn anvioù MediaWiki hag ar CSS/JavaScript implijer",
+       "grant-editmycssjs": "Kemmañ ho CSS/JavaScript implijer",
        "grant-editmyoptions": "Kemmañ ho penndibaboù implijer.",
        "grant-editmywatchlist": "Kemmañ ho roll evezhiañ",
        "grant-editpage": "Kemmañ pajennoù a zo anezho c'hoazh",
        "grant-editprotected": "Kemmañ pajennoù gwarezet",
+       "grant-highvolume": "Kemmañ kementadoù bras",
+       "grant-oversight": "Kuzhat an implijerien ha diverkañ an adweladennoù",
+       "grant-patrol": "Gwiriañ ar c'hemmoù graet d'ar pajennoù",
+       "grant-privateinfo": "Gwelet an titouroù prevez",
        "grant-protect": "Gwareziñ ha diwareziñ pajennoù",
        "grant-rollback": "Distreiñ war ar c'hemmoù er pajennoù",
        "grant-sendemail": "Kas ur postel d'an implijerien all",
+       "grant-uploadeditmovefile": "Enporzhiañ, erlec'hiañ hag adenvel restroù",
        "grant-uploadfile": "Enporzhiañ restroù nevez",
        "grant-basic": "Gwirioù diazez",
        "grant-viewdeleted": "Gwelet ar restroù ha pajennoù dilamet",
        "grant-viewmywatchlist": "Gwelet ho roll evezhiañ",
+       "grant-viewrestrictedlogs": "Diskouez an enmontoù marilh kuzh",
        "newuserlogpage": "Marilh ar c'hontoù krouet",
        "newuserlogpagetext": "Marilh krouiñ ar c'hontoù implijer.",
        "rightslog": "Marilh statud an implijerien",
        "action-read": "lenn ar bajenn-mañ",
        "action-edit": "kemmañ ar bajenn-mañ",
        "action-createpage": "krouiñ ar bajenn-mañ",
-       "action-createtalk": "krouiñ pajennoù kaozeal",
+       "action-createtalk": "krouiñ ar bajenn-gaozeal-mañ",
        "action-createaccount": "krouiñ ar gont implijer-mañ",
+       "action-autocreateaccount": "Krouiñ ent emgefre ar gont implijer diavaez-mañ",
        "action-history": "gwelet istor ar bajenn-mañ",
        "action-minoredit": "merkañ ar c'hemm-mañ evel dister",
        "action-move": "dilec'hiañ ar bajenn-mañ",
        "action-upload_by_url": "pellgargañ ar restr-mañ adal ur chomlec'h URL",
        "action-writeapi": "Ober gant an API skrivañ",
        "action-delete": "diverkañ ar bajenn-mañ",
-       "action-deleterevision": "diverkañ ar stumm-mañ",
+       "action-deleterevision": "diverkañ adweladennoù",
        "action-deletedhistory": "Gwelet istor diverket ar bajenn-mañ",
        "action-browsearchive": "Klask pajennoù bet diverket",
-       "action-undelete": "diziverkañ ar bajenn-mañ",
-       "action-suppressrevision": "gwelet hag assevel ar stumm diverket-mañ",
+       "action-undelete": "diziverkañ pajennoù",
+       "action-suppressrevision": "gwiriañ hag assevel an adweladennoù kuzh",
        "action-suppressionlog": "gwelet ar marilh prevez-mañ",
        "action-block": "mirout ouzh an impplijer-mañ da zegas kemmoù",
        "action-protect": "kemmañ liveoù gwareziñ ar bajenn-mañ",
        "recentchanges-legend-newpage": "{{int:recentchanges-label-newpage}} (gwelet ivez [[Special:NewPages|roll ar pajennoù nevez]])",
        "recentchanges-submit": "Diskouez",
        "rcfilters-activefilters": "Siloù oberiant",
+       "rcfilters-clear-all-filters": "Riñsañ an holl siloù",
        "rcfilters-invalid-filter": "Sil direizh",
        "rcfilters-filterlist-title": "Siloù",
        "rcfilters-filterlist-noresults": "N'eus bet kavet sil ebet",
+       "rcfilters-filter-registered-label": "Marilhet",
+       "rcfilters-filter-unregistered-label": "Divarilh",
+       "rcfilters-filter-unregistered-description": "Aozerien n'int ket kevreet.",
        "rcfilters-filter-editsbyself-label": "Kemmet ganeoc'h",
        "rcfilters-filter-editsbyself-description": "Kemmet ganeoc'h",
        "rcfilters-filter-editsbyother-label": "Kemmet gant tud all",
        "rcfilters-filter-userExpLevel-learner-label": "Deskarded",
        "rcfilters-filter-userExpLevel-experienced-label": "Implijerien arroutet",
        "rcfilters-filter-userExpLevel-experienced-description": "Ouzhpenn 30 devezh oberiantiz ha 500 kemm.",
+       "rcfilters-filter-bots-label": "Robot",
+       "rcfilters-filter-bots-description": "Kemmoù graet gant ostilhoù emgefre.",
+       "rcfilters-filter-humans-label": "Den (ket ur robot)",
+       "rcfilters-filter-minor-label": "Kemmoù dister",
+       "rcfilters-filtergroup-changetype": "Seurt kemm",
+       "rcfilters-filter-pageedits-label": "Kemmoù pajennoù",
+       "rcfilters-filter-newpages-label": "Krouidigezhioù pajennoù",
+       "rcfilters-filter-categorization-label": "Kemmoù rummad",
        "rcnotefrom": "Setu aze {{PLURAL:$5|ar c'hemm|ar c'hemmoù}} c'hoarvezet abaoe an <strong>$3, $4</strong> (<strong>$1</strong> d'ar muiañ).",
        "rclistfrom": "Diskouez ar c'hemmoù diwezhañ abaoe an/ar $3 $2",
        "rcshowhideminor": "$1 ar c'hemmoù dister",
        "recentchangeslinked-to": "Diskouez ar c'hemmoù war-du ar pajennoù liammet kentoc'h eget re ar bajenn lakaet",
        "recentchanges-page-added-to-category": "[[:$1]] ouzhpennet d'ar rummad",
        "recentchanges-page-removed-from-category": "Diverket eo bet [[$1]] diouzh ar rummad",
+       "autochange-username": "Kemm emgefre gant MediaWiki",
        "upload": "Kargañ war ar servijer",
        "uploadbtn": "Kargañ ur restr",
        "reuploaddesc": "Distreiñ d'ar furmskrid.",
        "uploadstash-badtoken": "N'haller ket kas an ober-mañ da benn vat, marteze a-walc'h abalamour m'eo aet d'o zermen an titouroù kred ho poa roet. Klaskit en-dro.",
        "uploadstash-errclear": "N'eus ket bet gallet riñsañ ar restroù.",
        "uploadstash-refresh": "Freskaat roll ar restroù",
+       "uploadstash-thumbnail": "gwelet ar munud",
        "invalid-chunk-offset": "Direizh eo offset ar rannad",
        "img-auth-accessdenied": "Moned nac'het",
        "img-auth-nopathinfo": "Mankout a ra ar PATH_INFO.\nN'eo ket kefluniet ho servijer evit reiñ an titour-mañ.\nMarteze eo diazezet war CGI ha n'hall ket skorañ img_auth.\nGwelet https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Image_Authorization",
        "apisandbox-dynamic-parameters-add-label": "Ouzhpennañ un arventenn:",
        "apisandbox-dynamic-parameters-add-placeholder": "Anv an arventenn",
        "apisandbox-results": "Disoc'hoù",
-       "apisandbox-request-params-json": "Arventennoù JSON :",
        "apisandbox-request-url-label": "Goulenn URL :",
        "apisandbox-request-time": "Pad ar goulenn: $1",
        "apisandbox-continue": "Kenderc'hel",
        "apisandbox-continue-clear": "Riñsañ",
+       "apisandbox-multivalue-all-namespaces": "$1 (An holl esaouennoù anv)",
        "apisandbox-multivalue-all-values": "$1 (An holl dalvoudoù)",
        "booksources": "Oberennoù dave",
        "booksources-search-legend": "Klask en oberennoù dave",
        "tags-activate-submit": "Gweredekaat",
        "tags-deactivate-reason": "Abeg :",
        "tags-deactivate-submit": "Diweredekaat",
-       "tags-edit-existing-tags-none": "''Hini ebet''",
+       "tags-edit-existing-tags": "Tikedennoù zo anezho :",
+       "tags-edit-existing-tags-none": "<em>Hini ebet</em>",
        "tags-edit-new-tags": "Tikedennoù nevez :",
        "tags-edit-add": "Ouzhpennañ an tikedennoù-mañ :",
        "tags-edit-remove": "Dilemel an tikedennoù-mañ :",
index 86346d8..4b000e2 100644 (file)
        "badsig": "Loš sirovi potpis.\nProvjerite HTML tagove.",
        "badsiglength": "Vaš potpis je predug.\nMora biti manji od $1 {{PLURAL:$1|znaka|znaka|znakova}}.",
        "yourgender": "Kako želite da se predstavite?",
-       "gender-unknown": "Kad vas spominje, softver će pokušati koristiti srednji rod kad god je to moguće",
+       "gender-unknown": "Kad Vas spominje, softver će pokušati izbjegavati rod kad god je to moguće",
        "gender-male": "On uređuje wiki stranice",
        "gender-female": "Ona uređuje wiki stranice",
        "prefs-help-gender": "Postavljanje ovih podešavanja nije obavezno.\nSoftver koristi ove vrijednosti za vaše naslovljanje i ispravke gramatičkog roda u porukama softvera. Ova će informacija biti javna.",
        "rollbacklink": "vrati",
        "rollbacklinkcount": "vrati $1 {{PLURAL:$1|izmjenu|izmjene|izmjena}}",
        "rollbacklinkcount-morethan": "vrati više od $1 {{PLURAL:$1|izmjene|izmjene|izmjena}}",
-       "rollbackfailed": "Neuspešno vraćanje",
+       "rollbackfailed": "Neuspješno vraćanje",
        "cantrollback": "Ne mogu vratiti izmjenu;\nposljednji autor je ujedno i jedini.",
        "alreadyrolled": "Ne može se vratiti posljednja izmjena [[:$1]] od korisnika [[User:$2|$2]] ([[User talk:$2|razgovor]]{{int:pipe-separator}}[[Special:Contributions/$2|{{int:contribslink}}]]); neko je već izmijenio ili vratio članak na prethodnu provjerenu verziju.\n\nPosljednju izmjenu napravio je korisnik [[User:$3|$3]] ([[User talk:$3|razgovor]]{{int:pipe-separator}}[[Special:Contributions/$3|{{int:contribslink}}]]).",
        "editcomment": "Sažetak izmjene je bio: <em>$1</em>.",
        "changecontentmodel-title-label": "Naslov stranice",
        "changecontentmodel-model-label": "Novi model sadržaja",
        "changecontentmodel-reason-label": "Razlog:",
+       "changecontentmodel-submit": "Promijeni",
        "changecontentmodel-success-title": "Model sadržaja je promijenjen",
        "changecontentmodel-success-text": "Model sadržaja stranice [[:$1]] je promijenjen.",
        "changecontentmodel-cannot-convert": "Model sadržaja stranice [[:$1]] se ne može pretvoriti u vrstu $2.",
        "pageinfo-category-files": "Broj datoteka",
        "markaspatrolleddiff": "Označi kao patrolirano",
        "markaspatrolledtext": "Označi stranicu kao patroliranu",
+       "markaspatrolledtext-file": "Označi ovu verziju datoteke kao patroliranu",
        "markedaspatrolled": "Označeno kao patrolirano",
        "markedaspatrolledtext": "Izabrana revizija [[:$1]] je bila označena kao patrolirana.",
        "rcpatroldisabled": "Patroliranje nedavnih izmjena onemogućeno",
        "autoredircomment": "Preusmjereno na [[$1]]",
        "autosumm-new": "Nova stranica: $1",
        "autosumm-newblank": "Napravljena prazna stranica",
-       "size-bytes": "$1 B",
+       "size-bytes": "$1 {{PLURAL:$1|bajt|bajta|bajtova}}",
        "size-kilobytes": "$1 KB",
        "size-megabytes": "$1 MB",
        "size-gigabytes": "$1 GB",
        "expand_templates_preview": "Pregled",
        "expand_templates_preview_fail_html": "<em>Pošto stranica {{SITENAME}} ima uključen sirov HTML prikaz, te je bilo gubitka u podacima sesije, pregled je sakriven kao mjera predostrožnosti protiv JavaScript napada.</em>\n\n<strong>Ako je ovo ispravan pokušaj pretpregleda, molim da ponovo pokušate.</strong>\nAko i dalje ne bude radilo, pokušajte se [[Special:UserLogout|odjaviti]], pa ponovo prijaviti.",
        "expand_templates_preview_fail_html_anon": "<em>Pošto stranica {{SITENAME}} ima uključen sirov HTML prikaz, a vi se niste prijavili, pregled je sakriven kao mjera predostrožnosti protiv JavaScript napada.</em>\n\n<strong>Ako je ovo ispravan pokušaj pretpregleda, molim da se [[Special:UserLogin|prijavite]] i pokušate ponovo.</strong>",
-       "pagelanguage": "Odabir jezika stranice",
+       "pagelanguage": "Promijeni jezik stranice",
        "pagelang-name": "Stranica",
        "pagelang-language": "Jezik",
        "pagelang-use-default": "Koristi podrazumijevani jezik",
index 4b00d6d..dd4d006 100644 (file)
        "username": "{{GENDER:$1|Nom d'usuari}}:",
        "prefs-memberingroups": "{{GENDER:$2|Membre}} {{PLURAL:$1|del grup|dels grups}}:",
        "prefs-memberingroups-type": "$1",
+       "group-membership-link-with-expiry": "$1 (fins el $2)",
        "prefs-registration": "Hora de registre:",
        "prefs-registration-date-time": "$1",
        "yourrealname": "Nom real*:",
        "userrights-changeable-col": "Grups que podeu canviar",
        "userrights-unchangeable-col": "Grups que no podeu canviar",
        "userrights-irreversible-marker": "$1*",
+       "userrights-expiry-current": "Venç el $1",
+       "userrights-expiry-none": "No venç",
+       "userrights-expiry": "Venciment:",
+       "userrights-expiry-existing": "Temps de venciment actual: $3, $2",
+       "userrights-expiry-othertime": "Altre temps:",
        "userrights-conflict": "Conflicte de canvis dels permisos d'usuari. Reviseu i confirmeu els canvis.",
        "group": "Grup:",
        "group-user": "Usuaris",
        "recentchanges-legend-plusminus": "(''±123'')",
        "recentchanges-submit": "Mostra",
        "rcfilters-activefilters": "Filtres actius",
+       "rcfilters-restore-default-filters": "Restaura els filtres per defecte",
+       "rcfilters-clear-all-filters": "Esborra tots els filtres",
        "rcfilters-search-placeholder": "Canvis recents dels filtres (navegueu o comenceu a escriure)",
        "rcfilters-invalid-filter": "Filtre no vàlid",
+       "rcfilters-empty-filter": "No hi ha cap filtre actiu. Es mostren totes les contribucions.",
        "rcfilters-filterlist-title": "Filtres",
        "rcfilters-filterlist-noresults": "No s'ha trobat cap filtre",
+       "rcfilters-filtergroup-registration": "Registre d'usuari",
+       "rcfilters-filter-registered-label": "Registrats",
+       "rcfilters-filter-registered-description": "Editors que han iniciat sessió",
+       "rcfilters-filter-unregistered-label": "No registrats",
+       "rcfilters-filter-unregistered-description": "Editors que no han iniciat una sessió.",
        "rcfilters-filtergroup-authorship": "Modifica l'autoria",
        "rcfilters-filter-editsbyself-label": "Les vostres modificacions",
        "rcfilters-filter-editsbyself-description": "Modificacions vostres.",
        "rcfilters-filter-editsbyother-label": "Modificacions d'altres",
-       "rcfilters-filter-editsbyother-description": "Modificacions creades per altres usuaris (no vostres)",
-       "rcfilters-filtergroup-userExpLevel": "Nivell d'experiència d'usuari",
+       "rcfilters-filter-editsbyother-description": "Modificacions creades per altres usuaris (no vostres).",
+       "rcfilters-filtergroup-userExpLevel": "Nivell d'experiència (només per a usuaris registrats)",
        "rcfilters-filter-userExpLevel-newcomer-label": "Novells",
-       "rcfilters-filter-userExpLevel-newcomer-description": "Editors novells: menys de 10 edicions i 4 dies d'activitat.",
+       "rcfilters-filter-userExpLevel-newcomer-description": "Menys de 10 edicions i 4 dies d'activitat.",
        "rcfilters-filter-userExpLevel-learner-label": "Aprenents",
-       "rcfilters-filter-userExpLevel-learner-description": "Més dies d'activitat i més edicions que els 'Novells' però menys que els 'Usuaris experimentats'.",
+       "rcfilters-filter-userExpLevel-learner-description": "Més dies d'activitat i més edicions que els 'novells' però menys que els 'usuaris experimentats'.",
        "rcfilters-filter-userExpLevel-experienced-label": "Usuaris experimentats",
        "rcfilters-filter-userExpLevel-experienced-description": "Més de 30 dies d'activitat i més de 500 edicions.",
+       "rcfilters-filtergroup-automated": "Contribucions automatitzades",
+       "rcfilters-filter-bots-label": "Bot",
+       "rcfilters-filter-bots-description": "Modificacions fetes per eines automatitzades.",
+       "rcfilters-filter-humans-label": "Humà (no bot)",
+       "rcfilters-filter-humans-description": "Modificacions fetes per editors humans.",
+       "rcfilters-filtergroup-significance": "Significació",
+       "rcfilters-filter-minor-label": "Modificacions menors",
+       "rcfilters-filter-minor-description": "Modificacions que l'autor va etiquetar com a menors.",
+       "rcfilters-filter-major-label": "Modificacions no menors",
+       "rcfilters-filter-major-description": "Modificacions no etiquetades com a menors.",
+       "rcfilters-filtergroup-changetype": "Tipus de canvi",
+       "rcfilters-filter-pageedits-label": "Modificacions de pàgina",
+       "rcfilters-filter-pageedits-description": "Modificacions al contingut del wiki, discussions, descripcions de categories...",
+       "rcfilters-filter-newpages-label": "Creacions de pàgines",
+       "rcfilters-filter-newpages-description": "Edicions que creen noves pàgines.",
+       "rcfilters-filter-categorization-label": "Canvis de categoria",
+       "rcfilters-filter-categorization-description": "Registres de pàgines afegides o suprimides de les categories.",
+       "rcfilters-filter-logactions-label": "Accions registrades",
        "rcnotefrom": "A sota hi ha {{PLURAL:$5|el canvi|els canvis}} a partir de <strong>$3, $4</strong> (fins a <strong>$1</strong>).",
        "rclistfrom": "Mostra els canvis nous des de $3, $2",
        "rcshowhideminor": "$1 edicions menors",
        "apisandbox-sending-request": "S'està enviant una sol·licitud API...",
        "apisandbox-loading-results": "S'estan reben els resultats de l'API...",
        "apisandbox-results-error": "S'ha produït un error en carregar la resposta de la consulta de l'API: $1.",
-       "apisandbox-request-params-json": "Paràmetres JSON:",
        "apisandbox-request-url-label": "Sol·licita URL:",
+       "apisandbox-request-json-label": "JSON de sol·licitud:",
        "apisandbox-request-time": "Temps de sol·licitud: {{PLURAL:$1|$1 ms}}",
        "apisandbox-results-fixtoken": "Corregeix el testimoni i torna-ho a enviar",
        "apisandbox-results-fixtoken-fail": "No s'ha pogut recuperar el testimoni «$1».",
        "pagelang-language": "Idioma",
        "pagelang-use-default": "Utilitza l'idioma per defecte",
        "pagelang-select-lang": "Selecciona un idioma",
+       "pagelang-reason": "Motiu",
        "pagelang-submit": "Envia",
        "pagelang-nonexistent-page": "La pàgina $1 no existeix.",
        "pagelang-unchanged-language": "La pàgina $1 ja està configurada en la llengua: $2.",
index 8771631..2ded538 100644 (file)
        "uncategorizedcategories": "Nekategorizované kategorie",
        "uncategorizedimages": "Nekategorizované soubory",
        "uncategorizedtemplates": "Nekategorizované šablony",
+       "uncategorized-categories-exceptionlist": " # Obsahuje seznam kategorií, které se nemají objevovat na Speciální:Nekategorizované kategorie. Jedna kategorie na každém řádku, uvozená pomocí „*“. Řádky začínající jiným znakem (včetně bílých znaků) se ignorují. Komentáře vkládejte za „#“.",
        "unusedcategories": "Nepoužívané kategorie",
        "unusedimages": "Nepoužívané soubory",
        "wantedcategories": "Chybějící kategorie",
        "apisandbox-sending-request": "Odesílá se API požadavek…",
        "apisandbox-loading-results": "Přijímají se API výsledky…",
        "apisandbox-results-error": "Došlo k chybě při načítání odpovědi na API dotaz: $1.",
-       "apisandbox-request-params-json": "Parametry v JSON:",
        "apisandbox-request-url-label": "URL požadavku:",
        "apisandbox-request-time": "Trvání požadavku: {{PLURAL:$1|$1 ms}}",
        "apisandbox-results-fixtoken": "Opravit token a znovu odeslat",
        "emailccsubject": "Kopie Vaší zprávy pro uživatele $1: $2",
        "emailsent": "E-mail odeslán",
        "emailsenttext": "Váš e-mail byl odeslán.",
-       "emailuserfooter": "Tento e-mail byl odeslán z {{grammar:2sg|{{SITENAME}}}} pomocí funkce „{{int:emailuser}}“; {{GENDER:$1|odeslal ho uživatel|odeslala ho uživatelka}} $1 {{GENDER:$2|uživateli|uživatelce}} $2. Váš e-mail bude odeslán přímo {{GENDER:$1|původnímu odesílateli, čímž mu|původní odesílatelce, čímž jí}} prozradíte svou e-mailovou adresu.",
+       "emailuserfooter": "Tento e-mail byl odeslán z {{grammar:2sg|{{SITENAME}}}} pomocí funkce „{{int:emailuser}}“; {{GENDER:$1|odeslal ho uživatel|odeslala ho uživatelka}} $1 {{GENDER:$2|uživateli|uživatelce}} $2. Pokud na něj odpovíte, bude váš e-mail odeslán přímo {{GENDER:$1|původnímu odesílateli, čímž mu|původní odesílatelce, čímž jí}} prozradíte svou e-mailovou adresu.",
        "usermessage-summary": "Doručena zpráva od systému.",
        "usermessage-editor": "Systémový poslíček",
        "watchlist": "Sledované stránky",
        "usercssispublic": "Uvědomte si prosím, že podstránky s CSS by neměly obsahovat tajné údaje, protože jsou viditelné ostatním uživatelům.",
        "restrictionsfield-badip": "Neplatná IP adresa nebo rozsah: $1",
        "restrictionsfield-label": "Povolené rozsahy IP adres:",
-       "restrictionsfield-help": "Jedna IP adresa nebo CIDR rozsah na řádek. Všechno povolíte pomocí<br><code>0.0.0.0/0</code><br><code>::/0</code>",
+       "restrictionsfield-help": "Jedna IP adresa nebo CIDR rozsah na řádek. Všechno povolíte pomocí:<pre>0.0.0.0/0\n::/0</pre>",
        "revid": "revize $1",
        "pageid": "Stránka s ID $1"
 }
index 2a44a8b..c72b598 100644 (file)
        "patrol-log-header": "Patruljerede versioner.",
        "log-show-hide-patrol": "$1 patruljeringslog",
        "confirm-markpatrolled-button": "OK",
+       "confirm-markpatrolled-top": "Marker version $3 af $2 som patruljeret?",
        "deletedrevision": "Slettede gammel version $1",
        "filedeleteerror-short": "Fejl under sletning af fil: $1",
        "filedeleteerror-long": "Der opstod en fejl under sletningen af filen:\n\n$1",
index 5386eff..a5546df 100644 (file)
        "username": "{{GENDER:$1|Benutzername}}:",
        "prefs-memberingroups": "{{GENDER:$2|Mitglied}} der {{PLURAL:$1|Benutzergruppe|Benutzergruppen}}:",
        "prefs-memberingroups-type": "$2",
+       "group-membership-link-with-expiry": "$1 (bis $2)",
        "prefs-registration": "Anmeldezeitpunkt:",
        "prefs-registration-date-time": "$2, $3 Uhr",
        "yourrealname": "Bürgerlicher Name:",
        "userrights-nodatabase": "Die Datenbank $1 ist nicht vorhanden oder nicht lokal.",
        "userrights-changeable-col": "Gruppenzugehörigkeit, die du ändern kannst",
        "userrights-unchangeable-col": "Gruppenzugehörigkeit, die du nicht ändern kannst",
+       "userrights-expiry-current": "Ablauf: $1",
+       "userrights-expiry-none": "Kein Ablauf",
+       "userrights-expiry": "Ablauf:",
+       "userrights-expiry-existing": "Vorhandener Ablauf: $3, $2",
+       "userrights-expiry-othertime": "Andere Zeit:",
+       "userrights-expiry-options": "1 Tag:1 day,1 Woche:1 week,1 Monat:1 month,3 Monate:3 months,6 Monate:6 months,1 Jahr:1 year",
+       "userrights-invalid-expiry": "Die Ablaufzeit für die Gruppe „$1“ ist ungültig.",
+       "userrights-expiry-in-past": "Die Ablaufzeit für die Gruppe „$1“ liegt in der Vergangenheit.",
        "userrights-conflict": "Benutzerrechteänderungskonflikt! Bitte überprüfe und bestätige deine Änderungen.",
        "group": "Gruppe:",
        "group-user": "Benutzer",
        "recentchanges-legend-plusminus": "''(±123)''",
        "recentchanges-submit": "Anzeigen",
        "rcfilters-activefilters": "Aktive Filter",
+       "rcfilters-restore-default-filters": "Standardfilter wiederherstellen",
+       "rcfilters-clear-all-filters": "Alle Filter löschen",
        "rcfilters-search-placeholder": "Letzte Änderungen filtern (durchsuchen oder beginne mit der Eingabe)",
        "rcfilters-invalid-filter": "Ungültiger Filter",
+       "rcfilters-empty-filter": "Keine aktiven Filter. Es werden alle Beiträge angezeigt.",
        "rcfilters-filterlist-title": "Filter",
        "rcfilters-filterlist-noresults": "Keine Filter gefunden",
        "rcfilters-filtergroup-registration": "Benutzerregistrierung",
        "apisandbox-sending-request": "Sende API-Anfrage …",
        "apisandbox-loading-results": "Rufe API-Ergebnisse ab …",
        "apisandbox-results-error": "Beim Laden der API-Anfragenantwort ist ein Fehler aufgetreten: $1.",
-       "apisandbox-request-params-json": "JSON-Parameter:",
+       "apisandbox-request-selectformat-label": "Anfragedaten anzeigen als:",
+       "apisandbox-request-format-url-label": "URL-Abfrage-Zeichenfolge",
        "apisandbox-request-url-label": "Anforderungs-URL:",
+       "apisandbox-request-json-label": "Anfragen-JSON:",
        "apisandbox-request-time": "Dauer der Anfrage: {{PLURAL:$1|Eine Millisekunde|$1 Millisekunden}}",
        "apisandbox-results-fixtoken": "Token korrigieren und erneut übertragen",
        "apisandbox-results-fixtoken-fail": "Der „$1“-Token konnte nicht abgerufen werden.",
        "emailccsubject": "Kopie deiner Nachricht an $1: $2",
        "emailsent": "E-Mail verschickt",
        "emailsenttext": "Deine E-Mail wurde verschickt.",
-       "emailuserfooter": "Diese E-Mail wurde von „$1“ an „{{GENDER:$2|$2}}“ durch die Funktion „{{int:emailuser}}“ bei {{SITENAME}} {{GENDER:$1|gesendet}}. {{GENDER:$2|Deine}} E-Mail wird direkt an {{GENDER:$1|den Originalabsender|die Originalabsenderin}} gesendet mit der Preisgabe {{GENDER:$2|deiner}} E-Mail-Adresse an {{GENDER:$1|ihn|sie}}.",
+       "emailuserfooter": "Diese E-Mail wurde von „$1“ an „{{GENDER:$2|$2}}“ durch die Funktion „{{int:emailuser}}“ bei {{SITENAME}} {{GENDER:$1|gesendet}}. Falls {{GENDER:$2|du}} auf diese E-Mail antwortest, wird sie direkt an {{GENDER:$1|den Originalabsender|die Originalabsenderin}} gesendet. Dabei erfährt {{GENDER:$1|er|sie}} {{GENDER:$2|deine}} E-Mail-Adresse.",
        "usermessage-summary": "Systemnachricht gespeichert.",
        "usermessage-editor": "System-Messenger",
        "usermessage-template": "MediaWiki:Benutzernachricht",
        "logentry-tag-update-logentry": "$1 {{GENDER:$2|aktualisierte}} Markierungen des Logbucheintrags $5 der Seite $3 ($6 {{PLURAL:$7|hinzugefügt}}; $8 {{PLURAL:$9|entfernt}})",
        "rightsnone": "(–)",
        "revdelete-summary": "Zusammenfassungskommentar",
+       "rightslogentry-temporary-group": "$1 (temporär, bis $2)",
        "feedback-adding": "Rückmeldung wird zur Seite hinzugefügt …",
        "feedback-back": "Zurück",
        "feedback-bugcheck": "Super! Bitte überprüfe noch, ob es sich hierbei nicht um einen bereits [$1 bekannten Fehler] handelt.",
index def2be4..096bbaf 100644 (file)
        "mycustomjsprotected": "Desturê şıma çıniyo ke na pela JavaScripti bıvurnê.",
        "myprivateinfoprotected": "Ğısusi malumatana ğo timar kerdışire icazeta şıma çıniya.",
        "mypreferencesprotected": "Terciha timar kerdışire icazeta şıam çıniya.",
-       "ns-specialprotected": "Pelê xısusiyi nênê vurnayış.",
+       "ns-specialprotected": "Perrê xısusiy nêvırniyenê.",
        "titleprotected": "No sername terefê [[User:$1|$1]] ra, afernayene ra şevekiyayo.\nSebebê xo <em>$2</em> dero.",
        "filereadonlyerror": "Dosyay vurnayışê \"$1\" nê abêno lakin depoy dosya da \"$2\" mod dê  salt wendi de yo.\n\nXızmetkarê  kılit kerdışi wa bewniro enay wa çım ra ravyarn o: \"$3\".",
        "invalidtitle-knownnamespace": "Canemey \"$2\" u metnê \"$3\" xırabo",
        "tooltip-preferences-save": "Terciha qeyd ke",
        "tooltip-summary": "Xulasa kılmek bınuse",
        "interlanguage-link-title": "$1 - $2",
-       "common.css": "/************************************************\n * COMMON CSS\n *\n * Any CSS placed in this page will be used on \n * all skins, please think carefully about if it\n * belongs here (and not in one of the skin CSS\n * pages) before adding it. Thanks.\n ************************************************/\n\n/* <table class=\"highlighthovertable\"> */\ntable.highlighthovertable tr:hover,\ntable.highlighthovertable tr:hover td,\ntable.mw-ext-translate-groupstatistics tr:hover,\ntable.mw-ext-translate-groupstatistics tr:hover td {\n background-color: white;\n}\n\n\n/* Babel wrapper layout. */\n/* XXX: This is either redundant or should be in-core */\n/* @noflip */table.mw-babel-wrapper {\n\twidth:        238px;\n\tfloat:        right;\n\tclear:        right;\n\tmargin:       1em;\n\tborder-style: solid;\n\tborder-width: 1px;\n\tborder-color: #99B3FF;\n}\n\n/* Babel box layout. */\n/* @noflip */div.mw-babel-box {\n\tfloat:  left;\n\tclear:  left;\n\tmargin: 1px;\n}\n\ndiv.mw-babel-box table {\n\twidth: 238px;\n}\n\ndiv.mw-babel-box table th {\n\twidth:       238px;\n\twidth:       45px;\n\theight:      45px;\n\tfont-size:   14pt;\n\tfont-family: monospace;\n}\n\ndiv.mw-babel-box table td {\n\tfont-size:   8pt;\n\tpadding:     4pt;\n\tline-height: 1.25em;\n}\n\n/* Babel box colours. */\ndiv.mw-babel-box-0 {\n\tborder: solid #B7B7B7 1px;\n}\n\ndiv.mw-babel-box-1 {\n\tborder: solid #C0C8FF 1px;\n}\n\ndiv.mw-babel-box-2 {\n\tborder: solid #77E0E8 1px;\n}\n\ndiv.mw-babel-box-3 {\n\tborder: solid #99B3FF 1px;\n}\n\ndiv.mw-babel-box-4 {\n\tborder: solid #CCCC00 1px;\n}\n\ndiv.mw-babel-box-5 {\n\tborder: solid #F99C99 1px;\n}\n\ndiv.mw-babel-box-N {\n\tborder: solid #6EF7A7 1px;\n}\n\ndiv.mw-babel-box-0 table th {\n\tbackground-color: #B7B7B7;\n}\n\ndiv.mw-babel-box-1 table th {\n\tbackground-color: #C0C8FF;\n}\n\ndiv.mw-babel-box-2 table th {\n\tbackground-color: #77E0E8;\n}\n\ndiv.mw-babel-box-3 table th {\n\tbackground-color: #99B3FF;\n}\n\ndiv.mw-babel-box-4 table th {\n\tbackground-color: #CCCC00;\n}\n\ndiv.mw-babel-box-5 table th {\n\tbackground-color: #F99C99;\n}\n\ndiv.mw-babel-box-N table th{\n\tbackground-color: #6EF7A7;\n}\n\ndiv.mw-babel-box-0 table {\n\tbackground-color: #E8E8E8;\n}\n\ndiv.mw-babel-box-1 table {\n\tbackground-color: #F0F8FF;\n}\n\ndiv.mw-babel-box-2 table {\n\tbackground-color: #D0F8FF;\n}\n\ndiv.mw-babel-box-3 table {\n\tbackground-color: #E0E8FF;\n}\n\ndiv.mw-babel-box-4 table {\n\tbackground-color: #FFFF99;\n}\n\ndiv.mw-babel-box-5 table {\n\tbackground-color: #F9CBC9;\n}\n\ndiv.mw-babel-box-N table {\n\tbackground-color: #C5FCDC;\n}\n\n.babel-box td.babel-footer {\n\ttext-align: center;\n}\n\n/* Styling for portals. */\ndiv.table {\n    display:        table;\n    vertical-align: top;\n    width:          100%;\n}\n\ndiv.table-row {\n    display:        table-row;\n    vertical-align: top;\n}\n\ndiv.table-cell {\n    display:        table-cell;\n    vertical-align: top;\n}\n\nbody.ns-100 table.mw-babel-wrapper {\n    border:           solid 1px #bbbbbb;\n    background-color: #f0f0f0;\n    margin-left:      1em;\n}\n\n.graytext {\n    color: #aaa;\n}\n\n/* On [[Special:RecentChanges]] and [[Special:Watchlist]] make the new pages symbol bold green and the minor edit symbol gray. */\n.newpage {\n    color:       green;\n    font-weight: bold\n}\n\n.minoredit,\n.minor {\n    color: gray;\n}\n\n/* Monospace diffs, this makes more sense since diffs show what would be seen in the edit box. */\n/* Note: Anno 2012 many browsers don't use monospace in the textarea anymore by default, notably Chrome and Safari don't (unless the user overrides this in the preferences) */\n.diff-context,\n.diff-deletedline,\n.diff-addedline {\n    font-family: monospace, \"Courier New\";\n/* Just guess does the stupid wikidiff2 extensions add extra whitespace around..... */\n    white-space: -moz-pre-wrap;\n    white-space: pre-wrap;\n}\n \n.diffchange {\n    border: 1px dotted rgb( 170, 170, 170 );\n}\n\n/* It is unclear what the following CSS does, please add comments if you can clarify. */\n/* The box which is 400px high and if its content is longer, it gets the scrollbar */\n.scrollme {\n    overflow: scroll;\n    width:    100%;\n    height:   400px;\n}\n\n/* Standard Navigationsleisten, aka box hiding thingy from .de.  Documentation at [[Wikipedia:NavFrame]]. */\ndiv.Boxmerge, div.NavFrame { margin: 0; padding: 4px; border-collapse: collapse;}\ndiv.Boxmerge div.NavFrame { border-style: none; border-style: hidden; }\ndiv.NavFrame + div.NavFrame { border-top-style: none; border-top-style: hidden; }\ndiv.NavFrame div.NavHead { height: 1.6em; position:relative; }\ndiv.NavEnd { margin: 0; padding: 0; line-height: 1px; clear: both; }\na.NavToggle { position: absolute; top: 0; right: 5px; }\n.note-flaggedrevs * a.NavToggle { right: 12px; } /* For [[Template:Flagged Revs]] */\n\n/* Template:Languages */\n.bw-languages {\n    border:          1px solid #aaaaaa;\n    padding:         0.2em;\n    border-collapse: collapse;\n    line-height:     1.2;\n    font-size:       95%;\n    margin:          1px 1px;\n}\n.bw-languages-title {\n    width:        180px;\n    border:       1px solid #aaaaaa;\n    background:   #EEF3E2;\n    padding:      0.5em;\n    font-weight:  bold;\n}\n.bw-languages-links { padding:0.5em; background:#F6F9ED; }\n\n/* Senseless in this project */\n#editpage-copywarn { display: none; }\n\n/* Hide warnings about bad links on MediaWiki:Common.css */\n.page-MediaWiki_Common_css .mw-translate-messagechecks { display: none; }\n\n/*******************\n** Faciliate RTL translation\n*******************/\n/* @noflip */\n#bodyContent .arabic a {\n\tpadding-right:0;\n\tbackground:none;\n}\n\n.vatop tr, tr.vatop, .vatop td, .vatop th {\n vertical-align: top;\n}\n\n.bw-languages {\n direction: ltr;\n}\n\n/* prevent wrapping of lines in LQT TOC if not necessary */\ntable.lqt_toc {\n\twidth: auto;\n}\n\n/* [[m:MediaZilla:35337]] */\n@media (-webkit-min-device-pixel-ratio: 1.5), (min-resolution: 1.5dppx) {\n        #p-logo a {\n                background-image: url(\"//translatewiki.net/images/thumb/7/7c/Translatewiki-logo-bare.svg/152px-Translatewiki-logo-bare.svg.png\") !important;\n                background-size: auto 135px;\n        }\n}\n@media (-webkit-min-device-pixel-ratio: 2), (min-resolution: 2dppx) {\n        #p-logo a {\n                background-image: url(\"//translatewiki.net/images/thumb/7/7c/Translatewiki-logo-bare.svg/202px-Translatewiki-logo-bare.svg.png\") !important;\n                background-size: auto 135px;\n        }\n}\n\n/* qqq visibility, [[Thread:Support/Suggestion: Add this CSS to MediaWiki:Common.css]] */\n \n.mw-sp-translate-edit-info .mw-content-ltr {\n  background-position:left center;\n  padding-left:45px;\n}\nfieldset.mw-sp-translate-edit-info .mw-centent-rtl {\n  background-position:right center;\n  padding-right:45px;\n}\n\n/* Semantic MediaWiki - make special properties easier to identify */\n\n.smwbuiltin a,\n.smwbuiltin a.new {\n\tcolor: #FF8000;\n}\n\n/* Recentchangestext toggle link */\n.white-link a {\n    color: #fff;\n}",
-       "common.js": "/* Any JavaScript here will be loaded for all users on every page load. */",
        "anonymous": "{{PLURAL:$1|karberê|karberê}} anonimi yê keyepelê {{SITENAME}}i",
        "siteuser": "karberê {{SITENAME}}i $1",
        "anonuser": "karberê anonim o {{SITENAME}}i $1",
index b023187..555b3a2 100644 (file)
        "preview": "Προεπισκόπηση",
        "showpreview": "Εμφάνιση προεπισκόπησης",
        "showdiff": "Εμφάνιση αλλαγών",
-       "blankarticle": "<strong>Προειδοποίηση:</strong> Η σελίδα που δημιουργείτε είναι κενή.\nΕάν κάνετε κλικ στο κουμπί \"{{int:savearticle}}\" και πάλι, η σελίδα θα δημιουργηθεί χωρίς κανένα περιεχόμενο.",
+       "blankarticle": "<strong>Προειδοποίηση:</strong> Η σελίδα που πάτε να δημιουργήσετε είναι κενή.\nΕάν ξανακάνετε κλικ στο κουμπί «{{int:savearticle}}» η σελίδα θα δημιουργηθεί χωρίς περιεχόμενο.",
        "anoneditwarning": "<strong>Προειδοποίηση:</strong> Δεν έχετε συνδεθεί. Η διεύθυνση IP σας θα είναι ορατή δημόσια αν κάνετε κάποια επεξεργασία. Αν <strong>[$1 συνδεθείτε]</strong> ή <strong>[$2 δημιουργήσετε λογαριασμό]</strong>, οι επεξεργασίες σας θα αποδοθούν στο όνομά χρήστη σας, μαζί με άλλα οφέλη.",
        "anonpreviewwarning": "''Δεν έχετε συνδεθεί. Η αποθήκευση θα καταγράψει την διεύθυνσή IP σας στο ιστορικό επεξεργασίας αυτής της σελίδας.''",
        "missingsummary": "'''Υπενθύμιση:''' Δεν έχετε συμπληρώσει τη σύνοψη επεξεργασίας. Αν κάνετε κλικ στο κουμπί Αποθήκευση πάλι, η επεξεργασία σας θα αποθηκευτεί χωρίς σύνοψη.",
        "recentchanges-legend-newpage": "{{int:recentchanges-label-newpage}} (δείτε [[Special:NewPages|κατάλογος νέων σελίδων]])",
        "recentchanges-legend-plusminus": "(<em>±123</em>)",
        "recentchanges-submit": "Προβολή",
+       "rcfilters-restore-default-filters": "Επαναφορά προεπιλεγμένων φίλτρων",
+       "rcfilters-clear-all-filters": "Εκκαθάριση όλων των φίλτρων",
+       "rcfilters-empty-filter": "Χωρίς ενεργά φίλτρα. Εμφανίζονται όλες οι συνεισφορές.",
        "rcnotefrom": "Παρακάτω {{PLURAL:$5|είναι η αλλαγή|είναι οι αλλαγές}} από <strong>$3, $4</strong> (έως <strong>$1</strong> που εμφανίζεται).",
        "rclistfrom": "Εμφάνιση νέων αλλαγών αρχίζοντας από τις $3 στις $2",
        "rcshowhideminor": "$1 μικρών τροποποιήσεων",
        "apisandbox-sending-request": "Αποστολή αιτήματος API...",
        "apisandbox-loading-results": "Λήψη αποτελεσμάτων API...",
        "apisandbox-request-url-label": "Αίτηση URL:",
+       "apisandbox-request-json-label": "Αίτημα JSON:",
        "apisandbox-request-time": "Χρόνος αιτήματος: {{PLURAL:$1|$1 ms}}",
        "booksources": "Πηγές βιβλίων",
        "booksources-search-legend": "Αναζήτηση για πηγές βιβλίων",
        "emailccsubject": "Αντίγραφο του μηνυματός σας στο $1: $2",
        "emailsent": "Το μήνυμα έχει σταλεί",
        "emailsenttext": "Το μήνυμά σας έχει σταλεί.",
-       "emailuserfooter": "Αυτό το μήνυμα ηλεκτρονικού ταχυδρομείου στάλθηκε από {{GENDER:$1|το χρήστη|τη χρήστρια}} $1 {{GENDER:$2|στο χρήστη|στη χρήστρια}} $2 μέσω της λειτουργίας «{{int:emailuser}}» στο {{SITENAME}}.",
+       "emailuserfooter": "Αυτό το μήνυμα ηλεκτρονικού ταχυδρομείου στάλθηκε από {{GENDER:$1|το χρήστη|τη χρήστρια}} $1 {{GENDER:$2|στο χρήστη|στη χρήστρια}} $2 μέσω της λειτουργίας «{{int:emailuser}}» στο {{SITENAME}}. Αν {{GENDER:$2|σας}} απαντήσετε σε αυτό το μήνυμα ηλεκτρονικού ταχυδρομείου, το e-mail {{GENDER:$2|σας}}  θα αποσταλεί απευθείας {{GENDER:$1|στον|στην}} αρχικό αποστολέα, αποκαλύπτοντας τη διεύθυνση e-mail για {{GENDER:$2|σας}} σε {{GENDER:$1|αυτόν|αυτήν}}.",
        "usermessage-summary": "Φεύγετε από τις ειδοποιήσεις συστήματος.",
        "usermessage-editor": "Μηνύματα συστήματος",
        "usermessage-template": "MediaWiki:UserMessage",
        "protect-legend": "Επιβεβαίωση κλειδώματος",
        "protectcomment": "Αιτία:",
        "protectexpiry": "Λήξη",
-       "protect_expiry_invalid": "Î\9f Ï\87Ï\81Ï\8cνοÏ\82 Î»Î®Î¾Î·Ï\82 ÎµÎ¯Î½Î±Î¹ Î¬κυρος.",
+       "protect_expiry_invalid": "Î\9f Ï\87Ï\81Ï\8cνοÏ\82 Î»Î®Î¾Î·Ï\82 Î´ÎµÎ½ ÎµÎ¯Î½Î±Î¹ Î­Î³κυρος.",
        "protect_expiry_old": "Ο χρόνος λήξης αναφέρεται στο παρελθόν.",
        "protect-unchain-permissions": "Ξεκλείδωμα περαιτέρω επιλογών προστασίας",
        "protect-text": "Μπορείτε να δείτε και να αλλάξετε το επίπεδο προστασίας εδώ για τη σελίδα '''$1'''.",
        "block-log-flags-angry-autoblock": "ενισχυμένος αυτόματος αποκλεισμός ενεργοποιημένος",
        "block-log-flags-hiddenname": "όνομα χρήστη κρυμμένο",
        "range_block_disabled": "Η δυνατότητα του διαχειριστή να δημιουργεί περιοχές φραγής είναι απενεργοποιημένη.",
-       "ipb_expiry_invalid": "Î\86κυρος χρόνος λήξης",
+       "ipb_expiry_invalid": "Î\9cη Î­Î³κυρος χρόνος λήξης",
        "ipb_expiry_old": "Ο χρόνος λήξης αναφέρεται στο παρελθόν.",
        "ipb_expiry_temp": "Οι κρυμμένες φραγές ονομάτων χρηστών πρέπει να είναι μόνιμες.",
        "ipb_hide_invalid": "Μη εφικτή καταστολή αυτού του λογαριασμού. Μπορεί να έχει περισσότερες από {{PLURAL:$1|μια επεξεργασία|$1 επεξεργασίες}}.",
        "pageinfo-toolboxlink": "Πληροφορίες σελίδας",
        "pageinfo-redirectsto": "Ανακατευθύνει σε",
        "pageinfo-redirectsto-info": "πληροφορίες",
-       "pageinfo-contentpage": "Î\9aαÏ\84αμετράται ως σελίδα περιεχομένου",
+       "pageinfo-contentpage": "ΠÏ\81οÏ\83μετράται ως σελίδα περιεχομένου",
        "pageinfo-contentpage-yes": "Ναι",
        "pageinfo-protect-cascading": "Οι προστασίες ξεκινούν τη διαδοχή τους από εδώ",
        "pageinfo-protect-cascading-yes": "Ναι",
        "limitreport-templateargumentsize-value": "$1 από $2 {{PLURAL:$2|byte|bytes}}",
        "limitreport-expansiondepth": "Μεγαλύτερο βάθος ανάπτυξης",
        "limitreport-expensivefunctioncount": "Πλήθος ακριβών συναρτήσεων συντακτικού αναλυτή",
-       "expandtemplates": "Î\95Ï\80έκÏ\84εινε Ï\84α Ï\80Ï\81Ï\8cÏ\84Ï\85Ï\80α",
+       "expandtemplates": "Î\95Ï\80έκÏ\84αÏ\83η Ï\80Ï\81οÏ\84Ï\8dÏ\80Ï\89ν",
        "expand_templates_intro": "Αυτή η ειδική σελίδα παίρνει κείμενο και αναπτύσσει όλα τα πρότυπα σε αυτό αναδρομικά. \nΕπίσης αναπτύσσει συναρτήσεις συντακτικού αναλυτή όπως η\n<nowiki>{{</nowiki>#language:…}}, και μεταβλητές όπως η\n<nowiki>{{</nowiki>CURRENTDAY}}.\nΟυσιαστικά επεκτείνει οτιδήποτε βρίσκεται σε διπλές αγκύλες.",
        "expand_templates_title": "Τίτλων συμφραζόμενων, για την {{FULLPAGENAME}} κ.τ.λ.:",
        "expand_templates_input": "Κείμενο εισόδου:",
index b86ca92..81d9af1 100644 (file)
        "username": "{{GENDER:$1|Username}}:",
        "prefs-memberingroups": "{{GENDER:$2|Member}} of {{PLURAL:$1|group|groups}}:",
        "prefs-memberingroups-type": "$1",
+       "group-membership-link-with-expiry": "$1 (until $2)",
        "prefs-registration": "Registration time:",
        "prefs-registration-date-time": "$1",
        "yourrealname": "Real name:",
        "userrights-changeable-col": "Groups you can change",
        "userrights-unchangeable-col": "Groups you cannot change",
        "userrights-irreversible-marker": "$1*",
+       "userrights-expiry-current": "Expires $1",
+       "userrights-expiry-none": "Does not expire",
+       "userrights-expiry": "Expires:",
+       "userrights-expiry-existing": "Existing expiration time: $3, $2",
+       "userrights-expiry-othertime": "Other time:",
+       "userrights-expiry-options": "1 day:1 day,1 week:1 week,1 month:1 month,3 months:3 months,6 months:6 months,1 year:1 year",
+       "userrights-invalid-expiry": "The expiry time for group \"$1\" is invalid.",
+       "userrights-expiry-in-past": "The expiry time for group \"$1\" is in the past.",
        "userrights-conflict": "Conflict of user rights changes! Please review and confirm your changes.",
        "group": "Group:",
        "group-user": "Users",
        "recentchanges-legend-plusminus": "(<em>±123</em>)",
        "recentchanges-submit": "Show",
        "rcfilters-activefilters": "Active filters",
+       "rcfilters-restore-default-filters": "Restore default filters",
+       "rcfilters-clear-all-filters": "Clear all filters",
        "rcfilters-search-placeholder": "Filter recent changes (browse or start typing)",
        "rcfilters-invalid-filter": "Invalid filter",
+       "rcfilters-empty-filter": "No active filters. All contributions are shown.",
        "rcfilters-filterlist-title": "Filters",
        "rcfilters-filterlist-noresults": "No filters found",
        "rcfilters-filtergroup-registration": "User registration",
        "apisandbox-sending-request": "Sending API request...",
        "apisandbox-loading-results": "Receiving API results...",
        "apisandbox-results-error": "An error occurred while loading the API query response: $1.",
-       "apisandbox-request-params-json": "JSON parameters:",
+       "apisandbox-request-selectformat-label": "Show request data as:",
+       "apisandbox-request-format-url-label": "URL query string",
        "apisandbox-request-url-label": "Request URL:",
+       "apisandbox-request-format-json-label": "JSON",
+       "apisandbox-request-json-label": "Request JSON:",
        "apisandbox-request-time": "Request time: {{PLURAL:$1|$1 ms}}",
        "apisandbox-results-fixtoken": "Correct token and resubmit",
        "apisandbox-results-fixtoken-fail": "Failed to fetch \"$1\" token.",
        "emailccsubject": "Copy of your message to $1: $2",
        "emailsent": "Email sent",
        "emailsenttext": "Your email message has been sent.",
-       "emailuserfooter": "This email was {{GENDER:$1|sent}} by $1 to {{GENDER:$2|$2}} by the \"{{int:emailuser}}\" function at {{SITENAME}}. {{GENDER:$2|Your}} email will be sent directly to the {{GENDER:$1|original sender}}, revealing {{GENDER:$2|your}} email address to {{GENDER:$1|them}}.",
+       "emailuserfooter": "This email was {{GENDER:$1|sent}} by $1 to {{GENDER:$2|$2}} by the \"{{int:emailuser}}\" function at {{SITENAME}}. If {{GENDER:$2|you}} reply to this email, {{GENDER:$2|your}} email will be sent directly to the {{GENDER:$1|original sender}}, revealing {{GENDER:$2|your}} email address to {{GENDER:$1|them}}.",
        "usermessage-summary": "Leaving system message.",
        "usermessage-editor": "System messenger",
        "usermessage-template": "MediaWiki:UserMessage",
        "newuserlog-autocreate-entry": "Account created automatically",
        "rightslogentry": "changed group membership for $1 from $2 to $3",
        "rightslogentry-autopromote": "was automatically promoted from $2 to $3",
+       "rightslogentry-temporary-group": "$1 (temporary, until $2)",
        "feedback-adding": "Adding feedback to page...",
        "feedback-back": "Back",
        "feedback-bugcheck": "Great! Just check that it is not already one of the [$1 known bugs].",
index 65be6b0..be9b811 100644 (file)
@@ -50,7 +50,8 @@
                        "Orikrin1998",
                        "Gamliel Fishkin",
                        "Kastanoto",
-                       "Rafaneta"
+                       "Rafaneta",
+                       "NMaia"
                ]
        },
        "tog-underline": "Substrekado de ligiloj:",
        "searcharticle": "Ek",
        "history": "Historio de paĝo",
        "history_short": "Historio",
+       "history_small": "historio",
        "updatedmarker": "ĝisdatigita de post mia lasta vizito",
        "printableversion": "Presebla versio",
        "permalink": "Konstanta ligilo",
        "botpasswords-label-delete": "Forigi",
        "botpasswords-label-resetpassword": "Rekomencigi la pasvorton",
        "botpasswords-label-grants": "Uzeblaj permesdonoj:",
-       "botpasswords-help-grants": "Rajtigiloj permesas aliron al rajtoj jam provizita al via uzantkonto. Ebligi rajtigilojn ĉi tie ne provizas aliron al ajnaj rajtoj ke via uzantkonto ne alie havus. Vidu la [[Special:MyLanguage/Special:ListGrants|tablo de gratifikoj]] por pli da informo.",
+       "botpasswords-help-grants": "Rajtigiloj permesas aliron al rajtoj jam provizita al via uzantkonto. Ebligi rajtigilojn ĉi tie ne provizas aliron al ajnaj rajtoj ke via uzantkonto ne alie havus. Vidu la [[Special:ListGrants|tablo de rajtigiloj]] por pli da informo.",
        "botpasswords-label-grants-column": "Permeso donita",
        "botpasswords-bad-appid": "La robota nomo \"$1\" estas malvalida.",
        "botpasswords-insert-failed": "Aldono de la robota nomo \"$1\" ne sukcesis. Ĉu ĝi jam estis aldonita?",
        "recentchanges-legend-newpage": "{{int:recentchanges-label-newpage}} (vidu ankaŭ [[Special:NewPages|liston de novaj paĝoj]])",
        "recentchanges-submit": "Montri",
        "rcfilters-activefilters": "Aktivaj filtriloj",
+       "rcfilters-restore-default-filters": "Restarigi defaŭltajn filtrilojn",
+       "rcfilters-clear-all-filters": "Nuligi ĉiujn filtrilojn",
        "rcfilters-search-placeholder": "Filtri lastajn ŝanĝojn (vi povas elekti aŭ ekskribi)",
        "rcfilters-invalid-filter": "Nevalida filtrilo",
+       "rcfilters-empty-filter": "Ekzistas neniuj aktivaj filtriloj. Ĉiuj kontribuaĵoj estas montritaj.",
        "rcfilters-filterlist-title": "Filtriloj",
        "rcfilters-filterlist-noresults": "Neniuj filtriloj troviĝis",
+       "rcfilters-filtergroup-registration": "Registrado de uzanto",
+       "rcfilters-filter-registered-label": "Registrita",
+       "rcfilters-filter-registered-description": "Ensalutitaj redaktantoj.",
+       "rcfilters-filter-unregistered-label": "Neregistrita",
+       "rcfilters-filter-unregistered-description": "Redaktantoj kiuj ne estas ensalutita.",
        "rcfilters-filtergroup-authorship": "Redakta aŭtoreco",
        "rcfilters-filter-editsbyself-label": "Viaj redaktoj",
        "rcfilters-filter-editsbyself-description": "Viaj redaktoj.",
        "rcfilters-filter-editsbyother-label": "Redaktoj de aliuloj",
-       "rcfilters-filter-editsbyother-description": "Redaktoj de la aliaj uzantoj (krom vi)",
-       "rcfilters-filtergroup-userExpLevel": "Uzanta spertonivelo",
+       "rcfilters-filter-editsbyother-description": "Redaktoj kreitaj far aliaj uzantoj (krom vi).",
+       "rcfilters-filtergroup-userExpLevel": "Spertonivelo (nur por registritaj uzantoj)",
        "rcfilters-filter-userExpLevel-newcomer-label": "Novuloj",
-       "rcfilters-filter-userExpLevel-newcomer-description": "Tre novaj redaktantoj: malpli ol 10 redaktoj kaj 4 tagoj da aktiveco",
+       "rcfilters-filter-userExpLevel-newcomer-description": "Malpli ol 10 redaktoj kaj 4 tagoj de aktiveco.",
        "rcfilters-filter-userExpLevel-learner-label": "Lernantoj",
-       "rcfilters-filter-userExpLevel-learner-description": "Pliaj tagoj da aktiveco kaj redaktoj ol 'Novuloj' sed malpli ol 'Spertaj uzantoj.'",
+       "rcfilters-filter-userExpLevel-learner-description": "Pliaj tagoj da aktiveco kaj redaktoj ol \"Novuloj\" sed malpli ol \"Spertaj uzantoj\".",
        "rcfilters-filter-userExpLevel-experienced-label": "Spertaj uzantoj",
        "rcfilters-filter-userExpLevel-experienced-description": "Pli ol 30 tagoj da aktiveco kaj 500 redaktoj.",
+       "rcfilters-filtergroup-automated": "Aŭtomatigitaj kontribuoj",
+       "rcfilters-filter-bots-label": "Roboto",
+       "rcfilters-filter-bots-description": "Redaktoj farita de aŭtomatigitaj iloj.",
+       "rcfilters-filter-humans-label": "Homa (ne robota)",
+       "rcfilters-filter-humans-description": "Redaktoj farita de homaj redaktantoj.",
+       "rcfilters-filtergroup-significance": "Signifo",
+       "rcfilters-filter-minor-label": "Etaj redaktoj",
+       "rcfilters-filter-minor-description": "Redaktoj kiujn la aŭtoro markis kiel \"redakteto\".",
+       "rcfilters-filter-major-label": "Redaktoj kiujn la aŭtoro ne markis kiel \"redakteto\".",
+       "rcfilters-filter-major-description": "Redaktoj kiujn la aŭtoro ne markis kiel \"redakteto\".",
+       "rcfilters-filtergroup-changetype": "Tipo de ŝanĝo",
+       "rcfilters-filter-pageedits-label": "Redaktoj de paĝoj",
+       "rcfilters-filter-pageedits-description": "Redaktoj al vikia enhavo, diskutoj, kategoriaj priskriboj...",
+       "rcfilters-filter-newpages-label": "Kreaĵoj de paĝo",
+       "rcfilters-filter-newpages-description": "Redaktoj kiuj faras novajn paĝojn.",
+       "rcfilters-filter-categorization-label": "Ŝanĝoj de kategorioj",
+       "rcfilters-filter-categorization-description": "Registroj de paĝoj aldonitaj aŭ forigitaj de kategorioj",
+       "rcfilters-filter-logactions-label": "Registritaj agoj",
+       "rcfilters-filter-logactions-description": "Administraciaj agoj, kontaj kreoj, paĝaj forigoj, alŝutoj....",
        "rcnotefrom": "Malsupre estas la {{PLURAL:$5|ŝanĝo|ŝanĝoj}} ekde <strong>$3, $4</strong> (montrante ĝis <strong>$1</strong>).",
        "rclistfrom": "Montri novajn ŝanĝojn ekde \"$3 $2\"",
        "rcshowhideminor": "$1 etajn redaktojn",
        "uncategorizedcategories": "Neenkategoriitaj kategorioj",
        "uncategorizedimages": "Neenkategoriigitaj dosieroj",
        "uncategorizedtemplates": "Neenkategoriigitaj ŝablonoj",
+       "uncategorized-categories-exceptionlist": "# Enhavas liston de kategorioj, kiuj ne devus esti menciitaj en Specialaĵo:UncategorizedCategories. Unu po linio, komencante per \"*\". Linioj komencantaj kun alia karaktero (inkluzivante blankspaco) estas ignorata. Uzu \"#\" por rimarkoj.",
        "unusedcategories": "Neuzitaj kategorioj",
        "unusedimages": "Neuzataj bildoj",
        "wantedcategories": "Dezirataj kategorioj",
        "apisandbox-sending-request": "Sendanta aplikprograminterfacan peton…",
        "apisandbox-loading-results": "Ricevas APIajn rezultojn…",
        "apisandbox-results-error": "Eraro okazis dum ŝutis la APIan petan respondon: $1.",
-       "apisandbox-request-params-json": "JSON-parametroj:",
        "apisandbox-request-url-label": "Mendi URL-on.",
        "apisandbox-request-time": "Tempo de peto:{{PLURAL:$1|$1 ms}}",
        "apisandbox-results-fixtoken": "Korekti ĵetonon kaj resendi",
        "emailccsubject": "Kopio de via mesaĝo al $1: $2",
        "emailsent": "Retmesaĝo sendita",
        "emailsenttext": "Via retmesaĝo estas sendita.",
-       "emailuserfooter": "Ĉi tiu retpoŝtmesaĝo estis {{GENDER:$1|sendita}} de $1 al {{GENDER:$2|$2}} per la funkcio \"{{int:emailuser}}\" ĉe {{SITENAME}}. {{GENDER:$2|Via}} retpoŝto estos sendita rekte al la {{{{GENDER:$1|}}|originala sendinto}}, rivelanta {{GENDER:$2|via}} retpoŝta adreso al {{GENDER:$1|ili}}.",
+       "emailuserfooter": "Ĉi tiu retpoŝtmesaĝo estis {{GENDER:$1|sendita}} de $1 al {{GENDER:$2|$2}} per la funkcio \"{{int:emailuser}}\" ĉe {{SITENAME}}. Se {{GENDER:$2|vi}} respondas al ĉi tiu retpoŝto,  {{GENDER:$2|via}} retpoŝto estos sendita rekte al la {{{{GENDER:$1|}}|originala sendinto}}, rivelanta {{GENDER:$2|via}} retpoŝta adreso al {{GENDER:$1|ili}}.",
        "usermessage-summary": "Lasanta sisteman mesaĝon.",
        "usermessage-editor": "Mesaĝanto de sistemo",
        "watchlist": "Mia atentaro",
        "exporttext": "Vi povas elporti la tekston kaj la redaktohistorion de aparta paĝo aŭ de paĝaro kolektita en ia XML.\nĈi tio povas esti enportita en alian programon funkciantan per MediaWiki per la [[Special:Import|enportpaĝo]].\n\nPor elporti paĝojn, enigu la titolojn en la jena tekst-skatolo, po unu por linio, kaj elektu ĉu vi volas kaj la nunan version kaj ĉiujn antaŭajn versiojn, kun la paĝaj historiaj linioj, aŭ la nunan version kun la informo pri la lasta redakto.\n\nEn la lasta okazo, vi ankaŭ povas uzi ligilon, ekz-e [[{{#Special:Export}}/{{MediaWiki:Mainpage}}]] por la paĝo \"[[{{MediaWiki:Mainpage}}]]\".",
        "exportall": "Elporti ĉiujn paĝojn",
        "exportcuronly": "Entenas nur la aktualan version, ne la malnovajn.",
-       "exportnohistory": "----\n'''Notu:''' Eksportado de la plena historio de paĝoj per ĉi paĝo estis malebligita pro funkciigaj kialoj.",
+       "exportnohistory": "----\n'''Notu:''' Elportado de la plena historio de paĝoj per ĉi paĝo estis malebligita pro funkciigaj kialoj.",
        "exportlistauthors": "Inkluzivi plenan liston de kontribuantoj por ĉiu paĝo.",
        "export-submit": "Elporti",
        "export-addcattext": "Aldoni paĝojn el kategorio:",
        "usercssispublic": "Bonvolu noti: subpaĝoj en CSS ne enhavu konfidenciajn datumojn ĉar ili estas videblaj por aliaj uzantoj.",
        "restrictionsfield-badip": "Malvalida IP-adreso de la intervalo: $1",
        "restrictionsfield-label": "Permesita IP-intervalo:",
-       "restrictionsfield-help": "Unu IP-adreso aŭ CIDR-intervalo per linio. Por permesigi ĉion, uzu<br><code>0.0.0.0/0</code><br><code>::/0</code>",
+       "restrictionsfield-help": "Unu IP-adreso aŭ CIDR-intervalo per linio. Por permesigi ĉion, uzu:<pre>0.0.0.0/0</code>\n<code>::/0</pre>",
        "revid": "revizio $1",
        "pageid": "Identigilo de paĝo $1"
 }
index 4868777..8e9a71e 100644 (file)
        "youremail": "Correo electrónico:",
        "username": "{{GENDER:$1|Nombre de usuario|Nombre de usuaria}}:",
        "prefs-memberingroups": "{{GENDER:$2|Miembro}} {{PLURAL:$1|del grupo|de los grupos}}:",
+       "group-membership-link-with-expiry": "$1 (hasta $2)",
        "prefs-registration": "Fecha y hora de registro:",
        "yourrealname": "Nombre real:",
        "yourlanguage": "Idioma:",
        "userrights-nodatabase": "La base de datos $1 no existe o no es local.",
        "userrights-changeable-col": "Grupos que puedes cambiar",
        "userrights-unchangeable-col": "Grupos que no puedes cambiar",
+       "userrights-expiry-options": "1 día:1 day,1 semana:1 week,1 mes:1 month,3 meses:3 months,6 meses:6 months,1 año:1 year",
        "userrights-conflict": "¡Conflicto de cambio de los permisos de usuario! Por favor, revisa y confirma tus cambios.",
        "group": "Grupo:",
        "group-user": "Usuarios",
        "recentchanges-legend-newpage": "{{int:recentchanges-label-newpage}} (véase también la [[Special:NewPages|lista de páginas nuevas]])",
        "recentchanges-submit": "Mostrar",
        "rcfilters-activefilters": "Filtros activos",
+       "rcfilters-restore-default-filters": "Restaurar filtros predeterminados",
+       "rcfilters-clear-all-filters": "Borrar todos los filtros",
        "rcfilters-search-placeholder": "Filtrar cambios recientes (navega o empieza a escribir)",
        "rcfilters-invalid-filter": "Filtro no válido",
+       "rcfilters-empty-filter": "No hay filtros activos. Se muestran todas las contribuciones.",
        "rcfilters-filterlist-title": "Filtros",
        "rcfilters-filterlist-noresults": "No se encontraron filtros",
        "rcfilters-filtergroup-registration": "Registro de usuario",
        "apisandbox-sending-request": "Enviando pedido a la API...",
        "apisandbox-loading-results": "Recibiendo resultados de la API...",
        "apisandbox-results-error": "Ocurrió un error durante la carga de la respuesta a la consulta API: $1",
-       "apisandbox-request-params-json": "Parámetros JSON:",
+       "apisandbox-request-selectformat-label": "Mostrar los datos de la petición como:",
+       "apisandbox-request-format-url-label": "Cadena de consulta de la URL",
        "apisandbox-request-url-label": "URL solicitante:",
        "apisandbox-request-time": "Tiempo de solicitud: {{PLURAL:$1|$1 ms}}",
        "apisandbox-results-fixtoken": "Corrige el token y vuelve a enviar",
        "emailccsubject": "Copia de tu mensaje a $1: $2",
        "emailsent": "Correo electrónico enviado",
        "emailsenttext": "Se ha enviado tu mensaje de correo electrónico.",
-       "emailuserfooter": "Este correo electrónico fue {{GENDER:$1|enviado}} por $1 a {{GENDER:$2|$2}} a través de la función «{{int:emailuser}}» en {{SITENAME}}. {{GENDER:$2|Tu}} correo electrónico se enviará directamente {{GENDER:$1|al emisor|a la emisora}} original, y {{GENDER:$1|le}} revelará {{GENDER:$2|tu}} dirección de correo electrónico.",
+       "emailuserfooter": "Este correo electrónico fue {{GENDER:$1|enviado}} por $1 a {{GENDER:$2|$2}} a través de la función «{{int:emailuser}}» en {{SITENAME}}. Si {{GENDER:$2|respondes}}, tu correo electrónico se enviará directamente {{GENDER:$1|al emisor|a la emisora}} original, y {{GENDER:$1|le}} revelará {{GENDER:$2|tu}} dirección de correo electrónico.",
        "usermessage-summary": "Dejando un mensaje de sistema.",
        "usermessage-editor": "Mensajero del sistema",
        "watchlist": "Lista de seguimiento",
        "exif-compression-6": "JPEG (antiguo)",
        "exif-copyrighted-true": "Con derechos de autor",
        "exif-copyrighted-false": "No se ha definido el estado del copyright",
+       "exif-photometricinterpretation-0": "Blanco y negro (blanco es 0)",
        "exif-photometricinterpretation-1": "Blanco y negro (el negro es 0)",
        "exif-photometricinterpretation-4": "Máscara de transparencia",
        "exif-photometricinterpretation-5": "Separados (Probablemente CMYK)",
        "usercssispublic": "Recuerda: las subpáginas CSS no deberían contener datos confidenciales, pues otros usuarios los pueden ver.",
        "restrictionsfield-badip": "Dirección o intervalo IP no válidos: $1",
        "restrictionsfield-label": "Intervalos de IP permitidos:",
-       "restrictionsfield-help": "Una dirección IP o intervalo de CIDR por renglón. Para habilitar todo, utiliza <pre>0.0.0.0/0\n::/0</pre>",
+       "restrictionsfield-help": "Una dirección IP o intervalo de CIDR por renglón. Para activarlo todo, utiliza <pre>0.0.0.0/0\n::/0</pre>",
        "revid": "revisión $1",
        "pageid": "ID de página $1"
 }
index 6b113b3..c93e9f9 100644 (file)
        "mergehistory-empty": "Ühtegi redaktsiooni ei saa liita.",
        "mergehistory-done": "Lehekülje $1 {{PLURAL:$3|üks redaktsioon|$3 redaktsiooni}} liideti lehega [[:$2]].",
        "mergehistory-fail": "Muudatuste ajaloo liitmine ebaõnnestus. Palun kontrolli lehekülje ja aja parameetreid.",
+       "mergehistory-fail-bad-timestamp": "Ajatempel on vigane.",
+       "mergehistory-fail-invalid-source": "Alliklehekülg on vigane.",
+       "mergehistory-fail-invalid-dest": "Sihtlehekülg on vigane.",
+       "mergehistory-fail-no-change": "Ajalugude liitmisel ei liidetud ühtegi redaktsiooni. Palun kontrolli lehekülgede ja aja parameetrid veelkord üle.",
+       "mergehistory-fail-permission": "Ajalugude liitmiseks vajalikud õigused puuduvad.",
+       "mergehistory-fail-self-merge": "Allik- ja sihtlehekülg on üks ja sama lehekülg.",
+       "mergehistory-fail-timestamps-overlap": "Alliklehekülje redaktsioonid kattuvad ajaliselt sihtlehekülje redaktsioonidega või on neist uuemad.",
        "mergehistory-fail-toobig": "Ajalugusid ei õnnestu liita, sest teisaldada tuleks rohkem kui {{PLURAL:$1|üks redaktsioon|$1 redaktsiooni}}, mis on piirmäär.",
        "mergehistory-no-source": "Alliklehekülge $1 pole olemas.",
        "mergehistory-no-destination": "Sihtlehekülge $1 pole olemas.",
        "search-external": "Välisotsing",
        "searchdisabled": "Otsimine on preagu keelatud.\nVahepeal saad otsimiseks Google'it kasutada.\nPane tähele, et Google'is talletatud {{GRAMMAR:genitive|{{SITENAME}}}} sisu võib olla iganenud.",
        "search-error": "Otsimise ajal ilmnes tõrge: $1",
+       "search-warning": "Otsimisel esines hoiatus: $1",
        "preferences": "Eelistused",
        "mypreferences": "Eelistused",
        "prefs-edits": "Redigeerimiste arv:",
        "userrights-user-editname": "Sisesta kasutajanimi:",
        "editusergroup": "Laadi kasutajarühmad",
        "editinguser": "Kasutaja '''[[User:$1|$1]]''' $2 õiguste muutmine",
+       "viewinguserrights": "{{GENDER:$1|Kasutaja}} <strong>[[User:$1|$1]]</strong> $2 õiguste vaatamine",
        "userrights-editusergroup": "Kasutajarühmade muutmine",
+       "userrights-viewusergroup": "Kasutajarühmade vaatamine",
        "saveusergroups": "Salvesta {{GENDER:$1|kasutajarühmad}}",
        "userrights-groupsmember": "Kuulub rühmadesse:",
        "userrights-groupsmember-auto": "Kuulub vaikimisi rühmadesse:",
        "right-applychangetags": "Rakendada [[Special:Tags|märgiseid]] enda muudatuste suhtes",
        "right-changetags": "Lisada ja eemaldada käsitsi rakendatavaid [[Special:Tags|märgiseid]] üksikute redaktsioonide ja logisissekannete juures",
        "right-deletechangetags": "Kustutada andmebaasist [[Special:Tags|märgiseid]]",
+       "grant-generic": "Volituse \"$1\" õiguste komplekt",
        "grant-group-page-interaction": "Interaktsioon lehekülgedega",
        "grant-group-file-interaction": "Interaktsioon meediafailidega",
        "grant-group-watchlist-interaction": "Interaktsioon sinu jälgimisloendiga",
        "grant-group-high-volume": "Suuremahuline tegevus",
        "grant-group-customization": "Kohandamine ja eelistused",
        "grant-group-administration": "Administraatori toimingud",
+       "grant-group-private-information": "Juurdepääs enda eraandmetele",
        "grant-group-other": "Mitmesugused toimingud",
        "grant-blockusers": "Kasutajate blokeerimine ja blokeeringute eemaldamine",
        "grant-createaccount": "Kontode loomine",
        "grant-highvolume": "Suuremahuline redigeerimine",
        "grant-oversight": "Kasutajate peitmine ja redaktsioonide varjamine",
        "grant-patrol": "Lehekülgede muudatuste kontroll",
+       "grant-privateinfo": "Juurdepääs erateabele",
        "grant-protect": "Lehekülgede kaitsmine ja kaitse eemaldamine",
        "grant-rollback": "Lehekülgede muudatuste tühistamine",
        "grant-sendemail": "Kasutajatele e-kirjade saatmine",
        "grant-basic": "Põhiõigused",
        "grant-viewdeleted": "Kustutatud failide ja lehekülgede vaatamine",
        "grant-viewmywatchlist": "Oma jälgimisloendi vaatamine",
+       "grant-viewrestrictedlogs": "Pääsupiiranguga andmete vaatamine",
        "newuserlogpage": "Konto loomise logi",
        "newuserlogpagetext": "Siin on logitud kasutajate registreerimine.",
        "rightslog": "Kasutajaõiguste logi",
index 9d540c1..f51c6ed 100644 (file)
@@ -47,7 +47,7 @@
        "tog-watchdeletion": "Ezabatzen ditudan orrialdeak eta fitxategiak nire jarraipen-zerrendara gehitu",
        "tog-watchuploads": "Gehitu igotzen ditudan fitxategiak nire jarraipen zerrendara",
        "tog-watchrollback": "Nire jarraipen zerrendan rollbacka egin dudan orrialdeak erakutsi",
-       "tog-minordefault": "Lehenetsi bezala aldaketa txiki bezala markatu guztiak",
+       "tog-minordefault": "Aukera lehenetsitzat, markatu aldaketa guztiak txikitzat",
        "tog-previewontop": "Aurrebista aldaketa koadroaren aurretik erakutsi",
        "tog-previewonfirst": "Lehen aldaketan aurrebista erakutsi",
        "tog-enotifwatchlistpages": "Bidal iezadazue e-posta bat, jarraitzen ari naizen orrialde edo fitxategi bat aldatzen denean",
        "subcategories": "Azpikategoriak",
        "category-media-header": "Media \"$1\" kategorian",
        "category-empty": "''Kategoria honek ez dauka artikulurik uneotan.''",
-       "hidden-categories": "{{PLURAL:$1|Izkutuko kategoria|Izkutuko kategoriak}}",
+       "hidden-categories": "{{PLURAL:$1|Ezkutuko kategoria|Ezkutuko kategoriak}}",
        "hidden-category-category": "Kategoria ezkutuak",
        "category-subcat-count": "{{PLURAL:$2|Kategoria honek beste honako azpikategoria baino ez du.|Kategoria honek honako {{PLURAL:$1|azpikategoria du|$1 azpikategoriak ditu}}, guztira dauden $2tik.}}",
        "category-subcat-count-limited": "Kategoria honek {{PLURAL:$1|azpikategoria hau du|$1 azpikategoria hauek ditu}}.",
        "prefs-help-recentchangescount": "Honek azken aldaketak, orrialdeen historiak eta logak barne-biltzen ditu.",
        "prefs-help-watchlist-token2": "Hau da zure jarraipen zerrendako web jarioaren giltza sekretua.\nEzagutzen duen orok zure jarraipen zerrenda irakurtzeko aukera izango du, ez partekatu.\n[[Special:ResetTokens|Klik egin hemen berrezarri behar baduzu]]",
        "savedprefs": "Zure hobespenak gorde egin dira.",
-       "savedrights": "{{GENDER:$1|$1}} erabiltzailearen eskubideak gorde dira.",
+       "savedrights": "{{GENDER:$1|$1}} erabiltzailearen taldeak gorde dira.",
        "timezonelegend": "Ordu-eremua:",
        "localtime": "Ordu lokala:",
        "timezoneuseserverdefault": "Erabili lehenetsitako wikia ($1)",
        "recentchanges-legend-heading": "<strong>Azalpenak:</strong>",
        "recentchanges-legend-newpage": "{{int:recentchanges-label-newpage}} (ikus, gainera, [[Special:NewPages|orri berrien zerrenda]])",
        "recentchanges-submit": "Erakutsi",
+       "rcfilters-filterlist-title": "Iragazkiak",
+       "rcfilters-filtergroup-authorship": "Edizioaren egiletza",
+       "rcfilters-filter-bots-label": "Bot",
+       "rcfilters-filter-minor-label": "Aldaketa txikiak",
        "rcnotefrom": "Jarraian azaltzen diren aldaketak data honetatik aurrerakoak dira: <b>$2</b> (gehienez <b>$1</b> erakusten dira).",
        "rclistfrom": "Erakutsi $3 $2 ondorengo aldaketa berriak",
        "rcshowhideminor": "$1 aldaketa txikiak",
        "apisandbox-dynamic-parameters-add-placeholder": "Parametroaren izena",
        "apisandbox-dynamic-error-exists": "$1 parametro izena dagoeneko existitzen da",
        "apisandbox-results": "Emaitzak",
+       "apisandbox-continue": "Jarraitu",
+       "apisandbox-continue-clear": "Garbitu",
        "booksources": "Iturri liburuak",
        "booksources-search-legend": "Liburuen bilaketa",
        "booksources-search": "Bilatu",
        "previousdiff": "← Aldaketa zaharragoa",
        "nextdiff": "Aldaketa berriagoa →",
        "mediawarning": "'''Oharra''': Fitxategi honek kode mingarria izan lezake.\nZure sisteman exekutatzea arriskutsua izan liteke.",
-       "imagemaxsize": "Irudiaren tamainaren muga:<br />''(fitxategi deskribapen-orrietarako)''",
+       "imagemaxsize": "Irudiaren tamainaren muga:<br />''(fitxategia deskribatzen duten orrietarako)''",
        "thumbsize": "Irudi txikiaren tamaina:",
        "widthheightpage": "$1 × $2, $3 {{PLURAL:$3|orri|orri}}",
        "file-info": "fitxategiaren tamaina: $1, MIME mota: $2",
index 54f5134..1953747 100644 (file)
        "tooltip-pt-login": "Te recomendamus que te rustris, inque nu es mestel.",
        "tooltip-pt-logout": "Salil",
        "tooltip-ca-talk": "Caraba al tentu el artículu",
-       "tooltip-ca-edit": "Pueis eital esta página.\nPol favol, gasta el botón \"previsoreal\" enantis d'emburacal.",
+       "tooltip-ca-edit": "Eital esta páhina",
        "tooltip-ca-addsection": "Prencipial una nueva seción",
        "tooltip-ca-viewsource": "Esta páhina está protehia (nu pueis hazel chambus).",
        "tooltip-ca-history": "Velsionis anterioris d'esta página.",
index c2638ad..730bcc3 100644 (file)
        "searcharticle": "Siirry",
        "history": "Sivun historia",
        "history_short": "Historia",
+       "history_small": "historia",
        "updatedmarker": "päivitetty viimeisimmän käyntisi jälkeen",
        "printableversion": "Tulostettava versio",
        "permalink": "Ikilinkki",
        "recentchanges-legend-newpage": "{{int:recentchanges-label-newpage}} (katso myös [[Special:NewPages|lista uusista sivuista]])",
        "recentchanges-legend-plusminus": "(''±123'')",
        "recentchanges-submit": "Näytä",
+       "rcfilters-activefilters": "Aktiiviset suodattimet",
+       "rcfilters-invalid-filter": "Suodatin on epäkelpo",
+       "rcfilters-filterlist-title": "Suodattimet",
+       "rcfilters-filterlist-noresults": "Ei löytynyt suodattimia",
        "rcnotefrom": "Alla ovat muutokset <strong>$3, $4</strong> lähtien. (Enintään <strong>$1</strong> näytetään.)",
        "rclistfrom": "Näytä uudet muutokset $3 kello $2 alkaen",
        "rcshowhideminor": "$1 pienet muutokset",
        "pageinfo-length": "Sivun pituus (tavuina)",
        "pageinfo-article-id": "Sivun tunnistenumero",
        "pageinfo-language": "Sivun sisällön kieli",
+       "pageinfo-language-change": "vaihda",
        "pageinfo-content-model": "Sivun sisältömalli",
        "pageinfo-content-model-change": "muuta",
        "pageinfo-robot-policy": "Hakukonemerkinnät",
        "feedback-useragent": "User agent:",
        "searchsuggest-search": "Hae {{GRAMMAR:elative|{{SITENAME}}}}",
        "searchsuggest-containing": "sisältää...",
-       "api-error-autoblocked": "Sinun IP-osoitteesi on estetty automaattisesti, koska sitä on käyttänyt estetty käyttäjätunnus.",
-       "api-error-badaccess-groups": "Sinulla ei ole oikeutta tallentaa tiedostoja tähän wikiin.",
        "api-error-badtoken": "Sisäinen virhe: virheellinen tarkistussumma.",
-       "api-error-blocked": "Sinut on estetty muokkaamasta.",
-       "api-error-copyuploaddisabled": "Tallentaminen URL-osoitteesta ei ole käytössä.",
-       "api-error-duplicate": "Samansisältöisiä tiedostoja löytyi {{PLURAL:$1|yksi kappale|useampia kappaleita}}.",
-       "api-error-duplicate-archive": "Sivustolla oli aiemmin {{PLURAL:$1|toinen samansisältöinen tiedosto|toisia samansisältöisiä tiedostoja}}, mutta {{PLURAL:$1|se|ne}} poistettiin.",
-       "api-error-empty-file": "Määrittämäsi tiedosto on tyhjä.",
        "api-error-emptypage": "Ei ole sallittua luoda uutta, tyhjää sivua.",
-       "api-error-fetchfileerror": "Sisäinen virhe: Jotakin meni pieleen kun tiedostoa haettiin.",
-       "api-error-fileexists-forbidden": "Tiedosto nimellä \"$1\" on jo olemassa eikä sitä voi korvata.",
-       "api-error-fileexists-shared-forbidden": "Tiedosto nimeltä \"$1\" on jo olemassa yhteisessä tietovarastossa eikä sitä voi korvata.",
-       "api-error-file-too-large": "Määrittämäsi tiedosto on liian iso.",
-       "api-error-filename-tooshort": "Tiedoston nimi on liian lyhyt.",
-       "api-error-filetype-banned": "Tämän tyyppisten tiedostojen tallentaminen on kielletty.",
-       "api-error-filetype-banned-type": "$1 {{PLURAL:$4|ei ole sallittu tiedostomuoto|eivät ole sallittuja tiedostomuotoja}}. {{PLURAL:$3|Sallittu tiedostomuoto on|Sallittuja tiedostomuotoja ovat}} $2.",
-       "api-error-filetype-missing": "Tiedostolta puuttuu tiedostopääte.",
-       "api-error-hookaborted": "Laajennuskoodi esti yrittämäsi muutoksen.",
-       "api-error-http": "Sisäinen virhe: palvelimeen ei saatu yhteyttä.",
-       "api-error-illegal-filename": "Tiedoston nimi ei kelpaa.",
-       "api-error-internal-error": "Sisäinen virhe: jotain meni vikaan tallennuksesi käsittelyssä.",
-       "api-error-invalid-file-key": "Sisäinen virhe: tiedostoa ei löytynyt välikaisvarastosta.",
-       "api-error-missingparam": "Sisäinen virhe: pyynnöstä puutuu parametreja.",
-       "api-error-missingresult": "Sisäinen virhe: ei voitu varmistaa, että tallennus onnistui.",
-       "api-error-mustbeloggedin": "Sinun pitää olla kirjautunut sisään, jotta voisit tallentaa tiedostoja.",
-       "api-error-mustbeposted": "Sisäinen virhe: HTTP POST-pyyntö edellytetty.",
-       "api-error-noimageinfo": "Tallennus onnistui, mutta palvelin ei antanut meille tietoja tiedostosta.",
-       "api-error-nomodule": "Sisäinen virhe: tallennusmoduulia ei ole asetettu.",
-       "api-error-ok-but-empty": "Sisäinen virhe: palvelimelta ei saatu vastausta.",
-       "api-error-overwrite": "Olemassa olevan tiedoston korvaaminen toisella ei ole sallittua.",
-       "api-error-ratelimited": "Yrität tallentaa lyhyessä ajassa enemmän tiedostoja kuin tämä wiki sallii.\nYritä uudelleen muutaman minuutin kuluttua.",
-       "api-error-stashfailed": "Sisäinen virhe: Väliaikaisen tiedoston tallentaminen epäonnistui.",
        "api-error-publishfailed": "Sisäinen virhe: Väliaikaisen tiedoston julkaiseminen epäonnistui.",
-       "api-error-stasherror": "Tiedostoa ladattaessa tapahtui virhe.",
-       "api-error-stashedfilenotfound": "Tallennettavaa tiedostoa ei löytynyt säilöstä.",
-       "api-error-stashpathinvalid": "Hakupolku, jossa säilötyn tiedoston olisi pitänyt olla, oli virheellinen.",
-       "api-error-stashfilestorage": "Tiedoston tallentaminen säilöön epäonnistui.",
-       "api-error-stashzerolength": "Palvelin ei voinut säilöä tiedostoa, koska sen pituus oli nolla.",
-       "api-error-stashnotloggedin": "Sinun täytyy kirjautua sisään, jotta voit tallentaa tiedostoja lataussäilöön.",
-       "api-error-stashwrongowner": "Tiedosto, jota yritit käyttää säilössä, ei ole sinun omasi.",
-       "api-error-stashnosuchfilekey": "Tiedoston avainta, jota yritit käyttää säilössä, ei ole olemassa.",
-       "api-error-timeout": "Palvelin ei vastannut odotetun ajan kuluessa.",
-       "api-error-unclassified": "Tapahtui tuntematon virhe.",
-       "api-error-unknown-code": "Tuntematon virhe: $1.",
-       "api-error-unknown-error": "Sisäinen virhe: Jotain meni vikaan kun tiedostoasi yritettiin tallentaa.",
+       "api-error-stashfailed": "Sisäinen virhe: Väliaikaisen tiedoston tallentaminen epäonnistui.",
        "api-error-unknown-warning": "Tuntematon varoitus: $1.",
        "api-error-unknownerror": "Tuntematon virhe: $1.",
-       "api-error-uploaddisabled": "Tiedostojen tallentaminen ei ole käytössä.",
-       "api-error-verification-error": "Tiedosto voi olla vioittunut, tai sillä saattaa olla väärä tiedostopääte.",
-       "api-error-was-deleted": "Tämänniminen tiedosto on aikaisemmin tallennettu ja sittemmin poistettu.",
        "duration-seconds": "$1 {{PLURAL:$1|sekunti|sekuntia}}",
        "duration-minutes": "$1 {{PLURAL:$1|minuutti|minuuttia}}",
        "duration-hours": "$1 {{PLURAL:$1|tunti|tuntia}}",
index ab07152..5550e71 100644 (file)
        "recentchanges-legend-plusminus": "(''±123'')",
        "recentchanges-submit": "Lister",
        "rcfilters-activefilters": "Filtres actifs",
+       "rcfilters-restore-default-filters": "Rétablir les filtres par défaut",
+       "rcfilters-clear-all-filters": "Effacer tous les filtres",
        "rcfilters-search-placeholder": "Modifications récentes de filtres (naviguer ou commencer à saisir)",
        "rcfilters-invalid-filter": "Filtre non valide",
+       "rcfilters-empty-filter": "Aucun filtre actif. Toutes les contributions sont affichées.",
        "rcfilters-filterlist-title": "Filtres",
        "rcfilters-filterlist-noresults": "Aucun filtre trouvé",
        "rcfilters-filtergroup-registration": "Inscription de l’utilisateur",
        "upload_directory_read_only": "Le serveur web n’a pas accès en écriture au répertoire d’import de fichier ($1).",
        "uploaderror": "Erreur lors de l’import",
        "upload-recreate-warning": "<strong>Attention : Un fichier portant ce nom a été supprimé ou déplacé.</strong>\n\nLe journal des suppressions et celui des déplacements de cette page sont affichés ici pour informations :",
-       "uploadtext": "Utilisez ce formulaire pour importer des fichiers sur le serveur.\nPour voir ou rechercher des images précédemment envoyées, consultez la [[Special:FileList|liste des images]]. L’import est aussi enregistré dans le [[Special:Log/upload|journal d’import des fichiers]], et les suppressions dans le [[Special:Log/delete|journal des suppressions]].\n\nPour inclure un fichier dans une page, utilisez un lien de la forme :\n* '''<code><nowiki>[[</nowiki>{{ns:file}}<nowiki>:fichier.jpg]]</nowiki></code>''', pour afficher le fichier en pleine résolution (dans le cas d’une image) ;\n* '''<code><nowiki>[[</nowiki>{{ns:file}}<nowiki>:fichier.png|200px|thumb|left|texte descriptif]]</nowiki></code>''' pour utiliser une miniature de 200 pixels de large dans une boîte à gauche avec « texte descriptif » comme description ;\n* '''<code><nowiki>[[</nowiki>{{ns:media}}<nowiki>:fichier.ogg]]</nowiki></code>''' pour lier directement vers le fichier sans l’afficher.",
+       "uploadtext": "Utilisez ce formulaire pour téléverser des fichiers sur le serveur.\nPour voir ou rechercher des images précédemment envoyées, consultez la [[Special:FileList|liste des fichiers téléversés]]. Les envois multiples sont également tracés dans le [[Special:Log/upload|journal des téléversements]], et les suppressions dans le [[Special:Log/delete|journal des suppressions]].\n\nPour inclure un fichier dans une page, utilisez un lien ayant l'un des formats suivants :\n* <strong><code><nowiki>[[</nowiki>{{ns:file}}<nowiki>:fichier.jpg]]</nowiki></code></strong>, pour afficher le fichier en pleine résolution (dans le cas d’une image) ;\n* <strong><code><nowiki>[[</nowiki>{{ns:file}}<nowiki>:fichier.png|200px|thumb|left|texte descriptif]]</nowiki></code></strong> pour utiliser une miniature de 200 pixels de large dans une boîte à gauche avec « texte descriptif » comme description ;\n* <strong><code><nowiki>[[</nowiki>{{ns:media}}<nowiki>:fichier.ogg]]</nowiki></code></strong> pour relier directement le fichier sans l’afficher.",
        "upload-permitted": "{{PLURAL:$2|Format|Formats}} de fichiers {{PLURAL:$2|autorisé|autorisés}} : $1.",
        "upload-preferred": "{{PLURAL:$2|Format|Formats}} de fichiers {{PLURAL:$2|préféré|préférés}} : $1.",
        "upload-prohibited": "‎{{PLURAL:$2|Format|Formats}} de fichiers {{PLURAL:$2|interdit|interdits}} : $1.",
        "apisandbox-sending-request": "Envoi de la requête à l'API...",
        "apisandbox-loading-results": "Réception des résultats de l'API...",
        "apisandbox-results-error": "Une erreur s'est produite lors du chargement de la réponse à la requête de l'API: $1.",
-       "apisandbox-request-params-json": "Paramètres JSON :",
+       "apisandbox-request-selectformat-label": "Afficher les données de la requête comme :",
+       "apisandbox-request-format-url-label": "Chaîne de requête de l’URL",
        "apisandbox-request-url-label": "Requête URL :",
+       "apisandbox-request-json-label": "Demander du JSON :",
        "apisandbox-request-time": "Durée de la demande: {{PLURAL:$1|$1 ms}}",
        "apisandbox-results-fixtoken": "Corrigez le jeton et renvoyez",
        "apisandbox-results-fixtoken-fail": "Impossible de récupérer le jeton \"$1\"",
        "emailccsubject": "Copie de votre message à $1 : $2",
        "emailsent": "Courriel envoyé",
        "emailsenttext": "Votre message a été envoyé par courriel.",
-       "emailuserfooter": "Ce courriel a été {{GENDER:$1|envoyé}} par « $1 » à « {{GENDER:$2|$2}} » par la fonction « {{int:emailuser}} » de {{SITENAME}}. {{GENDER:$2|Votre}} courriel sera envoyé directement à l'{{GENDER:$1|émetteur initial}}, en {{GENDER:$1|lui}} mentionnant {{GENDER:$2|votre}} adresse courriel .",
+       "emailuserfooter": "Ce courriel a été {{GENDER:$1|envoyé}} par « $1 » à « {{GENDER:$2|$2}} » par la fonction « {{int:emailuser}} » de {{SITENAME}}. Si {{GENDER:$2|vous}} répondez à ce courriel, {{GENDER:$2|votre}} courriel sera envoyé directement à l’{{GENDER:$1|émetteur initial}}, en {{GENDER:$1|lui}} mentionnant {{GENDER:$2|votre}} adresse courriel .",
        "usermessage-summary": "Laisser un message système.",
        "usermessage-editor": "Messager du système",
        "watchlist": "Liste de suivi",
index 006492e..f2eaec5 100644 (file)
        "passwordreset-emaildisabled": "Les fonccionalitâts de mèssageria èlèctronica sont étâyes dèsactivâyes sur cél vouiqui.",
        "passwordreset-username": "Nom d’utilisator :",
        "passwordreset-domain": "Domêno :",
-       "passwordreset-capture": "Vos voléd vêre lo mèssâjo rèsultent ?",
-       "passwordreset-capture-help": "Se vos pouentâd cela câsa, lo mèssâjo (avouéc lo contresegno temporèro) vos serat montrâ quand serat mandâ a l’utilisator.",
        "passwordreset-email": "Adrèce èlèctronica :",
        "passwordreset-emailtitle": "Dètalys du comptio dessus {{SITENAME}}",
        "passwordreset-emailtext-ip": "Yon (de sûr vos, avouéc l’adrèce IP $1) at demandâ na remês’a zérô de voutron\ncontresegno por {{SITENAME}} ($4). {{PLURAL:$3|Ceti comptio utilisator est associyê|Cetos comptios utilisators sont associyês}}\na cel’adrèce èlèctronica :\n\n$2\n\n{{PLURAL:$3|Cél contresegno temporèro èxpirerat|Celos contresegnos temporèros èxpireront}} dens {{PLURAL:$5|un jorn|$5 jorns}}.\nOra vos vos dête branchiér et pués chouèsir un contresegno novél. Se cela demanda vint pas de vos\nou ben se vos vos éte rapelâ de voutron contresegno originâl et que vos en voléd pas més changiér,\nvos pouede ignorar cél mèssâjo et continuar a empleyér voutron viely contresegno.",
        "saveprefs": "Encartar",
        "restoreprefs": "Rètablir tota la configuracion per dèfôt (dedens totes les sèccions)",
        "prefs-editing": "Changement",
-       "rows": "Renches :",
-       "columns": "Colones :",
        "searchresultshead": "Rechèrche",
        "stub-threshold": "Lendâr por lo formatâjo des lims de vers los començons ($1) :",
        "stub-threshold-sample-link": "ègzemplo",
        "userrights-reason": "Rêson :",
        "userrights-no-interwiki": "Vos éd pas la pèrmission de changiér de drêts d’utilisator sur d’ôtros vouiquis.",
        "userrights-nodatabase": "La bâsa de balyês « $1 » ègziste pas ou ben est pas locâla.",
-       "userrights-nologin": "Vos vos dête [[Special:UserLogin|branchiér]] avouéc un comptio d’administrator por balyér de drêts d’utilisator.",
-       "userrights-notallowed": "Vos éd pas la pèrmission de balyér enlevar de drêts d’utilisator.",
        "userrights-changeable-col": "Les tropes que vos pouede changiér",
        "userrights-unchangeable-col": "Les tropes que vos pouede pas changiér",
        "userrights-conflict": "Disputa de changement de drêts d’utilisator ! Se vos plét, controlâd et pués confirmâd voutros changements.",
-       "userrights-removed-self": "Vos éd enlevâ los voutros drêts. Cen fât que vos pouede pas més arrevar a cela pâge.",
        "group": "Tropa :",
        "group-user": "Utilisators",
        "group-autoconfirmed": "Utilisators ôtoconfirmâs",
        "right-siteadmin": "Cotar et dècotar la bâsa de balyês",
        "right-override-export-depth": "Èxportar les pâges avouéc les pâges liyêes tant qu’a na provondior de 5 nivéls",
        "right-sendemail": "Mandar un mèssâjo ux ôtros utilisators",
-       "right-passwordreset": "Vêre los mèssâjos de remês’a zérô des contresegnos",
        "right-managechangetags": "Fâre et suprimar de [[Special:Tags|balises]] de la bâsa de balyês",
        "right-applychangetags": "Aplicar les [[Special:Tags|balises]] avouéc los sins changements",
        "right-changetags": "Apondre et enlevar de façon arbitrèra de [[Special:Tags|balises]] sur des vèrsions endividuèles et des entrês de jornâl",
        "feedback-subject": "Sujèt :",
        "feedback-submit": "Sometre",
        "feedback-thanks": "Grant-marci ! Voutron avis at étâ postâ sur la pâge « [$2 $1] ».",
-       "searchsuggest-search": "Rechèrchiér",
+       "searchsuggest-search": "Rechèrchiér dessus {{SITENAME}}",
        "searchsuggest-containing": "que contint...",
-       "api-error-badaccess-groups": "Vos éte pas ôtorisâ a tèlèchargiér des fichiérs sur ceti vouiqui.",
        "api-error-badtoken": "Èrror de dedens : crouyo « jeton ».",
-       "api-error-copyuploaddisabled": "Los tèlèchargements per URL sont dèsactivâs sur cél sèrvor.",
-       "api-error-duplicate": "Y at {{PLURAL:$1|un ôtro fichiér|d’ôtros fichiérs}} ja sur lo seto avouéc lo mémo contegnu.",
-       "api-error-duplicate-archive": "Y avéve {{PLURAL:$1|un ôtro fichiér|d’ôtros fichiérs}} ja sur lo seto avouéc lo mémo contegnu, mas {{PLURAL:$1|il at étâ suprimâ|ils ont étâ suprimâs}}.",
-       "api-error-empty-file": "Lo fichiér que vos éd somês ére vouedo.",
        "api-error-emptypage": "La crèacion de pâges novèles vouedes est pas ôtorisâ.",
-       "api-error-fetchfileerror": "Èrror de dedens : quârque-ren s’est mâl passâ pendent la rècupèracion du fichiér.",
-       "api-error-file-too-large": "Lo fichiér que vos éd somês ére trop grant.",
-       "api-error-filename-tooshort": "Lo nom du fichiér est trop côrt.",
-       "api-error-filetype-banned": "Cél tipo de fichiér est dèfendu.",
-       "api-error-filetype-banned-type": "$1 {{PLURAL:$4|est pas un tipo de fichiér ôtorisâ|sont pas des tipos de fichiérs ôtorisâs}}. {{PLURAL:$3|Lo tipo de fichiér ôtorisâ est|Los tipos de fichiérs ôtorisâs sont}} $2.",
-       "api-error-filetype-missing": "L’èxtension du fichiér est manquenta.",
-       "api-error-hookaborted": "Lo changement que vos éd tâchiê de fâre est étâ anulâ per n’èxtension.",
-       "api-error-http": "Èrror de dedens : sè pôt pas branchiér u sèrvor.",
-       "api-error-illegal-filename": "Lo nom du fichiér est pas ôtorisâ.",
-       "api-error-internal-error": "Èrror de dedens : quârque-ren s’est mâl passâ pendent lo trètament de voutron tèlèchargement sur lo vouiqui.",
-       "api-error-invalid-file-key": "Èrror de dedens : gins de fichiér trovâ dens lo stocâjo temporèro.",
-       "api-error-missingparam": "Èrror de dedens : manque des paramètres dens la requéta.",
-       "api-error-missingresult": "Èrror de dedens : nos ens pas possu dètèrmenar se la copia avéve reussia.",
-       "api-error-mustbeloggedin": "Vos dête étre branchiê por tèlèchargiér des fichiérs.",
-       "api-error-mustbeposted": "Èrror de dedens : la requéta at fôta d’HTTP POST.",
-       "api-error-noimageinfo": "Lo tèlèchargement at reussi, mas lo sèrvor at pas balyê d’enformacions sur lo fichiér.",
-       "api-error-nomodule": "Èrror de dedens : gins de modulo de tèlèchargement dèfeni.",
-       "api-error-ok-but-empty": "Èrror de dedens : lo sèrvor at pas rèpondu.",
-       "api-error-overwrite": "Ècllafar un fichiér ègzistent est pas ôtorisâ.",
        "api-error-stashfailed": "Èrror de dedens : lo sèrvor at pas possu encartar lo fichiér temporèro.",
-       "api-error-timeout": "Lo sèrvor at pas rèpondu dens lo dèlê atendu.",
-       "api-error-unclassified": "Una èrror encognua est arrevâ",
-       "api-error-unknown-code": "Èrror encognua : « $1 ».",
-       "api-error-unknown-error": "Èrror de dedens : quârque-ren s’est mâl passâ pendent lo tèlèchargement de voutron fichiér.",
        "api-error-unknown-warning": "Avèrtissement encognu : $1",
        "api-error-unknownerror": "Èrror encognua : « $1 ».",
-       "api-error-uploaddisabled": "Lo tèlèchargement est dèsactivâ sur ceti vouiqui.",
-       "api-error-verification-error": "Cél fichiér pôt étre corrompu, ou ben son èxtension est fôssa.",
        "duration-seconds": "$1 second{{PLURAL:$1|a|es}}",
        "duration-minutes": "$1 menut{{PLURAL:$1|a|es}}",
        "duration-hours": "$1 hor{{PLURAL:$1|a|es}}",
index 47584f2..5f765d5 100644 (file)
        "youremail": "Correo electrónico:",
        "username": "Nome de {{GENDER:$1|usuario|usuaria}}:",
        "prefs-memberingroups": "{{GENDER:$2|Membro}} {{PLURAL:$1|do grupo|dos grupos}}:",
+       "group-membership-link-with-expiry": "$1 (ata $2)",
        "prefs-registration": "Data e hora de rexistro:",
        "yourrealname": "Nome real:",
        "yourlanguage": "Lingua:",
        "userrights-nodatabase": "A base de datos \"$1\" non existe ou non é local.",
        "userrights-changeable-col": "Os grupos que pode cambiar",
        "userrights-unchangeable-col": "Os grupos que non pode cambiar",
+       "userrights-expiry-current": "Caduca 1$",
+       "userrights-expiry-none": "Non caduca",
+       "userrights-expiry": "Caduca:",
+       "userrights-expiry-options": "1 día:1 día,1 semana:1 semana,1 mes:1 mes,3 meses:3 meses,6 meses:6 meses,1 ano:1 ano",
        "userrights-conflict": "Hai un conflito na modificación dos dereitos de usuario! Por favor, revíseo e confirme os seus cambios.",
        "group": "Grupo:",
        "group-user": "Usuarios",
        "rcfilters-invalid-filter": "Filtro no válido",
        "rcfilters-filterlist-title": "Filtros",
        "rcfilters-filterlist-noresults": "Non se atoparon filtros",
+       "rcfilters-filtergroup-registration": "Rexistro de usuario",
+       "rcfilters-filter-registered-label": "Rexistrado",
+       "rcfilters-filter-unregistered-label": "Non rexistrado",
        "rcfilters-filtergroup-authorship": "Editar autoría",
        "rcfilters-filter-editsbyself-label": "As súas propias edicións",
        "rcfilters-filter-editsbyself-description": "Edicións súas.",
        "rcfilters-filter-editsbyother-label": "Edicións doutros.",
        "rcfilters-filter-editsbyother-description": "Edicións creadas por outros usuarios.",
-       "rcfilters-filtergroup-userExpLevel": "Nivel de experiencia de usuario",
+       "rcfilters-filtergroup-userExpLevel": "Nivel de experiencia (só para usuarios rexistrados)",
        "rcfilters-filter-userExpLevel-newcomer-label": "Chegados recentemente",
-       "rcfilters-filter-userExpLevel-newcomer-description": "Editores moi novosː menos de 10 edicións e 4 días de actividade.",
+       "rcfilters-filter-userExpLevel-newcomer-description": "Menos de 10 edicións e 4 días de actividade.",
        "rcfilters-filter-userExpLevel-learner-label": "Aprendices",
        "rcfilters-filter-userExpLevel-learner-description": "Máis días de actividade e edicións que 'novatos' pero menos que 'usuarios experimentados'.",
        "rcfilters-filter-userExpLevel-experienced-label": "Usuarios experimentados",
        "rcfilters-filter-userExpLevel-experienced-description": "Máis de 30 días de actividade e 500 edicións.",
+       "rcfilters-filter-bots-label": "Bot",
+       "rcfilters-filter-humans-label": "Humano (non bot)",
+       "rcfilters-filter-minor-label": "Edicións menores",
+       "rcfilters-filter-minor-description": "Edicións que o autor etiquetou como menores.",
+       "rcfilters-filtergroup-changetype": "Tipo de cambio",
+       "rcfilters-filter-pageedits-label": "Edicións de páxinas",
        "rcnotefrom": "A continuación {{PLURAL:$5|móstrase o cambio feito|móstranse os cambios feitos}} desde o <strong>$3</strong> ás <strong>$4</strong> (móstranse <strong>$1</strong> como máximo).",
        "rclistfrom": "Mostrar os cambios novos desde o $3 ás $2",
        "rcshowhideminor": "$1 as edicións pequenas",
        "uncategorizedcategories": "Categorías sen categorías",
        "uncategorizedimages": "Ficheiros sen categorías",
        "uncategorizedtemplates": "Modelos sen categorías",
+       "uncategorized-categories-exceptionlist": "# Contén unha lista de categorías que non van aparecer en Especial:UncategorizedCategories. Unha por liña, comezando con \"*\". As liñas que comecen con outro carácter (incluíndo espazos en branco) ignóranse. Use \"#\" para  engadir comentarios.",
        "unusedcategories": "Categorías sen uso",
        "unusedimages": "Imaxes sen uso",
        "wantedcategories": "Categorías requiridas",
        "apisandbox-sending-request": "Enviando a petición á API...",
        "apisandbox-loading-results": "Recibindo os resultados da API...",
        "apisandbox-results-error": "Produciuse un erro mentres se cargaba a resposta da petición á API: $1.",
-       "apisandbox-request-params-json": "Parámetros JSON:",
        "apisandbox-request-url-label": "URL da solicitude:",
        "apisandbox-request-time": "Duración da solicitude: {{PLURAL:$1|$1 ms}}",
        "apisandbox-results-fixtoken": "Corrixir o identificador e reenviar",
        "logentry-tag-update-logentry": "$1 {{GENDER:$2|actualizou}} etiquetas da entrada do rexistro $5 da páxina $3 ({{PLURAL:$7|engadiu}} $6; {{PLURAL:$9|eliminou}} $8)",
        "rightsnone": "(ningún)",
        "revdelete-summary": "o resumo de edición",
+       "rightslogentry-temporary-group": "$1 (temporal, ata $2)",
        "feedback-adding": "Enviando os comentarios...",
        "feedback-back": "Volver",
        "feedback-bugcheck": "Perfecto! Comprobe que aínda non está entre os [$1 erros coñecidos].",
index 1648e9e..46af76a 100644 (file)
        "jumptonavigation": "گردسن",
        "jumptosearch": "وامج",
        "view-pool-error": "سرورؤنˇ سر پۊر بار هننأ. پۊر پۊرˇ کارگيرؤن حقسأى کأدرن که اي ولگه فأندرن. \nلؤطف بۊکۊنين ىيسکالى صبر بدأرين.\n\n$1",
-       "aboutsite": "راجه به {{SITENAME}}",
+       "aboutsite": "راجع به {{SITENAME}}",
        "aboutpage": "Project:راجه به",
        "copyrightpage": "{{ns:project}}:چاکۊدنحق",
        "currentevents": "هسأىي تفاقؤن",
        "newpageletter": "نؤ",
        "boteditletter": "ر",
        "number_of_watching_users_pageview": "[$1 {{PLURAL:$1|کارگير}} پىگير]",
-       "rc-change-size-new": "$1 {{PLURAL:$1|باÙ\89ت}} ØªØºÙ\89يرˇ پسي",
+       "rc-change-size-new": "$1 {{PLURAL:$1|باÙ\89ت}} ØªØºÙ\8aيرˇ پسي",
        "recentchangeslinked": "مۊرتبطˇ تغىيرؤن",
        "recentchangeslinked-toolbox": "مۊرتبطˇ تغىيرؤن",
        "recentchangeslinked-summary": "اي جير، ىکته ليسته تينين بىنين آخري تغييرؤن أجي اۊ ولگؤنˇ مئن کي اي ولگˇ جي خال ببؤن (ىا جرگهٔ مؤردˇ نظرˇ جي). اۊ ولگؤني که [[Special:Watchlist|شيمئه پىگيري ليست]]۱ميئن دبۊن پۊررنگ نۊشؤن بدأبۊنن.",
        "tooltip-pt-login": "بئتره ديرين بشين؛ بسچی گه ايجباری نیه.",
        "tooltip-pt-logout": "بيرين شؤن",
        "tooltip-pt-createaccount": "بئتره کارگیري حساب چاکۊنين ؤ ديرين بشين؛ بسچي که حساب چاؤدن ايجباری نیه.",
-       "tooltip-ca-talk": "گب راجه به ولگˇ مؤحتوا",
+       "tooltip-ca-talk": "گب راجع به ولگˇ مؤحتوا",
        "tooltip-ca-edit": "اي ولگه دچينواچين بۊکۊنين",
        "tooltip-ca-addsection": "ىکته تازه وابين چاکۊن",
        "tooltip-ca-viewsource": "اي ولگ بپاسأکه.\nتؤنين اينˇ سربسه بينين",
index a3d9b83..e52e9d4 100644 (file)
@@ -17,7 +17,7 @@
        "tog-previewonfirst": "Poileach bodolacher zolok dakhoi",
        "tog-enotifwatchlistpages": "Mhojea sadurvollerintlem pan vo fail bodol'li zalear mhaka email dhadd",
        "tog-shownumberswatching": "Nodor dovorpi vangdianche sonkhya dakhoi",
-       "tog-oldsig": "Sodheachi soy:",
+       "tog-oldsig": "Tujea sod'dheachi soy:",
        "tog-uselivepreview": "Boroitastana zolok dahkoi",
        "tog-watchlisthideown": "Sadurvollerint mhojeo bodlopam lipoi",
        "tog-watchlisthidebots": "Sadurvollerint robotani kel'lim bodlopam lipoi",
        "newwindow": "(novea zonelant uktem zata)",
        "cancel": "Rod'd kor",
        "moredotdotdot": "Anik...",
-       "morenotlisted": "Hi suchi purn na",
+       "morenotlisted": "Hi suchi purn nasonk xekta.",
        "mypage": "Pan",
        "mytalk": "Bhasabhas",
        "navigation": "Dixa-niontronn",
        "passwordreset-domain": "Domain:",
        "passwordreset-email": "Email potto:",
        "passwordreset-emailelement": "Vapurpeachem nanv: \n$1\n\nTatpurtem gupitutor: \n$2",
-       "passwordreset-emailsentemail": "Gupitutor portun tharaipacho email dhadla.",
+       "passwordreset-emailsentemail": "Ho email pot'to tujea kontak zodlelem asa zalear, gupitutor portun tharaipacho email dhadlelem zatelem.",
        "changeemail": "Email potto bodol vo kad",
        "changeemail-oldemail": "Sodhyacho email potto:",
        "changeemail-newemail": "Novo email potto:",
        "searchprofile-advanced-tooltip": "Khaxel'lea nanvthollanni sod",
        "search-result-size": "$1 {{PLURAL:$2|1 utor|$2 utram}}",
        "search-result-category-size": "{{PLURAL:$1|1 vangddi|$1 vangddi}} ({{PLURAL:$2|1 upvorg|$2 upvorg}}, {{PLURAL:$3|1 fichier|$3 fichieri}})",
-       "search-redirect": "(punornirdexon $1)",
+       "search-redirect": "($1 savn punornirdexit)",
        "search-section": "(vibhag $1)",
        "search-suggest": "Tu mhonnunk sodi: $1 ?",
        "search-rewritten": "$1 hachim porinamam dakhoilean. Hea vantteache $2 ak sod.",
        "recentchanges-label-plusminus": "Hea panacho akar itlea baitani bodol'lo",
        "recentchanges-legend-heading": "<strong>Kunji:</strong>",
        "recentchanges-legend-newpage": "{{int:recentchanges-label-newpage}} ([[Special:NewPages|nove pananchi suchi]]-ui polloi)",
-       "rcnotefrom": "Sokoil <strong>$3, $4<strong> savnsavn {{PLURAL:$5|zalelem bodlop dilam|zalelim bodolpam dileant}} (<strong>$1<strong> meren {{PLURAL:$5|dakhoilam|dakhoileant}}).",
+       "rcnotefrom": "Sokoil <strong>$3, $4<strong> savn {{PLURAL:$5|zalelem bodlop dilam|zalelim bodolpam dileant}} (<strong>$1<strong> meren {{PLURAL:$5|dakhoilam|dakhoileant}}).",
        "rclistfrom": "$3 $2 savn suru zatelim novim bodolpam dakhoi",
        "rcshowhideminor": "$1 dhaktteo bodlopam",
        "rcshowhideminor-show": "Dakhoi",
        "uploadlogpage": "Uploadachem sotr",
        "filedesc": "Sar",
        "fileuploadsummary": "Aapros",
+       "large-file": "Faylachem akar $1 akin odik naslear borem; hi fayl $2 -anchi asa.",
        "watchthisupload": "Hea faylar dixtt dovor",
        "license": "Porvangi",
        "license-header": "Porvangi",
        "whatlinkshere-hideredirs": "$1 punornirdexonam",
        "whatlinkshere-hidetrans": "$1 durasth-somaveso",
        "whatlinkshere-hidelinks": "$1 zoddnio",
-       "whatlinkshere-hideimages": "Failinchim zoddpam $1",
+       "whatlinkshere-hideimages": "$1 faylinchim zoddni",
        "whatlinkshere-filters": "Challnio",
        "ipboptions": "2 voram:2 hours,1 dis:1 day,3 dis:3 days,1 satollo:1 week,2 satolle:2 weeks,1 mhoino:1 month,3 mhoine:3 months,6 mhoine:6 months,1 voros:1 year,sasnnank:infinite",
        "ipblocklist": "Addhailele vaporpi",
        "logentry-move-move": "$1-an $3 panak $4 {{GENDER:$2|haloilea}}",
        "logentry-newusers-create": "Vapurpeacho kont $1 {{GENDER:$2|rochlam}}",
        "logentry-upload-upload": "$1-an $3 {{GENDER:$2|upload kela}}",
-       "searchsuggest-search": "Sod",
+       "searchsuggest-search": "{{SITENAME}} sod",
        "special-characters-group-latin": "Romi",
        "special-characters-group-latinextended": "Romi (anink-ui)",
        "special-characters-group-ipa": "IPA",
index 1006cc8..2f79206 100644 (file)
        "nov": "Nop",
        "dec": "Des",
        "january-date": "$1 Yanuari",
-       "february-date": "$1 Peburuari",
+       "february-date": "$1 Pebruari",
        "march-date": "$1 Maret",
        "april-date": "$1 April",
        "may-date": "$1 Mei",
-       "june-date": "$1 Yuni",
-       "july-date": "$1 Yuli",
+       "june-date": "$1 Juni",
+       "july-date": "$1 Juli",
        "august-date": "$1 Agustus",
        "september-date": "$1 September",
        "october-date": "$1 Oktober",
        "edit-local": "Ubawa deskripsi lokal",
        "create": "Mohutu",
        "create-local": "Duhengi deskripsi lokal",
-       "editthispage": "Ubawa halaamani boti",
-       "create-this-page": "Pohutuwa halaamani boti",
+       "editthispage": "Boli'a halaman botiye",
+       "create-this-page": "Pohutuwa halamani botiye",
        "delete": "Luluta",
-       "deletethispage": "Luluta halaamani boti",
+       "deletethispage": "Luluta halaman botiye",
        "undeletethispage": "Bataliya moluluto",
        "undelete_short": "Batali moluluto {{PLURAL:$1|tuwawu uba|$1 ubawa}}",
        "viewdeleted_short": "Bilohi {{PLURAL:$1|tuwawu yiluluto uba|$1 yiluluto ubawa}}",
        "protect": "Dahawa",
-       "protect_change": "gantiyi",
+       "protect_change": "boli'a",
        "protectthispage": "Dahawa halaman boti",
        "unprotect": "dudaha ubaalo",
        "unprotectthispage": "ubawa dudaha halaman botiye",
        "talk": "Biisalawa",
        "views": "Bibilohu",
        "toolbox": "Pilaakasi",
+       "tool-link-userrights-readonly": "Bilohi lembo'a {{GENDER:$1|pengguna}}",
+       "tool-link-emailuser": "Lawola email ode {{GENDER:$1|user}}",
        "userpage": "Bilohi halaman pengguna",
        "projectpage": "Bilohi halaman proyek",
        "imagepage": "Bilohi halaman berkas",
        "disclaimers": "Momaahu",
        "disclaimerpage": "Project:Momaahu umum",
        "edithelp": "Wubodu momoli'o",
-       "helppage-top-gethelp": "Tuulungi",
+       "helppage-top-gethelp": "Wubodu",
        "mainpage": "Halaman Bungaliyo",
        "mainpage-description": "Halaman bungaliyo",
        "policy-url": "Project:Kebijakan",
        "toc": "Tuwango",
        "showtoc": "popobilehe",
        "hidetoc": "wanto'a",
-       "collapsible-collapse": "Lolohubu",
-       "collapsible-expand": "Duhengi",
+       "collapsible-collapse": "Wanto'a",
+       "collapsible-expand": "Bu'ade",
        "confirmable-confirm": "Delo {{GENDER:$1|yi'o}} yakini?",
        "confirmable-yes": "Jo",
        "confirmable-no": "De'e",
        "logentry-move-move": "$1 {{GENDER:$2|moheyi}} halaman $3 ode $4",
        "logentry-newusers-create": "Ta ohu'uwo akun $1 {{GENDER:$2|mohutu}}",
        "logentry-upload-upload": "$1 {{GENDER:$2|mengunggah}} $3",
-       "searchsuggest-search": "Lolohe"
+       "searchsuggest-search": "Lolohe {{SITENAME}}"
 }
index cf03a8e..2e3a445 100644 (file)
        "youremail": "דואר אלקטרוני:",
        "username": "שם {{GENDER:$1|המשתמש|המשתמשת}}:",
        "prefs-memberingroups": "{{GENDER:$2|חבר|חברה}} {{PLURAL:$1|בקבוצה|בקבוצות}}:",
+       "group-membership-link-with-expiry": "$1 (עד $2)",
        "prefs-registration": "זמן ההרשמה:",
        "yourrealname": "שם אמיתי:",
        "yourlanguage": "שפת הממשק:",
        "userrights-nodatabase": "בסיס הנתונים $1 אינו קיים או אינו מקומי.",
        "userrights-changeable-col": "{{PLURAL:$1|קבוצה|קבוצות}} שבאפשרותך לשנות",
        "userrights-unchangeable-col": "{{PLURAL:$1|קבוצה|קבוצות}} שאין באפשרותך לשנות",
+       "userrights-expiry-current": "פוקעת ב־$1",
+       "userrights-expiry-none": "אינה פוקעת",
+       "userrights-expiry": "פקיעה:",
+       "userrights-expiry-existing": "זמן הפקיעה הנוכחי: $3, $2",
+       "userrights-expiry-othertime": "זמן אחר:",
+       "userrights-expiry-options": "יום:1 day,שבוע:1 week,חודש:1 month,שלושה חודשים:3 months,שישה חודשים:6 months,שנה:1 year",
+       "userrights-invalid-expiry": "זמן הפקיעה לקבוצה \"$1\" אינו תקין.",
+       "userrights-expiry-in-past": "זמן הפקיעה לקבוצה \"$1\" הוא בעבר.",
        "userrights-conflict": "התנגשות בין שינויי הרשאות משתמש! אנא בִּדקו את השינויים שלכם ואשרו אותם.",
        "group": "קבוצה:",
        "group-user": "משתמשים",
        "recentchanges-legend-plusminus": "(<em>±123</em>)",
        "recentchanges-submit": "הצגה",
        "rcfilters-activefilters": "מסננים פעילים",
+       "rcfilters-restore-default-filters": "שחזור למסנני ברירת המחדל",
+       "rcfilters-clear-all-filters": "מחיקת כל המסננים",
        "rcfilters-search-placeholder": "סינון שינויים אחרונים (עיינו או התחילו להקליד)",
        "rcfilters-invalid-filter": "מסנן בלתי־תקין",
+       "rcfilters-empty-filter": "אין מסננים פעילים. כל התרומות מוצגות.",
        "rcfilters-filterlist-title": "מסננים",
        "rcfilters-filterlist-noresults": "לא נמצאו מסננים",
        "rcfilters-filtergroup-registration": "רישום העורכים",
        "apisandbox-sending-request": "בקשת ה־API בשליחה...",
        "apisandbox-loading-results": "תוצאות ה־API בתהליך קבלה...",
        "apisandbox-results-error": "אירעה שגיאה בעת טעינת תשובת ה־API לבקשה: $1.",
-       "apisandbox-request-params-json": "הפרמטרים בפורמט JSON:",
+       "apisandbox-request-selectformat-label": "הצגת המידע שבבקשה כ:",
+       "apisandbox-request-format-url-label": "מחרוזת השאילתה (query string) של כתובת ה־URL",
        "apisandbox-request-url-label": "כתובת ה־URL של הבקשה:",
+       "apisandbox-request-json-label": "ייצוג הבקשה כ־JSON:",
        "apisandbox-request-time": "זמן הבקשה: {{PLURAL:$1|מילישנייה אחת|$1 מילישניות}}",
        "apisandbox-results-fixtoken": "אנא תקנו את האסימון ושלחו שוב",
        "apisandbox-results-fixtoken-fail": "קבלת האסימון \"$1\" נכשלה.",
        "emailccsubject": "העתק של הודעתך למשתמש $1: $2",
        "emailsent": "הדואר נשלח",
        "emailsenttext": "הודעת הדואר האלקטרוני שלך נשלחה.",
-       "emailuserfooter": "$1 {{GENDER:$1|שלח|שלחה}} את הדוא\"ל הזה ל{{GENDER:$2|משתמש|משתמשת}} $2 באמצעות התכונה \"{{int:emailuser}}\" באתר {{SITENAME}}. התשובה שלך תישלח ישירות {{GENDER:$1|לשולח המקורי|לשולחת המקורית}}, והיא תחשוף {{GENDER:$1|בפניו|בפניה}} את כתובת הדוא\"ל שלך.",
+       "emailuserfooter": "$1 {{GENDER:$1|ש×\9c×\97|ש×\9c×\97×\94}} ×\90ת ×\94×\93×\95×\90\"×\9c ×\94×\96×\94 ×\9c{{GENDER:$2|×\9eשת×\9eש|×\9eשת×\9eשת}} $2 ×\91×\90×\9eצע×\95ת ×\94ת×\9b×\95× ×\94 \"{{int:emailuser}}\" ×\91×\90תר {{SITENAME}}. ×\90×\9d {{GENDER:$2|ת×\92×\99×\91|ת×\92×\99×\91×\99}} ×\9c×\93×\95×\90\"×\9c ×\94×\96×\94, ×\94תש×\95×\91×\94 ×©×\9c×\9a ×ª×\99ש×\9c×\97 ×\99ש×\99ר×\95ת {{GENDER:$1|×\9cש×\95×\9c×\97 ×\94×\9eק×\95ר×\99\9cש×\95×\9c×\97ת ×\94×\9eק×\95ר×\99ת}}, ×\95×\94×\99×\90 ×ª×\97ש×\95×£ {{GENDER:$1|×\91פנ×\99×\95\91פנ×\99×\94}} ×\90ת ×\9bת×\95×\91ת ×\94×\93×\95×\90\"×\9c ×©×\9c×\9a.",
        "usermessage-summary": "השארת הודעת מערכת.",
        "usermessage-editor": "שולח הודעות המערכת",
        "watchlist": "רשימת המעקב",
        "logentry-tag-update-logentry": "$1 {{GENDER:$2|עדכן|עדכנה}} את התגיות ברשומת היומן $5 של הדף $3 ({{PLURAL:$7|הוסיף|הוסיפה}} את $6; {{PLURAL:$9|הסיר|הסירה}} את $8)",
        "rightsnone": "(כלום)",
        "revdelete-summary": "תקציר העריכה",
+       "rightslogentry-temporary-group": "$1 (זמני, עד $2)",
        "feedback-adding": "הוספת משוב לדף...",
        "feedback-back": "חזרה",
        "feedback-bugcheck": "מצוין! נא לבדוק שזה לא אחד מה[$1 באגים הידועים].",
index ad9acfd..ade5f1b 100644 (file)
        "apisandbox-sending-request": "Sending API request...",
        "apisandbox-loading-results": "Receiving API results...",
        "apisandbox-results-error": "An error occurred while loading the API query response: $1.",
-       "apisandbox-request-params-json": "JSON parameters:",
        "apisandbox-request-url-label": "Request ke URL:",
        "apisandbox-request-time": "Request time: {{PLURAL:$1|$1 ms}}",
        "apisandbox-results-fixtoken": "Token ke sudhaar ke resubmit karo",
index 7d68aad..a66ea05 100644 (file)
        "searcharticle": "Kreni",
        "history": "Stare izmjene",
        "history_short": "Stare izmjene",
+       "history_small": "stare izmjene",
        "updatedmarker": "obnovljeno od posljednjeg posjeta",
        "printableversion": "Inačica za ispis",
        "permalink": "Trajna poveznica",
        "views": "Pogledi",
        "toolbox": "Pomagala",
        "tool-link-userrights": "Promijeni {{GENDER:$1|suradnikove|suradničine}} grupe",
+       "tool-link-userrights-readonly": "Vidi {{GENDER:$1|suradnikovu|suradničinu|suradničku}} pripadnost skupinama",
        "tool-link-emailuser": "Pošalji e-poštu {{GENDER:$1|suradniku|suradnici}}",
        "userpage": "Vidi suradnikovu stranicu",
        "projectpage": "Vidi stranicu o projektu",
        "userlogin-resetpassword-link": "Zaboravili ste zaporku?",
        "userlogin-helplink2": "Pomoć pri prijavi",
        "userlogin-loggedin": "Već ste prijavljeni kao {{GENDER:$1|$1}}.\nRabite donji obrazac da biste se prijavili kao drugi suradnik.",
+       "userlogin-reauth": "Morate se ponovno prijaviti da biste potvrdili da ste Vi {{GENDER:$1|$1}}.",
        "userlogin-createanother": "Stvori još jedan račun",
        "createacct-emailrequired": "Adresa e-pošte",
        "createacct-emailoptional": "Adresa e-pošte",
        "eauthentsent": "Na navedenu adresu poslana je e-poruka s potvrdom.\nPrije nego što pošaljemo daljnje poruke, molimo Vas otvorite e-poruku i slijedite u njemu sadržana uputstva kako biste potvrdili da je adresa e-pošte zaista Vaša.",
        "throttled-mailpassword": "Već Vam je poslan e-mail za promjenu zaporke, u {{PLURAL:$1|posljednjih sat vremena|posljednja $1 sata|posljednjih $1 sati}}.\nDa bi spriječili zloupotrebu, moguće je poslati samo jedan e-mail za promjenu zaporke {{PLURAL:$1|svakih sat vremena|svaka $1 sata|svakih $1 sati}}.",
        "mailerror": "Pogrješka pri slanju e-pošte: $1",
-       "acct_creation_throttle_hit": "Posjetitelji ovog wikija koji rabe Vašu IP adresu napravili su {{PLURAL:$1|1 račun|$1 računa}} u posljednjem danu, što je najveći dopušteni broj u tom vremenskom razdoblju.\nZbog toga posjetitelji s ove IP adrese trenutačno ne mogu otvoriti nove suradničke račune.",
+       "acct_creation_throttle_hit": "Posjetitelji ovog wikija koji rabe Vašu IP adresu napravili su {{PLURAL:$1|1 račun|$1 računa}} u posljednjih $2, što je najveći dopušteni broj u tom vremenskom razdoblju.\nZbog toga posjetitelji s ove IP adrese trenutačno ne mogu otvoriti nove suradničke račune.",
        "emailauthenticated": "Vaša adresa e-pošte potvrđena je $2 u $3.",
        "emailnotauthenticated": "Vaša adresa e-pošte još nije potvrđena.\nNe možemo poslati e-poruku ni u jednoj od sljedećih naredbi.",
        "noemailprefs": "Nije navedena adresa elektroničke pošte, stoga sljedeće naredbe ne će raditi.",
        "createacct-another-realname-tip": "Pravo ime nije obvezno. \nAko ga navedete, bit će korišteno za pripisivanje Vaših doprinosa.",
        "pt-login": "Prijavi se",
        "pt-login-button": "Prijavi se",
+       "pt-login-continue-button": "Nastavi prijavu",
        "pt-createaccount": "Otvori novi suradnički račun",
        "pt-userlogout": "Odjavi se",
        "php-mail-error-unknown": "Nepoznata pogrješka u funkciji PHP-poruke()",
        "botpasswords-bad-appid": "Ime bota \"$1\" nije valjano.",
        "botpasswords-insert-failed": "Nije moguće dodavanje imena bota \"$1\". Možda je već dodano?",
        "botpasswords-update-failed": "Nije moguće ažurirati bot s imenom \"$1\". Možda je izbrisan?",
+       "botpasswords-created-title": "Stvorena bot zaporka",
        "resetpass_forbidden": "Zaporka ne može biti promijenjena",
        "resetpass-no-info": "Morate biti prijavljeni da biste izravno pristupili ovoj stranici.",
        "resetpass-submit-loggedin": "Promijeni zaporku",
        "passwordreset-emailtext-user": "Suradnik $1 na {{SITENAME}} zatražio je podsjetnik o pojedinostima vašeg računa za {{SITENAME}}\n($4). Sljedeći {{PLURAL:$3|račun suradnika je|računi suradnika su}} povezani s ovom e-mail adresom:\n\n$2\n\n{{PLURAL:$3|Ova privremena zaporka|Ove privremene zaporke}} će isteći u {{PLURAL:$5|jedan dan|$5 dana}}.\nTrebate se prijaviti i odabrati novu zaporku. Ukoliko je netko drugi napravio ovaj\nzahtjev, ili ako ste se sjetili Vaše izvorne zaporke, a više je ne želite promijeniti, \nmožete zanemariti ovu poruku i nastavite koristiti staru zaporku.",
        "passwordreset-emailelement": "Suradničko ime: \n$1\n\nPrivremena zaporka: \n$2",
        "passwordreset-emailsentemail": "Ako je ova adresa povezana s Vašim suradničkim računom, na nju će biti poslan podsjetnik na zaporku.",
+       "passwordreset-invalidemail": "Nevaljala adresa e-pošte",
        "changeemail": "Promijeni ili izbriši e-mail adresu",
        "changeemail-header": "Promijeni adresu e-pošte računa",
        "changeemail-no-info": "Morate biti prijavljeni da biste izravno pristupili ovoj stranici.",
        "changeemail-oldemail": "Trenutačna adresa e-pošte:",
        "changeemail-newemail": "Nova adresa e-pošte:",
+       "changeemail-newemail-help": "Ako želite izbrisati adresu Vaše e-pošte, ostavite ovo polje praznim. U tom slučaju, nećete biti u mogućnosti ponovno postaviti zaboravljenu zaporku i nećete moći primati e-poštu s ovog wikija.",
        "changeemail-none": "(ništa)",
        "changeemail-password": "Zaporka za projekt {{SITENAME}}:",
        "changeemail-submit": "Promijeni E-mail",
        "prefs-help-signature": "Komentari na stranicama za razgovor trebali bi biti potpisani s \"<nowiki>~~~~</nowiki>\" što će biti pretvoreno u Vaš potpis i datum.",
        "badsig": "Kôd Vašeg potpisa nije valjan; provjerite HTML tagove.",
        "badsiglength": "Vaš potpis je predugačak.\nNe smije biti duži od $1 {{PLURAL:$1|znaka|znaka|znakova}}.",
-       "yourgender": "Spol:",
-       "gender-unknown": "Neodređeni",
-       "gender-male": "Muški",
-       "gender-female": "Ženski",
+       "yourgender": "Na koji način želite da Vam se ostali suradnici obraćaju?",
+       "gender-unknown": "Kad Vas se spominje, programska će oprema pokušati upotrijebiti srednji rod kad god je to moguće.",
+       "gender-male": "Uređivač sam wikistranica.",
+       "gender-female": "Uređivačica sam wikistranica.",
        "prefs-help-gender": "Mogućnost softvera da ispravno oslovljava razlikujući spol. Ovaj će podatak biti javan.",
        "email": "Adresa elektroničke pošte *",
        "prefs-help-realname": "Pravo ime nije obvezno. Ako ga navedete, može biti rabljeno za pripisivanje Vaših doprinosa.",
        "statistics-users": "Prijavljeni [[Special:ListUsers|suradnici]]",
        "statistics-users-active": "Aktivni suradnici",
        "statistics-users-active-desc": "Suradnici koji su napravili neku od radnji u posljednjih {{PLURAL:$1|dan|$1 dana}}",
-       "pageswithprop": "Stranice sa osobinom stranice",
-       "pageswithprop-legend": "Stranice sa osobinom stranice",
+       "pageswithprop": "Stranice s određenim osobinama",
+       "pageswithprop-legend": "Stranice s određenim osobinama",
+       "pageswithprop-text": "Ovo je popis stranica koje koriste određene osobine stranica.",
        "pageswithprop-prop": "Ime osobine:",
        "pageswithprop-submit": "Idi",
        "doubleredirects": "Dvostruka preusmjeravanja",
        "booksources-search": "Traži",
        "booksources-text": "Ovdje je popis vanjskih poveznica na internetskim stranicama koje prodaju nove i rabljene knjige, ali mogu sadržavati i ostale podatke o knjigama koje tražite:",
        "booksources-invalid-isbn": "Čini se da dani ISBN nije valjan; provjerite greške kopirajući iz izvornika.",
+       "magiclink-tracking-rfc": "Stranice s čarobnim RFC poveznicama",
+       "magiclink-tracking-rfc-desc": "Ova stranica rabi čarobne RFC poveznice. Za njihovu migraciju vidi [https://www.mediawiki.org/wiki/Special:MyLanguage/Help:Magic_links mediawiki.org].",
+       "magiclink-tracking-pmid": "Stranice s čarobnim PMID poveznicama",
+       "magiclink-tracking-pmid-desc": "Ova stranica rabi čarobne PMID poveznice. Za njihovu migraciju vidi [https://www.mediawiki.org/wiki/Special:MyLanguage/Help:Magic_links mediawiki.org].",
        "magiclink-tracking-isbn": "Stranice s čarobnim ISBN poveznicama",
        "magiclink-tracking-isbn-desc": "Ova stranica rabi čarobne ISBN poveznice. Za njihovu migraciju vidi [https://www.mediawiki.org/wiki/Special:MyLanguage/Help:Magic_links mediawiki.org].",
        "specialloguserlabel": "Suradnik:",
        "activeusers-intro": "Ovo je popis suradnika koji su napravili neku aktivnost u {{PLURAL:$1|posljednji $1 dan|posljednja $1 dana|posljednjih $1 dana}}.",
        "activeusers-count": "{{PLURAL:$1|nedavna $1 izmjena|nedavne $1 izmjene|nedavnih $1 izmjena}} u {{PLURAL:$3|posljednji $3 dan|posljednja $3 dana|posljednjih $3 dana}}",
        "activeusers-from": "Prikaži suradnike počevši od:",
+       "activeusers-groups": "Prikaži suradnike koji pripadaju suradničkim skupinama:",
+       "activeusers-excludegroups": "Isključi iz prikaza suradnike koji pripadaju ovim suradničkim skupinama:",
        "activeusers-noresult": "Niti jedan suradnik nije nađen.",
        "activeusers-submit": "Prikaz aktivnih suradnika",
        "listgrouprights": "Prava suradničkih skupina",
        "listgrants-summary": "Slijedi popis dozvola s pridruženim pristupom suradničkim pravima. Suradnici mogu omogućiti aplikacijama uporabu svojih računa, ali s ograničenim ovlastima na temelju dozvola koje je suradnik dodijelio aplikaciji. Aplikacija koja djeluje u ime suradnika međutim ne može rabiti prava koje suradnik nema.\nMoguće su [[{{MediaWiki:Listgrouprights-helppage}}|dodatne informacije]] o pojedinim pravima.",
        "listgrants-grant": "Dozvola",
        "listgrants-rights": "Prava",
+       "trackingcategories": "Kategorije za praćenje",
+       "trackingcategories-msg": "Praćene kategorije",
+       "trackingcategories-name": "Naziv poruke",
+       "trackingcategories-desc": "Kriteriji za uključenje u kategoriju",
        "restricted-displaytitle-ignored": "Stranice sa zanemarenim naslovima za prikaz",
+       "restricted-displaytitle-ignored-desc": "Na stranici je zanemaren <code><nowiki>{{DISPLAYTITLE}}</nowiki></code> jer ne odgovara trenutačnom naslovu stranice.",
        "trackingcategories-nodesc": "Opis nije dostupan.",
+       "trackingcategories-disabled": "Kategorija onemogućena",
        "mailnologin": "Nema adrese pošiljatelja",
        "mailnologintext": "Morate biti [[Special:UserLogin|prijavljeni]]\ni imati valjanu adresu e-pošte u svojim [[Special:Preferences|postavkama]]\nda bi mogli slati poštu drugim suradnicima.",
        "emailuser": "Pošalji mu e-poruku",
        "export-download": "Ponudi opciju snimanja u datoteku",
        "export-templates": "Uključi predloške",
        "export-pagelinks": "Uključi povezane stranice do dubine od:",
+       "export-manual": "Ručno dodaj stranice u polje:",
        "allmessages": "Sve poruke sustava",
        "allmessagesname": "Ime",
        "allmessagesdefault": "Prvotni tekst",
        "autoredircomment": "preusmjeravanje na [[$1]]",
        "autosumm-new": "nova stranica: $1",
        "autosumm-newblank": "stvorena prazna stranica",
+       "size-bytes": "$1 {{PLURAL:$1|bajt|bajta|bajtova}}",
        "lag-warn-normal": "Moguće je da izmjene nastale posljednjih $1 {{PLURAL:$1|sekundu|sekundi}} neće biti vidljive na ovom popisu.",
        "lag-warn-high": "Zbog kašnjenja baze podataka, moguće je da promjene napravljene u posljednjih $1 {{PLURAL:$1|sekundu|sekunde|sekundi}} nisu prikazane u popisu.",
        "watchlistedit-normal-title": "Uredi popis praćenja",
        "log-action-filter-rights-autopromote": "automatska promjena",
        "log-action-filter-upload-upload": "novo postavljanje",
        "log-action-filter-upload-overwrite": "ponovno postavljanje",
+       "authmanager-provider-temporarypassword": "Privremena zaporka",
        "changecredentials": "Promjena vjerodajnica",
-       "removecredentials": "Uklanjanje vjerodajnica"
+       "changecredentials-submit": "Promijeni vjerodajnice",
+       "removecredentials": "Uklanjanje vjerodajnica",
+       "removecredentials-submit": "Ukloni vjerodajnice",
+       "credentialsform-provider": "Vrsta vjerodajnica:",
+       "credentialsform-account": "Suradnički račun:"
 }
index 558b166..2c78830 100644 (file)
        "passwordreset-emaildisabled": "E-mejlowe funkcije su so na tutym wikiju znjemóžnili.",
        "passwordreset-username": "Wužiwarske mjeno:",
        "passwordreset-domain": "Domena:",
-       "passwordreset-capture": "E-mejlku sej wobhladać?",
-       "passwordreset-capture-help": "Jeli nakřižuješ tutón kašćik, budźe so e-mejlka z nachwilnym hesło pokazować a tež wužiwarjej pósłać.",
        "passwordreset-email": "E-mejlowa adresa:",
        "passwordreset-emailtitle": "Kontowe podrobnosće na {{GRAMMAR:lokatiw|{{SITENAME}}}}",
        "passwordreset-emailtext-ip": "Něchtó (najskerje ty, z IP-adresu $1) je anulowanje hesła za {{GRAMMAR:akuzatiw|{{SITENAME}}}} požadał ($4).  {{PLURAL:$3|Slědowace wužiwarske konto je|Slědowacej wužiwarskej konće stej|Slědowace wužiwarske konta su}} z tutej e-mejlowej adresu {{PLURAL:$3|zwjazane|zwjazanej|zwjazane}}:\n\n$2\n\n{{PLURAL:$3|Tute nachwilne hesło spadnje|Tutej nachwilnej hesle spadnjetej|Tute nachwilne hesła spadnu}} za {{PLURAL:$5|jedyn dźeń|$5 dnjej|$5 dny|$5 dnjow}}.\nTy měł so nětko přizjewić a nowe hesło wubrać. Jeli něchtó druhi je tute naprašowanje pósłał, abo jeli sy so zaso na prěnjotne hesło dopomnił a wjace nochceš jo změnić, móžeš tutu zdźělenku ignorować a swoje stare hesło dale wužiwać.",
        "saveprefs": "Składować",
        "restoreprefs": "Wšě standardne nastajenja wobnowić (w druhich wotrězkach)",
        "prefs-editing": "Wobdźěłowanje",
-       "rows": "Rjadki:",
-       "columns": "Stołpiki:",
        "searchresultshead": "Pytać",
        "stub-threshold": "Wotkazowe formatowanje małych stronow ($1):",
        "stub-threshold-disabled": "Znjemóžnjeny",
        "userrights-reason": "Přičina:",
        "userrights-no-interwiki": "Nimaš prawo wužiwarske prawa w druhich wikijach změnić.",
        "userrights-nodatabase": "Datowa banka $1 njeeksistuje abo lokalna njeje.",
-       "userrights-nologin": "Dyrbiš so z admininstratorowym kontom [[Special:UserLogin|přizjewić]], zo by wužiwarske prawa změnił.",
-       "userrights-notallowed": "Nimaš trěbne prawa, zo by wužiwarske prawa přidźěliło abo zebrało.",
        "userrights-changeable-col": "Skupiny, kotrež móžeš změnić",
        "userrights-unchangeable-col": "Skupiny, kotrež njemóžeš změnić",
        "userrights-conflict": "Konflikt změnow wužiwarskich prawow! Prošu přepruwuj a wobkruć swoje změny.",
-       "userrights-removed-self": "Sy swoje prawa wotstronił. Tohodla nimaš hižo přistup na tutu stronu měć.",
        "group": "Skupina:",
        "group-user": "wužiwarjo",
        "group-autoconfirmed": "Awtomatisce potwjerdźeni wužiwarjo",
        "right-siteadmin": "Datowu banku zawrěć abo wotewrić",
        "right-override-export-depth": "Strony inkluziwnje wotkazanych stronow hač do hłubokosće 5 eksportować",
        "right-sendemail": "Druhim wužiwarjam e-mejl pósłać",
-       "right-passwordreset": "E-mejlki za wróćostajenje hesłow sej wobhladać",
        "right-managechangetags": "[[Special:Tags|Markěrowanja]] wutworić a z(nje)móžnić",
        "right-applychangetags": "[[Special:Tags|Markěrowanja]] hromadźe ze změnami nałožować",
        "newuserlogpage": "Protokol nowych wužiwarjow",
        "badipaddress": "Njepłaćiwa IP-adresa",
        "blockipsuccesssub": "Zablokowanje wuspěšne",
        "blockipsuccesstext": "[[Special:Contributions/$1|$1]] bu {{GENDER:$1|zablokowany|zablokowana}}.<br />\nHlej [[Special:BlockList|lisćinu blokowanjow]], zo by zablokowanjow pruwował.",
-       "ipb-blockingself": "Chceš samoho blokować! Chceš to woprawdźe činić?",
+       "ipb-blockingself": "Chceš runje sebi sam blokować! Chceš to woprawdźe činić?",
        "ipb-confirmhideuser": "Chceš runje wužiwarja z nastajenjom \"wužiwarja schować\" blokować. To k tomu dowjedźe, zo mjeno wužiwarja so we wšch lisćinach a protokolowych zapiskach potłóči. Chceš to woprawdźe činić?",
        "ipb-confirmaction": "Jeli sy sej wěsty, zo chceš to woprawdźe činić, přepruwuj prošu deleka polo \"{{int:ipb-confirm}}\".",
        "ipb-edit-dropdown": "přičiny zablokowanjow wobdźěłać",
        "feedback-useragent": "Identifikator wobhladowaka:",
        "searchsuggest-search": "Pytać",
        "searchsuggest-containing": "wobsahuje...",
-       "api-error-badaccess-groups": "Nimaš prawo dataje do tutoho wikija nahrać.",
        "api-error-badtoken": "Nutřkowny zmylk: Wopačny token.",
-       "api-error-copyuploaddisabled": "Nahrawanje přez URL je na tutym serwerje znjemóžnjene.",
-       "api-error-duplicate": "{{PLURAL:$1|Je|Stej|Su}} hižo {{PLURAL:$1|druha dataja|druhej dataji|druhe dataje}} ze samsnym wobsahom na sydle.",
-       "api-error-duplicate-archive": "{{PLURAL:$1|Bě druha dataja|Běštej druhej dataji|Běchu druhe dataje|Bě druhich datajow}} hižo na websydle ze samsnym wobsahom, ale {{PLURAL:$1|je so zhašała|stej so zhašałoj|su so zhašeli|je so zhašało}}.",
-       "api-error-empty-file": "Dataja, kotruž sy nahrał, je prózdna.",
        "api-error-emptypage": "Wutworjenje nowych, prózdnych stronow njeje dowolene.",
-       "api-error-fetchfileerror": "Nutřkowny zmylk: při wobstarowanju dataje je so něšto nimokuliło.",
-       "api-error-fileexists-forbidden": "Dataja z mjenom \"$1\" hižo eksistuje, a njeda so přepisać.",
-       "api-error-fileexists-shared-forbidden": "Dataja z mjenom \"$1\" hižo eksistuje w zhromadnym datajowym repozitoriju a njeda so přepisać.",
-       "api-error-file-too-large": "Dataja, kotruž sy nahrał, bě přewulka.",
-       "api-error-filename-tooshort": "Datajowe mjeno překrótko",
-       "api-error-filetype-banned": "Tutón datajowy typ je zawrjeny.",
-       "api-error-filetype-banned-type": "$1 {{PLURAL:$4|dowoleny datajowy typ njeje|dowolenej datajowej typaj njejstej|dowolene datajowe typy njejsu|dowolene datajowe typy njejsu}}. {{PLURAL:$3|Dowoleny datajowy typ je|Dowolenej datajowej typaj stej|Dowolene datajowe typy su|Dowolene datajowe typy su}} $2.",
-       "api-error-filetype-missing": "Dataja nima datajowu kóncowku.",
-       "api-error-hookaborted": "Změna, kotruž pospytowaše přewjesć, bu přez rozšěrjensku hoku přetorhnjena.",
-       "api-error-http": "Nutřkowny zmylk: Zwisk ze serwerom njemóžno.",
-       "api-error-illegal-filename": "Datajowe mjeno njedowolene.",
-       "api-error-internal-error": "Nutřkowny zmylk: Při předźěłowanju twojeho nahraća na wiki je so něšto nimokuliło.",
-       "api-error-invalid-file-key": "Nutřkowny zmylk: dataja njeje so w nachwilnym składowaku namakała.",
-       "api-error-missingparam": "Nutřkowny zmylk: falowace parametry při naprašowanju.",
-       "api-error-missingresult": "Nutřkowny zmylk: njeda so zwěsćić, hač kopěrowanje je so poradźiło.",
-       "api-error-mustbeloggedin": "Dyrbiš přizjewjeny być, zo by dataje nahrał.",
-       "api-error-mustbeposted": "Nutřkowny zmylk: Naprašowanje wužaduje sej HTTP POST.",
-       "api-error-noimageinfo": "Nahraće je so poradźiło, ale serwer njeje nam žane informacije wo dataji dał.",
-       "api-error-nomodule": "Nutřkowny zmylk: Žadyn modul nastajeny.",
-       "api-error-ok-but-empty": "Nutřkowny zmylk: žana wotmołwa wot serwera.",
-       "api-error-overwrite": "Přepisowanje eksistowaceje dataje njeje dowolene.",
-       "api-error-stashfailed": "Nutřkowny zmylk: Serwer njemóžeše nachwilnu dataju składować.",
        "api-error-publishfailed": "Nutřkowny zmylk: Serwer njemóžeše nachwilnu dataju wozjewić.",
-       "api-error-stasherror": "Při nahrawanju dataje do chowanki je zmylk wusutpił.",
-       "api-error-timeout": "Serwer njeje znutřka wočakowaneho časa wotmołwił.",
-       "api-error-unclassified": "Njeznaty zmylk je wustupił.",
-       "api-error-unknown-code": "Njeznaty zmylk: \"$1\"",
-       "api-error-unknown-error": "Nutřkowny zmylk: Při nahrawanju twojeje dataje je so něšto nimokuliło.",
+       "api-error-stashfailed": "Nutřkowny zmylk: Serwer njemóžeše nachwilnu dataju składować.",
        "api-error-unknown-warning": "Njeznate warnowanje: $1",
        "api-error-unknownerror": "Njeznaty zmylk: \"$1\".",
-       "api-error-uploaddisabled": "Nahraća su na tutym wikiju znjemóžnjene.",
-       "api-error-verification-error": "Tuta dataja móhła wobkškodźena być abo wopačny sufiks měć.",
        "duration-seconds": "$1 {{PLURAL:$1|sekunda|sekundźe|sekundy|sekundow}}",
        "duration-minutes": "$1 {{PLURAL:$1|mjeńšina|mjeńšinje|mjeńšiny|mjeńšin}}",
        "duration-hours": "$1 {{PLURAL:$1|hodźina|hodźinje|hodźiny|hodźin}}",
index 2588da0..fae4caf 100644 (file)
        "searcharticle": "Menj",
        "history": "Laptörténet",
        "history_short": "Laptörténet",
+       "history_small": "laptörténet",
        "updatedmarker": "az utolsó látogatásom óta frissítették",
        "printableversion": "Nyomtatható változat",
        "permalink": "Hivatkozás erre a változatra",
        "views": "Nézetek",
        "toolbox": "Eszközök",
        "tool-link-userrights": "{{GENDER:$1|Felhasználócsoportok}} módosítása",
+       "tool-link-userrights-readonly": "{{GENDER:$1|Felhasználói}} csoportok megtekintése",
        "tool-link-emailuser": "E-mail küldése ennek a {{GENDER:$1|felhasználónak}}",
        "userpage": "Felhasználó lapjának megtekintése",
        "projectpage": "Projektlap megtekintése",
        "subject-preview": "Tárgy előnézete:",
        "previewerrortext": "Hiba történt a változások előnézete megjelenítése során.",
        "blockedtitle": "A szerkesztő blokkolva van",
-       "blockedtext": "'''A szerkesztőnevedet vagy az IP-címedet blokkoltuk.'''\n\nA blokkolást $1 végezte el.\nAz általa felhozott indok: ''$2''.\n\n* A blokk kezdete: $8\n* A blokk lejárata: $6\n* Blokkolt szerkesztő: $7\n\nKapcsolatba léphetsz $1 szerkesztőnkkel, vagy egy másik [[{{MediaWiki:Grouppage-sysop}}|adminisztrátorral]], és megbeszélheted vele a blokkolást.\nAz 'E-mail küldése ennek a szerkesztőnek' funkciót csak akkor használhatod, ha érvényes e-mail címet adtál meg\n[[Special:Preferences|fiókbeállításaidban]], és nem blokkolták a használatát.\nJelenlegi IP-címed: $3, a blokkolás azonosítószáma: #$5.\nKérjük, hogy érdeklődés esetén mindkettőt add meg.",
+       "blockedtext": "<strong>A szerkesztőnevedet vagy az IP-címedet blokkoltuk.</strong>\n\nA blokkolást $1 végezte el.\nAz általa felhozott indok: <em>$2.</em>\n\n* A blokk kezdete: $8\n* A blokk lejárata: $6\n* Blokkolt szerkesztő: $7\n\nKapcsolatba léphetsz $1 szerkesztőnkkel vagy egy másik [[{{MediaWiki:Grouppage-sysop}}|adminisztrátorral]], és megbeszélheted vele a blokkolást.\nAz „E-mail küldése ennek a szerkesztőnek” funkciót csak akkor használhatod, ha érvényes e-mail címet adtál meg [[Special:Preferences|fiókbeállításaidban]], és nem blokkolták a használatát.\nJelenlegi IP-címed: $3, a blokkolás azonosítószáma: #$5.\nKérjük, hogy érdeklődés esetén minden fenti részletet adj meg.",
        "autoblockedtext": "Az IP-címed automatikusan blokkolva lett, mert korábban egy olyan szerkesztő használta, akit $1 blokkolt, az alábbi indoklással:\n\n:''$2''\n\n*A blokk kezdete: '''$8'''\n*A blokk lejárata: '''$6'''\n*Blokkolt szerkesztő: '''$7'''\n\nKapcsolatba léphetsz $1 szerkesztőnkkel, vagy egy másik [[{{MediaWiki:Grouppage-sysop}}|adminisztrátorral]], és megbeszélheted vele a blokkolást.\n\nAz 'E-mail küldése ennek a szerkesztőnek' funkciót csak akkor használhatod, ha érvényes e-mail címet adtál meg\n[[Special:Preferences|fiókbeállításaidban]], és nem blokkolták a használatát.\n\nJelenlegi IP-címed: $3, a blokkolás azonosítószáma: #$5.\nKérjük, hogy érdeklődés esetén mindkettőt add meg.",
+       "systemblockedtext": "A felhasználónevedet vagy IP-címedet automatikusan blokkolta a MediaWiki.\nA blokkolás indoka:\n\n:<em>$2</em>\n\n* A blokk kezdete: $8\n* A blokk lejárata: $6\n* Blokkolt szerkesztő: $7\n\nA jelenlegi IP-címed: $3.\nKérjük, hogy érdeklődés esetén minden fenti részletet adj meg.",
        "blockednoreason": "nem adott meg okot",
        "whitelistedittext": "Lapok szerkesztéséhez $1.",
        "confirmedittext": "Lapok szerkesztése előtt meg kell erősítened az e-mail címedet. Kérjük, hogy a [[Special:Preferences|szerkesztői beállításaidban]] add meg, majd erősítsd meg az e-mail címedet.",
        "youremail": "Az e-mail címed:",
        "username": "{{GENDER:$1|Szerkesztőnév}}:",
        "prefs-memberingroups": "{{GENDER:$2|{{PLURAL:$1|Csoporttagság|Csoporttagságok}}}}:",
+       "group-membership-link-with-expiry": "$1 (a következő időpontig: $2)",
        "prefs-registration": "Regisztráció ideje:",
        "yourrealname": "Valódi neved:",
        "yourlanguage": "A felület nyelve:",
        "userrights-user-editname": "Add meg a szerkesztő nevét:",
        "editusergroup": "Szerkesztőcsoportok betöltése",
        "editinguser": "<strong>[[User:$1|$1]]</strong> felhasználó jogainak megváltoztatása $2",
+       "viewinguserrights": "<strong>[[User:$1|$1]]</strong> felhasználói csoportjainak megtekintése $2",
        "userrights-editusergroup": "Szerkesztőcsoportok módosítása",
+       "userrights-viewusergroup": "Felhasználói csoportok megtekintése",
        "saveusergroups": "{{GENDER:$1|Szerkesztőcsoportok}} mentése",
        "userrights-groupsmember": "Csoporttag:",
        "userrights-groupsmember-auto": "Alapértelmezetten tagja:",
        "userrights-nodatabase": "$1 adatbázis nem létezik vagy nem helyi.",
        "userrights-changeable-col": "Megváltoztatható csoportok",
        "userrights-unchangeable-col": "Nem megváltoztatható csoportok",
+       "userrights-expiry-current": "Lejár ekkor: $1",
+       "userrights-expiry-none": "Nem jár le",
+       "userrights-expiry": "Lejárat:",
+       "userrights-expiry-existing": "Jelenleg érvényben lévő lejárati idő: $2, $3",
+       "userrights-expiry-othertime": "Más idő:",
+       "userrights-expiry-options": "1 nap:1 day,1 hét:1 week,1 hónap:1 month,3 hónap:3 months,6 hónap:6 months,1 év:1 year",
+       "userrights-invalid-expiry": "A(z) „$1” csoport lejárati ideje érvénytelen.",
+       "userrights-expiry-in-past": "A(z) „$1” csoport lejárati ideje már elmúlt.",
        "userrights-conflict": "Felhasználói jogok ütközése! Kérlek, végezd el újra a változtatásokat.",
        "group": "Csoport:",
        "group-user": "szerkesztők",
        "grant-basic": "alapvető jogosultságok",
        "grant-viewdeleted": "törölt fájlok és lapok megtekintése",
        "grant-viewmywatchlist": "figyelőlista megtekintése",
+       "grant-viewrestrictedlogs": "korlátozott naplóbejegyzések megtekintése",
        "newuserlogpage": "Új szerkesztők naplója",
        "newuserlogpagetext": "Ez a napló az újonnan regisztrált szerkesztők listáját tartalmazza.",
        "rightslog": "Szerkesztői jogosultságok naplója",
        "action-writeapi": "író API használata",
        "action-delete": "lap törlése",
        "action-deleterevision": "változatok törlése",
+       "action-deletelogentry": "naplóbejegyzések törlése",
        "action-deletedhistory": "lap törölt laptörténetének megtekintése",
+       "action-deletedtext": "törölt lapváltozat szövegének megtekintése",
        "action-browsearchive": "keresés a törölt lapok között",
        "action-undelete": "lapok helyreállítása",
        "action-suppressrevision": "rejtett változatok megtekintése és helyreállítása",
        "action-userrights-interwiki": "más wikik szerkesztői jogainak módosítása",
        "action-siteadmin": "adatbázis lezárása vagy felnyitása",
        "action-sendemail": "e-mailek küldése",
+       "action-editmyoptions": "saját beállításaid szerkesztése",
        "action-editmywatchlist": "saját figyelőlista szerkesztése",
        "action-viewmywatchlist": "saját figyelőlista megtekintése",
        "action-viewmyprivateinfo": "személyes adatok megtekintése",
        "recentchanges-legend-heading": "<strong>Jelmagyarázat:</strong>",
        "recentchanges-legend-newpage": "{{int:recentchanges-label-newpage}} (lásd még: [[Special:NewPages|új lapok listája]])",
        "recentchanges-submit": "Megjelenítés",
+       "rcfilters-activefilters": "Aktív szűrők",
+       "rcfilters-restore-default-filters": "Alapértelmezett szűrők visszaállítása",
+       "rcfilters-clear-all-filters": "Összes szűrő kikapcsolása",
+       "rcfilters-search-placeholder": "Friss változtatások szűrése (böngészd vagy kezdj el gépelni)",
+       "rcfilters-invalid-filter": "Érvénytelen szűrő",
+       "rcfilters-empty-filter": "Nincs aktív szűrő. Minden közreműködés látható.",
+       "rcfilters-filterlist-title": "Szűrők",
+       "rcfilters-filterlist-noresults": "Nem található szűrő",
+       "rcfilters-filter-registered-label": "Regisztrált",
+       "rcfilters-filter-registered-description": "Bejelentkezett szerkesztők.",
+       "rcfilters-filter-unregistered-label": "Nem regisztrált",
+       "rcfilters-filter-unregistered-description": "Nem bejelentkezett szerkesztők.",
+       "rcfilters-filtergroup-authorship": "Szerkesztő",
+       "rcfilters-filter-editsbyself-label": "Saját szerkesztéseid",
+       "rcfilters-filter-editsbyself-description": "Saját szerkesztések",
+       "rcfilters-filter-editsbyother-label": "Mások szerkesztései",
+       "rcfilters-filter-editsbyother-description": "Más felhasználók által végzett szerkesztések (nem sajátok)",
+       "rcfilters-filter-userExpLevel-newcomer-label": "Újoncok",
+       "rcfilters-filter-userExpLevel-newcomer-description": "Kevesebb mint 10 szerkesztés és 4 nap aktivitás.",
+       "rcfilters-filter-userExpLevel-learner-label": "Tanulók",
+       "rcfilters-filter-userExpLevel-learner-description": "Több aktív nap és szerkesztés, mint az „újoncok”, de kevesebb, mint a „tapasztalt szerkesztők”.",
+       "rcfilters-filter-userExpLevel-experienced-label": "Tapasztalt szerkesztők",
+       "rcfilters-filter-userExpLevel-experienced-description": "Több mint 30 nap aktivitás és 500 szerkesztés.",
+       "rcfilters-filtergroup-automated": "Automatikus szerkesztések",
+       "rcfilters-filter-bots-label": "Bot",
+       "rcfilters-filter-bots-description": "Automatizált eszközök szerkesztései.",
+       "rcfilters-filter-humans-label": "Ember (nem bot)",
+       "rcfilters-filter-humans-description": "Emberi szerkesztők szerkesztései",
+       "rcfilters-filter-minor-label": "Apró szerkesztések",
+       "rcfilters-filter-minor-description": "Szerző által aprónak jelölt szerkesztések",
+       "rcfilters-filter-major-label": "Nem apró szerkesztések",
+       "rcfilters-filter-major-description": "Nem aprónak jelölt szerkesztések.",
+       "rcfilters-filtergroup-changetype": "Változtatás típusa",
+       "rcfilters-filter-pageedits-label": "Lapszerkesztések",
+       "rcfilters-filter-newpages-label": "Laplétrehozások",
+       "rcfilters-filter-newpages-description": "Új oldalt létrehozó szerkesztések.",
+       "rcfilters-filter-categorization-label": "Kategóriaváltoztatások",
+       "rcfilters-filter-logactions-label": "Naplózott műveletek",
+       "rcfilters-filter-logactions-description": "Adminisztratív műveletek, fióklétrehozások, laptörlések, feltöltések…",
        "rcnotefrom": "Alább a <strong>$3 $4</strong> óta történt változtatások láthatóak (legfeljebb <b>$1</b> db).",
        "rclistfrom": "$3, $2 után történt változtatások megtekintése",
        "rcshowhideminor": "apró szerkesztések $1",
        "apisandbox-loading-results": "API-válaszok fogadása…",
        "apisandbox-results-error": "Hiba történt az API-lekérdezés válaszának betöltése közben: $1.",
        "apisandbox-request-url-label": "Kérő URL:",
+       "apisandbox-request-json-label": "JSON kérése:",
        "apisandbox-request-time": "Kérés hossza: $1 ms",
        "apisandbox-results-fixtoken": "Token javítása és újrapróbálkozás",
        "apisandbox-results-fixtoken-fail": "A(z) „$1” token lekérése sikertelen.",
        "apisandbox-continue": "Folytatás",
        "apisandbox-continue-clear": "Törlés",
        "apisandbox-continue-help": "A {{int:apisandbox-continue}} [https://www.mediawiki.org/wiki/API:Query#Continuing_queries folytatja] az utolsó kérést; a {{int:apisandbox-continue-clear}} törli a folytatáshoz kapcsolódó paramétereket.",
+       "apisandbox-param-limit": "Használj <kbd>max</kbd>-ot a maximális értékhez.",
+       "apisandbox-multivalue-all-namespaces": "$1 (minden névtér)",
+       "apisandbox-multivalue-all-values": "$1 (minden érték)",
        "booksources": "Könyvforrások",
        "booksources-search-legend": "Könyvforrások keresése",
        "booksources-search": "Keresés",
        "activeusers-intro": "Ez a lap azon felhasználók listáját tartalmazza, akik végeztek valamilyen tevékenységet az elmúlt {{PLURAL:$1|egy|$1}} napban.",
        "activeusers-count": "$1 művelet az elmúlt $3 napban",
        "activeusers-from": "Szerkesztők listázása a következő névtől kezdve:",
+       "activeusers-groups": "A következő csoportokba tartozó felhasználók megjelenítése:",
+       "activeusers-excludegroups": "A következő csoportokba tartozó felhasználók kizárása:",
        "activeusers-noresult": "Nem található ilyen szerkesztő.",
        "activeusers-submit": "Aktív szerkesztők megjelenítése",
        "listgrouprights": "Szerkesztői csoportok jogai",
        "emailccsubject": "$1 szerkesztőnek küldött $2 tárgyú üzenet másolata",
        "emailsent": "E-mail elküldve",
        "emailsenttext": "E-mail üzenetedet elküldtük.",
-       "emailuserfooter": "Ezt az e-mailt $1 küldte $2 számára, az „{{int:emailuser}}” funkció használatával a(z) {{SITENAME}} wikin.",
+       "emailuserfooter": "Ezt az e-mailt $1 küldte $2 számára, az „{{int:emailuser}}” funkció használatával a(z) {{SITENAME}} wikin. Ha válaszolsz erre az üzenetre, az a választ közvetlenül az eredeti feladónak küldöd, felfedve az e-mail-címedet neki.",
        "usermessage-summary": "Rendszerüzenet megadása.",
        "usermessage-editor": "Rendszerüzenetek",
        "watchlist": "Figyelőlistám",
        "changecontentmodel-emptymodels-title": "Nincs elérhető tartalommodell",
        "changecontentmodel-emptymodels-text": "A(z) [[:$1]] lapon lévő tartalom nem alakítható át semmilyen típusúvá.",
        "log-name-contentmodel": "Tartalommodell-változások naplója",
-       "log-description-contentmodel": "Egy lap tartalommodelljéhez kapcsolódó események",
+       "log-description-contentmodel": "Ez a napló lapok tartalommodelljének változását és az alapértelmezettől eltérő tartalommodellel létrehozott lapokat listázza.",
        "logentry-contentmodel-new": "$1 {{GENDER:$2|létrehozta}} a(z) $3 lapot nem alapértelmezett „$5” tartalommodellel.",
        "logentry-contentmodel-change": "$1 {{GENDER:$2|megváltoztatta}} a(z) $3 lap tartalommodeljét erről: „$4” erre: „$5”",
        "logentry-contentmodel-change-revertlink": "visszaállítás",
        "modifiedarticleprotection": "megváltoztatta a(z) „[[$1]]” lap védelmi szintjét",
        "unprotectedarticle": "eltávolította a védelmet a(z) „[[$1]]” lapról",
        "movedarticleprotection": "áthelyezte „[[$2]]” védelmi beállításait „[[$1]]” cím alá",
+       "protectedarticle-comment": "„[[$1]]” {{GENDER:$2|levédve}}",
+       "modifiedarticleprotection-comment": "„[[$1]]” védelmi szintje {{GENDER:$2|módosítva}}",
+       "unprotectedarticle-comment": "„[[$1]]” lapvédelme {{GENDER:$2|feloldva}}",
        "protect-title": "„$1” levédése",
        "protect-title-notallowed": "„$1” védelmi szintjének megtekintése",
        "prot_1movedto2": "[[$1]] lapot átneveztem [[$2]] névre",
        "proxyblockreason": "Az IP-címeden ''nyílt proxy'' üzemel. Amennyiben nem használsz proxyt, vedd fel a kapcsolatot egy informatikussal vagy az internetszolgáltatóddal ezen súlyos biztonsági probléma ügyében.",
        "sorbsreason": "Az IP-címed nyitott proxyként szerepel e webhely által használt DNSBL listán.",
        "sorbs_create_account_reason": "Az IP-címed nyitott proxyként szerepel e webhely által használt DNSBL listán. Nem hozhatsz létre fiókot.",
+       "softblockrangesreason": "Az anonim szerkesztések nem engedélyezettek az IP-címedről ($1). Jelentkezz be a szerkesztéshez.",
        "xffblockreason": "Az X-Forwarded-For fejlécben lévő IP-cím, akár a tied, akár a használt proxy szerveré, blokkolva van. Az eredeti blokkolási ok: $1",
        "cant-see-hidden-user": "A felhasználó, akit blokkolni próbáltál már blokkolva és rejtve van. Mivel nincs felhasználó elrejtése jogosultságod, nem láthatod és nem szerkesztheted a felhasználó blokkját.",
        "ipbblocked": "Nem blokkolhatsz és nem oldhatod fel más felhasználók blokkjait, mert te magad is blokkolva vagy",
        "cant-move-to-user-page": "Nincs jogosultságod átnevezni egy lapot szerkesztői lapnak (kivéve annak allapjának).",
        "cant-move-category-page": "Nincs jogosultságod kategórialapok átnevezéséhez.",
        "cant-move-to-category-page": "Nincs jogosultságod átnevezni egy lapot kategórialapnak.",
+       "cant-move-subpages": "Nincs jogosultságod az allapok átnevezéséhez.",
+       "namespace-nosubpages": "A(z) „$1” névtérben nem használhatóak allapok.",
        "newtitle": "Az új cím:",
        "move-watch": "Figyeld a lapot",
        "movepagebtn": "Lap átnevezése",
        "pageinfo-length": "Lap hossza (bájtokban)",
        "pageinfo-article-id": "Lapazonosító",
        "pageinfo-language": "Laptartalom nyelve",
+       "pageinfo-language-change": "módosítás",
        "pageinfo-content-model": "Oldal tartalom modell",
        "pageinfo-content-model-change": "módosítás",
        "pageinfo-robot-policy": "Indexelés robottal",
        "patrol-log-header": "Ez az ellenőrzött változatok naplója.",
        "log-show-hide-patrol": "járőrnapló $1",
        "log-show-hide-tag": "címkenapló $1",
+       "confirm-markpatrolled-button": "OK",
+       "confirm-markpatrolled-top": "Ellenőrzöttnek jelölöd a(z) $2 lap $3 változatát?",
        "deletedrevision": "Régebbi változat törölve: $1",
        "filedeleteerror-short": "Hiba a fájl törlésekor: $1",
        "filedeleteerror-long": "Hibák merültek föl a következő fájl törlésekor:\n\n$1",
        "tags-deactivate": "deaktiválás",
        "tags-hitcount": "{{PLURAL:$1|Egy|$1}} változtatás",
        "tags-manage-no-permission": "Nincs engedélyed a változtatások címkéinek kezeléséhez.",
-       "tags-manage-blocked": "Nem tudja kezelni a változás kategóriát, amíg blokkolt.",
+       "tags-manage-blocked": "Nem kezelheted a módosításcímkéket, amíg blokkolva {{GENDER:$1|vagy}}.",
        "tags-create-heading": "Új címke létrehozása",
        "tags-create-explanation": "Alapértelmezés szerint az újonnan létrehozott címkék felhasználók és botok által manuálisan hozzáadhatók lesznek.",
        "tags-create-tag-name": "Címke neve:",
        "tags-deactivate-not-allowed": "Nem lehetséges a(z) „$1” címkét deaktiválni.",
        "tags-deactivate-submit": "Deaktiválás",
        "tags-apply-no-permission": "Nincs jogosultságod a szerkesztéseidet címkékkel ellátni.",
-       "tags-apply-blocked": "Nem módosíthatsz címkéket, amíg blokkolva vagy.",
+       "tags-apply-blocked": "Nem használhatsz módosításcímkéket a szerkesztéseidhez, amíg blokkolva {{GENDER:$1|vagy}}.",
        "tags-apply-not-allowed-one": "A(z) „$1” címke nem alkalmazható manuálisan.",
        "tags-apply-not-allowed-multi": "A következő {{PLURAL:$2|címke|címkék}} nem alkalmazhatók manuálisan: $1",
        "tags-update-no-permission": "Nincs jogosultságod egyedi változatok és naplóbejegyzések címkézésére és címkék eltávolítására.",
-       "tags-update-blocked": "Nem adhatsz hozzá vagy távolíthatsz el címkéket, amíg blokkolva vagy.",
+       "tags-update-blocked": "Nem adhatsz hozzá vagy távolíthatsz el címkéket, amíg blokkolva {{GENDER:$1|vagy}}.",
        "tags-update-add-not-allowed-one": "A(z) „$1” címke nem adható hozzá manuálisan.",
        "tags-update-add-not-allowed-multi": "A következő {{PLURAL:$2|címke|címkék}} nem adhatók hozzá manuálisan: $1",
        "tags-update-remove-not-allowed-one": "A  „$1” címkét nem lehet törölni.",
        "htmlform-user-not-exists": "<strong>$1</strong> nem létezik.",
        "htmlform-user-not-valid": "<strong>$1</strong> nem egy érvényes felhasználónév.",
        "logentry-delete-delete": "$1 törölte a következő lapot: $3",
+       "logentry-delete-delete_redir": "$1 {{GENDER:$2|törölte}} a(z) $3 átirányítást felülírással",
        "logentry-delete-restore": "$1 helyreállította a következő lapot: $3",
        "logentry-delete-event": "$1 megváltoztatta {{PLURAL:$5|egy napló bejegyzés|$5 napló bejegyzés}} láthatóságát a(z) $3 című lapon: $4",
        "logentry-delete-revision": "$1 {{GENDER:$2|módosította}} a(z) $3 című lap {{PLURAL:$5|egy|$5}} lapváltozatának láthatóságát: $4",
        "logentry-tag-update-logentry": "$1 {{GENDER:$2|frissítette}} a címkéket a(z) $3 lap $5 napló bejegyzésénél ({{PLURAL:$7|hozzáadta}}: $6; {{PLURAL:$9|eltávolította}}: $8)",
        "rightsnone": "(semmi)",
        "revdelete-summary": "a szerkesztési összefoglalóját",
+       "rightslogentry-temporary-group": "$1 (ideiglenesen, a következő időpontig: $2)",
        "feedback-adding": "Visszajelzés elmentése...",
        "feedback-back": "Vissza",
        "feedback-bugcheck": "Nagyszerű! Ellenőrizd, hogy ez nem egy [$1 ismert hiba].",
        "pagelang-language": "Nyelv",
        "pagelang-use-default": "Alapértelmezett nyelv használata",
        "pagelang-select-lang": "Nyelv kiválasztása",
+       "pagelang-reason": "Indoklás",
        "pagelang-submit": "Küldés",
+       "pagelang-nonexistent-page": "A(z) $1 lap nem létezik.",
+       "pagelang-unchanged-language": "A(z) $1 lap már $2 nyelvű.",
+       "pagelang-unchanged-language-default": "A(z) $1 lap már a wiki alapértelmezett tartalomnyelvére van állítva.",
        "right-pagelang": "oldal nyelvének megváltoztatása",
        "action-pagelang": "oldal nyelvének módosítása",
        "log-name-pagelang": "Nyelvváltoztatások naplója",
        "mw-widgets-dateinput-no-date": "Nincs kiválasztott dátum",
        "mw-widgets-dateinput-placeholder-day": "ÉÉÉÉ-HH-NN",
        "mw-widgets-dateinput-placeholder-month": "ÉÉÉÉ-HH",
+       "mw-widgets-mediasearch-input-placeholder": "Média keresése",
+       "mw-widgets-mediasearch-noresults": "Nincs találat.",
        "mw-widgets-titleinput-description-new-page": "a lap még nem létezik",
        "mw-widgets-titleinput-description-redirect": "átirányítás ide: $1",
+       "mw-widgets-categoryselector-add-category-placeholder": "Kategória hozzáadása…",
        "sessionmanager-tie": "Nem kombinálható többféle hitelesítési típus: $1.",
        "sessionprovider-generic": "$1-munkamenetek",
        "sessionprovider-mediawiki-session-cookiesessionprovider": "sütialapú munkamenetek",
        "log-action-filter-contentmodel-change": "Tartalommodell módosítása",
        "log-action-filter-contentmodel-new": "Lap létrehozása nem alapértelmezett tartalommodellel",
        "log-action-filter-delete-delete": "Laptörlés",
+       "log-action-filter-delete-delete_redir": "Átirányítás felülírása",
        "log-action-filter-delete-restore": "Visszaállítás",
        "log-action-filter-delete-event": "Naplótörlés",
        "log-action-filter-delete-revision": "Lapváltozat-törlés",
        "usercssispublic": "Figyelem: CSS-allapokon ne tárolj bizalmas adatokat, mivel minden felhasználó számára láthatóak.",
        "restrictionsfield-badip": "Érvénytelen IP-cím vagy -tartomány: $1",
        "restrictionsfield-label": "Engedélyezett IP-tartományok:",
-       "restrictionsfield-help": "Egy IP-cím vagy CIDR-tartomány soronként. Minden engedélyezéséhez használd a következő tartományokat:<br><code>0.0.0.0/0</code><br><code>::/0</code>"
+       "restrictionsfield-help": "Egy IP-cím vagy CIDR-tartomány soronként. Minden engedélyezéséhez használd a következő tartományokat:\n<pre>\n0.0.0.0/0\n::/0\n</pre>",
+       "revid": "$1 változat",
+       "pageid": "$1 lapazonosító"
 }
index 2c17ff8..96bb80c 100644 (file)
        "youremail": "E-mail:",
        "username": "{{GENDER:$1|Nomine de usator}}:",
        "prefs-memberingroups": "{{GENDER:$2|Membro}} de {{PLURAL:$1|gruppo|gruppos}}:",
+       "group-membership-link-with-expiry": "$1 (usque a $2)",
        "prefs-registration": "Data de registration:",
        "yourrealname": "Nomine real:",
        "yourlanguage": "Lingua:",
        "userrights-nodatabase": "Le base de datos $1 non existe o non es local.",
        "userrights-changeable-col": "Gruppos que tu pote modificar",
        "userrights-unchangeable-col": "Gruppos que tu non pote modificar",
+       "userrights-expiry-current": "Expiration: $2",
+       "userrights-expiry-none": "Non expira",
+       "userrights-expiry": "Expiration:",
+       "userrights-expiry-existing": "Expiration existente: le $2 a $3",
+       "userrights-expiry-othertime": "Altere hora:",
+       "userrights-expiry-options": "1 die:1 day,1 septimana:1 week,1 mense:1 month,3 menses:3 months,6 menses:6 months,1 anno:1 year",
+       "userrights-invalid-expiry": "Le hora de expiration pro le gruppo \"$1\" es invalide.",
+       "userrights-expiry-in-past": "Le hora de expiration pro le gruppo \"$1\" es in le passato.",
        "userrights-conflict": "Conflicto inter cambiamentos de derectos de usator! Per favor revide e confirma tu cambiamentos.",
        "group": "Gruppo:",
        "group-user": "Usatores",
        "recentchanges-legend-plusminus": "(''±123'')",
        "recentchanges-submit": "Monstrar",
        "rcfilters-activefilters": "Filtros active",
+       "rcfilters-restore-default-filters": "Restaurar filtros predefinite",
+       "rcfilters-clear-all-filters": "Rader tote le filtros",
        "rcfilters-search-placeholder": "Filtrar le modificationes recente (naviga o comencia a scriber)",
        "rcfilters-invalid-filter": "Filtro non valide",
+       "rcfilters-empty-filter": "Nulle filtro active. Tote le contributiones es monstrate.",
        "rcfilters-filterlist-title": "Filtros",
        "rcfilters-filterlist-noresults": "Nulle filtro trovate",
+       "rcfilters-filtergroup-registration": "Registration del usator",
+       "rcfilters-filter-registered-label": "Registrate",
+       "rcfilters-filter-registered-description": "Redactores que ha aperite session.",
+       "rcfilters-filter-unregistered-label": "Non registrate",
+       "rcfilters-filter-unregistered-description": "Redactores que non ha aperite session.",
        "rcfilters-filtergroup-authorship": "Autor del modificationes",
        "rcfilters-filter-editsbyself-label": "Tu proprie modificationes",
        "rcfilters-filter-editsbyself-description": "Modificationes per te.",
        "rcfilters-filter-editsbyother-label": "Modificationes per alteres",
        "rcfilters-filter-editsbyother-description": "Modificationes create per altere usatores (non te).",
-       "rcfilters-filtergroup-userExpLevel": "Nivello de experientia del usator",
+       "rcfilters-filtergroup-userExpLevel": "Nivello de experientia (solmente pro usatores registrate)",
        "rcfilters-filter-userExpLevel-newcomer-label": "Novicios",
-       "rcfilters-filter-userExpLevel-newcomer-description": "Autores multo nove: minus de 10 modificationes e 4 dies de activitate.",
+       "rcfilters-filter-userExpLevel-newcomer-description": "Minus de 10 modificationes e 4 dies de activitate.",
        "rcfilters-filter-userExpLevel-learner-label": "Apprentisses",
-       "rcfilters-filter-userExpLevel-learner-description": "Plus dies de activitate e modificationes que 'Novicios' ma minus que \"Usatores con experientia'.",
+       "rcfilters-filter-userExpLevel-learner-description": "Plus dies de activitate e modificationes que \"Novicios\" ma minus que \"Usatores con experientia\".",
        "rcfilters-filter-userExpLevel-experienced-label": "Usatores con experientia",
        "rcfilters-filter-userExpLevel-experienced-description": "Plus de 30 dies de activitate e 500 modificationes.",
+       "rcfilters-filtergroup-automated": "Contributiones automatisate",
+       "rcfilters-filter-bots-label": "Robot",
+       "rcfilters-filter-bots-description": "Modificationes facite per instrumentos automatisate.",
+       "rcfilters-filter-humans-label": "Persona (non robot)",
+       "rcfilters-filter-humans-description": "Modificationes facite per esseres human.",
+       "rcfilters-filtergroup-significance": "Importantia",
+       "rcfilters-filter-minor-label": "Modificationes minor",
+       "rcfilters-filter-minor-description": "Modificationes que le autor ha marcate como minor.",
+       "rcfilters-filter-major-label": "Modificationes non minor",
+       "rcfilters-filter-major-description": "Modificationes non marcate como minor.",
+       "rcfilters-filtergroup-changetype": "Typo de cambiamento",
+       "rcfilters-filter-pageedits-label": "Modificationes de paginas",
+       "rcfilters-filter-pageedits-description": "Modificationes de contento wiki, discussiones, descriptiones de categorias…",
+       "rcfilters-filter-newpages-label": "Creationes de paginas",
+       "rcfilters-filter-newpages-description": "Modificationes que face nove paginas.",
+       "rcfilters-filter-categorization-label": "Cambios de categoria",
+       "rcfilters-filter-categorization-description": "Registros del addition o remotion de paginas a/de categorias.",
+       "rcfilters-filter-logactions-label": "Actiones traciate",
+       "rcfilters-filter-logactions-description": "Actiones administrative, creation de contos, deletion de paginas, incargamentos…",
        "rcnotefrom": "Ecce le {{PLURAL:$5|modification|modificationes}} a partir del <strong>$3 a $4</strong> (usque a <strong>$1</strong> entratas monstrate).",
        "rclistfrom": "Monstrar nove modificationes a partir del $3 a $2",
        "rcshowhideminor": "$1 modificationes minor",
        "apisandbox-sending-request": "Invia requesta API...",
        "apisandbox-loading-results": "Recipe resultatos API...",
        "apisandbox-results-error": "Un error ha occurrite durante le cargamento del responsa al consulta API: $1.",
-       "apisandbox-request-params-json": "Parametros JSON:",
+       "apisandbox-request-selectformat-label": "Monstrar datos del requesta como:",
+       "apisandbox-request-format-url-label": "Catena de requesta del URL",
        "apisandbox-request-url-label": "URL de requesta:",
+       "apisandbox-request-json-label": "JSON del requesta:",
        "apisandbox-request-time": "Duration del requesta: {{PLURAL:$1|$1 ms}}",
        "apisandbox-results-fixtoken": "Corrige le indicio e reinvia",
        "apisandbox-results-fixtoken-fail": "Impossibile recuperar indicio \"$1\".",
        "emailccsubject": "Copia de tu message a $1: $2",
        "emailsent": "E-mail inviate",
        "emailsenttext": "Tu message de e-mail ha essite inviate.",
-       "emailuserfooter": "Iste e-mail ha essite {{GENDER:$1|inviate}} per $1 a {{GENDER:$2|$2}} con le function \"{{int:emailuser}}\" in {{SITENAME}}.\n{{GENDER:$2|Le}} message ha essite inviate directemente al {{GENDER:$1|expeditor|expeditrice}} original, revelante {{GENDER:$2|tu}} adresse de e-mail a {{GENDER:$1|ille|illa}}.",
+       "emailuserfooter": "Iste e-mail ha essite {{GENDER:$1|inviate}} per $1 a {{GENDER:$2|$2}} con le function \"{{int:emailuser}}\" in {{SITENAME}}.\nSi {{GENDER:$2|tu}} responde a iste message, {{GENDER:$2|tu}} responsa essera inviate directemente al {{GENDER:$1|expeditor|expeditrice}} original, revelante {{GENDER:$2|tu}} adresse de e-mail a {{GENDER:$1|ille|illa}}.",
        "usermessage-summary": "Lassante un message de systema.",
        "usermessage-editor": "Messagero del systema",
        "watchlist": "Observatorio",
        "logentry-tag-update-logentry": "$1 {{GENDER:$2|actualisava}} etiquettas sur le entrata de registro $5 del pagina $3 ({{PLURAL:$7|addeva}} $6; {{PLURAL:$9|removeva}} $8)",
        "rightsnone": "(nulle)",
        "revdelete-summary": "summario del modification",
+       "rightslogentry-temporary-group": "$1 (temporari, usque a $2)",
        "feedback-adding": "Le responsa es addite al pagina...",
        "feedback-back": "Retornar",
        "feedback-bugcheck": "Bon! Ma per favor verifica que iste falta non es [$1 jam cognoscite].",
        "usercssispublic": "Nota ben: Subpaginas CSS non debe continer datos confidential perque altere usatores pote vider los.",
        "restrictionsfield-badip": "Adresse o intervallo IP non valide: $1",
        "restrictionsfield-label": "Intervallos IP permittite:",
-       "restrictionsfield-help": "Un adresse IP o intervallo CIDR per linea. Pro activar toto, usa<br><code>0.0.0.0/0</code><br><code>::/0</code>",
+       "restrictionsfield-help": "Un adresse IP o intervallo CIDR per linea. Pro activar toto, usa:<pre>0.0.0.0/0\n::/0</pre>",
        "revid": "version $1",
        "pageid": "ID de pagina $1"
 }
index 1da92ba..66762ee 100644 (file)
@@ -63,7 +63,9 @@
        "tog-prefershttps": "Sempre uzar sekura konekto kande facar log in",
        "underline-always": "Sempre",
        "underline-never": "Nulatempe",
+       "underline-default": "Pre-ajustaji pri sub-strekizar ligili",
        "editfont-style": "Stilo di fonto uzata por editar la texto:",
+       "editfont-default": "Preajustaji di navigilo",
        "editfont-monospace": "Tipo por redaktar kun singla spaco",
        "editfont-sansserif": "tipo Sans-serif",
        "editfont-serif": "tipo di fonto Serif",
        "restorelink": "{{PLURAL:$1|1 redakto efacita|$1 redakti efacita}}",
        "feedlinks": "Fonto RSS:",
        "feed-invalid": "Tipo di fonto RSS nevalida",
+       "feed-unavailable": "Abonata publikaji ne esas disponebla",
        "site-rss-feed": "$1 RSS Provizajo",
        "site-atom-feed": "$1 Atom Provizajo",
        "page-rss-feed": "\"$1\" RSS Provizajo",
        "formerror": "Eroro: Onu ne povis sendar la kontenajo di la formularo",
        "badarticleerror": "Ica ago ne povas facesar en ca pagino.",
        "cannotdelete": "Ne es posibla efacar la pagino od arkivo \"$1\".\nForsan, ulu ja efacis ol.",
+       "cannotdelete-title": "Ne povas efacar pagino \"$1\"",
+       "no-null-revision": "Ne povis krear nova nula-revizo por pagino \"$1\"",
        "badtitle": "Nekorekta titulo",
        "badtitletext": "La solicitita pagino esas nevalida, vakua od esas\nnekorekta interlinguale od interwikale ligilo.",
+       "title-invalid-empty": "La demandita pagino-titulo es vakua o kontenas nur la nome di \"namespace\".",
+       "title-invalid-utf8": "La demandita pagino-titulo kontenas ne-valida sequo UTF-8.",
+       "title-invalid-interwiki": "La demandita pagino-titulo kontenas inter-wiki-ala ligilo, olqua ne povas uzesar en tituli.",
+       "title-invalid-talk-namespace": "La demandita pagino-titulo referas a diskuto-pagino, qua ne existas.",
+       "title-invalid-characters": "La demandita pagino-titulo kontenas ne-valida literi: \"$1\".",
        "perfcached": "La sequanta datumi esas kashizita* e li povus ne aktualigesar nuntempe. A maximum of {{PLURAL:$1|one result is|$1 results are}} available in the cache.",
        "viewsource": "Vidar font-kodo",
        "protectedpagetext": "Ta pagino protektesis por preventar redaktadi od altra agi.",
        "emailnotauthenticated": "Vua e-postal adreso ne ja autentikigesas.\nNula mesaji sendesos por irga di la sequanta funcioni.",
        "noemailprefs": "Prizentez e-postal adreso en vua preferaji por disponar ita funcioni.",
        "emailconfirmlink": "Konfirmez vua adreso di e-posto",
+       "cannotchangeemail": "E-posto-adreso dil konto ne povas chanjesar ye ta wikio.",
+       "emaildisabled": "Ita ret-sito ne povas sendar e-mesaji.",
        "accountcreated": "Konto kreesis",
-       "accountcreatedtext": "La uzantokonto por $1 kreatesis.",
+       "accountcreatedtext": "La uzerokonto por [[{{ns:User}}:$1|$1]] ([[{{ns:User talk}}:$1|diskuto]]) kreesis.",
        "createaccount-title": "Kreo di konto en {{SITENAME}}",
+       "createaccount-text": "Ulu kreis konto por vua e-posto adreso ye {{SITENAME}} ($4) nomita \"$2\", kun pasovorto \"$3\".\nVu devas enirar la konto e chanjar vua pasovorto nun.\n\nVu darfas ignorar ita mesajo, se ita konto kreesis en eroro.",
+       "login-throttled": "Vu probis enirar tro multafoye.\nVoluntez vartar $1 ante riprobar.",
+       "login-abort-generic": "Vua eniro-probo faliis - Cesigita",
+       "login-migrated-generic": "Vua konto esas migrata, e vua uzeronomo ne plus existas che ita wikio.",
        "loginlanguagelabel": "Linguo: $1",
        "pt-login": "Enirar",
        "pt-login-button": "Enirar",
        "resetpass-recycled": "Voluntez chanjar vua pasovorto ad ulo diferanta de vua aktuala pasovorto.",
        "resetpass-temp-emailed": "Vu eniris uzante provizora pasovorto.\nPor parkompletigar enirado, vu mustas krear nova pasovorto hike:",
        "resetpass-temp-password": "Provizora pasovorto:",
+       "passwordreset": "Sendez nova pasovorto per e-posto",
        "passwordreset-username": "Uzantonomo:",
+       "passwordreset-invalidemail": "Ne-valida e-posto-adreso",
+       "passwordreset-nodata": "Nek uzeronomo nek e-posto-adreso esis provizita",
        "changeemail": "Chanjar od efacar e-postal adreso",
+       "changeemail-header": "Plenigez ita formulario por chanjar vua e-posto-adreso. Se vu volas forigar irga e-posto-adreso de vua konto, lasez la nova e-posto-adreso vakua en la formulario.",
+       "changeemail-no-info": "Vu mustas enirar la konto por acesar ita pagino direte.",
+       "changeemail-oldemail": "Aktuala e-posto-adreso:",
+       "changeemail-newemail": "Nova e-posto-adreso:",
+       "changeemail-none": "(nula)",
+       "changeemail-password": "Vua {{SITENAME}} pasovorto:",
+       "changeemail-submit": "Chanjar e-posto-adreso",
+       "changeemail-throttled": "Vu probis enirar tro multafoye.\nVoluntez vartar $1 ante riprobar.",
+       "changeemail-nochange": "Voluntez skribar diferanta nova e-posto-adreso.",
+       "resettokens": "Rinovigar klefi",
+       "resettokens-no-tokens": "Esas nula klefi rinovigebla.",
+       "resettokens-tokens": "Klefi:",
+       "resettokens-token-label": "$1 (nuna valoro: $2)",
+       "resettokens-done": "Klefi rinovigita.",
+       "resettokens-resetbutton": "Rinovigar selektita klefi",
        "bold_sample": "Dika literi",
        "bold_tip": "Dika literi",
        "italic_sample": "Kursiva literi",
        "accmailtext": "Hazarde genitita pasovorto por [[User talk:$1|$1]] sendesis ad $2.\n\nLa pasovorto por ica nova konto povas chanjesar che la ''[[Special:ChangePassword|chanjar pasovorto]]'' pagino pos on eniras.",
        "newarticle": "(nova)",
        "newarticletext": "Vu sequis ligilo a pagino qua ne existas ankore.\nPor krear ica pagino, voluntez startar skribar en la infra buxo.\n(regardez la [$1 helpo] por plusa informo).\nSe vu esas hike erore, kliktez sur la butono por retrovenar en vua navigilo.",
-       "noarticletext": "Prezente, ne esas texto en ica pagino.\nVu povas [[Special:Search/{{PAGENAME}}|serchar ica titulo]] en altra pagini,\n<span class=\"plainlinks\">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} serchar en la relata registri],\no [{{fullurl:{{FULLPAGENAME}}|action=edit}} redaktar ica pagino]</span>.",
+       "noarticletext": "Til nun ne existas texto en ica pagino.\nVu povas [[Specala:Search/{{PAGENAME}}|serchar ica titulo]] en altra pagini,\n<span class=\"plainlinks\">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} serchar en la relata registri],\no [{{fullurl:{{FULLPAGENAME}}|action=edit}} redaktar ica pagino]</span>.",
        "userpage-userdoesnotexist": "Uzeronomo \"$1\" no registragesis.\nVoluntez konfirmez se vu volas krear/redaktar ica pagino.",
        "userpage-userdoesnotexist-view": "Uzeronomo \"$1\" no registragesis.",
        "clearyourcache": "'''Atencez: Pos registragar, vu probable mustas renovigar la tempala-magazino di vua navigilo por vidar la chanji.'''\n'''Mozilla / Firefox / Safari:''' tenez ''Shift'' kliktante ''Reload'', o presez sive  ''Ctrl-F5'' sive ''Ctrl-R'' (''Command-R'' ye Mac);\n'''Konqueror''': kliktez ''Reload'' o presez ''F5'';\n'''Opera:''' vakuigez la tempala-magazino en ''Tools → Preferences'';\n'''Internet Explorer:''' tenez ''Ctrl'' kliktante ''Refresh,'' o presez ''Ctrl-F5''.",
        "rev-showdeleted": "montrar",
        "revdelete-show-file-submit": "Yes",
        "revdelete-hide-image": "Celar kontenajo dil arkivo",
-       "revdelete-hide-comment": "Celar komento pri redakto",
-       "revdelete-hide-user": "Celar uzantonomo od IP di redaktanto",
+       "revdelete-hide-comment": "Rezumo di redakto",
+       "revdelete-hide-user": "uzeronomo di redaktanto/IP-adreso",
        "revdelete-radio-set": "Celita",
        "revdelete-radio-unset": "Videbla",
        "revdelete-log": "Motivo:",
        "revdelete-reasonotherlist": "Altra motivo",
        "mergehistory-reason": "Motivo:",
        "revertmerge": "Desmixar",
-       "history-title": "Versionaro di \"$1\"",
+       "history-title": "Version-historio di \"$1\"",
+       "difference-title": "Diferi inter la revizi di $1",
        "lineno": "Lineo $1:",
        "compareselectedversions": "Komparar selektita versioni",
        "editundo": "des-facez",
+       "diff-multi-sameuser": "(ne montresas {{PLURAL:$1|1 meza revizo|$1 meza revizi}} facita da la sama uzero)",
        "searchresults": "Rezultaji dil sercho",
        "searchresults-title": "Sercho-rezultaji por \"$1\"",
        "titlematches": "Koincidi de titulo di artiklo",
        "searchprofile-articles-tooltip": "Serchez en $1",
        "searchprofile-images-tooltip": "Serchez arkivi",
        "search-result-size": "$1 ({{PLURAL:$2|1 vorto|$2 vorti}})",
-       "search-redirect": "(ridirektilo $1)",
+       "search-redirect": "(Ridirektita de $1)",
        "search-section": "(seciono $1)",
        "search-suggest": "Ka vu volis dicar: $1",
        "search-interwiki-caption": "Altra projekti",
-       "search-interwiki-default": "Rezultaji di $1:",
+       "search-interwiki-default": "Rezultaji de $1:",
        "search-interwiki-more": "(plusa)",
        "searchall": "omna",
        "showingresults": "Montrante infre {{PLURAL:$1|'''1''' rezulto|'''$1''' rezulti}}, qui komencas kun numero #'''$2'''.",
+       "search-nonefound": "Nula rezulto trovesis por lua serchado.",
        "powersearch-legend": "Avancita sercho",
        "powersearch-ns": "Serchez en nomari:",
        "powersearch-toggleall": "Omna",
        "prefs-rc": "Recenta chanji",
        "prefs-watchlist": "Surveyo-listo",
        "prefs-watchlist-days": "Dii montrata en surveyaji:",
-       "prefs-watchlist-days-max": "Maximum $1 {{PLURAL:$1|day|days}}",
+       "prefs-watchlist-days-max": "Maxime $1 {{PLURAL:$1|dio|dii}}",
        "prefs-watchlist-edits-max": "Maxima nombro: 1000",
        "prefs-misc": "Mixaji",
        "prefs-resetpass": "Chanjar pasovorto",
        "prefs-namespaces": "Nomari",
        "prefs-files": "Arkivi",
        "youremail": "Vua e-adreso:",
-       "username": "Uzantonomo:",
-       "prefs-memberingroups": "Membro di la {{PLURAL:$1|grupo|grupi}}:",
+       "username": "{{GENDER:$1|Uzeronomo}}:",
+       "prefs-memberingroups": "{{GENDER:$2|Membro}} di {{PLURAL:$1|grupo|grupi}}:",
        "yourrealname": "Reala nomo:",
        "yourlanguage": "Linguo:",
        "yournick": "Signaturo:",
        "group-sysop": "Administranti",
        "group-bureaucrat": "Burokrati",
        "group-all": "(omna)",
-       "group-user-member": "Uzanto",
-       "group-bot-member": "Roboto",
-       "group-sysop-member": "Administranto",
-       "group-bureaucrat-member": "Burokrato",
+       "group-user-member": "{{GENDER:$1|uzero}}",
+       "group-bot-member": "{{GENDER:$1|roboto}}",
+       "group-sysop-member": "{{GENDER:$1|administrero}}",
+       "group-bureaucrat-member": "{{GENDER:$1|burokrato}}",
        "grouppage-user": "{{ns:project}}:Uzanti",
        "grouppage-bot": "{{ns:project}}:Roboti",
        "grouppage-sysop": "{{ns:project}}:Administranti",
        "rightslog": "Uzero-yuri-registraro",
        "action-read": "lektar ca pagino",
        "action-edit": "redaktar ca pagino",
-       "action-createpage": "krear pagini",
+       "action-createpage": "kreez ita pagino",
        "action-move": "movar ca pagino",
        "action-movefile": "movar ca arkivo",
        "action-upload": "adkargar ca arkivo",
        "action-browsearchive": "serchar pagini efacita",
        "nchanges": "$1 {{PLURAL:$1|chanjo|chanji}}",
+       "enhancedrc-history": "Versionaro",
        "recentchanges": "Recenta chanji",
        "recentchanges-legend": "Recenta chanji preferaji",
        "recentchanges-summary": "Regardez la maxim recenta chanji en Wiki per ica pagino.",
        "recentchanges-label-newpage": "Ca redaktajo kreis nova pagino",
        "recentchanges-label-minor": "Ica es mikra redaktajo",
        "recentchanges-label-bot": "Ta chanjo facita da bot",
+       "recentchanges-label-unpatrolled": "Ica modifiko ne patroliesas ankore.",
+       "recentchanges-label-plusminus": "La pagino modifikesis segun ica quanto di *bicoki",
        "recentchanges-legend-newpage": "$1 - nova pagino",
        "rcfilters-filter-userExpLevel-experienced-description": "Plu kam 30 dii di agemeso e 500 redakti.",
        "rcnotefrom": "Infre esas la lasta chanji depos '''$2''' (montrita til '''$1''').",
        "rclistfrom": "Montrar nova chanji startante de $3 $2",
        "rcshowhideminor": "$1 mikra redakti",
+       "rcshowhideminor-show": "Montrar",
+       "rcshowhideminor-hide": "Celar",
        "rcshowhidebots": "$1 roboti",
-       "rcshowhideliu": "$1 enirinta uzanti",
+       "rcshowhidebots-show": "Montrar",
+       "rcshowhidebots-hide": "Celar",
+       "rcshowhideliu": "$1 enrejistrita uzeri",
+       "rcshowhideliu-hide": "Celar",
        "rcshowhideanons": "$1 anonima uzanti",
+       "rcshowhideanons-show": "Montrar",
+       "rcshowhideanons-hide": "Celar",
        "rcshowhidemine": "$1 mea redakti",
+       "rcshowhidemine-show": "Montrar",
+       "rcshowhidemine-hide": "Celar",
        "rclinks": "Montrar la lasta $1 chanji dum la lasta $2 dii<br />$3",
        "diff": "dif",
        "hist": "vers",
        "minoreditletter": "m",
        "newpageletter": "N",
        "boteditletter": "r",
-       "rc_categories_any": "Ula",
+       "rc_categories_any": "Irga selektita",
+       "rc-change-size-new": "$1 {{PLURAL:$1|bicoko|bicoki}} pos la modifiki",
        "newsectionsummary": "/* $1 */ nova seciono",
-       "rc-enhanced-expand": "Montrar detali (JavaScript bezonesas)",
+       "rc-enhanced-expand": "Montrez detali",
        "rc-enhanced-hide": "Celar detali",
        "recentchangeslinked": "Relatanta chanji",
        "recentchangeslinked-feed": "Relatanta chanji",
        "uploadbtn": "Adkargar arkivo",
        "reuploaddesc": "Retrovenar al adkargo-formularo.",
        "uploadnologin": "Vu ne eniris",
-       "uploadnologintext": "Vu mustas [[Special:UserLogin|enirir]] por adkargar arkivi.",
+       "uploadnologintext": "Voluntez $1 por adkargar arkivi.",
        "uploaderror": "Eroro dum adkargo",
        "uploadlogpage": "Adkargo-registraro",
        "uploadlogpagetext": "Infre esas listo di la plu recenta adkargaji.\nVidez rezumo plu vidala en la [[Special:NewFiles|galerio di nova arkivi]].",
        "filesource": "Fonto:",
        "ignorewarning": "Ignorar la averto e gardar la arkivo irgakaze.",
        "badfilename": "La imajo-nomo chanjesis a \"$1\".",
-       "fileexists": "Arkivo kun ica nomo ja existas.\nVolutez kontrolar <strong>[[:$1]]</strong> se vu ne esas certa pri chanjar olu.\n[[$1|thumb]]",
+       "fileexists": "Arkivo kun ta nomo ja existas.\nVolutez kontrolar <strong>[[:$1]]</strong> se {{GENDER:|vu}} ne esas certa pri chanjar olu.\n[[$1|thumb]]",
        "uploadwarning": "Averto pri la adkargo di arkivo",
        "savefile": "Registragar arkivo",
        "uploaddisabled": "Pardonez, la adkargo esas desaktiva.",
        "linkstoimage": "La {{PLURAL:$1|pagino|$1 pagini}} infre ligas a ca arkivo:",
        "nolinkstoimage": "Nula pagino ligas a ca pagino.",
        "sharedupload": "Ca arkivo esas de $1 e posible esas uzata da altra projekti.",
+       "sharedupload-desc-here": "Ca arkivo jacas en $1, e povas uzesar en altra projeti.\nLa deskriptado en lua [$2 pagino di deskriptado] montresas infre.",
        "uploadnewversion-linktext": "Adkargez nova versiono dil arkivo",
        "shared-repo-from": "ek $1",
+       "upload-disallowed-here": "Vu ne povas modifikar ica arkivo.",
        "filerevert-comment": "Motivo:",
        "filedelete": "Efacar $1",
        "filedelete-legend": "Efacar arkivo",
        "ancientpages": "Maxim anciena artikli",
        "move": "Movar",
        "movethispage": "Rinomizar ica pagino",
-       "unusedimagestext": "Voluntez egardez ke altra ret-situi povus ligar a arkivo per direta URL, e do ol povus esar enlistizita hike malgre olu havas aktiva uzo.",
+       "unusedimagestext": "La sequanta arkivi existas ma ne enterigita en irga pagino.\nVoluntez remarkar ke altra ret-siti povus ligar ad arkivo per direta URL, e do ol povus esar listizita hike malgre ke on aktive uzas lo.",
        "notargettitle": "Ne esas vakua pagino",
        "notargettext": "Vu ne definis en qua pagino agar ica funciono.",
        "pager-newer-n": "{{PLURAL:$1|plu nova 1|plu nova $1}}",
        "apisandbox-loading": "Charjas informo pri modulo « $1 » di API...",
        "booksources": "Fonti di libri",
        "booksources-search-legend": "Serchez librala fonti",
-       "specialloguserlabel": "Uzanto:",
-       "speciallogtitlelabel": "Titulo:",
+       "booksources-search": "Serchar",
+       "specialloguserlabel": "Agero:",
+       "speciallogtitlelabel": "Skopo (titulo od {{ns:user}}:uzernomo por uzero):",
        "log": "Registrari",
        "all-logs-page": "Omna publika registrari",
        "allpages": "Omna pagini",
        "categories": "Kategorii",
        "deletedcontributions": "Efacita uzero-kontributadi",
        "deletedcontributions-title": "Efacita uzero-kontributadi",
-       "linksearch": "Extera ligili",
+       "linksearch": "Sercho di extera ligili",
        "linksearch-ns": "Nomaro:",
        "linksearch-ok": "Serchez",
        "listusers-submit": "Montrez",
        "mailnologin": "Ne sendar adreso",
        "mailnologintext": "Vu mustas [[Special:UserLogin|enirir]] e havar valida e-adreso en vua [[Special:Preferences|preferaji]] por sendar e-posto ad altra uzanti.",
        "emailuser": "Sendar e-posto a ca uzero",
-       "defemailsubject": "E-posto di {{SITENAME}}",
+       "defemailsubject": "{{SITENAME}} e-mesaji de uzero \"$1\"",
        "noemailtitle": "Ne esas e-adreso",
        "emailfrom": "De:",
        "emailto": "Ad:",
        "mywatchlist": "Surveyaji",
        "nowatchlist": "Vu ne havas objekti en vua listo di surveyaji.",
        "watchnologin": "Vu ne startis sesiono",
-       "addedwatchtext": "La pagino \"<nowiki>$1</nowiki>\" atachesis a vua [[Special:Watchlist|listo de surveyaji]]. Futura chanji di ica pagino ed olua relatanta debato-pagini montresos ibe, ed la pagino aparos per '''dika literi''' en la [[Special:RecentChanges|listo de recenta chanji]] por faciligar sua trovebleso.\n\n<p> Se vu volas efacar la pagino de vua listo de surveyaji pose, presez \"Ne plus surveyar\" en la selektaro.",
-       "removedwatchtext": "La pagino \"[[:$1]]\" forigesis de [[Special:Watchlist|vua surveyado]].",
+       "addedwatchtext": "\"[[:$1]]\" atachesis a vua [[Special:Watchlist|listo di surveyaji]].",
+       "removedwatchtext": "\"[[:$1]]\" ed relatanta diskutado forigesis de [[Special:Watchlist|vua surveyado]].",
        "watch": "Surveyar",
        "watchthispage": "Surveyar ica pagino",
        "unwatch": "Ne plus surveyar",
        "unwatchthispage": "Ne plus surveyar",
        "notanarticle": "Ne esas artiklo",
-       "wlnote": "Infre esas la lasta {{PLURAL:$1|chanjo|'''$1''' chanji}} dum la lasta {{PLURAL:$2|horo|'''$2''' hori}}.",
-       "wlshowlast": "Montrar la lasta $1 hori $2 dii",
+       "wlnote": "Yen la maxim recenta {{PLURAL:$1|chanjo|<strong>$1</strong> chanji}} dum la lasta {{PLURAL:$2|horo|<strong>$2</strong> hori}}, desde $3,$4.",
+       "wlshowlast": "Montrez la lasta $1 hori $2 dii",
        "watchlist-options": "Surveryo-listo selekti",
        "watching": "Surveyanta…",
        "unwatching": "Cesanta surveyar…",
        "exbeforeblank": "La kontenajo ante efaco esis: '$1'",
        "delete-confirm": "Efacar \"$1\"",
        "delete-legend": "Efacar",
-       "historywarning": "Egardez: La pagino, quan vu efaceskas, havas versionaro:",
+       "historywarning": "<strong>Averto:</strong> La pagino quan vu efaceskas havas historio kun $1 {{PLURAL:$1|revizo|revizi}}:",
        "actioncomplete": "Ago kompletigita",
        "deletedtext": "\"$1\" efacesis.\nVidez $2 por obtenar registro di recenta efaci.",
        "dellogpage": "Efaco-registraro",
        "deletecomment": "Motivo:",
        "deleteotherreason": "Altra/suplementala motivo:",
        "deletereasonotherlist": "Altra motivo",
-       "deletereason-dropdown": "*Ordinara motivi por efaco\n** Demandita da autoro\n** Kopiyuro Violaco\n** Korupto",
+       "deletereason-dropdown": "*Ordinara motivi por efacado\n** \"Spam\" nedezirata mesaji\n** Vandalismo\n** Kopiyuro Violaco\n** Demandita da autoro\n** Nefuncionanta ligilo",
        "rollback": "Retrorulez redakti",
        "rollbacklink": "retrorulez",
+       "rollbacklinkcount": "nuligar $1 {{PLURAL:$1|modifiko|modifiki}}",
        "rollbackfailed": "Retrorular ne sucesis",
        "cantrollback": "Ne esas posibla retrorular. La lasta kontributanto esas la nura autoro di ica pagino.",
        "alreadyrolled": "Vu ne povas retrorular la lasta chanjo di [[:$1]] da [[User:$2|$2]] ([[User talk:$2|Diskutez]]{{int:pipe-separator}}[[Special:Contributions/$2|{{int:contribslink}}]]);\nulu pluse ja redaktis o retrorulis ica pagino.\n\nLa lasta chanjo a la pagino esis da [[User:$3|$3]] ([[User talk:$3|Diskutez]]{{int:pipe-separator}}[[Special:Contributions/$3|{{int:contribslink}}]]).",
        "rollback-success": "Desfacis redakti da $1;\nrestauris ad lasta versiono da $2.",
        "protectlogpage": "Protekto-registraro",
        "protectedarticle": "protektita \"[[$1]]\"",
-       "unprotectedarticle": "desprotektita [[$1]]",
+       "unprotectedarticle": "desprotektita de \"[[$1]]\"",
        "protect-title": "Protektante \"$1\"",
        "prot_1movedto2": "[[$1]] movita a [[$2]]",
        "protect-legend": "Konfirmar protekto",
        "protect_expiry_invalid": "Expirotempo es ne-valida.",
        "protect_expiry_old": "Expirotempo es in pasinta.",
        "protect-default": "Permisar omna uzanti",
-       "protect-fallback": "Bezonar permiso \"$1\"",
-       "protect-level-sysop": "Nur administranti",
+       "protect-fallback": "Permisez nur uzeri kun permiso \"$1\"",
+       "protect-level-sysop": "Permisez nur administreri",
        "protect-summary-cascade": "kaskade",
        "protect-expiring": "expiras ye $1 (UTC)",
        "protect-expiry-indefinite": "nefinita",
        "undelete": "Vidar efacita pagini",
        "undeletepage": "Vidar e restaurar efacita pagini",
        "undeletepagetext": "La sequanta {{PLURAL:$1|pagino|pagini}} efacesis ma {{PLURAL:$1|ol|li}} ankore esas en la arkivo ed esas restaurebla. La arkivo povas netigesar periodale.",
-       "undeleterevisions": "$1 {{PLURAL:$1|revizo|revizi}} konservita",
+       "undeleterevisions": "$1 {{PLURAL:$1|revizo|revizi}} efacita",
        "undeletebtn": "Restaurar",
        "undeletelink": "vidar/restaurar",
        "undeleteviewlink": "videz",
-       "undeletecomment": "Komento:",
+       "undeletecomment": "Motivo:",
        "undelete-search-box": "Serchez efacita pagini",
        "undelete-search-submit": "Serchar",
        "undelete-show-file-submit": "Yes",
        "contributions": "Kontributadi dil {{GENDER:$1|uzero}}",
        "contributions-title": "Uzero-kontributadi di $1",
        "mycontris": "Kontributadi",
+       "anoncontribs": "Kontributadi",
        "contribsub2": "Pro $1 ($2)",
        "nocontribs": "Ne trovesis chanji qui fitez ita kriterii.",
        "uctop": "(aktuala)",
        "importtext": "Voluntez exportacar l' arkivo de la fonto-wiki uzante la utensilo \"Special:Export\", registragar ol a vua disko ed adkargar ol hike.",
        "importfailed": "La importaco faliis: $1",
        "importsuccess": "Importaco sucesoza!",
-       "tooltip-pt-userpage": "Vua uzanto-pagino",
-       "tooltip-pt-mytalk": "Vua diskuto-pagino",
-       "tooltip-pt-preferences": "Mea preferaji",
+       "tooltip-pt-userpage": "{{GENDER:|Vua uzero}} pagino",
+       "tooltip-pt-mytalk": "{{GENDER:|Vua}} diskuto-pagino",
+       "tooltip-pt-preferences": "{{GENDER:|Vua}} preferaji",
        "tooltip-pt-watchlist": "Listo di pagini quin vu kontrolas",
-       "tooltip-pt-mycontris": "Listo di vua kontributaji",
+       "tooltip-pt-mycontris": "Listo di {{GENDER:|vua}} kontributaji",
        "tooltip-pt-login": "Vu darfas enirar uzante vua pas-vorto, ma lo ne esas preskriptata.",
        "tooltip-pt-logout": "Ekirar",
+       "tooltip-pt-createaccount": "Vu stimulesas a krear konto e facar \"log in\". Tamen, to ne esas obliganta",
        "tooltip-ca-talk": "Diskuto pri la pagino di kontenajo",
-       "tooltip-ca-edit": "Vu darfas chanjar ta pagino. Voluntez pre-vidar chanji ante registragar oli.",
+       "tooltip-ca-edit": "Redaktar ita pagino",
        "tooltip-ca-addsection": "Komencar nova seciono",
        "tooltip-ca-viewsource": "Ca pagino esas protektita. Vu povas vidar olua fonto-kodo",
        "tooltip-ca-history": "Pasinta versioni di ca pagino",
        "tooltip-t-recentchangeslinked": "Recenta chanji di pagini ligita de ca pagino",
        "tooltip-feed-rss": "RSS provizero por ica pagino",
        "tooltip-feed-atom": "Atom provizero por ica pagino",
-       "tooltip-t-contributions": "Videz kontributaji di ta uzanto",
-       "tooltip-t-emailuser": "Sendez mesajo al uzanto",
+       "tooltip-t-contributions": "Videz kontributaji di {{GENDER:$1|ta uzanto}}",
+       "tooltip-t-emailuser": "Sendez mesajo al {{GENDER:$1|uzanto}}",
        "tooltip-t-info": "Plua informo pri ca pagino",
        "tooltip-t-upload": "Adkargez arkivi",
        "tooltip-t-specialpages": "Montrez listo di omna specala pagini",
        "tooltip-t-permalink": "Permananta ligilo vers ita versiono di ta pagino",
        "tooltip-ca-nstab-main": "Vidar la kontenajo di ca pagino",
        "tooltip-ca-nstab-user": "Vidar la pagino dil uzero",
-       "tooltip-ca-nstab-special": "Ito esas specala pagino, vu ne povas redaktar la pagino ipsa",
+       "tooltip-ca-nstab-special": "Ito esas specala pagino, ed es ne-redaktebla",
        "tooltip-ca-nstab-project": "Vidar la projekto-pagino",
        "tooltip-ca-nstab-image": "Videz la pagino dil arkivo",
        "tooltip-ca-nstab-template": "Vidar la shablono",
        "lastmodifiedatby": "Ica pagino modifikesis ye $2, $1 da $3.",
        "othercontribs": "Bazizita en la laboro da $1.",
        "others": "altra",
-       "siteusers": "{{PLURAL:$2|Uzanto|Uzanti}} che {{SITENAME}} $1",
+       "siteusers": "{{PLURAL:$2|{{GENDER:$1|uzero}}|uzeri}} $1 di {{SITENAME}}",
        "spamprotectiontitle": "Filtrilo kontre spamo",
+       "simpleantispam-label": "Surveyo kontre \"spam\".\n<strong>NE SKRIBEZ</strong> hike!",
        "pageinfo-toolboxlink": "Informo di ca pagino",
        "previousdiff": "← Plu anciena versiono",
        "nextdiff": "Plu recenta versiono →",
        "widthheightpage": "$1 × $2, $3 {{PLURAL:$3|pagino|pagini}}",
        "file-nohires": "Ne existas grandeso plu granda.",
-       "show-big-image": "Grandeso kompleta",
+       "svg-long-desc": "arkivo SVG, nominale $1 x $2 \"pixels\", kun $3",
+       "show-big-image": "Arkivo originala",
+       "show-big-image-size": "$1 x $2 pixels",
        "newimages": "Galerio di nova arkivi",
        "imagelisttext": "Infre esas listo di '''$1''' {{PLURAL:$1|arkivo|arkivi}} rangizita $2.",
        "newimages-legend": "Filtrilo",
        "ilsubmit": "Serchar",
        "bydate": "per dato",
        "metadata": "Metadonaji",
+       "metadata-help": "Ca arkivo kontenas plusa informo, probable furnisita per la kamero elektronikala o per la \"scanner\" uzata por krear o kopiar l'imajo.\nSe l'arkivo modifikesos de lua originala stando, kelka detali povos ne reprezentar exakte l'arkivo modifikata.",
+       "metadata-fields": "Image metadata fields listed in this message will be included on image page display when the metadata table is collapsed.\nOthers will be hidden by default.\n* make\n* model\n* datetimeoriginal\n* exposuretime\n* fnumber\n* isospeedratings\n* focallength\n* artist\n* copyright\n* imagedescription\n* gpslatitude\n* gpslongitude\n* gpsaltitude",
        "exif-imagewidth": "Larjeso",
        "exif-imagelength": "Alteso",
+       "exif-orientation": "Orientizo",
+       "exif-xresolution": "Horizontala distingivo",
+       "exif-yresolution": "Vertikala distingivo",
+       "exif-datetime": "Dio e horo di la modifiko dil arkivo",
+       "exif-make": "Fabrikanto di la fotografilo",
+       "exif-model": "Fotografilo uzita",
+       "exif-software": "*Komputeroprogramo uzata",
        "exif-artist": "Autoro",
+       "exif-exifversion": "versiono Exif",
+       "exif-datetimeoriginal": "Dio e horo di produktado di la datumaro",
+       "exif-datetimedigitized": "Dio e horo di la kopio kun \"scanner\"",
        "exif-exposuretime-format": "$1 sek ($2)",
        "exif-gpslatitude": "Latitudo",
        "exif-gpslongitude": "Longitudo",
        "watchlisttools-view": "Vidar relatanta chanji",
        "watchlisttools-edit": "Vidar e redaktar surveyo-listo",
        "watchlisttools-raw": "Redaktar texto di surveyo-listo",
+       "signature": "[[{{ns:user}}:$1|$2]] ([[{{ns:user_talk}}:$1|diskuto]])",
        "version": "Versiono",
        "version-specialpages": "Specala pagini",
        "version-other": "Altra",
        "version-version": "($1)",
-       "version-license": "Licenco",
+       "version-license": "MediaWiki Licenco",
        "version-software-product": "Produkturo",
        "version-software-version": "Versiono",
        "fileduplicatesearch-submit": "Serchar",
        "specialpages-group-redirects": "Specala pagini di ridirektili",
        "blankpage": "Pagino sen-skribura",
        "tag-filter-submit": "Filtrez",
+       "tag-list-wrapper": "([[Special:Tags|{{PLURAL:$1|Etikedo|Etikedi}}]]: $2)",
        "tags-edit": "redaktar",
        "tags-hitcount": "$1 {{PLURAL:$1|chanjo|chanji}}",
        "htmlform-reset": "Desfacar chanji",
        "htmlform-selectorother-other": "Altra",
        "htmlform-cloner-create": "Adjuntar plue",
+       "logentry-move-move": "$1 {{GENDER:$2|movis}} la pagino $3 a $4",
+       "logentry-newusers-create": "La konto dil uzero $1 kreesis.",
+       "logentry-upload-upload": "$1 {{GENDER:$2|uploaded}} $3",
        "rightsnone": "(nula)",
        "revdelete-summary": "redakto-rezumo",
-       "searchsuggest-search": "Serchez",
+       "searchsuggest-search": "Serchez en {{SITENAME}}",
        "searchsuggest-containing": "quan kontenas...",
        "expand_templates_output": "Rezulto",
        "expand_templates_ok": "O.K.",
index f1f4416..985a8cd 100644 (file)
                        "Anto",
                        "Saracrovetto",
                        "Tosky",
-                       "Selven"
+                       "Selven",
+                       "Margherita.mignanelli"
                ]
        },
        "tog-underline": "Sottolinea i collegamenti:",
        "userrights-nodatabase": "Il database $1 non esiste o non è un database locale.",
        "userrights-changeable-col": "Gruppi modificabili",
        "userrights-unchangeable-col": "Gruppi non modificabili",
+       "userrights-expiry-none": "Non ha scadenza",
        "userrights-conflict": "Conflitto di modifica dei diritti utente! Controlla e conferma le tue modifiche.",
        "group": "Gruppo:",
        "group-user": "Utenti",
        "recentchanges-legend-plusminus": "(''±123'')",
        "recentchanges-submit": "Mostra",
        "rcfilters-activefilters": "Filtri attivi",
+       "rcfilters-restore-default-filters": "Ripristina i filtri predefiniti",
+       "rcfilters-clear-all-filters": "Pulisci tutti i filtri",
        "rcfilters-search-placeholder": "Filtra le ultime modifiche (naviga o inizia a digitare)",
        "rcfilters-invalid-filter": "Filtro non valido",
+       "rcfilters-empty-filter": "Nessun filtro attivo. Sono mostrati tutti i contributi.",
        "rcfilters-filterlist-title": "Filtri",
        "rcfilters-filterlist-noresults": "Nessun filtro trovato",
        "rcfilters-filtergroup-registration": "Registrazione utente",
        "apisandbox-sending-request": "Invio richiesta di API...",
        "apisandbox-loading-results": "Ricezione dei risultati di API in corso...",
        "apisandbox-results-error": "Si è verificato un errore durante il caricamento della risposta all'interrogazione API: $1",
-       "apisandbox-request-params-json": "Parametri JSON:",
+       "apisandbox-request-selectformat-label": "Mostra i dati richiesti come:",
        "apisandbox-request-url-label": "URL di richiesta:",
        "apisandbox-request-time": "Tempo richiesto: {{PLURAL:$1|$1 ms}}",
        "apisandbox-results-fixtoken": "Correggi token e reinvia",
        "emailccsubject": "Copia del messaggio inviato a $1: $2",
        "emailsent": "Messaggio inviato",
        "emailsenttext": "Il messaggio e-mail è stato inviato.",
-       "emailuserfooter": "Questa email è stata {{GENDER:$1|inviata}} da $1 a {{GENDER:$2|$2}} attraverso la funzione \"{{int:emailuser}}\" su {{SITENAME}}. La {{GENDER:$2|tua}} eventuale email di risposta sarà inviata direttamente al {{GENDER:$1|mittente originale}}, rivelando il  {{GENDER:$2|tuo}} indirizzo di posta elettronica a {{GENDER:$1|lui|lei}}.",
+       "emailuserfooter": "Questa email è stata inviata da $1 a $2 attraverso la funzione \"{{int:emailuser}}\" su {{SITENAME}}. Se {{GENDER:$2|risponderai}}, la tua email di risposta sarà inviata direttamente {{GENDER:$1|al|alla}} mittente originale, rivelando{{GENDER:$1|gli|le}} il {{GENDER:$2|tuo}} indirizzo di posta elettronica.",
        "usermessage-summary": "Messaggio di sistema",
        "usermessage-editor": "Messaggero di sistema",
        "usermessage-template": "MediaWiki:MessaggioUtente",
index 7280e51..b3b404f 100644 (file)
@@ -77,7 +77,8 @@
                        "ネイ",
                        "Mirinano",
                        "Suchichi02",
-                       "にょきにょき"
+                       "にょきにょき",
+                       "おはぐろ蜻蛉"
                ]
        },
        "tog-underline": "リンクの下線:",
        "fileuploadsummary": "概要:",
        "filereuploadsummary": "ファイルの変更:",
        "filestatus": "著作権情報:",
-       "filesource": "出典:",
+       "filesource": "情報源:",
        "ignorewarning": "警告を無視してファイルを保存",
        "ignorewarnings": "警告を無視",
        "minlength1": "ファイル名には少なくとも1文字必要です。",
        "feedback-useragent": "ユーザーエージェント:",
        "searchsuggest-search": "{{SITENAME}}内を検索",
        "searchsuggest-containing": "この語句を全文検索",
-       "api-error-autoblocked": "あなたの IP アドレスは、過去にブロックされた利用者によって使用されていたため、自動的にブロックされました。",
-       "api-error-badaccess-groups": "このウィキへのファイルのアップロードが許可されていません。",
        "api-error-badtoken": "内部エラー: トークンが正しくありません。",
-       "api-error-blocked": "あなたは編集ブロックされています。",
-       "api-error-copyuploaddisabled": "URLによるアップロードはこのサーバーでは無効になっています。",
-       "api-error-duplicate": "当ウェブサイト上には、既に同じ内容の{{PLURAL:$1|他のファイルが|他のファイルがいくつか}}存在しています。",
-       "api-error-duplicate-archive": "サイト上に同じ内容の{{PLURAL:$1|別のファイルが|他のファイルがいくつか}}既にありましたが、{{PLURAL:$1|それは|それらは}}削除されました。",
-       "api-error-empty-file": "送信されたファイルは空でした。",
        "api-error-emptypage": "内容がないページの新規作成は許可されていません。",
-       "api-error-fetchfileerror": "内部エラー: ファイルを取得する際に問題が発生しました。",
-       "api-error-fileexists-forbidden": "「$1」という名前のファイルは存在しており、上書きはできません。",
-       "api-error-fileexists-shared-forbidden": "「$1」という名前のファイルは共有ファイルリポジトリに存在しており、上書きはできません。",
-       "api-error-file-too-large": "送信されたファイルは大きすぎます。",
-       "api-error-filename-tooshort": "ファイル名が短すぎます。",
-       "api-error-filetype-banned": "この形式のファイルは禁止されています。",
-       "api-error-filetype-banned-type": "$1{{PLURAL:$4|は許可されていないファイル形式です}}。許可されている{{PLURAL:$3|ファイル形式}}は$2です。",
-       "api-error-filetype-missing": "ファイルに拡張子がありません。",
-       "api-error-hookaborted": "拡張機能のフックによって、修正が中断されました。",
-       "api-error-http": "内部エラー: サーバーに接続できませんでした。",
-       "api-error-illegal-filename": "ファイル名が許可されていません。",
-       "api-error-internal-error": "内部エラー: ウィキ上でアップロードを処理する際に問題が発生しました。",
-       "api-error-invalid-file-key": "内部エラー: 一時格納場所にファイルが見つかりませんでした。",
-       "api-error-missingparam": "内部エラー: リクエストのパラメーターが足りません。",
-       "api-error-missingresult": "内部エラー: 複製に成功したかどうか判断できませんでした。",
-       "api-error-mustbeloggedin": "ファイルをアップロードするにはログインする必要があります。",
-       "api-error-mustbeposted": "内部エラー: リクエストは HTTP の POST メソッドである必要があります。",
-       "api-error-noimageinfo": "アップロードには成功しましたが、サーバーはファイルに関する情報を返しませんでした。",
-       "api-error-nomodule": "内部エラー: アップロードを処理するモジュールが設定されていません。",
-       "api-error-ok-but-empty": "内部エラー: サーバーからの応答がありません。",
-       "api-error-overwrite": "既存のファイルへの上書きは許可されていません。",
-       "api-error-ratelimited": "あなたは短時間の間に、このウィキで許容されている数より多くのファイルをアップロードしようとしています。\n数分後にもう一度お試しください。",
-       "api-error-stashfailed": "内部エラー: サーバーは一時ファイルを格納できませんでした。",
        "api-error-publishfailed": "内部エラー: サーバーは一時ファイルを発行できませんでした。",
-       "api-error-stasherror": "ファイルを未公開アップロードする際にエラーが発生しました。",
-       "api-error-stashedfilenotfound": "未公開場所からアップロードしようとしましたが、隠しファイルが見つかりませんでした。",
-       "api-error-stashpathinvalid": "隠しファイルのパスが無効です。",
-       "api-error-stashfilestorage": "未公開ファイルを格納する際にエラーが発生しました。",
-       "api-error-stashzerolength": "長さが0であるため、サーバーはファイルを隠しておくことができませんでした。",
-       "api-error-stashnotloggedin": "未公開ファイルを保存するにはログインが必要です。",
-       "api-error-stashwrongowner": "未公開場所にアクセスしようとしていたファイルは、あなたに属していません。",
-       "api-error-stashnosuchfilekey": "未公開場所にアクセスしようとしていたファイルのキーが存在しません。",
-       "api-error-timeout": "サーバーが決められた時間内に応答しませんでした。",
-       "api-error-unclassified": "不明なエラーが発生しました。",
-       "api-error-unknown-code": "不明なエラー:「$1」",
-       "api-error-unknown-error": "内部エラー: ファイルをアップロードする際に問題が発生しました。",
+       "api-error-stashfailed": "内部エラー: サーバーは一時ファイルを格納できませんでした。",
        "api-error-unknown-warning": "不明な警告:「$1」",
        "api-error-unknownerror": "不明なエラー:「$1」",
-       "api-error-uploaddisabled": "このウィキではアップロードは無効になっています。",
-       "api-error-verification-error": "このファイルは壊れているか、間違った拡張子になっています。",
-       "api-error-was-deleted": "この名前のファイルは、以前にアップロードされており、その後削除されています。",
        "duration-seconds": "$1 {{PLURAL:$1|秒}}",
        "duration-minutes": "$1 {{PLURAL:$1|分}}",
        "duration-hours": "$1 {{PLURAL:$1|時間}}",
index 21d55f9..a3f6370 100644 (file)
        "userrights-nodatabase": "데이터베이스 $1이 존재하지 않거나 로컬에 있지 않습니다.",
        "userrights-changeable-col": "바꿀 수 있는 권한",
        "userrights-unchangeable-col": "바꿀 수 없는 권한",
+       "userrights-expiry-none": "만료하지 않음",
+       "userrights-expiry-existing": "현재 만료 시간: $2 $3",
+       "userrights-expiry-othertime": "다른 시간:",
+       "userrights-invalid-expiry": "그룹 \"$1\"의 만료 시간이 유효하지 않습니다.",
+       "userrights-expiry-in-past": "그룹 \"$1\"의 만료 시간이 과거입니다.",
        "userrights-conflict": "사용자 권한 바꾸기가 충돌합니다! 바뀜을 검토하고 확인하세요.",
        "group": "그룹:",
        "group-user": "사용자",
        "recentchanges-legend-plusminus": "(<em>±123</em>)",
        "recentchanges-submit": "보기",
        "rcfilters-activefilters": "사용 중인 필터",
+       "rcfilters-restore-default-filters": "기본 필터 복구",
+       "rcfilters-clear-all-filters": "필터 모두 지우기",
        "rcfilters-search-placeholder": "필터 최근 바뀜 (찾아보거나 입력을 시작하십시오)",
        "rcfilters-invalid-filter": "유효하지 않은 필터",
+       "rcfilters-empty-filter": "활성화된 필터가 없습니다. 모든 기여가 표시됩니다.",
        "rcfilters-filterlist-title": "필터",
        "rcfilters-filterlist-noresults": "필터를 찾을 수 없습니다",
        "rcfilters-filtergroup-registration": "사용자 등록",
+       "rcfilters-filter-registered-label": "등록됨",
+       "rcfilters-filter-registered-description": "로그인된 편집자.",
+       "rcfilters-filter-unregistered-label": "등록 안 됨",
+       "rcfilters-filter-unregistered-description": "로그인하지 않은 편집자.",
        "rcfilters-filtergroup-authorship": "원작자 편집",
        "rcfilters-filter-editsbyself-label": "자신의 편집",
        "rcfilters-filter-editsbyself-description": "당신의 편집.",
        "rcfilters-filter-editsbyother-label": "다른 사용자의 편집",
-       "rcfilters-filter-editsbyother-description": "다른 사용자에 의한 편집. (당신의 편집이 아님)",
-       "rcfilters-filtergroup-userExpLevel": "사용자 경험 수준",
+       "rcfilters-filter-editsbyother-description": "다른 사용자에 의한 편집 (당신의 편집이 아님).",
+       "rcfilters-filtergroup-userExpLevel": "경험 수준 (등록된 사용자 전용)",
        "rcfilters-filter-userExpLevel-newcomer-label": "신규 사용자",
-       "rcfilters-filter-userExpLevel-newcomer-description": "신규 편집자: 10개 미만의 편집 및 4일 미만의 활동.",
+       "rcfilters-filter-userExpLevel-newcomer-description": "10회 미만의 편집 및 4일 미만의 활동.",
        "rcfilters-filter-userExpLevel-learner-label": "학습자",
-       "rcfilters-filter-userExpLevel-learner-description": "'신규 사용자' 보다 활동일 및 편집 수가 더 많지만 '능숙한 사용자' 보다는 적습니다.",
+       "rcfilters-filter-userExpLevel-learner-description": "\"신규 사용자\" 보다 활동일 및 편집 수가 더 많지만 \"능숙한 사용자\" 보다는 적습니다.",
        "rcfilters-filter-userExpLevel-experienced-label": "능숙한 사용자",
        "rcfilters-filter-userExpLevel-experienced-description": "30일 이상의 활동 및 500개 이상의 편집.",
+       "rcfilters-filtergroup-automated": "자동으로 된 기여",
        "rcfilters-filter-bots-label": "봇",
+       "rcfilters-filter-bots-description": "자동 도구를 이용한 편집.",
        "rcfilters-filter-humans-label": "사람 (봇이 아님)",
+       "rcfilters-filter-humans-description": "수동으로 한 편집.",
+       "rcfilters-filtergroup-significance": "의미",
        "rcfilters-filter-minor-label": "사소한 편집",
        "rcfilters-filter-major-label": "사소하지 않은 편집",
+       "rcfilters-filter-major-description": "사소한 편집으로 표시되지 않은 편집.",
+       "rcfilters-filtergroup-changetype": "차이 종류",
        "rcfilters-filter-pageedits-label": "문서 편집",
+       "rcfilters-filter-newpages-label": "문서 생성",
+       "rcfilters-filter-newpages-description": "새 문서를 만드는 편집.",
+       "rcfilters-filter-categorization-label": "분류 차이",
+       "rcfilters-filter-categorization-description": "분류에서 추가되거나 제거되는 페이지의 기록.",
        "rcnotefrom": "아래는 <strong>$3, $4</strong>부터 시작하는 {{PLURAL:$5|바뀜이 있습니다}}. (최대 <strong>$1</strong>개가 표시됨)",
        "rclistfrom": "$3 $2부터 시작하는 새로 바뀐 문서 보기",
        "rcshowhideminor": "사소한 편집 $1",
        "apisandbox-sending-request": "API 요청을 보내는 중...",
        "apisandbox-loading-results": "API 결과를 받는 중...",
        "apisandbox-results-error": "API 질의 응답을 불러오는 도중 오류 발생: $1.",
-       "apisandbox-request-params-json": "JSON 변수:",
+       "apisandbox-request-format-url-label": "URL 쿼리 문자열",
        "apisandbox-request-url-label": "요청 URL:",
        "apisandbox-request-time": "요청 처리 시간: {{PLURAL:$1|$1 ms}}",
        "apisandbox-results-fixtoken": "토큰 수정 후 다시 제출",
index 16ddbcd..9317066 100644 (file)
        "continue-editing": "Here qada sazandinê",
        "editing": "\"$1\" tê guherandin",
        "creating": "\"$1\" tê çêkirin",
-       "editingsection": "Tê guherandin: $1 (beş)",
+       "editingsection": "\"$1\" (beş) tê guherandin",
        "editingcomment": "$1 (beşek nû) tê guherandin.",
        "editconflict": "Têkçûna guherandinan: $1",
        "explainconflict": "Ji dema te dest bi guherandinê kir heta niha kesekê/î din ev rûpel guherand.\nLi jor guhertoya heyî tê dîtîn.\nGuherandinên te li jêr tên nîşandan.\nDivê tu wan bikî yek.\nHeke niha tomar bikî, '''bi tenê''' nivîsara qutiya jor wê bê tomarkirin.",
        "protectedarticle": "parastî [[$1]]",
        "modifiedarticleprotection": "parastina \"[[$1]]\" guherand",
        "unprotectedarticle": "parastina \"[[$1]]\" rakir",
-       "protect-title": "parastina \"$1\" biguherîne",
+       "protect-title": "Parastina \"$1\" biguherîne",
        "prot_1movedto2": "Navê [[$1]] weke [[$2]] hate guhertin",
        "protect-norestrictiontypes-title": "Rûpela neparastbar",
        "protect-legend": "Parastinê bipesinîne",
        "hours-ago": "berî $1 {{PLURAL:$1|demjimêr|demjimêran}}",
        "variantname-ku-arab": "Tîpên erebî",
        "variantname-ku-latn": "Tîpên latînî",
-       "variantname-ku": "disable",
+       "variantname-ku": "Kurdî/کوردی",
        "metadata": "Daneyên meta",
        "metadata-expand": "Detayên dirêj nîşan bide",
        "metadata-collapse": "Detayên dirêj veşêre",
index a124e42..18d958d 100644 (file)
        "youremail": "E-Mail-Adress:",
        "username": "{{GENDER:$1|Benotzernumm}}:",
        "prefs-memberingroups": "{{GENDER:$2|Member}} vun {{PLURAL:$1|der Benotzergrupp|de Benotzergruppen}}:",
+       "group-membership-link-with-expiry": "$1 (bis $2)",
        "prefs-registration": "Zäitpunkt vum Opmaache vum Benotzerkont:",
        "yourrealname": "Richtegen Numm:",
        "yourlanguage": "Sprooch:",
        "userrights-nodatabase": "D'Datebank $1 gëtt et net oder se ass net lokal.",
        "userrights-changeable-col": "Gruppen déi Dir ännere kënnt",
        "userrights-unchangeable-col": "Gruppen déi Dir net ännere kënnt",
+       "userrights-expiry-none": "Leeft net of",
+       "userrights-expiry": "Valabel bis:",
        "userrights-conflict": "Konflikt bei de Benotzerrechter! Kuckt Är Ännerunge w.e.g. no a maacht se w.e.g. nach eng Kéier.",
        "group": "Grupp:",
        "group-user": "Benotzer",
        "recentchanges-legend-plusminus": "''(±123)''",
        "recentchanges-submit": "Weisen",
        "rcfilters-activefilters": "Aktiv Filteren",
+       "rcfilters-restore-default-filters": "Standardfiltere restauréieren",
+       "rcfilters-clear-all-filters": "All Filteren eidelmaachen",
        "rcfilters-search-placeholder": "Rezent Ännerunge filteren (duerchsichen oder ufänke mat tippen)",
        "rcfilters-invalid-filter": "Net valabele Filter",
        "rcfilters-filterlist-title": "Filteren",
        "rcfilters-filter-editsbyself-description": "Ännerunge vun Iech.",
        "rcfilters-filter-editsbyother-label": "Ännerunge vun Aneren",
        "rcfilters-filter-editsbyother-description": "Ännerunge vun anere Benotzer (net vun Iech).",
-       "rcfilters-filtergroup-userExpLevel": "Niveau vun der Erfahrung vum Benotzer",
+       "rcfilters-filtergroup-userExpLevel": "Niveau vun der Erfahrung (just fir registréiert Benotzer)",
        "rcfilters-filter-userExpLevel-newcomer-label": "Neier",
-       "rcfilters-filter-userExpLevel-newcomer-description": "Ganz nei Auteuren: manner wéi 10 Ännerungen a manner wéi 4 Deeg Aktivitéit.",
+       "rcfilters-filter-userExpLevel-newcomer-description": "Manner wéi 10 Ännerungen a manner wéi 4 Deeg Aktivitéit.",
        "rcfilters-filter-userExpLevel-learner-label": "Ufänger",
-       "rcfilters-filter-userExpLevel-learner-description": "Aktivitéit vu méi Deeg a méi Ännerunge wéi 'Nei Benotzer' awer manner wéi 'Erfuere Benotzer'.",
+       "rcfilters-filter-userExpLevel-learner-description": "Aktivitéit vu méi Deeg a méi Ännerunge wéi ''Nei Benotzer'' awer manner wéi ''Erfuere Benotzer''.",
        "rcfilters-filter-userExpLevel-experienced-label": "Erfuere Benotzer.",
        "rcfilters-filter-userExpLevel-experienced-description": "Méi wéi 30 Deeg Aktivitéit a méi wéi 500 Ännerungen.",
        "rcfilters-filter-minor-label": "Kleng Ännerungen",
        "apisandbox-results": "Resultater",
        "apisandbox-sending-request": "Schécke vun der API-Ufro...",
        "apisandbox-loading-results": "Ofruffe vun den API-Resultater...",
-       "apisandbox-request-params-json": "JSON-Parameteren:",
        "apisandbox-request-url-label": "URL fir Ufroen:",
        "apisandbox-request-time": "Dauer vun der Ufro: {{PLURAL:$1|$1 ms}}",
        "apisandbox-alert-page": "Felder op dëser Säit sinn net valabel.",
        "emailccsubject": "Kopie vun denger Noriicht un $1: $2",
        "emailsent": "E-Mail geschéckt",
        "emailsenttext": "Är E-Mail gouf fortgeschéckt.",
-       "emailuserfooter": "Dës E-Mail gouf {{GENDER:$1|vum}} $1  {{GENDER:$2|dem}} $2 geschéckt dobäi gouf d'Funktioun \"{{int:emailuser}}\" op {{SITENAME}} benotzt. {{GENDER:$2|Är}} E-Mail gëtt direkt un den {{GENDER:$1|originalen Absender}} geschéckt do bäi gesäit  {{GENDER:$1|deen}} {{GENDER:$2|Är}} E-Mail-Adress.",
+       "emailuserfooter": "Dës E-Mail gouf {{GENDER:$1|vum}} $1  {{GENDER:$2|dem}} $2 geschéckt dobäi gouf d'Funktioun \"{{int:emailuser}}\" op {{SITENAME}} benotzt.Wann {{GENDER:$2|Dir}} op dës E-Mail äntwert, gëtt {{GENDER:$2|Är}} E-Mail direkt un den {{GENDER:$1|originalen Absender}} geschéckt dobäi gesäit {{GENDER:$1|deen}} {{GENDER:$2|Är}} E-Mail-Adress.",
        "usermessage-summary": "Benoriichtegung hannerloossen.",
        "usermessage-editor": "Benoriichtegungs-System",
        "watchlist": "Iwwerwaachungslëscht",
index 3a8e61b..1d786c2 100644 (file)
@@ -6,38 +6,62 @@
                        "Malafaya",
                        "Reedy",
                        "Urhixidur",
-                       "아라"
+                       "아라",
+                       "Katxis",
+                       "Chabi"
                ]
        },
        "tog-underline": "Sulinia lias:",
        "tog-hideminor": "Asconda editas minor en cambias resente",
+       "tog-hidepatrolled": "Asconde editas patruliada de cambias resente",
+       "tog-newpageshidepatrolled": "Asconde pajes patruliada de lista de pajes nova",
+       "tog-hidecategorization": "Asconde categori de pajes",
        "tog-extendwatchlist": "Grandi la lista oservada per mostra tota cambias aplicable",
        "tog-usenewrc": "Aumenta cambias resente (JavaScript)",
        "tog-numberheadings": "Dona automatica numeros a titula",
        "tog-showtoolbar": "Mostra la bara de utiles per edita (JavaScript)",
        "tog-editondblclick": "Edita pajes a du clicas (JavaScript)",
        "tog-editsectiononrightclick": "Engrana la edita de sesion par clica a la destra a titulos de sesion (JavaScript)",
-       "tog-watchcreations": "Junta la pajes ce me ia creada a me lista de pajes oservada",
-       "tog-watchdefault": "Junta pajes ce me ia edita a me lista de pajes oservada",
-       "tog-watchmoves": "Junta pajes ce me ia moveda a me lista de pajes oservada",
-       "tog-watchdeletion": "Junta pajes ce me ia sutrae a me lista de pajes oservada",
+       "tog-watchcreations": "Junta la pajes cual me ia crea e fixes cual me ia carga  a mea lista de pajes oservada",
+       "tog-watchdefault": "Junta pajes e imajes cual me ia edita a mea lista de pajes oservada",
+       "tog-watchmoves": "Junta pajes e fixes cual me ia moveda a mea lista de pajes oservada",
+       "tog-watchdeletion": "Junta pajes cual me ia sutrae a mea lista de pajes oservada",
+       "tog-watchuploads": "Ajunta fixes nova cual me ia carga a mea lista de pajes oservada",
+       "tog-watchrollback": "Ajunta pajes a cual me ia reversa a mea lista de pajes oservada",
        "tog-minordefault": "Marca costumal tota editas como minor",
        "tog-previewontop": "Mostra la previde ante la caxa de editas",
        "tog-previewonfirst": "Mostra la previde a la edita prima",
-       "tog-enotifwatchlistpages": "Envia un eposta a me cuando un paje ce me oserva es cambiada",
+       "tog-enotifwatchlistpages": "Envia un eposta a me cuando un paje o fix cual me oserva es cambiada",
        "tog-enotifusertalkpages": "Envia me un eposta cuando me paje de discutes es cambiada",
-       "tog-enotifminoredits": "Ance envia un eposta a me con edita minor de pajes",
+       "tog-enotifminoredits": "Ance envia un eposta a me con editas minor de pajes e fixes",
        "tog-enotifrevealaddr": "Descovre la me adirije de eposta en postas de nota",
        "tog-shownumberswatching": "Mostra la numero de usores oservante",
-       "tog-fancysig": "Sinias simple (sin lia automatica)",
+       "tog-oldsig": "Tua suscrive presente",
+       "tog-fancysig": "Trata la suscrive como vicitesto (sin lia automatica)",
+       "tog-uselivepreview": "Usa un previde direta",
+       "tog-forceeditsummary": "Recorda me cuando entera un resoma vacua de edita",
        "tog-watchlisthideown": "Asconde me editas de la lista de pajes oservada",
        "tog-watchlisthidebots": "Asconde editas par bot de la lista de pajes oservada",
        "tog-watchlisthideminor": "Asconde editas minor de la lista de pajes oservada",
+       "tog-watchlisthideliu": "Asconde editas par usores identifiada de la lista de pajes oservada",
+       "tog-watchlistreloadautomatically": "Recarga automata la lista de pajes oservada cuando un filtre es cambiada (JavaScript nesesada)",
+       "tog-watchlisthideanons": "Asconde editas par usores anonim de la lista de pajes oservada",
+       "tog-watchlisthidepatrolled": "Asconde editas patruliada de la lista de pajes oservada",
+       "tog-watchlisthidecategorization": "Asconde la categori de pajes",
        "tog-ccmeonemails": "Envia copias de la epostas ce me envia a otras a me ance",
+       "tog-diffonly": "No mostra la conteni de paje su diffes",
        "tog-showhiddencats": "Mostra categorias ascondeda",
+       "tog-norollbackdiff": "No mostra diff pos un reversa",
+       "tog-useeditwarning": "Avisa me cuando me sorti un paje de edita con cambias nonsalvada",
+       "tog-prefershttps": "Sempre usa un lia secur cuando identifiada",
        "underline-always": "A tota tempo",
        "underline-never": "A no tempo",
-       "underline-default": "Surfador costumal",
+       "underline-default": "Inisial de pel o surfador",
+       "editfont-style": "Edita area de stilo de leteras",
+       "editfont-default": "Inisial de surfador",
+       "editfont-monospace": "Leteras monospasida",
+       "editfont-sansserif": "Leteras sin serifes",
+       "editfont-serif": "Leteras con serifes",
        "sunday": "soldi",
        "monday": "lundi",
        "tuesday": "martedi",
        "oct": "oto",
        "nov": "nov",
        "dec": "des",
+       "january-date": "$1 janero",
+       "february-date": "$1 febrero",
+       "march-date": "$1 marto",
+       "april-date": "$1 april",
+       "may-date": "$1 maio",
+       "june-date": "$1 junio",
+       "july-date": "$1 julio",
+       "august-date": "$1 agosto",
+       "september-date": "$1 setembre",
+       "october-date": "$1 otobre",
+       "november-date": "$1 novembre",
+       "december-date": "$1 desembre",
+       "period-am": "am",
+       "period-pm": "pm",
        "pagecategories": "{{PLURAL:$1|Categoria|Categorias}}",
        "category_header": "Articles en categoria \"$1\"",
        "subcategories": "Sucategorias",
        "category-empty": "''Aora, esta categoria no conteni pajes o medio.''",
        "hidden-categories": "{{PLURAL:$1|Categoria|Categorias}} ascondeda",
        "hidden-category-category": "Categorias ascondeda",
+       "category-subcat-count": "{{PLURAL:$2|Esta categoria ave sola la sucategoria seguente.|Esta categoria ave la {{PLURAL:$1|sucategoria|$1 sucategorias}} seguente, entre $2 tota.}}",
+       "category-subcat-count-limited": "Esta categoria ave la {{PLURAL:$1|sucategoria|$1sucategorias}} seguente.",
+       "category-article-count": "{{PLURAL:$2|Esta categoria conteni sola la paje seguente.|La {{PLURAL:$1|paje es|$1 pajes es}} seguente en esta categoria, estra $2 tota.}}",
+       "category-article-count-limited": "La {{PLURAL:$1|paje|$1pajes}} seguente es en la categoria presente.",
+       "category-file-count": "{{PLURAL:$2|Esta categoria conteni sola la fix seguente.|La {{PLURAL:$1|fix|$1 fixes}} seguente es en esta categoria, estra $2 tota.}}",
+       "category-file-count-limited": "The {{PLURAL:$1|fix|$1 fixes}} seguente es en la categoria presente.",
        "listingcontinuesabbrev": "cont.",
+       "index-category": "Pajes indiseda",
+       "noindex-category": "Pajes nonindiseda",
+       "broken-file-category": "Pajes con lias rompeda de fixes",
        "about": "Supra",
        "article": "Paje de contenis",
        "newwindow": "(va abri en fenetra nova)",
        "cancel": "Cansela",
        "moredotdotdot": "Plu...",
-       "mypage": "Me paje",
+       "morenotlisted": "Esta lista es posible noncompleta.",
+       "mypage": "Paje",
        "mytalk": "Discutes",
-       "anontalk": "Discutes per esta IP",
+       "anontalk": "Discute",
        "navigation": "Naviga",
        "and": "&#32;e",
        "qbfind": "Trova",
        "qbedit": "Edita",
        "qbpageoptions": "Esta paje",
        "qbmyoptions": "Me pajes",
+       "faq": "Demandas comun",
+       "faqpage": "Project: Demandas comun",
+       "actions": "Atas",
+       "namespaces": "Locas de nom",
+       "variants": "Varias",
+       "navigation-heading": "Menu per naviga",
        "errorpagetitle": "Era",
        "returnto": "Restora a $1.",
        "tagline": "De {{SITENAME}}",
        "help": "Disionario",
        "search": "Xerca",
+       "search-ignored-headings": " #<!-- leave this line exactly as it is --> <pre>\n# Titulos cual va es iniorada par xerca.\n# Cambias a esta va aveni pronto cuando la paje con la titulo es indiseda.\n# Tu pote forsa la reindise de un paje par fa un edita vacua.\n# La sintax es como la seguente:\n#   * Tota de la sinia \"#\" a la fini de la linia es un comenta.\n#   * Tota linia nonvacua es la titulo esata per iniora, incluinte caso etc.\nReferes\nLias esterna\nVide ance\n #</pre> <!-- leave this line exactly as it is -->",
        "searchbutton": "Xerca",
        "go": "Vade",
        "searcharticle": "Vade",
        "history": "Istoria de paje",
        "history_short": "Istoria",
+       "history_small": "istoria",
        "updatedmarker": "renovida de me visita presedente",
        "printableversion": "Varia primable",
        "permalink": "Lia permanente",
        "print": "Primi",
+       "view": "Vide",
+       "view-foreign": "Vide a $1",
        "edit": "Cambia",
+       "edit-local": "Edita descrive local",
        "create": "Crea",
+       "create-local": "Ajunta descrive local",
        "editthispage": "Cambia esta paje",
        "create-this-page": "Crea esta paje",
        "delete": "Sutrae",
        "deletethispage": "Sutrae esta paje",
+       "undeletethispage": "Desutrae esta paje",
        "undelete_short": "Desutrae {{PLURAL:$1|edita|editas}}",
+       "viewdeleted_short": "Vide {{PLURAL:$1|un edit desutraeda|$1 editas desutraeda}}",
        "protect": "Proteje",
        "protect_change": "cambia",
        "protectthispage": "Proteje esta paje",
-       "unprotect": "desproteje",
-       "unprotectthispage": "Desproteje esta paje",
+       "unprotect": "Cambia la proteje",
+       "unprotectthispage": "Cambia la proteje de esta paje",
        "newpage": "Paje nova",
        "talkpage": "Discute esta paje",
        "talkpagelinktext": "Parla",
        "talk": "Discutes",
        "views": "Vides",
        "toolbox": "Utiles",
+       "tool-link-userrights": "Cambia grupos de {{GENDER:$1|usor}}",
+       "tool-link-userrights-readonly": "Vide grupos de {{GENDER:$1|usor}}",
+       "tool-link-emailuser": "E-posta esta {{GENDER:$1|usor}}",
        "userpage": "Vide paje de usor",
        "projectpage": "Vide la paje de projeta",
        "imagepage": "Vide paje de fix",
        "otherlanguages": "En otra linguas",
        "redirectedfrom": "(Redirijeda de $1)",
        "redirectpagesub": "Redireta la paje",
+       "redirectto": "Redirije a:",
+       "lastmodifiedat": "Esta paje ia es cambiada a $1, a $2",
        "viewcount": "Esta paje es asesada a $1 {{PLURAL:$1|ves|veses}}.",
        "protectedpage": "Paje protejeda",
        "jumpto": "Salta a:",
        "jumptonavigation": "naviga",
        "jumptosearch": "xerca",
+       "view-pool-error": "Pardona, la servadores es tro cargada a esta ora.\nTro multe usores es atenta vide esta paje.\nPer favore espeta ante cuanto tu atenta vide esta paje denova.\n\n$1",
+       "generic-pool-error": "Pardona, la servadores es tro cargada a esta ora.\nTro multe usores es atentante vide esta recurso.\nPer favore espeta ante cuando tu atenta vide esta recurso denova.",
        "aboutsite": "Supra {{SITENAME}}",
        "aboutpage": "Project:Supra",
        "copyrightpage": "{{ns:project}}:Diretos de autor",
        "disclaimers": "Negas de respondablia",
        "disclaimerpage": "Project:Nega jeneral de respondablia",
        "edithelp": "Aida con edita",
+       "helppage-top-gethelp": "Aida",
        "mainpage": "Paje Prima",
        "mainpage-description": "Paje Prima",
        "policy-url": "Project:Politica",
        "toc": "Contenida",
        "showtoc": "mostra",
        "hidetoc": "asconde",
+       "collapsible-collapse": "Colasa",
+       "collapsible-expand": "Estende",
+       "confirmable-confirm": "Esce {{GENDER:$1|tu}} es serta?",
+       "confirmable-yes": "Si",
+       "confirmable-no": "No",
        "viewdeleted": "Vide $1?",
        "feedlinks": "Flue:",
        "site-rss-feed": "$1 RSS Flue",
        "site-atom-feed": "$1 Atom Flue",
        "page-rss-feed": "\"$1\" RSS Flue",
+       "page-atom-feed": "\"$1\" Enflue de atom",
        "red-link-title": "$1 (paje no esiste)",
        "nstab-main": "Paje",
        "nstab-user": "Paje de usor",
        "nstab-template": "Model",
        "nstab-help": "Paje de aida",
        "nstab-category": "Categoria",
+       "mainpage-nstab": "Paje Prima",
        "error": "Era",
        "databaseerror": "Era de base de datos",
        "missingarticle-diff": "(Difere: $1, $2)",
        "badtitletext": "La titulo de la paje tu ia desira ia es nonlegal, es vacua, o es un titulo intervici o interlingual no liada coreta. Es posable ce es un o plu simboles ce no pote es usada en titulos.",
        "viewsource": "Vide la orijin",
        "viewsourcetext": "Tu pote vide e copia la orijin de esta paje:",
+       "mycustomcssprotected": "Tu no ave permete per edita esta paje CSS.",
+       "mycustomjsprotected": "Tu no ave permete per edita esta paje JavaScript.",
+       "myprivateinfoprotected": "Tu no ave permete per edita tua informa privata.",
+       "mypreferencesprotected": "Tu no ave permete per edita tua preferes.",
+       "ns-specialprotected": "La pajes spesial no pote es editada.",
+       "welcomeuser": "Bonveni, $1!",
        "yourname": "Nom de usor:",
+       "userlogin-yourname": "Nom de usor",
+       "userlogin-yourname-ph": "Entra tua nom de usor",
        "yourpassword": "Sinia de entra:",
+       "userlogin-yourpassword": "Clave",
+       "userlogin-yourpassword-ph": "Entra tua sinia secreta",
+       "createacct-yourpassword-ph": "Entra un sinia secreta",
        "yourpasswordagain": "Retape la sinia:",
+       "createacct-yourpasswordagain": "Confirma la sinia secreta",
+       "createacct-yourpasswordagain-ph": "Entra un sinia secreta denova",
+       "userlogin-remembermypassword": "Reteni me como identifiada",
        "yourdomainname": "Tu domina:",
        "login": "Identifia",
        "nav-login-createaccount": "Sinia per entra",
        "userlogin": "Sinia per entra",
        "logout": "Retira",
        "userlogout": "Sinia per retira",
+       "userlogin-noaccount": "Tu no ave un conta?",
+       "userlogin-joinproject": "Crea un conta con {{SITENAME}}",
        "nologin": "Tu no ave un conta? '''$1'''.",
        "nologinlink": "Crea  un conta",
        "createaccount": "Crea un conta",
        "gotaccount": "Tu ave ja un conta? '''$1'''.",
        "gotaccountlink": "Sinia per entra",
+       "userlogin-resetpassword-link": "Tu ia oblida tua sinia secreta?",
+       "userlogin-helplink2": "Aida me per identifia me",
+       "createacct-emailrequired": "Adirije de e-posta",
+       "createacct-emailoptional": "Adirije de e-posta (elejable)",
+       "createacct-email-ph": "Entra tua adirije de e-posta",
+       "createacct-another-email-ph": "Entra tua adirije de e-posta",
+       "createaccountreason": "Razona:",
+       "createacct-reason": "Razona:",
+       "createacct-submit": "Crea tua conta",
+       "createacct-another-submit": "Crea un conta",
+       "createacct-benefit-heading": "{{SITENAME}} es fabricada par persones como tu.",
+       "createacct-benefit-body1": "{{PLURAL:$1|edita|editas}}",
+       "createacct-benefit-body2": "{{PLURAL:$1|paje|pajes}}",
+       "createacct-benefit-body3": "{{PLURAL:$1|contribuor|contribuores}}",
        "loginerror": "Era de entra",
-       "loginsuccesstitle": "Entra susedente",
+       "loginsuccesstitle": "Tu ia entra",
        "loginsuccess": "'''Tu ia entrada aora a {{SITENAME}} como \"$1\".'''",
-       "nosuchuser": "Es no usor con la nom \"$1\".\nEsamina la spele, o [[Special:CreateAccount|crea un conta nova]].",
+       "nosuchuser": "On no ave un usor con la nom \"$1\".\nOn distingui entre leteras major e minor per nomes de usores.\nEsamina la spele, o [[Special:CreateAccount|crea un conta nova]].",
        "nosuchusershort": "Es no usor con esta nom \"$1\". Esamina la spele.",
        "nouserspecified": "Tu debe indica un nom de usor.",
        "wrongpassword": "La sinia de entra no es coreta. Per favore, atenta ancora.",
        "wrongpasswordempty": "La sinia de entra es vacua. Per favore, atenta ancora.",
-       "passwordtooshort": "Tu sinia secreta no es legal o es tro corta.\nEl debe ave a min {{PLURAL:$1|1 simbol|$1 simboles}} e debe difere de tu nom de usor.",
-       "mailmypassword": "Envia la sinia secreta nova par eposta",
+       "passwordtooshort": "Sinias secreta debe ave minima {{PLURAL:$1|1 simbol|$1 simboles}}.",
+       "passwordtoolong": "Sinias secreta no pote ave plu ca {{PLURAL:$1|1 simbol|$1 simboles}}.",
+       "passwordtoopopular": "Sinias secreta comun debe no es usada. Per favore, eleje un sinia plu unica.",
+       "mailmypassword": "Cambia tua sinia secreta",
        "passwordremindertitle": "Sinia secreta temporer nova per {{SITENAME}}",
-       "passwordremindertext": "Algun (tu, probable, de adirije IP $1)\nia demanda ce nos envia a tu un sinia secreta nova per {{SITENAME}} ($4).\nLa sinia secreta per usor \"$2\" es aora \"$3\".\nTu debe sinia per entra e cambia tu sinia secreta aora.\n\nSi algun otra ce tu ia envia esta demanda a nos, o si tu ia recorda tu sinia secreta e no vole cambia el aora, tu pote iniora esta mesaje e continua usa tu sinia secreta vea.",
+       "passwordremindertext": "Algun (tu, probable, de adirije IP $1)\nia demanda un sinia secreta nova per {{SITENAME}} ($4).\nLa sinia secreta tempora per usor \"$2\" es aora \"$3\". Si esta ia es tua intende, tu debe identifia tu denova per entra e eleje tua sinia nova aora.\nTua sinia tempora va desvalidi en {{PLURAL:$5|un dia|$5 dias}}.\n\nSi algun otra ca tu ia envia esta demanda a nos, o si tu ia recorda tua sinia secreta e no vole cambia lo aora, tu pote iniora esta mesaje e continua usa tua sinia secreta vea.",
        "noemail": "No es un adirije de eposta per usor \"$1\".",
        "passwordsent": "Un sinia secreta ia es enviada a la adirije de eposta per \"$1\".\nPer favore, sinia per entra ancora pos tu ia reseta el.",
-       "eauthentsent": "Un eposta de serti ia es enviada a la adirije de eposta proposada.\nAnte alga otra eposta es enviada a la conta, tu va nesesa segue la instruis en la eposta, per serti ce la conta es vera de tu.",
+       "eauthentsent": "Un eposta de serti ia es enviada a la adirije de eposta spesifada.\nAnte cualce otra epostas es enviada a tua conta, tu va nesesa segue la instruis en la eposta, per serti ce la conta es vera la tua.",
        "emailconfirmlink": "Aproba tu adirije de eposta",
+       "accountcreated": "Conta es creada",
        "loginlanguagelabel": "Lingua: $1",
+       "pt-login": "Identifia se",
+       "pt-login-button": "Identifia tua",
+       "pt-createaccount": "Crea un conta",
+       "pt-userlogout": "Desidentifia",
        "oldpassword": "Sinia secreta vea:",
        "newpassword": "Sinia secreta nova:",
        "retypenew": "Re-entra tu sinia secreta nova:",
        "resetpass-submit-loggedin": "Cambia la sinia secreta",
        "resetpass-temp-password": "Sinia secreta tempora:",
+       "passwordreset": "Reinisia sinia secreta",
+       "passwordreset-username": "Nom de usor:",
+       "passwordreset-domain": "Domina:",
+       "passwordreset-email": "Adirije de e-posta",
+       "passwordreset-invalidemail": "Adirije de e-posta no es valida",
+       "changeemail-submit": "Cambia e-posta",
        "bold_sample": "Testo en leteras forte",
        "bold_tip": "Testo en leteras forte",
        "italic_sample": "Testo en leteras italica",
        "sig_tip": "Tu sinia con la primi de la ora",
        "hr_tip": "Linia orizonal (usa nonfrecuente)",
        "summary": "Soma:",
-       "subject": "Sujeto/titulo:",
+       "subject": "Sujeto:",
        "minoredit": "Esta es un cambia minor",
        "watchthis": "Oserva esta paje",
        "savearticle": "Fisa paje",
+       "publishpage": "Publici paje",
+       "publishchanges": "Publica la cambias",
        "preview": "Previde",
        "showpreview": "Mostra previde",
        "showdiff": "Mostra diferes",
-       "anoneditwarning": "'''Avisa:''' Tu no ia sinia per entra.\nTu adirije de IP va es memorada en la istoria de revisas de esta paje.",
+       "anoneditwarning": "'''Avisa:''' Tu no ia identifia se.\nTu adirije de IP va es memorada en la istoria de revisas de esta paje. Si tu <strong>[$1 identifia se]</strong> o <strong>[$2 crea un conta]</strong>, tua editas va es atribuida a tua nom de usor, con otra benefias.",
        "summary-preview": "Previde soma:",
        "blockedtitle": "Usor es impedida",
        "blockedtext": "'''Tu nom de usor o adirije de IP ia es impedida.'''\n\nLa impedi ia es fada par $1.\nLa razon donada es ''$2''.\n\n* Comensa de impedi: $8\n* Fini de impedi: $6\n* Ci algun intende impedi: $7\n\nTu pote contata $1 o un otra [[{{MediaWiki:Grouppage-sysop}}|dirijor]] per discute esta impedi.\nTu no pote usa la 'envia un eposta a esta usor' sin un adirije de eposta legal es indicada en tu\n[[Special:Preferences|preferis de conta]] e tu no es impedida de usa el.\nTu adirije de IP es aora $3, e la identia de la impedi es #$5.\nPer favore inclui tota esta detales en tu demandas.",
+       "loginreqtitle": "Entra de identia nesesada",
+       "loginreqlink": "Identifia se",
        "newarticle": "(Nova)",
        "newarticletext": "Tu ia segue un lia a un paje ce no esista ja.\nPer crea la paje, comensa scrive en la caxa a su\n(vide la [$1 paje de aida] per plu).\nSi tu es asi par era, clica a la boton '''retro''' de tu surfador.",
-       "noarticletext": "Es aora no testo a esta paje.\nTu pote [[Special:Search/{{PAGENAME}}|xerca per la titulo de esta paje]] en otra pajes,\n<span class=\"plainlinks\">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} xerca la arcivos relatada],\no [{{fullurl:{{FULLPAGENAME}}|action=edit}} edita esta paje]</span>.",
+       "noarticletext": "On ave aora no testo a esta paje.\nTu pote [[Special:Search/{{PAGENAME}}|xerca per la titulo de esta paje]] en otra pajes,\n<span class=\"plainlinks\">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} xerca la arcivos relatada],\no [{{fullurl:{{FULLPAGENAME}}|action=edit}} edita esta paje]</span>.",
+       "noarticletext-nopermission": "On ave presente no testo en esta paje.\nTu pote [[Special:Search/{{PAGENAME}}|xerca per esta titulo de paje]] en otra pajes, o <span class=\"plainlinks\">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} xerca arcivos relatada]</span>, ma tu no es permeteda per crea esta paje.",
        "previewnote": "'''Esta sola un previde; cambias no es fisada ja'''",
        "editing": "En la prosede de edita $1",
+       "creating": "Creante $1",
        "editingsection": "Edita $1 (sesion)",
        "editingcomment": "Edita $1 (sesion nova)",
        "yourdiff": "Diferes",
        "templatesusedpreview": "{{PLURAL:$1|Modele|Modeles}} usada en esta previde:",
        "template-protected": "(protejeda)",
        "template-semiprotected": "(proteje en parte)",
+       "hiddencategories": "Esta paje es un membro de {{PLURAL:$1|1 categoria ascondeda|$1 categorias ascondeda}}:",
        "nocreatetext": "{{SITENAME}} ave un restringe a la capas per crea pajes nova.\nTu pote vade a retro e edita un paje esistente, o  [[Special:UserLogin|sinia per entra o crea un conta]].",
-       "recreate-moveddeleted-warn": "'''Avisa: Tu es recrea un paje ce ia es sutraed en la pasada.'''\nTu debe pensa ce es bon continua edita esta paje.\nLa arcivo de sutraes per esta paje es asi per conveni:",
+       "permissionserrorstext-withaction": "Tua no es permeteda per $2, per la {{PLURAL:$1|razona|razonas}} seguente:",
+       "recreate-moveddeleted-warn": "<strong>Avisa: Tu es recreante un paje cual ia es sutraeda a ante.</strong>\nTu debe pensa si la continua de edita de esta paje conveni.\nLa arcivo de sutraes e moves per esta paje es asi per tua conveni:",
+       "moveddeleted-notice": "Esta paje ia es sutraeda.\nLa arcivo de sutraes e moves per la paje es furnida a su per refere.",
        "viewpagelogs": "Vide la arcivo de esta paje",
        "currentrev": "Cambia presente",
        "currentrev-asof": "Cambia presente a departi di $1",
        "page_last": "final",
        "histlegend": "Diferente eleje: Marca la caxas de radio de esta varias per compare e clica entra o la boton a la funda.<br />\n(presente) = difere de la varia presente,\n(presedente) = difere con varia presedente, M = edita minor.",
        "history-fieldset-title": "Surfa istoria",
-       "histfirst": "Prima",
-       "histlast": "Ultima",
+       "histfirst": "La plu vea",
+       "histlast": "La plu nova",
        "historysize": "({{PLURAL:$1|1 otuple|$1 otuples}})",
        "historyempty": "(vacua)",
        "history-feed-title": "Istoria de revises",
        "history-feed-item-nocomment": "$1 a $2",
        "rev-delundel": "mostra/asconde",
+       "rev-showdeleted": "mostra",
+       "revdelete-show-file-submit": "Si",
+       "revdelete-radio-set": "Ascondeda",
+       "revdelete-radio-unset": "Vidable",
+       "pagehist": "Istoria de paje",
+       "deletedhist": "Istoria sutraeda",
        "history-title": "Istoria de cambias de \"$1\"",
+       "difference-title": "Difere entre revisas de \"$1\"",
        "lineno": "Linia $1:",
        "compareselectedversions": "Compare varias elejeda",
        "editundo": "desfa",
+       "diff-multi-sameuser": "({{PLURAL:$1|Un revisa media|$1 revisas media}} par la mesma usor no mostrada)",
        "searchresults": "Resultas de xerca",
+       "searchresults-title": "Xerca la resultas per \"$1\"",
        "prevn": "{{PLURAL:$1|$1}} presedente",
        "nextn": "{{PLURAL:$1|$1}} seguente",
+       "nextn-title": "Seguente $1 {{PLURAL:$1|resulta|resultas}}",
+       "shown-title": "Mostra $1 {{PLURAL:$1|resulta|resultas}} per paje",
        "viewprevnext": "Vide ($1 {{int:pipe-separator}} $2) ($3)",
+       "searchmenu-new": "<strong>Crea la paje \"[[:$1]]\" a esta wiki!</strong> {{PLURAL:$2|0=|Vide ance la paje trovada con tua xerca.|Vide ance la resultas trovada par la xerca.}}",
+       "searchprofile-articles": "Pajes de contenis",
+       "searchprofile-images": "Multimedios",
+       "searchprofile-everything": "Tota",
+       "searchprofile-advanced": "Avansada",
+       "searchprofile-articles-tooltip": "Xerca en $1",
+       "searchprofile-images-tooltip": "Xerca per fixes",
+       "searchprofile-everything-tooltip": "Xerca tota contenidas (incluinte pajes de conversa)",
+       "searchprofile-advanced-tooltip": "Xerca en nomspasios unica",
        "search-result-size": "$1 ({{PLURAL:$2|1 parola|$2 parolas}})",
+       "search-redirect": "(redirije de $1)",
        "search-section": "(sesion $1)",
+       "search-suggest": "Tu ia intende: $1",
        "search-interwiki-default": "Resultas de $1:",
        "search-interwiki-more": "(plu)",
        "searchall": "tota",
+       "search-showingresults": "{{PLURAL:$4|Resulta <strong>$1</strong> de <strong>$3</strong>|Resultas <strong>$1 - $2</strong> de <strong>$3</strong>}}",
+       "search-nonefound": "On ave no resultas cual conforma con la demanda.",
+       "powersearch-toggleall": "Tota",
+       "powersearch-togglenone": "Zero",
        "preferences": "Preferis",
        "mypreferences": "Preferis",
        "skin-preview": "Previde",
        "saveprefs": "Fisa",
-       "rows": "Linias:",
-       "columns": "Colonas:",
        "searchresultshead": "Xerca",
        "savedprefs": "Tu preferis es fisada",
        "timezoneregion-africa": "Africa",
        "timezoneregion-pacific": "Mar Pasifica",
        "prefs-files": "Fixes",
        "youremail": "Eposta:",
-       "username": "Nom de usor:",
-       "prefs-memberingroups": "Membro de la {{PLURAL:$1|grupo|grupos}}:",
+       "username": "{{GENDER:$1|Nom de usor}}:",
+       "prefs-memberingroups": "{{GENDER:$2|Membro}} de {{PLURAL:$1|grupo|grupos}}:",
        "yourrealname": "Nom vera:",
        "yourlanguage": "Lingua:",
        "yournick": "Suscrive:",
-       "yourgender": "Seso:",
-       "gender-male": "Mas",
-       "gender-female": "Fema",
+       "yourgender": "Como tu prefere ce tu es descriveda?",
+       "gender-male": "El edita pajes de wiki",
+       "gender-female": "El edita pajes de wiki",
        "email": "Eposta",
-       "prefs-help-realname": "Tu nom vera no es obligada, ma si tu vole dona tu nom vera, el va es usada per onora tu per tu labora.",
+       "prefs-help-realname": "Tu nom vera no es obligada, ma si tu vole dona tu nom vera, el va es usada per onora tu per tu labora.\n\nTu no debe entra tua nom vera. Ma si tu entra tua noma vera, lo pote es usada per atribui tua laboras a tu.",
        "prefs-signature": "Suscrive",
        "userrights": "Dirije de la diretos de usores",
        "saveusergroups": "Fisa la grupo de usores",
        "group-user": "Usores",
        "group-sysop": "Dirijores",
        "group-all": "(tota)",
-       "group-user-member": "Usor",
+       "group-user-member": "{{GENDER:$1|usor}}",
        "grouppage-user": "{{ns:project}}:Usores",
        "grouppage-sysop": "{{ns:project}}:Dirijores",
+       "right-writeapi": "Usa de la API de scrive",
+       "newuserlogpage": "Arcivo de creas de usor",
        "rightslog": "Catalogo de diretos de usor",
        "action-edit": "edita esta paje",
        "nchanges": "$1 {{PLURAL:$1|cambia|cambias}}",
+       "enhancedrc-history": "istoria",
        "recentchanges": "Cambias resente",
+       "recentchanges-legend": "Elejes  per cambias resente",
        "recentchanges-summary": "Asi la lista de cambias resente en la vici.",
        "recentchanges-feed-description": "Seque la cambias plu resente a la vici en esta flue.",
+       "recentchanges-label-newpage": "Esta edita ia crea un paje nova",
+       "recentchanges-label-minor": "Esta es un edita minor",
+       "recentchanges-label-bot": "Esta edita ia es fada par un bot",
+       "recentchanges-label-unpatrolled": "Esta edita no ia es ja patruliada",
+       "recentchanges-label-plusminus": "La grandia de esta paje es cambiada par esta cuantia de baites",
+       "recentchanges-legend-heading": "<strong>Titulo:</strong>",
+       "recentchanges-legend-newpage": "{{int:recentchanges-label-newpage}} (vide ance [[Special:NewPages|la lista de pajes nova]])",
        "rcnotefrom": "A su es la cambias de '''$2''' (asta '''$1''' es mostrada).",
        "rclistfrom": "Mostra cambias nova, comensante de $3 $2",
        "rcshowhideminor": "$1 editas minor",
+       "rcshowhideminor-show": "Mostra",
+       "rcshowhideminor-hide": "Asconde",
        "rcshowhidebots": "$1 botes",
-       "rcshowhideliu": "$1 usores ativa aora",
+       "rcshowhidebots-show": "Mostra",
+       "rcshowhidebots-hide": "Asconde",
+       "rcshowhideliu": "$1 usores identifiada aora",
+       "rcshowhideliu-hide": "Asconde",
        "rcshowhideanons": "$1 usores sin nom",
+       "rcshowhideanons-show": "Mostra",
+       "rcshowhideanons-hide": "Asconde",
        "rcshowhidepatr": "$1 editas patroliada",
        "rcshowhidemine": "$1 me editas",
+       "rcshowhidemine-show": "Mostra",
+       "rcshowhidemine-hide": "Asconde",
        "rclinks": "Mostra la $1 cambias presedente en la $2 dias presedente<br />$3",
        "diff": "dife",
        "hist": "isto",
        "minoreditletter": "m",
        "newpageletter": "N",
        "boteditletter": "b",
-       "rc_categories_any": "Cualce",
+       "rc_categories_any": "Cualce de la elejeda",
+       "rc-change-size-new": "$1 {{PLURAL:$1|bait|baites}}  pos cambia",
        "rc-enhanced-expand": "Mostra detalias",
        "rc-enhanced-hide": "Asconde detalias",
        "recentchangeslinked": "Cambias relateda",
        "recentchangeslinked-title": "Cambias relatada a \"$1\"",
        "recentchangeslinked-summary": "Esta lista conteni la cambias plu resente de la pajes liada a otra (o de la membros de un categoria).\nPajes a [[Special:Watchlist|tu lista de pajes oservada]] es en leteras '''forte'''.",
        "recentchangeslinked-page": "Nom de la paje:",
+       "recentchangeslinked-to": "En loca, mostra cambia a pajes liada a la paje presentada",
        "upload": "Envia fixes",
        "uploadbtn": "Envia la fix",
        "uploadlogpage": "Envia arcivo",
+       "filedesc": "Resoma",
        "savefile": "Fisa fix",
        "upload-file-error": "Era interna",
+       "license-header": "Lisensa",
        "imgfile": "fix",
        "listfiles": "Lista de imajes",
        "listfiles_name": "Nom",
        "filehist-help": "Clica a un data/tempo per vide la fix como el ia aperi alora.",
        "filehist-current": "aora",
        "filehist-datetime": "Date/Tempo",
+       "filehist-thumb": "Imajeta",
+       "filehist-thumbtext": "Imajeta per varia pos $1",
        "filehist-user": "Usor",
        "filehist-dimensions": "Mesuras",
        "filehist-filesize": "Grandia de fix",
        "linkstoimage": "Esta {{PLURAL:$1|paje|pajes}} lia a esta fix:",
        "nolinkstoimage": "Es no pajes ce lia a esta fix.",
        "sharedupload": "Esta fix es parte de $1 e pote es usada par otra projetas.",
+       "sharedupload-desc-here": "Esta fix es de $1 e pote es usada par otra projetas.\nLa descrive su sua [$2 paje de descrive de fix] ala es mostra a su.",
        "uploadnewversion-linktext": "Envia un varia nova de esta fix",
+       "upload-disallowed-here": "Tu no pote suprascrive esta arcivo.",
        "mimesearch": "Xerca de MIME",
        "listredirects": "Lista redirijes",
        "unusedtemplates": "modeles no usada",
        "wantedpages": "Pajes desirada",
        "mostlinked": "Pajes la plu liada",
        "mostlinkedcategories": "Categorias a ce es la plu lias",
-       "mostlinkedtemplates": "Modeles a ce es la plu lias",
+       "mostlinkedtemplates": "Pajes la plu liada",
        "mostcategories": "Pajes con la plu categorias",
        "mostimages": "Fixes a ce es la plu lias",
        "mostrevisions": "Pajes con la plu revisas",
        "longpages": "Pajes longa",
        "deadendpages": "Pajes sin sorti",
        "protectedpages": "Pajes protejeda",
+       "protectedpages-page": "Paje",
+       "protectedpages-expiry": "Desvalidi",
        "listusers": "Lista de usores",
        "newpages": "Pajes nova",
        "ancientpages": "Pajes la plu vea",
        "pager-newer-n": "{{PLURAL:$1|1 plu resente|$1 plu resentes}}",
        "pager-older-n": "{{PLURAL:$1|1 plu vea|$1 plu veas}}",
        "booksources": "Orijines de libros",
+       "booksources-search-legend": "Xerca per fontes de libros",
+       "booksources-search": "Xerca",
        "specialloguserlabel": "Usor:",
        "speciallogtitlelabel": "Titulo:",
        "log": "Lista de atas",
        "listgrouprights-group": "Grupo",
        "listgrouprights-members": "(lista de membros)",
        "emailuser": "Envia un eposta a esta usor",
-       "emailfrom": "De",
-       "emailto": "Per",
-       "watchlist": "Pajes oservada",
+       "emailfrom": "De:",
+       "emailto": "A:",
+       "emailsubject": "Sujeto:",
+       "emailmessage": "Mesaje:",
+       "emailsend": "Envia",
+       "emailsent": "E-posta ia es enviada",
+       "watchlist": "Lista de pajes oservada",
        "mywatchlist": "Lista de pajes oservada",
+       "watchlistfor2": "Per $1 $2",
        "nowatchlist": "Tu ave no cosas en tu lista oservada",
        "addedwatchtext": "La paje \"[[:$1]]\" ia es juntada a tu [[Special:Watchlist|lista de pajes oservada]].\nCambias future a esta paje e se paje de discutes va es listada ala, e la paje va apera en leteras '''forte''' en la [[Special:RecentChanges|lista de cambias resente]] per es plu fasil oservada.\n\nSi tu vole sutrae la paje de tu lista de pajes oservada en la futur, clica a \"no oserva\" en la bara a la lado.",
        "removedwatchtext": "La paje \"[[:$1]]\" ia es sutraeda de [[Special:Watchlist|tu lista de pajes oservada]].",
        "deleteotherreason": "Otra/plu razona:",
        "deletereasonotherlist": "Otra razona",
        "rollbacklink": "retro",
+       "rollbacklinkcount": "reversa $1 {{PLURAL:$1|edita|editas}}",
        "protectlogpage": "Catalogo de protejes",
        "protectedarticle": "\"[[$1]]\" protejeda",
        "unprotectedarticle": "''[[$1]]'' desprotejeda",
        "undelete-search-submit": "Xerca",
        "namespace": "Loca de nom:",
        "invert": "Reversa la eleje",
+       "tooltip-invert": "Marca esta caxa per asconde cambias a pajes en la nomspasio elejeda (e la nomspasio asosiada si marcada)",
+       "namespace_association": "Nomspasio asosiada",
+       "tooltip-namespace_association": "Marca esta caxa per inclui ance la nomspasio de discute o sujeto asosiada con la nomspasio elejeda",
        "blanknamespace": "(Prima)",
-       "contributions": "Contribuis de usor",
-       "mycontris": "Me contribuis",
+       "contributions": "Contribuis de {{GENDER:$1|usor}}",
+       "mycontris": "Mea contribuis",
+       "anoncontribs": "Contribuis",
        "contribsub2": "Per $1 ($2)",
        "uctop": "(culmine)",
        "month": "De mensa (e plu vea):",
        "nolinkshere": "No pajes lia a '''[[:$1]]'''.",
        "isredirect": "redirije paje",
        "istemplate": "inclui",
-       "isimage": "lia de imaje",
+       "isimage": "lia de fix",
        "whatlinkshere-prev": "{{PLURAL:$1|presesdente|$1 presedente}}",
        "whatlinkshere-next": "{{PLURAL:$1|seguente|$1 seguente}}",
        "whatlinkshere-links": "← lias",
        "whatlinkshere-hideredirs": "$1 redirijes",
+       "whatlinkshere-hidetrans": "$1 transcluis",
        "whatlinkshere-hidelinks": "$1 lias",
        "whatlinkshere-filters": "Filtros",
        "blockip": "Impedi usor",
        "move-page-legend": "Move paje",
        "movepagetext": "Usa la forma a su va cambia la nom de un paje, e va move tota se istoria a la nom nova.\nLa titulo vea va deveni un paje de redirije a la titulo nova.\nLias a la titulo de la paje vea no va es cambiada;\nTu debe vide serta ce es redirijes duple o rompeda.\nTu es respondable per es serta ce la lias va continua vade a la locas intendeda.\n\nNota ce la paje '''no''' va es moveda si es ja un paje a la titulo nova, sin el es vacua o un redirije e no ave un istoria de editas presedente.\nEsta sinifia ce tu pote cambia la nom de un paje a la loca presedente si tu era, e tu no pote scrive supra un paje ce esiste ja.\n\n'''AVISA!'''\nEsta pote es un cambia dramos e nonespetada per un paje poplal;\nper favore, es serta ce tu comprende la resulta de esta ata ante tu continua.",
        "movepagetalktext": "La paje de discuta de esta paje va es moveda automatica con el '''eseta si:'''\n*Un paje de discuta ce no es vacua esiste ja su la nom nova, o\n*Tu cambia la indica en la caxa su.\n\nEn esta casos, tu va nesesa move o fusa la paje per mano, si desirada.",
-       "newtitle": "A titulo nova:",
+       "newtitle": "Titulo nova:",
        "move-watch": "Oserva esta paje",
        "movepagebtn": "Move paje",
        "pagemovedsub": "La move ia susede",
        "thumbnail_error": "Era en crea la imajeta: $1",
        "import": "Emporta pajes",
        "importlogpage": "Importa arcivo",
-       "tooltip-pt-userpage": "Tu paje de usor",
-       "tooltip-pt-mytalk": "Tu paje de discutes",
-       "tooltip-pt-preferences": "Me preferis",
+       "tooltip-pt-userpage": "{{GENDER:|Tua}} page de usor",
+       "tooltip-pt-mytalk": "{{GENDER:|Tua}} paje de discutes",
+       "tooltip-pt-preferences": "{{GENDER:|Tua}} preferes",
        "tooltip-pt-watchlist": "La lista de pajes ce tu oserva per cambias",
-       "tooltip-pt-mycontris": "Lista de tu contribuis",
+       "tooltip-pt-mycontris": "Lista de tua contribuis",
        "tooltip-pt-login": "Nos preferi si tu sinia per entra, ma tu es no obligada.",
        "tooltip-pt-logout": "Sinia per retira",
+       "tooltip-pt-createaccount": "Tu es corajida per crea un conta e identifia se; an si, esta no es obligante",
        "tooltip-ca-talk": "Discute de la paje de contenis",
-       "tooltip-ca-edit": "Tu pote edita esta paje. Per favore, usa la boton de previde ante fisa.",
+       "tooltip-ca-edit": "Edita esta paje",
        "tooltip-ca-addsection": "Inisia un sesion nova",
        "tooltip-ca-viewsource": "Esta paje es protejeda. Tu pote vide se orijin.",
+       "tooltip-ca-history": "Revisas pasada de esta paje",
        "tooltip-ca-protect": "Proteje esta paje",
        "tooltip-ca-delete": "Sutrae esta paje",
        "tooltip-ca-move": "Move esta paje",
        "tooltip-ca-watch": "Junta esta paje a tu lista de pajes oservada",
        "tooltip-ca-unwatch": "Sutrae esta paje de tu lista de pajes oservada",
        "tooltip-search": "Xerca {{SITENAME}}",
+       "tooltip-search-go": "Vade a un paje con esta nom esata, si lo esiste",
+       "tooltip-search-fulltext": "MediaWiki:Tooltip-xerca-testoplen/lfn",
        "tooltip-p-logo": "Visita la paje prima",
        "tooltip-n-mainpage": "Visita la paje prima",
        "tooltip-n-mainpage-description": "Visita la paje prima",
        "tooltip-n-randompage": "Carga un paje acaso",
        "tooltip-n-help": "La loca per descovre.",
        "tooltip-t-whatlinkshere": "Lista de tota pajes de vici ce lia a asi",
-       "tooltip-t-contributions": "Vide la lista de contribuis de esta usor",
+       "tooltip-t-recentchangeslinked": "Cambia resente en pajes liada de esta paje",
+       "tooltip-feed-atom": "Enflue de atom per esta paje",
+       "tooltip-t-contributions": "Vide la lista de contribuis de {{GENDER:$1|esta usor}}",
        "tooltip-t-emailuser": "Envia un eposta a esta usor",
        "tooltip-t-upload": "Envia fixes",
        "tooltip-t-specialpages": "Lista de tota pajes spesial",
+       "tooltip-t-print": "Varia primable de esta paje",
+       "tooltip-t-permalink": "Lias permanente a esta revisa de la paje",
+       "tooltip-ca-nstab-main": "Vide la paje de contenis",
        "tooltip-ca-nstab-user": "Vide la paje de usor",
+       "tooltip-ca-nstab-special": "Esta es un paje special, e no pote es editada.",
        "tooltip-ca-nstab-project": "Vide la paje de la projeta",
        "tooltip-ca-nstab-image": "Vide la paje de fix",
        "tooltip-ca-nstab-template": "Mostra la model",
        "tooltip-diff": "Mostra tu cambias de la testo.",
        "tooltip-compareselectedversions": "Vide la diferes entre la du varias elejeda de esta paje.",
        "tooltip-watch": "Junta esta paje a tu lista de pajes oservada",
+       "tooltip-rollback": "\"Rollback\" reverts the last contributor's edit(s) to this page in one click\n\n\"Reversa\" reversa la edita o editas a esta paje par la contribuor presedente con un clica",
+       "tooltip-undo": "\"Desfa\" reversa esta edita e abri la forma de edita en la modo de previde. Lo permete la ajunta de un razona en la resoma.",
+       "tooltip-summary": "Entra un resoma corta",
        "others": "otras",
+       "simpleantispam-label": "Proba anti-spam.\n<strong>No</strong> completa esta!",
+       "pageinfo-toolboxlink": "Informa de paje",
        "previousdiff": "← Difere plu vea",
        "nextdiff": "Difere plu nova →",
        "widthheightpage": "$1 × $2, $3 {{PLURAL:$3|paje|pajes}}",
        "file-info-size": "$1 × $2 pixel, grandia de fix: $3, MIME tipo: $4",
        "file-nohires": "No plu densia posable.",
        "svg-long-desc": "SVG fix, per nom $1 × $2 pixeles, grandia de fix: $3",
-       "show-big-image": "Densia masima",
+       "show-big-image": "Arcivo orijinal",
+       "show-big-image-preview": "Grandia de esta previde: $1",
+       "show-big-image-other": "Otra {{PLURAL:$2|densia|densias}}: $1.",
+       "show-big-image-size": "$1 × $2 pixeles",
        "newimages": "Imajes nova",
        "ilsubmit": "Xerca",
        "bad_image_list": "La forma es la seguente:\n\nSola linias de un lista (ce comensa con *) es considerada.\nLa lia prima a la linia nesesa es un lia a un mal fix.\nCada lias seguente a la mesma linia es considerada es esetas, ce es, la pajes do la fix pote aveni enlinia.",
        "metadata-help": "Esta fix conteni plu informa, posable juntada de un camera dijital o un scanador usada per crea o dijiti el.\nSi la fix ia es cambiada de se stato orijinal, alga detalias pote no es clara en la fix cambiada.",
        "metadata-expand": "Mostra detalias estendente",
        "metadata-collapse": "Asconde detalias estendeda",
-       "metadata-fields": "Campos de EXIF metadata listada en esta mesaje va es inclui cuando la table de metadata es minimida.\n* make\n* model\n* datetimeoriginal\n* exposuretime\n* fnumber\n* isospeedratings\n* focallength\n* artist\n* copyright\n* imagedescription\n* gpslatitude\n* gpslongitude\n* gpsaltitude",
+       "metadata-fields": "Campos de EXIF metadata listada en esta mesaje va es incluida cuando la table de metadata es minimida.\n* make\n* model\n* datetimeoriginal\n* exposuretime\n* fnumber\n* isospeedratings\n* focallength\n* artist\n* copyright\n* imagedescription\n* gpslatitude\n* gpslongitude\n* gpsaltitude",
+       "exif-orientation": "Orienta",
+       "exif-xresolution": "Densia orizonal",
+       "exif-yresolution": "Densia vertical",
+       "exif-datetime": "Data e ora de cambia de fix",
+       "exif-make": "Fabricor de camera",
+       "exif-model": "Model de camera",
+       "exif-software": "Programas usada",
+       "exif-exifversion": "Varia de Exif",
+       "exif-colorspace": "Spasio de color",
+       "exif-datetimeoriginal": "Data e ora de jenera de datos",
+       "exif-datetimedigitized": "Data e ora de dijitali",
        "exif-exposuretime-format": "$1 sec. ($2)",
+       "exif-orientation-1": "Normal",
        "namespacesall": "tota",
        "monthsall": "tota",
        "confirm_purge_button": "Oce",
        "watchlisttools-view": "Vide cambias pertinente",
        "watchlisttools-edit": "Vide e edita la lista de pajes oservada",
        "watchlisttools-raw": "Edita la lista rua de pajes oservada",
+       "signature": "[[{{ns:user}}:$1|$2]] ([[{{ns:user_talk}}:$1|discute]])",
        "version": "Varia",
        "version-version": "($1)",
        "fileduplicatesearch-submit": "Xerca",
        "specialpages": "Pajes spesial",
+       "tag-filter": "Filtre de [[Special:Tags|eticeta]]:",
+       "tag-list-wrapper": "([[Special:Tags|{{PLURAL:$1|Tag|Tags}}]]: $2)",
+       "logentry-delete-delete": "$1 {{GENDER:$2|sutraeda}} paje $3",
+       "logentry-move-move": "$1 {{GENDER:$2|moveda}} paje $3 a $4",
+       "logentry-newusers-create": "Conta de usor $1 ia es {{GENDER:$2|creada}}",
+       "logentry-upload-upload": "$1 {{GENDER:$2|cargada}} $3",
+       "searchsuggest-search": "Xerca {{SITENAME}}",
        "expand_templates_ok": "Oce"
 }
index 54bd07e..d5033a8 100644 (file)
        "searcharticle": "Vanni",
        "history": "Stöia da pàgina",
        "history_short": "Stöia",
+       "history_small": "Stoia",
        "updatedmarker": "modificâ da-a mæ urtima vixita",
        "printableversion": "Verscion da stanpâ",
        "permalink": "Ingancio fisso",
        "blockedtitle": "L'utente o l'é bloccòu",
        "blockedtext": "''''O to nomme utente ò adresso IP o l'è stæto bloccòu.'''\n\nO blòcco o l'è stæto fæto da $1. A raxon dæta a l'è ''$2''.\n\n* Prinçippio do blocco: $8\n* Fin do blocco: $6\n* Utente blocou: $7\n\nL'è poscibbile contattâ $1 ò un atro [[{{MediaWiki:Grouppage-sysop}}|amministratô]] pe discûtte inscio blòcco.\nNo ti poeu doeuviâ o comando \"Manda un'e-mail a st'utente\" se no ti g'hæ 'n adreçço e-mail registròu inte to [[Special:Preferences|preferençe]] e se no t'ê stæto bloccòu ascì.\nO to adreçço IP o l'è $3, e o to blòcco ID o l'è #$5.\nPe piaxei, pe domandâ de informaçioin, speçifficali tutti doî.",
        "autoblockedtext": "O teu addresso IP o l'è stæto bloccòu outomaticamente perché o l'ea za usòu da 'n âtro utente, bloccòu da $1.\nA raxon dæta a l'è stæta:\n\n:''$2''\n\n* Prinsippio do blòcco: $8\n* Fin do blòcco: $6\n\nTi peu contattâ $1 ò un âtro\n[[{{MediaWiki:Grouppage-sysop}}|amministratô]] pe discutte o blòcco.\n\nDanni a mente a che no ti pêu ûsâ o comando \"manda 'na e-mail a sto utente\" se non ti g'hæ 'n addresso de posta elettronega registròu in te têu [[Special:Preferences|preferense]] e se ti no t'ê stæto bloccòu ascì.\n\nO to adresso IP o l'è $3, e o to blòcco ID o l'è #$5. Pe piaxei, pe domandâ informaçioin, speçifficali tutti doî.",
+       "systemblockedtext": "O to nomme utente ò l'adresso IP o l'è stæto blocou aotomaticamente da MediaWiki.\nA raxon do blocco a l'è:\n\n:''$2''\n\n* Començo do blocco: $8\n* Scadença do blocco: $6\n* Intervallo de blocco: $7\n\nL'adresso IP attoale o l'è $3.\nSe prega de specificâ tutti i dettalli chì incluxi into compilâ qualunque recesta de ciarimenti.",
        "blockednoreason": "nisciun-a motivaçion dæta",
        "whitelistedittext": "Pe modificâ e paggine l'è necessaio $1.",
        "confirmedittext": "Pe ese abilitæ a-a modiffica de paggine bezeugna confermâ o proppio addresso e-mail. Pe impostâ e confermâ l'adresso servîse de [[Special:Preferences|preferençe]].",
        "saveprefs": "Sarva",
        "restoreprefs": "Ripristina e impostaçioin predefinie (in tutte e seçioin)",
        "prefs-editing": "Cangia",
-       "rows": "Righe:",
-       "columns": "Colonne:",
        "searchresultshead": "Çerca",
        "stub-threshold": "Limmite pe-i collegamenti a-i sboççi ($1):",
        "stub-threshold-sample-link": "esempio",
        "userrights-user-editname": "Scrivi o teu nomme utente:",
        "editusergroup": "Carrega groppi utente",
        "editinguser": "Apreuvo a cangiâ i driti de l'{{GENDER:$1|utente}} <strong>[[User:$1|$1]]</strong> $2",
+       "viewinguserrights": "Vixualizaçion di driti de l'{{GENDER:$1|utente}} <strong>[[User:$1|$1]]</strong> $2",
        "userrights-editusergroup": "Modiffica i gruppi di utenti",
+       "userrights-viewusergroup": "Vixualizza groppi utente",
        "saveusergroups": "Sarva groppi {{GENDER:$1|utente}}",
        "userrights-groupsmember": "Membro de:",
        "userrights-groupsmember-auto": "Membro impliçito de:",
        "userrights-nodatabase": "O database $1 o no l'esiste ò o no l'è un database locale.",
        "userrights-changeable-col": "Gruppi che ti peu modificâ",
        "userrights-unchangeable-col": "Gruppi che no ti peu modificâ",
+       "userrights-expiry-current": "O descazze o $1",
+       "userrights-expiry-none": "O no descazze",
+       "userrights-expiry": "O descazze:",
        "userrights-conflict": "Conflito de modiffica di driti utente! Pe piaxei controlla e conferma e teu modiffiche.",
        "group": "Gruppo:",
        "group-user": "Ûtenti",
        "feedback-useragent": "Agente utente:",
        "searchsuggest-search": "Çerca in {{SITENAME}}",
        "searchsuggest-containing": "ch'o conten...",
-       "api-error-autoblocked": "O to adreçço IP o l'è stæto bloccou aotomaticamente, perché o l'è stæto doeuviou da un utente bloccou.",
-       "api-error-badaccess-groups": "No t'ê aotorizzou a caregâ di file insce questa wiki.",
        "api-error-badtoken": "Errô interno: token errou.",
-       "api-error-blocked": "T'ê stæto bloccou, no ti poeu fâ modiffiche.",
-       "api-error-copyuploaddisabled": "O caregamento trammite URL o l'è disabilitou insce questo server.",
-       "api-error-duplicate": "Gh'è za {{PLURAL:$1|un atro file|di atri files}} into scito co-o mæximo contegnuo.",
-       "api-error-duplicate-archive": "Gh'ea za {{PLURAL:$1|un atro file|di ltri file}} into scito co-o mæximo contegnuo, ma {{PLURAL:$1|o l'è stæto scassou|son stæti scassæ}}.",
-       "api-error-empty-file": "O file che t'hæ inviou o l'è voeuo.",
        "api-error-emptypage": "A creaçion de noeuve pagine voeue a no l'è consentia.",
-       "api-error-fetchfileerror": "Errô interno: s'è verificou un problema durante o recuppero do file.",
-       "api-error-fileexists-forbidden": "Un file de nomme \"$1\" o l'existe za e o no poeu ese sorvescrito.",
-       "api-error-fileexists-shared-forbidden": "Un file de nomme \"$1\" o l'existe za into repository condiviso e o no poeu ese sorvescrito.",
-       "api-error-file-too-large": "O file che t'hæ inviou o l'ea troppo grande.",
-       "api-error-filename-tooshort": "O nomme do file o l'è troppo curto.",
-       "api-error-filetype-banned": "Questo tipo de file o l'è proibio.",
-       "api-error-filetype-banned-type": "\"$1\" {{PLURAL:$4|o no l'è un tipo de file consentio|no son di tipi de file consentii}}. {{PLURAL:$3|O tipo de file consentio o l'è|I tipi de file consentii son}} $2.",
-       "api-error-filetype-missing": "A-o file gh'amanca l'estenscion.",
-       "api-error-hookaborted": "A modiffica che t'hæ çercou de fâ a l'è stæta interrotta da un'estenscion.",
-       "api-error-http": "Errô interno: imposcibbile connettise a-o server.",
-       "api-error-illegal-filename": "O nomme do file o no l'è ammisso.",
-       "api-error-internal-error": "Errô interno: quarcosa o l'è anæto storto con l'elaboaçion do to caregamento in sciâ wiki.",
-       "api-error-invalid-file-key": "Errô interno: file non presente inta cartella di file temporannei.",
-       "api-error-missingparam": "Errô interno: parammetri da recesta mancanti.",
-       "api-error-missingresult": "Errô interno: imposcibbile determinâ se a coppia a l'è ariescîa.",
-       "api-error-mustbeloggedin": "Pe caregâ di file ti devi primma intrâ.",
-       "api-error-mustbeposted": "Errô interno: a recesta a richiede HTTP POST.",
-       "api-error-noimageinfo": "O caregamento o l'è ariescio, ma o server o no n'ha dæto arcun-a informaçion  in sciô file.",
-       "api-error-nomodule": "Errô interno: no l'è stæto impostou o moddulo de caregamento.",
-       "api-error-ok-but-empty": "Errô interno: nisciun-a risposta da-o server.",
-       "api-error-overwrite": "No l'è permisso soviascrive un file existente.",
-       "api-error-ratelimited": "Ti çerchi de caregâ ciù file in meno tempo de quante questo wiki o permette.\nRiproeuva tra pochi menuti.",
-       "api-error-stashfailed": "Errô interno: o server o no l'è ariescio a memorizzâ o documento temporannio.",
        "api-error-publishfailed": "Errô interno: o server o no l'è ariescio a pubbricâ o documento temporannio.",
-       "api-error-stasherror": "S'è veificou un errô durante o caregamento do file inta stash.",
-       "api-error-stashedfilenotfound": "O file inta stash o no l'è stæto trovou durante o tentativo de caregâ da-a stash.",
-       "api-error-stashpathinvalid": "O percorso ch'o l'aviæ dovuo portâ a-o file inta stash o no l'ea vallido.",
-       "api-error-stashfilestorage": "S'è veificou un errô durante a memorizzaçion do file inta stash.",
-       "api-error-stashzerolength": "O server o no poeu insei o file inta stash, perché o g'ha longheçça zero.",
-       "api-error-stashnotloggedin": "Pe poei sarvâ di file inta stash de caregamento ti devi primma intrâ.",
-       "api-error-stashwrongowner": "O file a-o quæ ti çercavi d'accede inta stash o no t'apparten.",
-       "api-error-stashnosuchfilekey": "A ciave do file a-a quæ ti çercavi d'accede inta stash a no l'existe.",
-       "api-error-timeout": "O server o no l'ha risposto entro o tempo previsto.",
-       "api-error-unclassified": "Gh'è stæto un aro sconosciuo.",
-       "api-error-unknown-code": "Errô sconosciuo: \"$1\"",
-       "api-error-unknown-error": "Errô interno: quarcosa l'è anæto storto provando a caregâ o file.",
+       "api-error-stashfailed": "Errô interno: o server o no l'è ariescio a memorizzâ o documento temporannio.",
        "api-error-unknown-warning": "Avviso sconosciuo: $1",
        "api-error-unknownerror": "Errô sconosciuo: \"$1\"",
-       "api-error-uploaddisabled": "O caregamento o l'è disabilitou insce questa wiki.",
-       "api-error-verification-error": "Questo file o poriæ ese dannezou, o aveighe l'estenscion sbaliâ.",
-       "api-error-was-deleted": "Un file co-o mæximo nomme o l'è stæto precedentemente caregou e succescivamente eliminou.",
        "duration-seconds": "$1 {{PLURAL:$1|segondo|segondi}}",
        "duration-minutes": "$1 {{PLURAL:$1|menuto|menuti}}",
        "duration-hours": "$1 {{PLURAL:$1|oa|oe}}",
index 0d17e88..b08935b 100644 (file)
        "right-managechangetags": "ایجاد و حذف [[Special:Tags|برچسب‌ها]] از پایگاه داده",
        "right-applychangetags": "تائید [[Special:Tags|برچسب]] بر روی تغییرات یک نفر",
        "right-changetags": "افزودن یا حذف [[Special:Tags|برچسب]] قراردادی بر روی نسخه یا سیاهه ورودی‌ها",
+       "right-deletechangetags": "[[Special:Tags|tags]] را اژ پایگاه پاک بکه",
        "grant-generic": "حقوق \"$1\" بسته",
        "grant-group-page-interaction": "تعاول با صفحه",
        "grant-group-file-interaction": "تعامل با میدیا",
index 11a567f..1def888 100644 (file)
        "userrights-nodatabase": "Duomenų bazė $1 neegzistuoja arba yra ne vietinė.",
        "userrights-changeable-col": "Grupės, kurias galite keisti",
        "userrights-unchangeable-col": "Grupės, kurių negalite keisti",
+       "userrights-expiry-current": "Baigiasi $1",
+       "userrights-expiry-none": "Nesibaigia",
+       "userrights-expiry": "Baigiasi:",
+       "userrights-expiry-othertime": "Kitas laikas:",
        "userrights-conflict": "Naudotojo teisių konfliktas! Prašome dar kartą taikyti savo keitimus.",
        "group": "Grupė:",
        "group-user": "Naudotojai",
        "recentchanges-legend-heading": "<strong>Paaiškinimai:</strong>",
        "recentchanges-legend-newpage": "{{int:recentchanges-label-newpage}} (taip pat žiūrėkite [[Special:NewPages|naujausių straipsnių sąrašą]])",
        "recentchanges-submit": "Rodyti",
+       "rcfilters-activefilters": "Aktyvūs filtrai",
+       "rcfilters-clear-all-filters": "Valyti visus filtrus",
+       "rcfilters-invalid-filter": "Negalimas filtras",
+       "rcfilters-filterlist-title": "Filtrai",
+       "rcfilters-filterlist-noresults": "Nerastas toks filtras",
        "rcfilters-filtergroup-registration": "Vartotojo registracija",
+       "rcfilters-filter-registered-label": "Registruoti",
+       "rcfilters-filter-unregistered-label": "Neregistruoti",
+       "rcfilters-filter-editsbyself-label": "Jūsų keitimai",
+       "rcfilters-filter-editsbyself-description": "Jūsų keitimai.",
+       "rcfilters-filter-editsbyother-label": "Kitų keitimai",
        "rcfilters-filter-editsbyother-description": "Kaitimai sukurti kitų vartotojų (ne jūsų).",
+       "rcfilters-filtergroup-userExpLevel": "Patirties lygis (tik registruotiems vartotojams)",
+       "rcfilters-filter-userExpLevel-newcomer-label": "Naujokai",
+       "rcfilters-filter-userExpLevel-learner-label": "Mokiniai",
+       "rcfilters-filter-userExpLevel-experienced-label": "Patyrę vartotojai",
+       "rcfilters-filter-userExpLevel-experienced-description": "Daugiau nei 30 dienų veiklos ir 500 keitimų.",
+       "rcfilters-filter-bots-label": "Robotas",
+       "rcfilters-filter-bots-description": "Keitimai, atlikti automatinių įrankių.",
+       "rcfilters-filter-humans-label": "Žmogaus (ne roboto)",
        "rcfilters-filter-humans-description": "Keitimai atlikti žmonių.",
+       "rcfilters-filtergroup-significance": "Reikšmė",
+       "rcfilters-filter-minor-label": "Smulkūs pakeitimai",
        "rcfilters-filter-minor-description": "Keitimai, kuriuos autorius pažymėjo kaip mažus.",
+       "rcfilters-filter-major-label": "Nesmulkūs pakeitimai",
+       "rcfilters-filter-major-description": "Keitimai, nepažymėti kaip smulkūs.",
        "rcfilters-filtergroup-changetype": "Pakeitimo tipas",
+       "rcfilters-filter-pageedits-label": "Puslapių keitimai",
+       "rcfilters-filter-newpages-label": "Puslapių sukūrimai",
+       "rcfilters-filter-newpages-description": "Keitimai, kurie sukuria naujus puslapius.",
        "rcfilters-filter-categorization-label": "Kategorijų pakeitimai",
        "rcfilters-filter-categorization-description": "Įrašai puslapių, kurie yra pridedami ar pašalinami iš kategorijų.",
        "rcnotefrom": "Žemiau yra {{PLURAL:$5|pakeitimas|pakeitimai}} pradedant <strong>$3, $4</strong> (rodoma iki <strong>$1</strong> pakeitimų).",
        "proxyblockreason": "Jūsų IP adresas yra užblokuotas, nes jis yra atvirasis tarpinis serveris. Prašome susisiekti su savo interneto paslaugų tiekėju ar technine pagalba ir praneškite jiems apie šią svarbią saugumo problemą.",
        "sorbsreason": "Jūsų IP adresas yra įtrauktas į atvirųjų tarpinių serverių DNSBL sąrašą, naudojamą šios svetainės.",
        "sorbs_create_account_reason": "Jūsų IP adresas yra įtrauktas į atvirųjų tarpinių serverių DNSBL sąrašą, naudojamą šios svetainės. Jūs negalite sukurti paskyros",
+       "softblockrangesreason": "Anoniminiai įnašai nėra leidžiami iš jūsų IP adreso ($1). Prašome prisijungti.",
        "xffblockreason": "IP adresas esantys X-Forwarded-For antraštėje, jūsų ar tarpinio serverio, kuriuo jūs naudojatės, buvo užblokuotas. Originali bloko priežastis buvo: $1",
        "cant-see-hidden-user": "Naudotojas, kurį bandote užblokuoti, jau yra užblokuotas arba paslėptas.\nKadangi jūs neturi hideuser teisės, jūs negalite pamatyti arba pakeisti naudotojo blokavimo.",
        "ipbblocked": "Jūs negalite blokuoti ar atblokuoti kitų naudotojų, nes pats esate užblokuotas",
        "logentry-tag-update-logentry": "$1 {{GENDER:$2|atnaujino}} žymes $3 puslapio žurnalo įraše $5 ({{PLURAL:$7|pridėtas}} $6; {{PLURAL:$9|pašalintas}} $8)",
        "rightsnone": "(jokių)",
        "revdelete-summary": "keitimo paaiškinimas",
+       "rightslogentry-temporary-group": "$1 (laikinai, iki $2)",
        "feedback-adding": "Pridedamas atsiliepimas į puslapį ...",
        "feedback-back": "Atgal",
        "feedback-bugcheck": "Puiku! Tiesiog patikrinkite, ar tai ne viena [$1 jau žinomų klaidų].",
        "pagelang-language": "Kalba",
        "pagelang-use-default": "Naudoti numatytąją kalbą",
        "pagelang-select-lang": "Pasirinkite kalbą",
+       "pagelang-reason": "Priežastis",
        "pagelang-submit": "Pateikti",
+       "pagelang-nonexistent-page": "Puslapis $1 neegzistuoja.",
+       "pagelang-db-failed": "Duomenų bazei nepavyko pakeisti puslapio kalbos.",
        "right-pagelang": "Keisti puslapio kalbą",
        "action-pagelang": "keisti puslapio kalbą",
        "log-name-pagelang": "Kalbos keitimų žurnalas",
index 64d015a..06536c9 100644 (file)
        "monday-at": "Pirmdiena $1",
        "bad_image_list": "Formāts:\n\nTiek ņemti vērā tikai ieraksti rindiņā kas sākas ar *\nPirmajai saitei rindiņā ir jābūt uz attiecīgo failu\nJebkuras sekojošas saites tiks uzskatītas par izņēmumiem t.i. lapām kurās fails drīkt tikt izmantots",
        "metadata": "Metadati",
-       "metadata-help": "Šis fails satur papildu informāciju, kuru visticamk ir pievienojis digitālais fotoaparāts vai skeneris, kas šo failu izveidoja. Ja šis fails pēc tam ir ticis modificēts, šie dati var neatbilst izmaiņām (var būt novecojuši).",
+       "metadata-help": "Šis fails satur papildu informāciju, kuru visticamāk ir pievienojis digitālais fotoaparāts vai skeneris, kas šo failu izveidoja. Ja šis fails pēc tam ir ticis modificēts, šie dati var neatbilst izmaiņām (var būt novecojuši).",
        "metadata-expand": "Parādīt papildu detaļas",
        "metadata-collapse": "Paslēpt papildu detaļas",
        "metadata-fields": "Šajā paziņojumā esošie metadatu lauki būs redzami attēla lapā arī tad, kad metadatu tabula būs sakļauta.\nPārējie lauki, pēc noklusējuma, būs paslēpti.\n* make\n* model\n* datetimeoriginal\n* exposuretime\n* fnumber\n* isospeedratings\n* focallength\n* artist\n* copyright\n* imagedescription\n* gpslatitude\n* gpslongitude\n* gpsaltitude",
index 10969a8..1755524 100644 (file)
        "youremail": "Е-пошта:",
        "username": "{{GENDER:$1|Корисничко име}}:",
        "prefs-memberingroups": "{{GENDER:$2|Член}} на {{PLURAL:$1|групата|групите}}:",
+       "group-membership-link-with-expiry": "$1 (до $2)",
        "prefs-registration": "Време на регистрација:",
        "yourrealname": "Вистинско име:",
        "yourlanguage": "Јазик:",
        "userrights-changeable-col": "Групи кои може да ги промените",
        "userrights-unchangeable-col": "Групи кои не може да ги промените",
        "userrights-irreversible-marker": "$1*",
+       "userrights-expiry-current": "Истекува $1",
+       "userrights-expiry-none": "Не истекува",
+       "userrights-expiry": "Истекува:",
+       "userrights-expiry-existing": "Постоечки рок на истекување: $3, $2",
+       "userrights-expiry-othertime": "Друго време:",
+       "userrights-expiry-options": "1 ден:1 day,1 недела:1 week,1 месец:1 month,3 месеци:3 months,6 месеци:6 months,1 година:1 year",
+       "userrights-invalid-expiry": "Истекот за групата „$1“ е неважечки.",
+       "userrights-expiry-in-past": "Истекот за групата „$1“ е во минатото.",
        "userrights-conflict": "Спротиставеност во измените на корисничките права. Прегледајте ги и потврдете ги.",
        "group": "Група:",
        "group-user": "Корисници",
        "recentchanges-legend-plusminus": "(''±123'')",
        "recentchanges-submit": "Прикажи",
        "rcfilters-activefilters": "Активни филтри",
+       "rcfilters-restore-default-filters": "Поврати основни филтри",
+       "rcfilters-clear-all-filters": "Тргни ги сите филтри",
        "rcfilters-search-placeholder": "Филтрирај скорешни промени (прелстајте или почнете да пишувате)",
        "rcfilters-invalid-filter": "Неважечки филтер",
+       "rcfilters-empty-filter": "Нема активни филтри. Прикажани се сите придонеси.",
        "rcfilters-filterlist-title": "Филтри",
        "rcfilters-filterlist-noresults": "Не пронајдов ниеден филтер",
        "rcfilters-filtergroup-registration": "Регистрација на корисници",
        "apisandbox-sending-request": "Испраќам барање до извршникот...",
        "apisandbox-loading-results": "Добивам исход од извршникот...",
        "apisandbox-results-error": "Се појави грешка при вчитувањето на одговорот од барањето до извршникот: $1.",
-       "apisandbox-request-params-json": "JSON-параметри:",
+       "apisandbox-request-selectformat-label": "Прикажи ги побараните податоци како:",
+       "apisandbox-request-format-url-label": "URL-низа на барањето",
        "apisandbox-request-url-label": "URL на барањето:",
+       "apisandbox-request-json-label": "Побарај JSON:",
        "apisandbox-request-time": "Време за барањето: {{PLURAL:$1|$1 милисекунда|$1 милисекунди}}",
        "apisandbox-results-fixtoken": "Исправи ја шифрата и поднеси одново",
        "apisandbox-results-fixtoken-fail": "Не успеав да ја добијам шифрата „$1“.",
        "emailccsubject": "Копија од вашата порака до $1: $2",
        "emailsent": "Писмото е испратено",
        "emailsenttext": "Писмото е испратено.",
-       "emailuserfooter": "$1 го испрати писмово на {{GENDER:$2|$2}} со помош на функцијата „{{int:emailuser}}“ на {{SITENAME}}. {{GENDER:$2|Вашата}} е-пошта ќе му биде испратена право на {{GENDER:$1|изворниот испраќач}}, откривајќи {{GENDER:$1|му}} ја {{GENDER:$2|вашата}} адреса.",
+       "emailuserfooter": "$1 го испрати писмово на {{GENDER:$2|$2}} со помош на функцијата „{{int:emailuser}}“ на {{SITENAME}}. Ако {{GENDER:$2|одговорите}} на ова писмо, {{GENDER:$2|Вашата}} е-пошта ќе му биде испратена право на {{GENDER:$1|изворниот испраќач}}, откривајќи {{GENDER:$1|му}} ја {{GENDER:$2|вашата}} адреса.",
        "usermessage-summary": "Оставете системска порака.",
        "usermessage-editor": "Системски гласник",
        "usermessage-template": "MediaWiki:КорисникПорака",
        "logentry-tag-update-logentry": "$1 {{GENDER:$2|поднови}} ознаки во дневничкиот запис $5 на страницата $3 ({{PLURAL:$7|додадена|додадени}} $6; {{PLURAL:$9|отстранета|отстранети}} $8)",
        "rightsnone": "(нема)",
        "revdelete-summary": "опис на уредување",
+       "rightslogentry-temporary-group": "$1 (привремено, до $2)",
        "feedback-adding": "Го додавам искажаното мислење во страницата...",
        "feedback-back": "Назад",
        "feedback-bugcheck": "Одлично! Само проверете да не е една од [$1 веќе познатите грешки].",
index 887d754..dc267a8 100644 (file)
@@ -30,7 +30,8 @@
                        "아라",
                        "Viswaprabha",
                        "Nesi",
-                       "Macofe"
+                       "Macofe",
+                       "Jameela P."
                ]
        },
        "tog-underline": "കണ്ണികൾക്ക് അടിവരയിടുക:",
        "recentchanges-legend-heading": "<strong>സൂചന:</strong>",
        "recentchanges-legend-newpage": "{{int:recentchanges-label-newpage}} ([[Special:NewPages|പുതിയ താളുകളുടെ പട്ടികയും]] കാണുക)",
        "recentchanges-submit": "പ്രദർശിപ്പിക്കുക",
+       "rcfilters-filterlist-title": "അരിപ്പകൾ",
+       "rcfilters-filter-userExpLevel-newcomer-label": "പുതിയ അംഗങ്ങളുടെ തിരുത്തലുകൾ",
+       "rcfilters-filter-bots-label": "യന്ത്രം",
+       "rcfilters-filter-minor-label": "ചെറുതിരുത്തുകൾ",
        "rcnotefrom": "<strong>$3, $4</strong> മുതലുള്ള {{PLURAL:$5|മാറ്റം|മാറ്റങ്ങൾ}} ആണ് താഴെയുള്ളത്  (<strong>$1</strong> എണ്ണം വരെ കൊടുക്കുന്നതാണ്).",
        "rclistfrom": "$3 $2 മുതലുള്ള മാറ്റങ്ങൾ പ്രദർശിപ്പിക്കുക",
        "rcshowhideminor": "ചെറുതിരുത്തലുകൾ $1",
        "feedback-useragent": "യൂസർ ഏജന്റ്:",
        "searchsuggest-search": "തിരയുക",
        "searchsuggest-containing": "ഉൾപ്പെടുന്നവ...",
-       "api-error-badaccess-groups": "ഈ വിക്കിയിൽ പ്രമാണങ്ങൾ അപ്‌ലോഡ് ചെയ്യാൻ താങ്കൾക്കനുവാദമില്ല.",
        "api-error-badtoken": "ആന്തരിക പിഴവ്: ഗുണകരമല്ലാത്ത ചീട്ട്.",
-       "api-error-copyuploaddisabled": "യൂ.ആർ.എൽ. ഉപയോഗിച്ചുള്ള അപ്‌ലോഡ് ഈ സെർവറിൽ പ്രവർത്തനസജ്ജമാക്കിയിട്ടില്ല.",
-       "api-error-duplicate": "വിക്കിയിൽ ഇതേ ഉള്ളടക്കമുള്ള {{PLURAL:$1|മറ്റൊരു പ്രമാണം|മറ്റ് പ്രമാണങ്ങൾ}} മുമ്പേയുണ്ട്.",
-       "api-error-duplicate-archive": "സൈറ്റിൽ ഇതേ ഉള്ളടക്കമുള്ള {{PLURAL:$1|മറ്റൊരു പ്രമാണം|മറ്റ് പ്രമാണങ്ങൾ}} ഉണ്ടായിരുന്നു, പക്ഷേ {{PLURAL:$1|അത്|അവ}} മായ്ക്കപ്പെട്ടിട്ടുണ്ട്.",
-       "api-error-empty-file": "താങ്കൾ സമർപ്പിച്ച പ്രമാണം ശൂന്യമാണ്.",
        "api-error-emptypage": "ശൂന്യമായ പുതിയ താളുകൾ സൃഷ്ടിക്കുന്നത് അനുവദിക്കുന്നില്ല.",
-       "api-error-fetchfileerror": "ആന്തരിക പിഴവ്: പ്രമാണം ശേഖരിച്ചുകൊണ്ടിരുന്നപ്പോൾ എന്തോ പിഴവുണ്ടായി.",
-       "api-error-fileexists-forbidden": "\"$1\" എന്ന പേരിൽ ഒരു പ്രമാണം മുമ്പേയുണ്ട്, അതിന്റെ മുകളിലായി സൃഷ്ടിക്കാനാകില്ല.",
-       "api-error-fileexists-shared-forbidden": "\"$1\" എന്ന പേരിൽ ഒരു പ്രമാണം പങ്ക് വെച്ചുപയോഗിക്കുന്ന ശേഖരത്തിൽ മുമ്പേയുണ്ട്, അതിനു മുകളിലായി സൃഷ്ടിക്കാനാകില്ല.",
-       "api-error-file-too-large": "താങ്കൾ സമർപ്പിച്ച പ്രമാണം വളരെ വലുതാണ്.",
-       "api-error-filename-tooshort": "പ്രമാണത്തിന്റെ പേര് വളരെച്ചെറുതാണ്.",
-       "api-error-filetype-banned": "ഈ തരത്തിലുള്ള പ്രമാണങ്ങൾ നിരോധിച്ചിരിക്കുന്നു.",
-       "api-error-filetype-banned-type": "$1 {{PLURAL:$4|അനുവദനീയമല്ലാത്ത തരം പ്രമാണമാണ്‌|അനുവദനീയമല്ലാത്ത തരങ്ങളിലുള്ള പ്രമാണങ്ങളാണ്}}. $2 {{PLURAL:$3|തരത്തിലുള്ള പ്രമാണം|തരങ്ങളിലുള്ള പ്രമാണങ്ങൾ}} ആണ് അഭിലഷണീയം.",
-       "api-error-filetype-missing": "പ്രമാണത്തിന് എക്സ്‌റ്റെൻഷൻ ഇല്ല.",
-       "api-error-hookaborted": "താങ്കൾ വരുത്താൻ ശ്രമിച്ച മാറ്റം ഒരു അനുബന്ധത്തിന്റെ കൊളുത്തിനാൽ റദ്ദാക്കപ്പെട്ടു.",
-       "api-error-http": "ആന്തരിക പിഴവ്: സെർവറുമായി ബന്ധപ്പെടാൻ കഴിയുന്നില്ല.",
-       "api-error-illegal-filename": "പ്രമാണത്തിന്റെ പേര് അനുവദനീയമല്ല.",
-       "api-error-internal-error": "ആന്തരിക പിഴവ്: താങ്കളുടെ അപ്‌ലോഡ് കൈകാര്യം ചെയ്തപ്പോൾ എന്തോ കുഴപ്പണ്ടായി.",
-       "api-error-invalid-file-key": "ആന്തരിക പിഴവ്: താത്കാലിക സംഭരണിയിൽ നിന്ന് പ്രമാണം കണ്ടെത്താനായില്ല.",
-       "api-error-missingparam": "ആന്തരിക പിഴവ്: ഈ അഭ്യർത്ഥനയിൽ ആവശ്യമായ ചരങ്ങൾ ലഭിച്ചില്ല.",
-       "api-error-missingresult": "ആന്തരിക പിഴവ്: പകർത്തൽ വിജയകരമായിരുന്നോ എന്ന് നിർണ്ണയിക്കാനാവുന്നില്ല.",
-       "api-error-mustbeloggedin": "പ്രമാണങ്ങൾ അപ്‌ലോഡ് ചെയ്യാൻ താങ്കൾ ലോഗിൻ ചെയ്തിരിക്കണം.",
-       "api-error-mustbeposted": "ഈ സോഫ്റ്റ്‌വേറിൽ ബഗ് ഉണ്ട്; ഉപയോഗിക്കുന്നത് ശരിയായ എച്ച്.റ്റി.റ്റി.പി. രീതിയല്ല.",
-       "api-error-noimageinfo": "അപ്‌ലോഡ് വിജയകരമായിരുന്നു, പക്ഷേ സെർവർ പ്രമാണത്തെക്കുറിച്ച് യാതൊരു വിവരവും ഇവിടെ തന്നിട്ടില്ല.",
-       "api-error-nomodule": "ആന്തരിക പിഴവ്: അപ്‌ലോഡ് ഘടകം സജ്ജമാക്കിയിട്ടില്ല.",
-       "api-error-ok-but-empty": "ആന്തരിക പിഴവ്: സെർവറിൽ നിന്ന് പ്രതികരണമൊന്നും ലഭിക്കുന്നില്ല.",
-       "api-error-overwrite": "നിലവിലുള്ള പ്രമാണത്തിന്റെ മുകളിൽ സ്ഥാപിക്കൽ അനുവദിച്ചിട്ടില്ല.",
-       "api-error-stashfailed": "ആന്തരിക പിഴവ്: പ്രമാണം താത്കാലികമായി സംഭരിക്കുന്നതിൽ സെർവർ പരാജയപ്പെട്ടു.",
        "api-error-publishfailed": "ആന്തരിക പിഴവ്: താത്കാലിക പ്രമാണം പ്രസിദ്ധീകരിക്കുന്നതിൽ സെർവർ പരാജയപ്പെട്ടു.",
-       "api-error-stasherror": "പ്രമാണം സ്റ്റാഷിലേയ്ക്ക് അപ്‌ലോഡ് ചെയ്യുന്നതിനിടെ പിഴവുണ്ടായി.",
-       "api-error-timeout": "പ്രതീക്ഷിക്കപ്പെട്ട കാലാവധിക്കുള്ളിൽ സെർവർ പ്രതികരിച്ചില്ല.",
-       "api-error-unclassified": "അപരിചിതമായ പിഴവ് സംഭവിച്ചിരിക്കുന്നു",
-       "api-error-unknown-code": "അപരിചിതമായ പിഴവ്: \"$1\"",
-       "api-error-unknown-error": "ആന്തരിക പിഴവ്: പ്രമാണം അപ്‌ലോഡ് ചെയ്യാൻ ശ്രമിക്കുമ്പോൾ എന്തോ കുഴപ്പമുണ്ടായി.",
+       "api-error-stashfailed": "ആന്തരിക പിഴവ്: പ്രമാണം താത്കാലികമായി സംഭരിക്കുന്നതിൽ സെർവർ പരാജയപ്പെട്ടു.",
        "api-error-unknown-warning": "അപരിചിതമായ മുന്നറിയിപ്പ്: $1",
        "api-error-unknownerror": "അപരിചിതമായ പിഴവ്: \"$1\".",
-       "api-error-uploaddisabled": "ഈ വിക്കിയിൽ അപ്‌ലോഡിങ് പ്രവർത്തനരഹിതമാക്കിയിരിക്കുകയാണ്.",
-       "api-error-verification-error": "ഈ പ്രമാണത്തിൽ പിഴവുണ്ട്, അല്ലെങ്കിൽ തെറ്റായ എക്സ്‌റ്റെൻഷനാണുള്ളത്.",
        "duration-seconds": "{{PLURAL:$1|ഒരു സെക്കന്റ്|$1 സെക്കന്റ്}}",
        "duration-minutes": "{{PLURAL:$1|ഒരു മിനിറ്റ്|$1 മിനിറ്റ്}}",
        "duration-hours": "{{PLURAL:$1|ഒരു മണിക്കൂർ|$1 മണിക്കൂർ}}",
        "pagelang-language": "ഭാഷ",
        "pagelang-use-default": "സ്വതേയുള്ള ഭാഷ ഉപയോഗിക്കുക",
        "pagelang-select-lang": "ഭാഷ തിരഞ്ഞെടുക്കുക",
+       "pagelang-reason": "കാരണം",
        "pagelang-submit": "സമർപ്പിക്കുക",
        "right-pagelang": "താളിന്റെ ഭാഷ മാറ്റുക",
        "action-pagelang": "താളിന്റെ ഭാഷ മാറ്റുക",
index 30842e0..66b2190 100644 (file)
@@ -92,7 +92,7 @@
        "tog-ccmeonemails": "मी इतर सदस्यांना पाठविलेल्या ई-मेल च्या प्रती मलाही माझ्या ई-मेल पत्त्यावर पाठवा",
        "tog-diffonly": "निवडलेल्या आवृत्त्यांमधील बदल दाखवताना जुनी आवृत्ती दाखवू नका.",
        "tog-showhiddencats": "लपविलेले वर्ग दाखवा",
-       "tog-norollbackdiff": "दà¥\8dरà¥\81तमाà¤\98ार à¤\98à¥\87तलà¥\8dयास à¤¬à¤¦à¤² à¤µà¤\97ळा",
+       "tog-norollbackdiff": "दà¥\8dरà¥\81तमाà¤\98ार à¤\98à¥\87तलà¥\8dयास à¤«à¤°à¤\95 à¤¦à¤¾à¤\96वà¥\82 à¤¨à¤\95ा",
        "tog-useeditwarning": "जर मी संपादित करीत असलेल्या पानावरील माझे संपादिलेले बदल जतन न केल्यास मला इशारा द्या",
        "tog-prefershttps": "सनोंद प्रवेशित असतांना प्रत्येक वेळी  सुरक्षित अनुबंध वापरा",
        "underline-always": "नेहमी",
        "tagline": "{{SITENAME}} कडून",
        "help": "साहाय्य",
        "search": "शोधा",
+       "search-ignored-headings": " #<!-- leave this line exactly as it is --> <pre>\n# Headings that will be ignored by search.\n# Changes to this take effect as soon as the page with the heading is indexed.\n# You can force page reindexing by doing a null edit.\n# The syntax is as follows:\n#   * Everything from a \"#\" character to the end of the line is a comment.\n#   * Every non-blank line is the exact title to ignore, case and everything.\nReferences\nExternal links\nSee also\n #</pre> <!-- leave this line exactly as it is -->",
        "searchbutton": "शोधा",
        "go": "चला",
        "searcharticle": "जा",
        "history": "पानाचा इतिहास",
        "history_short": "इतिहास",
+       "history_small": "इतिहास",
        "updatedmarker": "माझ्या शेवटच्या भेटीनंतर अद्यतन केले",
        "printableversion": "छापण्यायोग्य आवृत्ती",
        "permalink": "शाश्वत दुवा",
        "nocookieslogin": "{{SITENAME}} सदस्यांना सनोंद-प्रवेश देतांना, त्यांच्या स्मृतिशेष (cookies) वापरते.तुम्ही स्मृतिशेष सुविधा अनुपलब्ध ठेवली आहे.स्मृतीशेष सुविधा कृपया उपलब्ध करा आणि सनोंद-प्रवेशासाठी पुन्हा प्रयत्न करा.",
        "nocookiesfornew": "हे सदस्य खाते अस्तित्वात नाही, त्यामुळे आम्ही त्याच्या स्रोताची खात्री करू शकलो नाही.\nतुमचे स्मृतिशेष उपलब्ध असण्याची खात्री करा,या पानास पुनर्भारण(रिलोड) करा  किंवा पुन्हा प्रयत्न करा.",
        "noname": "आपण वैध सदस्यनाम नमूद केले नाही.",
-       "loginsuccesstitle": "à¤\86पलà¥\8dया à¤¸à¤¨à¥\8bà¤\82द-पà¥\8dरवà¥\87शाà¤\9aà¥\80 à¤¨à¥\8bà¤\82दणà¥\80 à¤¯à¤¶à¤¸à¥\8dवà¥\80रà¥\80तà¥\8dया à¤ªà¥\82रà¥\8dण à¤\9dालà¥\80",
+       "loginsuccesstitle": "सनà¥\8bà¤\82द-पà¥\8dरवà¥\87शित",
        "loginsuccess": "'''तुम्ही {{SITENAME}} वर \"$1\" नावाने सनोंद प्रवेशित आहात.'''",
        "nosuchuser": "\"$1\" या नावाचा कोणताही सदस्य नाही.तुमचे शुद्धलेखन तपासा, किंवा [[Special:CreateAccount|नवीन खाते]] तयार करा.",
        "nosuchusershort": "\"$1\" या नावाचा सदस्य नाही. लिहीताना आपली चूक तर नाही ना झाली?",
        "newpassword": "नवीन परवलीचा शब्द:",
        "retypenew": "पुन्हा एकदा परवलीचा शब्द टंका:",
        "resetpass_submit": "परवलीचा शब्द टाका आणि सनोंद-प्रवेश करा",
-       "changepassword-success": "तà¥\81मà¤\9aा à¤ªà¤°à¤µà¤²à¥\80à¤\9aा à¤¶à¤¬à¥\8dद à¤¯à¤¶à¤¸à¥\8dवà¥\80रितà¥\8dया à¤¬à¤¦à¤²à¤²à¥\87ला à¤\86हà¥\87!",
+       "changepassword-success": "तुमचा परवलीचा शब्द बदललेला आहे!",
        "changepassword-throttled": "तुम्ही नुकतेच सनोंद- प्रवेशासाठी अनेकानेक प्रयत्न केले आहेत.\nकृपया, पुन्हा प्रयत्न करण्याआधी $1 थोडी उसंत घ्या.",
        "botpasswords": "सांगकाम्याचे परवलीचे शब्द",
        "botpasswords-summary": "<em>सांगकाम्याचे परवलीचे शब्द</em>हे त्या खात्याची मुख्य सनोंद-प्रवेश अधिकारपत्रे न वापरता, एपीआय मार्फत, सदस्य खात्याच्या प्रवेशास पोहोच देतात.सांगकाम्याचा परवलीचा शब्द वापरुन सनोंद प्रवेश केलेल्यांचे उपलब्ध सदस्य अधिकार प्रतिबंधित असू शकतात.\n\nजर आपणास कळत नसेल आपण हे कां करीत आहोत,तर आपण ते बहुतेक करावयास नको.कोणीही आपणास असे कधीही सांगु नये कि यापैकी एखादे उत्पादित करा व त्यांना द्या.",
        "watchthis": "या लेखावर लक्ष ठेवा",
        "savearticle": "हा लेख साठवा",
        "savechanges": "बदल जतन करा",
+       "publishpage": "पानाचे प्रकाशन करा",
        "publishchanges": "बदल प्रकाशित करा",
        "preview": "झलक",
        "showpreview": "झलक दाखवा",
        "right-changetags": "वैयक्तिक आवृत्त्यांना व नोंद प्रवेष्ट्यांना, आहेतुक(arbitrary) [[Special:Tags|खूणपताका]] जोडा अथवा हटवा",
        "grant-generic": "\"$1\" अधिकार गठ्ठा",
        "grant-group-email": "विपत्र पाठवा",
-       "grant-blockusers": "सदसà¥\8dयाà¤\82ना à¤ªà¥\8dरतिबà¤\82धन/अप्रतिबंधित करा",
+       "grant-blockusers": "सदसà¥\8dयाà¤\82ना à¤ªà¥\8dरतिबà¤\82धित/अप्रतिबंधित करा",
        "grant-createaccount": "खाते तयार करा",
        "grant-createeditmovepage": "पाने बनवा,संपादा व स्थानांतरण करा",
        "grant-delete": "पाने, आवृत्त्या व नोंदी वगळा",
        "grant-editinterface": "मिडियाविकि नामविश्व व सदस्यांची CSS/JS संपादा",
-       "grant-editmycssjs": "à¤\86पलà¥\87 सदस्य CSS/JavaScript संपादित करा",
+       "grant-editmycssjs": "à¤\86पलà¥\80 सदस्य CSS/JavaScript संपादित करा",
        "grant-editmyoptions": "आपला सदस्य पसंतीक्रम संपादा",
        "grant-editmywatchlist": "आपली निरीक्षणयादी संपादित करा",
        "grant-editpage": "अस्तित्वात असलेली पाने संपादा",
        "grant-highvolume": "अत्त्युच्च-जागा घेणारे संपादन",
        "grant-oversight": "सदस्य लपवा व आवृत्त्या दाबा",
        "grant-patrol": "पानांच्या बदलांवर गस्त घाला",
+       "grant-privateinfo": "वैयक्तिक माहिती बघा",
        "grant-protect": "पाने सुरक्षित किंवा असुरक्षित करा",
-       "grant-rollback": "पानाचे बदल परतवा",
+       "grant-rollback": "पानाà¤\82à¤\9aà¥\87 à¤¬à¤¦à¤² à¤ªà¤°à¤¤à¤µà¤¾",
        "grant-sendemail": "इतर सदस्यांना विपत्र पाठवा",
+       "grant-uploadeditmovefile": "संचिकांचे अपभारण, बदल व स्थानांतरण करा",
+       "grant-uploadfile": "नविन संचिका चढवा",
        "grant-basic": "मूळ अधिकार",
        "grant-viewdeleted": "वगळलेल्या संचिका व पाने बघा",
        "grant-viewmywatchlist": "आपली निरीक्षणसूची बघा",
+       "grant-viewrestrictedlogs": "प्रतिबंधित लॉग नोंदी बघा",
        "newuserlogpage": "नवीन सदस्यांची नोंद",
        "newuserlogpagetext": "ही नवीन सदस्यांची नोंद यादी आहे.",
        "rightslog": "सदस्य आधिकार नोंद",
        "action-upload_by_url": "यूआरएल वरुन संचिकेचे अपभारण करा",
        "action-writeapi": "लेखन एपीआय वापरा",
        "action-delete": "हे पान वगळा",
-       "action-deleterevision": "हे आवर्तन वगळा",
-       "action-deletedhistory": "या पानाचा वगळलेला इतिहास पहा",
+       "action-deleterevision": "आवर्तने वगळा",
+       "action-deletelogentry": "लॉग प्रविष्ट्या वगळा",
+       "action-deletedhistory": "एखाद्या पानाचा वगळलेला इतिहास पहा",
+       "action-deletedtext": "वगळलेल्या आवृत्तीतील मजकूर बघा",
        "action-browsearchive": "वगळलेली पाने शोधा",
-       "action-undelete": "वà¤\97ळà¥\8dलà¥\87लà¥\87 à¤ªà¥\83षà¥\8dठ पुनर्स्थापित करा",
-       "action-suppressrevision": "लपलà¥\87लà¥\87 à¤ªà¥\81नरावरà¥\8dतन à¤ªà¤¹à¤¾ à¤µ à¤¸à¤¦à¥\8dयसà¥\8dथितà¥\80त à¤\86णा",
+       "action-undelete": "वà¤\97ळà¥\8dलà¥\87लà¥\8dया à¤ªà¤¾à¤¨à¤¾à¤\82à¤\9aà¥\80 पुनर्स्थापित करा",
+       "action-suppressrevision": "लपविलà¥\87लà¥\8dया à¤\86वà¥\83तà¥\8dतà¥\8dया à¤ªà¤¹à¤¾ à¤µ à¤ªà¥\81नरà¥\8dसà¥\8dथापित à¤\95रा",
        "action-suppressionlog": "ही खासगी नोंद पहा",
        "action-block": "या सदस्यास संपादन करण्यापासून प्रतिबंधित करा",
        "action-protect": "या पानाचा सुरक्षास्तर बदला",
        "action-userrights-interwiki": "इतर विकिंवरच्या सदस्यांचे अधिकार संपादित करा",
        "action-siteadmin": "माहितीसाठ्याला कुलूप लावा अथवा काढा",
        "action-sendemail": "विपत्रे (ई-मेल्स) पाठवा.",
+       "action-editmyoptions": "आपल्या स्वत:चा 'पसंतीक्रम' संपादा",
        "action-editmywatchlist": "'माझी निरीक्षणसूची' संपादा",
        "action-viewmywatchlist": "'माझी निरीक्षणसूची' बघा",
        "action-viewmyprivateinfo": "आपली वैयक्तिक माहिती बघा",
        "action-editmyprivateinfo": "आपली वैयक्तिक माहिती संपादा",
        "action-editcontentmodel": "पानाचा आशय नमूना संपादा",
-       "action-managechangetags": "डाà¤\9fाबà¥\87समधà¥\8dयà¥\87 à¤\96à¥\82णपतà¤\95ा à¤¤à¤¯à¤¾à¤° à¤\95रा à¤\95िà¤\82वा à¤µà¤\97ळा",
+       "action-managechangetags": "à¤\96à¥\82णपताà¤\95ा à¤¤à¤¯à¤¾à¤° à¤\95रा à¤\95िà¤\82वा (à¤\85)सà¤\95à¥\8dरिय à¤\95रा",
        "action-applychangetags": "आपल्या बदलांसोबतच खूणपताका जोडा",
        "action-changetags": "वैयक्तिक आवृत्त्यांना व नोंद प्रवेष्ट्यांना, आहेतुक(arbitrary) खूणपताका जोडा अथवा हटवा",
+       "action-deletechangetags": "डाटाबेसमधून खूणपताका वगळा",
+       "action-purge": "या पानास तरोताजे (पर्ज) करा",
        "nchanges": "$1 {{PLURAL:$1|बदल}}",
        "enhancedrc-since-last-visit": "$1 {{PLURAL:$1|मागील भेटीनंतर}}",
        "enhancedrc-history": "इतिहास",
        "recentchanges-legend-newpage": "{{int:recentchanges-label-newpage}} ([[Special:NewPages|नविन पानांची यादी]] हेही पाहा)",
        "recentchanges-legend-plusminus": "(''±१२३'')",
        "recentchanges-submit": "दाखवा",
+       "rcfilters-activefilters": "सक्रिय गाळण्या",
+       "rcfilters-search-placeholder": "अलीकडील बदल गाळा (न्याहाळा किंवा टंकन सुरू करा)",
+       "rcfilters-invalid-filter": "अवैध गाळणी",
+       "rcfilters-filterlist-title": "गाळण्या",
+       "rcfilters-filterlist-noresults": "कोणतीच गाळणी सापडली नाही",
+       "rcfilters-filtergroup-registration": "सदस्य नोंदणी",
+       "rcfilters-filter-registered-label": "नोंदणीकृत",
+       "rcfilters-filter-registered-description": "प्रवेशलेले सदस्य",
+       "rcfilters-filter-unregistered-label": "अ-नोंदणीकृत",
+       "rcfilters-filter-unregistered-description": "संपादक जे प्रवेशित नाहीत.",
+       "rcfilters-filtergroup-authorship": "संपादनाचा लेखक",
+       "rcfilters-filter-editsbyself-label": "आपली स्वत:ची संपादने",
+       "rcfilters-filter-editsbyself-description": "आपली संपादने",
+       "rcfilters-filter-editsbyother-label": "इतरांची संपादने",
+       "rcfilters-filter-editsbyother-description": "इतर सदस्यांनी तयार केलेली संपादने (आपण नाही).",
+       "rcfilters-filtergroup-userExpLevel": "अनुभवाचा स्तर (फक्त नोंदणीकृत सदस्यांसाठीच)",
+       "rcfilters-filter-userExpLevel-newcomer-label": "नवागत",
+       "rcfilters-filter-userExpLevel-newcomer-description": "१० संपादनांपेक्षा कमी व ४ दिवसांची सक्रियता.",
+       "rcfilters-filter-userExpLevel-learner-label": "शिकाऊ",
        "rcnotefrom": "खाली {{PLURAL:$5|हा बदल आहे|हे बदल आहेत}} <strong>$3, $4</strong>पासून ते(<strong>$1</strong>पर्यंतचे  बदल दाखविले आहेत).",
        "rclistfrom": "$2,$3 पासून सुरुवात करुन, नविन केल्या गेलेले बदल दाखवा.",
        "rcshowhideminor": "छोटे बदल $1",
        "apisandbox-intro": "<strong>मिडियाविकि वेब सर्व्हीस एपीआय</strong> वर प्रयोग करण्यासाठी या पानाचा वापर करा. एपीआय वापरण्याच्या अधिक तपशिलासाठी  [[mw:API:Main page| एपीआय दस्ताऐवजीकरण]] हे पान बघा. उदाहरणार्थ:[https://www.mediawiki.org/wiki/API#A_simple_example मुख्य पानाचा आशय मिळवा]. अधिक उदाहरणे बघण्यास एखादी क्रिया निवडा.\n\nयाची नोंद घ्या कि ही धूळपाटी असली तरी, या पानावर आपण केलेल्या क्रियांद्वारे विकिवर फेरफार होऊ शकतो.",
        "apisandbox-submit": "विनंती करा",
        "apisandbox-reset": "हटवा",
-       "apisandbox-examples": "उदाहरण",
+       "apisandbox-examples": "उदाहरण",
        "apisandbox-results": "निकाल",
        "apisandbox-request-url-label": "'यूआरएल'ची विनंती करा:",
-       "apisandbox-request-time": "विनंती वेळ:$1",
+       "apisandbox-request-time": "विनंती वेळ:{{PLURAL:$1|$1 मिलीसेकंद}}",
        "booksources": "पुस्तक स्रोत",
        "booksources-search-legend": "पुस्तक स्रोत शोधा",
        "booksources-search": "शोधा",
        "modifiedarticleprotection": "\"[[$1]]\"करिता सुरक्षापातळी बदलली",
        "unprotectedarticle": "\"[[$1]]\" असुरक्षित केला.",
        "movedarticleprotection": "सुरक्षापातळी \"[[$2]]\" येथून \"[[$1]]\" येथे हलवली.",
+       "protectedarticle-comment": "\"[[$1]]\" ला {{GENDER:$2|ने संरक्षित केले}}",
+       "modifiedarticleprotection-comment": "\"[[$1]]\" ची {{GENDER:$2| ने संरक्षण पातळी बदलली}}",
+       "unprotectedarticle-comment": "\"[[$1]]\" ची {{GENDER:$2| ने सुरक्षा हटविली}}",
        "protect-title": "\"$1\" सुरक्षित करत आहे",
        "protect-title-notallowed": "\"$1\" ची सुरक्षा पातळी पहा",
        "prot_1movedto2": "\"[[$1]]\" हे पान \"[[$2]]\" मथळ्याखाली स्थानांतरित केले.",
        "pageinfo-display-title": "दृश्य शीर्षक",
        "pageinfo-default-sort": "डिफॉल्ट निवड-कळ (सॉर्ट कि)",
        "pageinfo-length": "पानाचा आकार (बाइट्समध्ये)",
-       "pageinfo-article-id": "पà¥\83षà¥\8dठ-परिà¤\9aय",
-       "pageinfo-language": "पानाच्या मजकूराची भाषा",
-       "pageinfo-content-model": "पान आशय नमूना",
+       "pageinfo-article-id": "पà¥\83षà¥\8dठ-à¤\93ळà¤\96ण",
+       "pageinfo-language": "पान-आशय भाषा",
+       "pageinfo-content-model": "पान-आशय नमूना",
        "pageinfo-content-model-change": "बदला",
-       "pageinfo-robot-policy": "यà¤\82तà¥\8dरमानवादà¥\8dवारà¥\87 à¤\85नà¥\81à¤\95à¥\8dरमन",
+       "pageinfo-robot-policy": "यà¤\82तà¥\8dरमानवाà¤\82दà¥\8dवारà¥\87 à¤\85नà¥\81à¤\95à¥\8dरमण",
        "pageinfo-robot-index": "अनुमती दिली",
        "pageinfo-robot-noindex": "अनुमती दिल्या जात नाही",
        "pageinfo-watchers": "पानावर पहारा देणाऱ्यांची संख्या",
+       "pageinfo-visiting-watchers": "या पानात झालेल्या अलीकडील संपादनांना पहारा देणाऱ्यांची संख्या",
        "pageinfo-few-watchers": "$1 पेक्षा कमी {{PLURAL:$1|पहारेदार}}",
        "pageinfo-redirects-name": "या पानास असलेली  पुनर्निर्देशनांची संख्या",
-       "pageinfo-subpages-name": "या à¤ªà¤¾à¤¨à¤¾à¤\9aà¥\87 à¤\89प-पान",
+       "pageinfo-subpages-name": "या à¤ªà¤¾à¤¨à¤¾à¤\9aà¥\80 à¤\89प-पानà¥\87",
        "pageinfo-subpages-value": "$1 ($2 {{PLURAL:$2|पुनर्निर्देशन|पुनर्निर्देशने}}; $3 {{PLURAL:$3|अ-पुनर्निर्देशन|अ-पुनर्निर्देशने}})",
-       "pageinfo-firstuser": "पà¥\83षà¥\8dठ à¤¨à¤¿à¤°à¥\8dमानक",
+       "pageinfo-firstuser": "पà¥\83षà¥\8dठ à¤¨à¤¿à¤°à¥\8dमाणक",
        "pageinfo-firsttime": "पान निर्मितीचा दिनांक",
        "pageinfo-lastuser": "अलीकडील संपादक",
        "pageinfo-lasttime": "अलीकडिल संपादनाचा दिनांक",
        "pageinfo-edits": "एकूण संपादने",
        "pageinfo-authors": "सुस्पष्ट-लेखकांची एकुण संख्या",
-       "pageinfo-recent-edits": "सध्याची संपादनसंख्या (मागील $1 मध्ये)",
+       "pageinfo-recent-edits": "सध्याची संपादनसंख्या (मागील $1)",
        "pageinfo-recent-authors": "सुस्पष्ट लेखकांची सध्या असलेली संख्या",
        "pageinfo-magic-words": "जादुई {{PLURAL:$1|शब्द}} ($1)",
        "pageinfo-hidden-categories": "लपविलेले {{PLURAL:$1|वर्ग}} ($1)",
        "pageinfo-category-pages": "पानांची संख्या",
        "pageinfo-category-subcats": "उपवर्गांची संख्या",
        "pageinfo-category-files": "संचिकांची संख्या",
+       "pageinfo-user-id": "सदस्य ओळखण",
        "markaspatrolleddiff": "टेहळणी केल्याची खूण करा",
        "markaspatrolledtext": "या पानावर गस्त झाल्याची खूण करा",
        "markaspatrolledtext-file": "या संचिकेच्या आवृत्तीस गस्त घातली म्हणून् खूण करा",
        "watchlistedit-raw-done": "तुमची पहाऱ्याची सूची परिष्कृत करण्यात आली आहे.",
        "watchlistedit-raw-added": "{{PLURAL:$1|1 शीर्षक होते |$1 शीर्षक होती }} भर घातली:",
        "watchlistedit-raw-removed": "{{PLURAL:$1|1 शीर्षक होते |$1 शीर्षक होती }} वगळले:",
-       "watchlistedit-clear-title": "निरà¥\80à¤\95à¥\8dषणसà¥\82à¤\9aà¥\80 à¤¸à¤¾à¤« à¤\95à¥\87लà¥\80",
+       "watchlistedit-clear-title": "निरà¥\80à¤\95à¥\8dषणसà¥\82à¤\9aà¥\80 à¤¸à¤¾à¤« à¤\95रा",
        "watchlistedit-clear-legend": "निरीक्षणसूची साफ करा",
-       "watchlistedit-clear-explain": "à¤\86पलà¥\8dया à¤¨à¤¨à¤¿à¤°à¥\80à¤\95à¥\8dषणसà¥\82à¤\9aà¥\80तà¥\80ल à¤¸à¤°à¥\8dव à¤¶à¤¿à¤°à¥\8dषà¤\95 à¤¹à¤\9fविलà¥\8dया à¤\9cातà¥\80ल.",
+       "watchlistedit-clear-explain": "आपल्या निरीक्षणसूचीतील सर्व शिर्षक हटविल्या जातील.",
        "watchlistedit-clear-titles": "शिर्षके:",
        "watchlistedit-clear-submit": "निरीक्षणसूची साफ करा(हे कायमस्वरुपी आहे!)",
        "watchlistedit-clear-done": "तुमची पहाऱ्याची सूची स्वच्छ करण्यात आली आहे.",
        "feedback-useragent": "सदस्य प्रतिनीधी:",
        "searchsuggest-search": "शोधा {{SITENAME}}",
        "searchsuggest-containing": ".......हे असलेले",
-       "api-error-badaccess-groups": "आपणास ह्या विकिवर संचिका चढवण्याची परवानगी नाही",
        "api-error-badtoken": "अंतर्गत चूक: अयोग्य टोकन",
-       "api-error-copyuploaddisabled": "या विदागारावर 'संकेतस्थळावरील संचिका चढविणे' अक्षम करण्यात आले आहे.",
-       "api-error-duplicate": "{{PLURAL:$1|दुसरी संचिका|दुसऱ्या इतर संचिका}}ही याच नावाने व याच आशयासह संकेतस्थळावर आहेत.",
-       "api-error-duplicate-archive": "{{PLURAL:$1|दुसरी संचिका|दुसऱ्या इतर संचिका}}ही याच नावाने व याच आशयासह संकेतस्थळावर आहे परंतु{{PLURAL:$1|ते वगळल्या गेले|ती वगळल्या गेलीत}}",
-       "api-error-empty-file": "तुम्ही प्रस्तुत केलेली संचिका रिकामी होती.",
        "api-error-emptypage": "नवीन आणि मोकळी पाने बनवायला परवानगी नाही",
-       "api-error-fetchfileerror": "अंतर्गत चूक: फाइल मिळवतांना काहीतरी चूक झाली आहे",
-       "api-error-fileexists-forbidden": "\"$1\" या नावाची संचिका पूर्वीच उपलब्ध आहे व त्यावर पुनर्लेखन करता येऊ शकत नाही.",
-       "api-error-fileexists-shared-forbidden": "\"$1\" या नावाची संचिका, 'सहभागी संचिका भांडारात' पूर्वीच उपलब्ध आहे,व त्यावर पुनर्लेखन करता येऊ शकत नाही.",
-       "api-error-file-too-large": "तुम्ही प्रस्तुत केलेली संचिका आकाराने खूप मोठी होती.",
-       "api-error-filename-tooshort": "संचिकेचे नाव खूपच छोटे आहे.",
-       "api-error-filetype-banned": "याप्रकारची संचिका प्रतिबंधित आहे.",
-       "api-error-filetype-banned-type": "$1 {{PLURAL:$4|हा परवानगी नसलेला  संचिका-प्रकार आहे|या परवानगी नसलेल्या संचिका-प्रकार आहेत}}. $2 {{PLURAL:$3|हा परवानगी असलेला संचिका-प्रकार आहे|या परवानगी असलेल्या संचिका-प्रकार आहेत}}.",
-       "api-error-filetype-missing": "या संचिकेस विस्तार(एक्सटेंशन) नाही.",
-       "api-error-hookaborted": "तुम्ही केलेला बदल extension ने उलटवला आहे",
-       "api-error-http": "अंतर्गत त्रुटी: सर्व्हरशी जोडणी होऊ शकली नाही.",
-       "api-error-illegal-filename": "हे संचिकानाम प्रतिबंधित आहे.",
-       "api-error-internal-error": "अंतर्गत त्रुटी:आपण विकिवर चढविलेल्या संचिकेवर प्रक्रिया करतांना काहीतरी चुकले आहे.",
-       "api-error-invalid-file-key": "अंतर्गत त्रुटी: तात्पुरत्या साठवणीत संचिका सापडली नाही.",
-       "api-error-missingparam": "अंतर्गत चूक: मागणीतील काही नोंदी राहून गेल्या आहेत",
-       "api-error-missingresult": "आंतरिक त्रुटी : प्रत यशस्वी झाली की नाही हे ठरवता  येत नाही",
-       "api-error-mustbeloggedin": "संचिका चढविण्यासाठी आपण दाखल होणे जरुरी आहे.",
-       "api-error-mustbeposted": "अंतर्गत चूक: मागणी पूर्ण करण्यासाठी HTTP POST असायला हवे",
-       "api-error-noimageinfo": "डाटा अपलोड यशस्वी झाले आहे पण सर्व्हर कडून तशी माहिती अजून मिळाली नाही",
-       "api-error-nomodule": "अंतर्गत चूक: module set चढवलेला नाही",
-       "api-error-ok-but-empty": "आंतरिक त्रुटी : विदादाता प्रतिक्रिया देत नहीं",
-       "api-error-overwrite": "अस्तित्वात असलेल्या संचिकेवर पुनर्लेखन प्रतिबंधित आहे.",
-       "api-error-ratelimited": "आपण, हा विकी परवानगी देत असल्यापेक्षा अधिक संचिका, कमी कालावधीत अपभारणाचा प्रयत्न करीत आहात.\nकाही मिनिटांनी पुन्हा प्रयत्न करा.",
-       "api-error-stashfailed": "इन्तरिक त्रुटी : विदादाता तात्पुरत्या स्वरूपाच्या संचिका जमा करण्यात अयशस्वी",
        "api-error-publishfailed": "अंतर्गत त्रुटी:विदादात्यास, या तात्पुरत्या संचिकेच्या प्रकाशनास अपयश आले.",
-       "api-error-stasherror": "स्टॅचमध्ये ही संचिका अपभारणात त्रुटी आली.",
-       "api-error-timeout": "अपेक्षित वेळेत विदागार (server)ने प्रतिसाद दिला नाही.",
-       "api-error-unclassified": "एक अज्ञात चूक उद्भवली.",
-       "api-error-unknown-code": "अज्ञात त्रुटी: \"$1\"",
-       "api-error-unknown-error": "अंतर्गत त्रुटी:आपली संचिका चढवितांना काहीतरी चुकले आहे.",
+       "api-error-stashfailed": "इन्तरिक त्रुटी : विदादाता तात्पुरत्या स्वरूपाच्या संचिका जमा करण्यात अयशस्वी",
        "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|तासापूर्वी|तासांपूर्वी}}",
index c8928af..b9f669c 100644 (file)
        "edithelp": "တည်းဖြတ်ခြင်း အကူအညီ",
        "helppage-top-gethelp": "အကူအညီ",
        "mainpage": "ဗဟိုစာမျက်နှာ",
-       "mainpage-description": "ဗ​ဟို​စာ​မျက်​နှာ​",
+       "mainpage-description": "ဗဟိုစာမျက်နှာ",
        "policy-url": "Project:မူဝါဒ",
        "portal": "ပေါင်းကူးနေရာ",
        "portal-url": "Project:ပေါင်းကူးနေရာ",
        "showhideselectedversions": "ရွေးချယ်ထားသော မူများကို ပြရန်/ဝှက်ရန်",
        "editundo": "နောက်ပြန် ပြန်ပြင်ရန်",
        "diff-empty": "(ကွဲပြားမှု မရှိ)",
+       "diff-multi-sameuser": "(တူညီသော အသုံးပြုသူ၏ {{PLURAL:$1|အလယ်ကြား မူတစ်ခု|အလယ်ကြား မူများ $1 ခု}} အား ပြသမထားပါ)",
        "searchresults": "ရှာဖွေမှု ရလဒ်များ",
        "searchresults-title": "\"$1\" အတွက် ရှာတွေ့သည့် ရလဒ်များ",
        "titlematches": "စာမျက်နှာခေါင်းစဉ်ကိုက်ညီသည်",
        "listduplicatedfiles": "ထပ်တူပုံပွားဖိုင်များ စာရင်း",
        "unusedtemplates": "မသုံးသော တမ်းပလိတ်များ",
        "unusedtemplateswlh": "အခြားလိပ်စာများ",
-       "randompage": "ကျ​ပန်း​စာ​မျက်​နှာ​",
+       "randompage": "ကျပန်းစာမျက်နှာ",
        "randomincategory": "ကဏ္ဍတွင်းရှိ ကျပန်း စာမျက်နှာ",
        "randomincategory-category": "ကဏ္ဍ:",
        "randomredirect": "ကျပန်းပြန်ညွှန်း",
        "listgrouprights-addgroup-self-all": "အုပ်စုအားလုံးကို မိမိ၏အကောင့်သို့ ပေါင်းထည့်ရန်",
        "listgrouprights-removegroup-self-all": "မိမိ၏အကောင့်မှ အုပ်စုအားလုံးကို ဖယ်ရှားရန်",
        "trackingcategories": "နောက်ယောင်ခံ ကဏ္ဍများ",
+       "trackingcategories-msg": "နောက်ယောင်ခံ ကဏ္ဍ",
        "mailnologin": "ပို့ရန်လိပ်စာ မရှိပါ",
        "emailuser": "ဤ​အ​သုံး​ပြု​သူ​အား​ အီး​မေး​ပို့​ပါ​",
        "emailuser-title-target": "{{GENDER:$1|အသုံးပြုသူ}}ကို အီးမေးပို့ရန်",
        "ipb_already_blocked": "\"$1\" ကို ပိတ်ပင်ထားပြီး ဖြစ်သည်။",
        "ipb-needreblock": "$1 ကို ပိတ်ပင်ထားပြီး ဖြစ်သည်။ အပြင်အဆင်များကို ပြောင်းလဲလိုပါသလား?",
        "move-page": "$1 ကို ရွှေ့ရန်",
-       "move-page-legend": "စာ​မျက်​နှာ​ကို ရွှေ့ပြောင်းရန်",
+       "move-page-legend": "စာမျက်နှာကို ရွှေ့ပြောင်းရန်",
        "movepagetext": "အောက်ပါပုံစံကို အသုံးပြုခြင်းသည် စာမျက်နှာကို အမည်ပြောင်းလဲပေးမည် ဖြစ်ပြီး အမည်သစ်သို့ ယင်း၏ မှတ်တမ်းနှင့်တကွ ရွှေ့ပေးမည် ဖြစ်သည်။\nအမည်ဟောင်းသည် အမည်သစ်သို့ ပြန်ညွှန်းစာမျက်နှာ ဖြစ်လာမည်။\nသင်သည် မူလခေါင်းစဉ်သို့ ပြန်ညွှန်းများကို အလိုအလျောက် အပ်ဒိတ် update လုပ်နိုင်သည်။\nအကယ်၍ မပြုလုပ်လိုပါက [[Special:DoubleRedirects|နှစ်ဆင့်ပြန်ညွှန်းများ]] သို့မဟုတ် [[Special:BrokenRedirects|ပြန်ညွှန်း အပျက်များ]] ကို မှတ်သားရန် မမေ့ပါနှင့်။\nလင့်များ ညွှန်းလိုသည့် နေရာသို့ ညွှန်ပြနေရန် သင့်တွင် တာဝန် ရှိသည်။\n\nအကယ်၍ ခေါင်းစဉ်အသစ်တွင် စာမျက်နှာတစ်ခု ရှိနှင့်ပြီး ဖြစ်ပါက (သို့) ယင်းစာမျက်နှာသည် အလွတ်မဖြစ်ပါက (သို့) ပြန်ညွှန်းတစ်ခု မရှိပါက (သို့) ယခင်က ပြုပြင်ထားသော မှတ်တမ်း မရှိပါက စာမျက်နှာသည် <strong>ရွေ့မည်မဟုတ်</strong> သည်ကို သတိပြုပါ။ \nဆိုလိုသည်မှာ သင်သည် အမှားတစ်ခု ပြုလုပ်မိပါက စာမျက်နှာကို ယခင်အမည်ကို ပြန်လည် ပြောင်းလဲပေးနိုင်သည်။ ရှိပြီသားစာမျက်နှာတစ်ခုကို စာမျက်နှာ အသစ်နှင့် ပြန်အုပ် overwrite ခြင်း မပြုနိုင်။\n\n<strong>မှတ်ချက်။</strong>\nဤသည်မှာ လူဖတ်များသော စာမျက်နှာတစ်ခုဖြစ်ပါက မမျှော်လင့်ထားသော၊ ကြီးမားသော အပြောင်းအလဲတစ်ခု ဖြစ်ပေါ်လာနိုင်သည်။\nထို့ကြောင့် ဆက်လက် မဆောင်ရွက်မီ သင်သည် နောက်ဆက်တွဲ အကျိုးဆက်များကို နားလည်ကြောင်း ကျေးဇူးပြု၍ သေချာပါစေ။",
        "movepagetext-noredirectfixer": "အောက်ပါပုံစံကို အသုံးပြုခြင်းသည် စာမျက်နှာကို အမည်ပြောင်းလဲပေးမည် ဖြစ်ပြီး အမည်သစ်သို့ ယင်း၏ မှတ်တမ်းနှင့်တကွ ရွှေ့ပေးမည် ဖြစ်သည်။\n[[Special:DoubleRedirects|နှစ်ဆင့်ပြန်ညွှန်းများ]] သို့မဟုတ် [[Special:BrokenRedirects|ပြန်ညွှန်း အပျက်များ]] ကို စစ်ဆေးရန် မမေ့ပါနှင့်။\nလင့်ခ်များ ညွှန်းလိုသည့် နေရာသို့ ညွှန်ပြနေရန် သင့်တွင် တာဝန် ရှိသည်။\n\nအကယ်၍ ခေါင်းစဉ်အသစ်တွင် စာမျက်နှာတစ်ခု ရှိနေနှင့်ပြီး ပြန်ညွှန်းတစ်ခု မရှိပါက သို့မဟုတ် ယခင်က ပြုပြင်ထားသော မှတ်တမ်း ရှိနေပါက စာမျက်နှာသည် <strong>ရွေ့မည်မဟုတ်</strong> သည်ကို သတိပြုပါ။ \nဆိုလိုသည်မှာ သင်သည် အမှားတစ်ခု ပြုလုပ်မိပါက စာမျက်နှာကို ယခင်အမည်ကို ပြန်လည် ပြောင်းလဲပေးနိုင်သည်။ ရှိပြီသားစာမျက်နှာတစ်ခုကို စာမျက်နှာ အသစ်နှင့် ပြန်အုပ် overwrite ခြင်း မပြုနိုင်။\n\n<strong>မှတ်ချက်။</strong>\nဤသည်မှာ လူဖတ်များသော စာမျက်နှာတစ်ခုဖြစ်ပါက မမျှော်လင့်ထားသော၊ ကြီးမားသော အပြောင်းအလဲတစ်ခု ဖြစ်ပေါ်လာနိုင်သည်။\nထို့ကြောင့် ဆက်လက် မဆောင်ရွက်မီ သင်သည် နောက်ဆက်တွဲ အကျိုးဆက်များကို နားလည်ကြောင်း ကျေးဇူးပြု၍ သေချာပါစေ။",
        "movepagetalktext": "ဤအကွက်ကို အမှန်ခြစ်လိုက်ခြင်းဖြင့် ဗလာမဟုတ်သော ဆွေးနွေးချက်စာမျက်နှာသည် ရှိနှင့်ပြီး မဟုတ်လျှင် ဆက်နွယ်နေသော ဆွေးနွေးချက် စာမျက်နှာကို ခေါင်းစဉ်အသစ်သို့  အလိုအလျောက် ရွှေ့ပစ်မည် ဖြစ်သည်။\n\nဤကိစ္စရပ်တွင် သင် ဆန္ဒရှိလျှင် စာမျက်နှာကို မိမိကိုယ်တိုင် သွားရောက်ရွှေ့ပြောင်း ပေါင်းစပ်နိုင်သည်။",
        "newtitle": "ခေါင်းစဉ်အသစ်:",
        "move-watch": "မူရင်းစာမျက်နှာနှင့် ဦးတည်ထားသော စာမျက်နှာတို့ကို စောင့်ကြည့်ရန်",
-       "movepagebtn": "စာ​မျက်​နှာ​ကို ရွှေ့ပြောင်းရန်",
+       "movepagebtn": "စာမျက်နှာကို ရွှေ့ပြောင်းရန်",
        "pagemovedsub": "ပြောင်းရွှေ့ခြင်းအောင်မြင်သည်",
        "movepage-moved": "'''\"$1\" ကို \"$2\" သို့ ရွှေ့ပြီးဖြစ်သည်'''",
        "movepage-moved-redirect": "ပြန်ညွှန်းတစ်ခုကို ဖန်တီးပြီးဖြစ်သည်။",
        "tooltip-preferences-save": "ရေးချယ်စရာများကို သိမ်းရန်",
        "tooltip-summary": "အတိုချုပ်ထည့်ရန်",
        "others": "အခြား",
+       "simpleantispam-label": "Anti-spam စစ်ဆေးခြင်း။\nဤအရာအား <strong>မဖြည့်ပါနှင့်</strong>!",
        "pageinfo-language": "စာမျက်နှာ စာကိုယ် ဘာသာစကား",
        "pageinfo-toolboxlink": "စာမျက်နှာ အချက်အလက်များ",
        "markaspatrolleddiff": "စောင့်ကြပ်စစ်ဆေးပြီးကြောင်း မှတ်သားရန်",
        "exif-imagewidth": "အကျယ်",
        "exif-imagelength": "အမြင့်",
        "exif-bitspersample": "အစိတ်အပိုင်းတစ်ခုတွင်ပါဝင်သော အပိုင်းငယ်များ",
+       "exif-orientation": "မျက်နှာပြင် အသားကျမှု",
        "exif-xresolution": "အလျားလိုက် ပုံရိပ်ပြတ်သားမှု",
        "exif-yresolution": "ဒေါင်လိုက် ပုံရိပ်ပြတ်သားမှု",
        "exif-datetime": "ဖိုင်အပြောင်းအလဲ ရက်စွဲနှင့် အချိန်",
        "signature": "[[{{ns:user}}:$1|$2]] ([[{{ns:user_talk}}:$1|ဆွေးနွေး]])",
        "duplicate-defaultsort": "'''သတိပေးချက် -''' ပုံမှန် sort key \"$2\" oသည် ယခင်ပုံမှန်ဖြစ်သော sort key \"$1\" ကို override ထပ်ရေးမည်ဖြစ်သည်.",
        "version": "ဗားရှင်း",
-       "version-specialpages": "အ​ထူး ​စာ​မျက်​နှာ​များ",
+       "version-specialpages": "အထူး စာမျက်နှာများ",
        "version-other": "အခြား",
        "version-license": "မီဒီယာဝီကီ လိုင်စင်",
        "version-software": "သွင်းထားသော ဆော့ဝဲ",
        "fileduplicatesearch": "နှစ်ခုထပ်နေသောဖိုင်များကို ရှာရန်",
        "fileduplicatesearch-filename": "ဖိုင်အမည် -",
        "fileduplicatesearch-submit": "ရှာဖွေရန်",
-       "specialpages": "အ​ထူး ​စာ​မျက်​နှာ​များ",
+       "specialpages": "အထူး စာမျက်နှာများ",
        "specialpages-note": "* ပုံမှန် အထူးစာမျက်နှာများ။\n* <span class=\"mw-specialpagerestricted\">ကန့်သတ်ထားသော အထူးစာမျက်နှာများ။</span>",
        "specialpages-group-maintenance": "ထိန်းသိမ်းမှု အစီရင်ခံချက်များ",
        "specialpages-group-other": "အခြားအထူးစာမျက်နှာများ",
        "revdelete-unrestricted": "အက်ဒမင်များအတွက် ကန့်သတ်ချက်များကို ဖယ်ရှားရန်",
        "logentry-suppress-block": "{{GENDER:$4|$3}} အား $5 ကြာအောင် $1 က {{GENDER:$2|ပိတ်ပင်ခဲ့သည်}} $6",
        "logentry-move-move": "$3 စာမျက်နှာကို $4 သို့ $1က {{GENDER:$2|ရွှေ့ခဲ့သည်}}",
-       "logentry-move-move-noredirect": "$3 á\80\99á\80¾ $4 á\80\9eá\80­á\80¯á\80· á\80\85á\80¬á\80\99á\80»á\80\80á\80ºá\80\94á\80¾á\80¬á\80\80á\80­á\80¯ á\80\95á\80¼á\80\94á\80ºá\80\8aá\80½á\80¾á\80\94á\80ºá\80¸á\80\81á\80»á\80\94á\80ºá\80\99á\80\91á\80¬á\80¸á\80\95ဲ $1 {{GENDER:$2|က ရွှေ့ခဲ့သည်}}",
+       "logentry-move-move-noredirect": "$3 á\80\99á\80¾ $4 á\80\9eá\80­á\80¯á\80· á\80\85á\80¬á\80\99á\80»á\80\80á\80ºá\80\94á\80¾á\80¬á\80\80á\80­á\80¯ á\80\95á\80¼á\80\94á\80ºá\80\8aá\80½á\80¾á\80\94á\80ºá\80¸á\80\81á\80»á\80\94á\80ºá\80\99á\80\91á\80¬á\80¸á\80\98ဲ $1 {{GENDER:$2|က ရွှေ့ခဲ့သည်}}",
        "logentry-move-move_redir": "$3 စာမျက်နှာကို $4 သို့ ပြန်ညွှန်းပေါ်ထပ်၍ $1 က {{GENDER:$2|ရွှေ့ခဲ့သည်}}",
+       "logentry-move-move_redir-noredirect": "$3 မှ $4 သို့ ပြန်ညွှန်ပေါ်ထပ်အုပ်ကာ ပြန်ညွှန်းချန်မထားဘဲ $1 က {{GENDER:$2|ရွှေ့ခဲ့သည်}}",
        "logentry-newusers-create": "အသုံးပြုသူအကောင့် $1 ကို {{GENDER:$2|ဖန်တီးခဲ့သည်}}",
        "logentry-newusers-autocreate": "အသုံးပြုသူအကောင့် $1 ကို အလိုအလျောက် {{GENDER:$2|ဖန်တီးခဲ့သည်}}",
        "logentry-upload-upload": "$1 သည် $3 ကို {{GENDER:$2|upload တင်ခဲ့သည်}}",
index 58efd6f..ecff7b5 100644 (file)
@@ -15,7 +15,7 @@
                        "Akapochtli"
                ]
        },
-       "tog-underline": "Mokìnxòîkuilòtzàswis tzòwilistìn:",
+       "tog-underline": "Moquinxoihcuilotzazhuiz tzohuiliztin:",
        "tog-hideminor": "Motlàtìs tepỉtzìn tlayèktlàlilistli ìpan welok tlapảtlalistli",
        "tog-hidepatrolled": "Motlàtìs tlapîpialli tlayèktlàlilistli ìpan welok tlapảtlalistli",
        "tog-newpageshidepatrolled": "Mokintlàtis tlapîpialtlaìxtlapaltìn ìwikpa ìtlapòpòwaltekpànal in yâyankuik tlaìxtlapaltìn",
        "category-subcat-count-limited": "Inin {{PLURAL:$1|neneuhcayotl quipiya|$1 in tetoquilli tlani-neneuhcayotl|in tetoquiltin tlani-neneuhcayomeh}}.",
        "category-article-count": "{{PLURAL:$2|Inin neneuhcayotl zan quipiya in tetoquilli tlahcuilolli.|{{PLURAL:$1|In tetoquilli tlahcuilolli itech pohui|In tetoquiltin $1 tlahcuiloltin itech pohui}}, inin neneuhcayotl itech tlacecempohualoni ipan $2.}}",
        "category-article-count-limited": "Inīn {{PLURAL:$1|zāzanilli cah|$1 zāzanilli cateh}} inīn neneuhcāyōc.",
-       "category-file-count": "{{PLURAL:$2|Inìn tlaìxmatkàyòtlàlilòtl san kipia|Inìn tlaìxmatkàyòtlalilòtl kimpia {{PLURAL:$1|inìn èwalli|inîke $1 èwaltìn}}, ìwikpa $2.}}",
+       "category-file-count": "{{PLURAL:$2|Inin neneuhcayotl zan quipiya|Inin neneuhcayotl quimpiya {{PLURAL:$1|inin ehualli|inihqueh $1 ehualtin}}, ihuicpa $2.}}",
        "category-file-count-limited": "{{PLURAL:$1|Inin tlahcuilolehualli kah|Inihqueh $1 tlahcuilolehualtin catehqueh}} ipan inin neneuhcayotl.",
        "listingcontinuesabbrev": "niman",
        "about": "Itechcopa",
        "prefs-resetpass": "Ticpatlāz motlahtōlichtacāyo",
        "saveprefs": "Xicpiya",
        "prefs-editing": "Tlapatlaliztli",
-       "rows": "Pāntli:",
        "searchresultshead": "Tlatemoliztli",
        "recentchangesdays": "Tōnaltin tiquinttāz yancuīc tlapatlalizpan:",
        "localtime": "Cāhuitl nicān:",
        "withoutinterwiki": "Zāzaniltin ahtle tzonhuiliztli",
        "withoutinterwiki-submit": "Tiquittāz",
        "nbytes": "$1 {{PLURAL:$1|byte}}",
-       "ncategories": "$1 {{PLURAL:$1|tlaìxmatkàyòtlàlilòtl|tlaìxmatkàyòtlàlilòme}}",
+       "ncategories": "$1 {{PLURAL:$1|neneuhcayotl|neneuhcayomeh}",
        "nlinks": "$1 {{PLURAL:$1|tzohuililiztli|tzohuililiztin}}",
        "nmembers": "$1 {{PLURAL:$1|tlahcuilolamatl|tlahcuilolamameh}}",
        "nrevisions": "$1 {{PLURAL:$1|tlapiyaliztli}}",
        "rightsnone": "ahtlein",
        "revdelete-summary": "ticpatlāz tlahcuilōltōn",
        "searchsuggest-search": "Tlatemoliztli",
-       "api-error-ok-but-empty": "Tlâtek îtlakawilistli: Âmò tènankilia in tlatèmakani.",
-       "api-error-overwrite": "Awel motlâkuilnepanòltis sè èwalli tlèn yi katki.",
        "api-error-stashfailed": "Tlâtek îtlakawilistli: In tlatèmakani awel òkeuh in èwalpanòni.",
-       "api-error-timeout": "In tlatèmakani âmò òwalnàwat kèn òmochìxtikatka.",
-       "api-error-unclassified": "Òpanòk sè âmò ìxmatkàyo îtlakawilistli.",
-       "api-error-unknown-code": "Âmò ìxmatkàyo îtlakawilistli: \"$1\".",
-       "api-error-unknown-error": "Tlâtek îtlakawilistli: Îtlâtlèn òîtlakauh îkuàk òmonekià motilànas in èwalli.",
        "api-error-unknown-warning": "Âmò ìxmatkàyo tlanawatilistli: \"$1\".",
        "api-error-unknownerror": "Âmò ìxmatkàyo îtlakawilistli: \"$1\".",
-       "api-error-uploaddisabled": "Sèuhtok in êkawilistli ìpan inìn wiki.",
-       "api-error-verification-error": "Inìn èwalli welis îtlakauhtok, noso âmò kualli motzòwîtok.",
        "expand_templates_ok": "Cayecualli",
        "expand_templates_preview": "Xiquitta achtochīhualiztli",
        "special-characters-group-latin": "Latintlahcuilolli",
index f598b36..de4ad44 100644 (file)
        "youremail": "E-post:",
        "username": "{{GENDER:$1|Brukernavn}}:",
        "prefs-memberingroups": "{{GENDER:$2|Medlem}} i følgende {{PLURAL:$1|gruppe|grupper}}:",
+       "group-membership-link-with-expiry": "$1 (til $2)",
        "prefs-registration": "Registreringstidspunkt:",
        "yourrealname": "Virkelig navn:",
        "yourlanguage": "Språk:",
        "userrights-changeable-col": "Grupper du kan endre",
        "userrights-unchangeable-col": "Grupper du ikke kan endre",
        "userrights-irreversible-marker": "$1 *",
+       "userrights-expiry-current": "Løper ut $1",
+       "userrights-expiry-none": "Utløper ikke",
+       "userrights-expiry": "Utløper:",
+       "userrights-expiry-existing": "Gjeldende utløpstid: $2 $3",
+       "userrights-expiry-othertime": "Annen tid:",
+       "userrights-expiry-options": "1 dag:1 day,1 uke:1 week,1 måned:1 month,3 måneder:3 months,6 måneder:6 months,1 år:1 year",
+       "userrights-invalid-expiry": "Utløpstiden for gruppa «$1» er ugyldig.",
+       "userrights-expiry-in-past": "Utløpstiden for gruppa «$1» har vært.",
        "userrights-conflict": "En konflikt med endringen av brukerrettigheter! Vær vennlig å sjekke og på nytt bekrefte endringene dine.",
        "group": "Gruppe:",
        "group-user": "Brukere",
        "recentchanges-legend-plusminus": "«(±123)»",
        "recentchanges-submit": "Vis",
        "rcfilters-activefilters": "Aktive filtre",
+       "rcfilters-restore-default-filters": "Gjenopprett standardfiltre",
+       "rcfilters-clear-all-filters": "Nullstill alle filtre",
        "rcfilters-search-placeholder": "Filtrer siste endringer (søk eller begyn å skrive)",
        "rcfilters-invalid-filter": "Ugyldig filter",
+       "rcfilters-empty-filter": "Ingen aktive filtre. Alle bidrag vises.",
        "rcfilters-filterlist-title": "Filtre",
        "rcfilters-filterlist-noresults": "Ingen filtre funnet",
+       "rcfilters-filtergroup-registration": "Brukerregistrering",
+       "rcfilters-filter-registered-label": "Registrerte",
+       "rcfilters-filter-registered-description": "Innloggede brukere.",
+       "rcfilters-filter-unregistered-label": "Uregistrerte",
+       "rcfilters-filter-unregistered-description": "Brukere som ikke er logget inn.",
        "rcfilters-filtergroup-authorship": "Redigeringens forfatter",
        "rcfilters-filter-editsbyself-label": "Dine egne redigeringer",
        "rcfilters-filter-editsbyself-description": "Redigeringer gjort av deg.",
        "rcfilters-filter-editsbyother-label": "Redigeringer av andre",
        "rcfilters-filter-editsbyother-description": "Redigeringer som er gjort av andre brukere enn deg.",
-       "rcfilters-filtergroup-userExpLevel": "Brukererfaringsnivå",
+       "rcfilters-filtergroup-userExpLevel": "Erfaringsnivå (kun for registrerte brukere)",
        "rcfilters-filter-userExpLevel-newcomer-label": "Nykommere",
-       "rcfilters-filter-userExpLevel-newcomer-description": "Veldig nye bidragsytere: Færre enn 10 redigeringer og 4 dagers aktivitet.",
+       "rcfilters-filter-userExpLevel-newcomer-description": "Færre enn 10 redigeringer og 4 dagers aktivitet.",
        "rcfilters-filter-userExpLevel-learner-label": "Nybegynnere",
        "rcfilters-filter-userExpLevel-learner-description": "Flere dagers aktivitet enn «Nykommere», men mindre enn «Erfarne brukere».",
        "rcfilters-filter-userExpLevel-experienced-label": "Erfarne brukere",
        "rcfilters-filter-userExpLevel-experienced-description": "Mer enn 30 dagers aktivitet og 500 redigeringer.",
+       "rcfilters-filtergroup-automated": "Automatiske bidrag",
+       "rcfilters-filter-bots-label": "Bot",
+       "rcfilters-filter-bots-description": "Redigeringer gjort med automatiske verktøy.",
+       "rcfilters-filter-humans-label": "Menneske (ikke bot)",
+       "rcfilters-filter-humans-description": "Redigeringer gjort av menneskelige brukere.",
+       "rcfilters-filtergroup-significance": "Betydning",
+       "rcfilters-filter-minor-label": "Mindre endringer",
+       "rcfilters-filter-minor-description": "Redigeringer merket som mindre av brukeren.",
+       "rcfilters-filter-major-label": "Ikke-mindre endringer",
+       "rcfilters-filter-major-description": "Redigeringer som ikke er merket som mindre.",
+       "rcfilters-filtergroup-changetype": "Type endring",
+       "rcfilters-filter-pageedits-label": "Sideredigeringer",
+       "rcfilters-filter-pageedits-description": "Redigeringer til wikiinnhold, diskusjoner, kategoribeskrivelser ...",
+       "rcfilters-filter-newpages-label": "Sideopprettelser",
+       "rcfilters-filter-newpages-description": "Redigeringer som oppretter nye sider.",
+       "rcfilters-filter-categorization-label": "Kategoriendringer",
+       "rcfilters-filter-categorization-description": "Sporer sider som legges til i eller fjernes fra kategorier.",
+       "rcfilters-filter-logactions-label": "Loggførte handlinger",
+       "rcfilters-filter-logactions-description": "Administrative handlinger, kontoopprettelser, sideslettinger, opplastinger ...",
        "rcnotefrom": "Nedenfor er vist {{PLURAL:$5|endringen|endringene}} som er gjort siden <strong>$3, $4</strong> (frem til <strong>$1</strong>).",
        "rclistfrom": "Vis nye endringer fra og med $3 $2",
        "rcshowhideminor": "$1 mindre endringer",
        "apisandbox-sending-request": "Sender API-forespørsel...",
        "apisandbox-loading-results": "Mottar API-resultater...",
        "apisandbox-results-error": "En feil oppsto under lasting av API-spørringssvaret: $1.",
-       "apisandbox-request-params-json": "JSON-parametre:",
+       "apisandbox-request-selectformat-label": "Vis forespørselsdata som:",
+       "apisandbox-request-format-url-label": "URL-spørringsstreng",
        "apisandbox-request-url-label": "Forespurt URL:",
+       "apisandbox-request-json-label": "Spør om JSON:",
        "apisandbox-request-time": "Forespørselstid: {{PLURAL:$1|$1 ms}}",
        "apisandbox-results-fixtoken": "Fiks nøkkelen og send på nytt",
        "apisandbox-results-fixtoken-fail": "Henting av nøkkelen «$1» mislyktes.",
        "emailccsubject": "Kopi av din beskjed til $1: $2",
        "emailsent": "E-post sendt",
        "emailsenttext": "E-postbeskjeden er sendt",
-       "emailuserfooter": "Denne e-posten ble {{GENDER:$1|sendt}} av $1 til {{GENDER:$2|$2}}  via funksjonen «{{int:emailuser}}» på {{SITENAME}}. {{GENDER:$2|Din}} epost vil bli sendt direkte til {{GENDER:$1|opprinnelig avsender}} og avsløre {{GENDER:$2|din}} epost-addresse til {{GENDER:$1|dem}}.",
+       "emailuserfooter": "Denne e-posten ble {{GENDER:$1|sendt}} av $1 til {{GENDER:$2|$2}}  via funksjonen «{{int:emailuser}}» på {{SITENAME}}. Om {{GENDER:$2|du}} svarer på denne eposten vil den sendes direkte til {{GENDER:$1|opprinnelig avsender}} og avsløre {{GENDER:$2|din}} epostadresse for {{GENDER:$1|ham|henne|dem}}.",
        "usermessage-summary": "Etterlater en systembeskjed.",
        "usermessage-editor": "Systembudbringer",
        "watchlist": "Overvåkningsliste",
        "htmlform-user-not-exists": "<strong>$1</strong> eksisterer ikke.",
        "htmlform-user-not-valid": "<strong>$1</strong> er ikke et gyldig brukernavn.",
        "logentry-delete-delete": "$1 {{GENDER:$2|slettet}} siden $3",
-       "logentry-delete-delete_redir": "$1 {{GENDER:$2|slettet}} omdirigeringen $3 ved å overskrive",
+       "logentry-delete-delete_redir": "$1 {{GENDER:$2|sletta}} omdirigeringa $3 gjennom overskriving",
        "logentry-delete-restore": "$1 {{GENDER:$2|gjenopprettet}} siden $3",
        "logentry-delete-event": "$1 {{GENDER:$2|endret}} synligheten av {{PLURAL:$5|en logghendelse|$5 logghendelser}} på $3: $4",
        "logentry-delete-revision": "$1 {{GENDER:$2|endret}} synligheten av {{PLURAL:$5|en revisjon|$5 revisjoner}} på side $3: $4",
        "logentry-tag-update-logentry": "$1 {{GENDER:$2|oppdaterte}} merker på loggposten $5 til siden $3\n({{PLURAL:$7|la til}} $6; {{PLURAL:$9|fjernet}} $8)",
        "rightsnone": "(ingen)",
        "revdelete-summary": "redigeringssammendrag",
+       "rightslogentry-temporary-group": "$1 (midlertidig, til $2)",
        "feedback-adding": "Tilføyer tilbakmelding til side ...",
        "feedback-back": "Tilbake",
        "feedback-bugcheck": "Suprert! Bare sjekk at den ikke er en av de [$1 kjente feilene]",
        "usercssispublic": "Merk: CSS-undersidene bør ikke inneholde konfidensielle data siden de kan ses av andre brukere.",
        "restrictionsfield-badip": "Ugyldig IP-adresse eller intervall: $1",
        "restrictionsfield-label": "Tillatte IP-intervaller:",
-       "restrictionsfield-help": "Én IP-adresse eller CIDR-intervall per linje. For å slå på alt, bruk <br /><code>0.0.0.0/0</code><br /><code>::/0</code>",
+       "restrictionsfield-help": "Én IP-adresse eller CIDR-intervall per linje. For å slå på alt, bruk: <pre>0.0.0.0/0\n::/0</pre>",
        "revid": "revisjon $1",
        "pageid": "side-ID $1"
 }
index 496bc7d..834e1c7 100644 (file)
        "youremail": "E-mailadres:",
        "username": "{{GENDER:$1|Gebruikersnaam}}:",
        "prefs-memberingroups": "{{GENDER:$2|Lid}} van {{PLURAL:$1|groep|groepen}}:",
+       "group-membership-link-with-expiry": "$1 (tot $2)",
        "prefs-registration": "Registratiedatum:",
        "yourrealname": "Echte naam:",
        "yourlanguage": "Taal:",
        "userrights-nodatabase": "De database $1 bestaat niet of is geen lokale database.",
        "userrights-changeable-col": "Groepen die u kunt beheren",
        "userrights-unchangeable-col": "Groepen die u niet kunt beheren",
+       "userrights-expiry-current": "Vervalt op $1",
+       "userrights-expiry-none": "Vervalt niet",
+       "userrights-expiry": "Vervalt:",
+       "userrights-expiry-existing": "Bestaande vervaldatum: $2 om $3",
+       "userrights-expiry-othertime": "Andere tijd:",
+       "userrights-expiry-options": "1 dag:1 day,1 week:1 week,1 maand:1 month,3 maanden:3 months,6 maanden:6 months,1 jaar:1 year",
+       "userrights-invalid-expiry": "De vervaltijd voor de groep \"$1\" is ongeldig.",
+       "userrights-expiry-in-past": "De vervaltijd voor de groep \"$1\" is in het verleden.",
        "userrights-conflict": "Er is een probleem opgetreden tijdens het instellen van de gebruikersrechten! Controleer en bevestig uw wijzigingen.",
        "group": "Groep:",
        "group-user": "gebruikers",
        "recentchanges-legend-plusminus": "(''±123'')",
        "recentchanges-submit": "Weergeven",
        "rcfilters-activefilters": "Actieve filters",
+       "rcfilters-restore-default-filters": "Standaard filters terugzetten",
+       "rcfilters-clear-all-filters": "Alle filters verwijderen",
        "rcfilters-search-placeholder": "Filter recente wijzigingen (blader of begin met intypen)",
        "rcfilters-invalid-filter": "Ongeldig filter",
+       "rcfilters-empty-filter": "Geen actieve filters. Alle bijdragen worden weergeven.",
        "rcfilters-filterlist-title": "Filters",
        "rcfilters-filterlist-noresults": "Geen filters gevonden",
        "rcfilters-filtergroup-registration": "Gebruikers-registratie",
        "rcfilters-filter-bots-description": "De wijzigingen van geautomatiseerde hulpmiddelen.",
        "rcfilters-filter-humans-label": "Menselijk (geen bot)",
        "rcfilters-filter-humans-description": "Bewerkingen door menselijke bewerkers.",
-       "rcfilters-filtergroup-significance": "Significantie",
+       "rcfilters-filtergroup-significance": "Belangrijkheid",
        "rcfilters-filter-minor-label": "Kleine bewerkingen",
        "rcfilters-filter-minor-description": "Bewerkingen die door de bewerker zijn gelabeld als klein.",
        "rcfilters-filter-major-label": "Geen kleine bewerking",
        "rcfilters-filter-pageedits-label": "Paginabewerkingen",
        "rcfilters-filter-pageedits-description": "Wijzigingen aan de wiki inhoud, discussies, categorie beschrijvingen....",
        "rcfilters-filter-newpages-label": "Nieuwe pagina's",
+       "rcfilters-filter-newpages-description": "Bewerkingen die een nieuwe pagina aanmaken.",
        "rcfilters-filter-categorization-label": "Categorie wijzigingen",
+       "rcfilters-filter-logactions-label": "Geregistreerde acties",
        "rcfilters-filter-logactions-description": "Administratieve handelingen, account creaties, pagina verwijderingen, uploads....",
        "rcnotefrom": "Wijzigingen sinds <strong>$3 om $4</strong> (maximaal <strong>$1</strong> {{PLURAL:$1|wijziging|wijzigingen}}).",
        "rclistfrom": "Wijzigingen bekijken vanaf $3 $2",
        "uncategorizedcategories": "Niet-gecategoriseerde categorieën",
        "uncategorizedimages": "Niet-gecategoriseerde bestanden",
        "uncategorizedtemplates": "Niet-gecategoriseerde sjablonen",
+       "uncategorized-categories-exceptionlist": "# Bevat een lijst van categorieën, welke niet op Speciaal:NietGecategoriseerdeCategorieën getoond moeten worden. Een per regel, beginnend met \"*\". Regels die starten met een ander teken (inclusief witruimte) worden genegeerd. Gebruik \"#\" voor opmerkingen.",
        "unusedcategories": "Ongebruikte categorieën",
        "unusedimages": "Ongebruikte bestanden",
        "wantedcategories": "Niet-bestaande categorieën met de meeste koppelingen",
        "apisandbox-sending-request": "API-verzoek verzenden...",
        "apisandbox-loading-results": "API-resultaten ontvangen...",
        "apisandbox-results-error": "Er is een fout opgetreden tijdens het laden van het antwoord op het API-verzoek: $1.",
-       "apisandbox-request-params-json": "JSON parameters:",
+       "apisandbox-request-selectformat-label": "Toon resultaat als:",
        "apisandbox-request-url-label": "Verzoek-URL:",
        "apisandbox-request-time": "Doorlooptijd verzoek: {{PLURAL:$1|$1 ms}}",
        "apisandbox-results-fixtoken": "Token corrigeren en opnieuw verzenden",
        "emailccsubject": "Kopie van uw bericht aan $1: $2",
        "emailsent": "E-mail verzonden",
        "emailsenttext": "Uw e-mail is verzonden.",
-       "emailuserfooter": "Deze e-mail is door $1 aan {{GENDER:$2|$2}} {{GENDER:$1|verstuurd}} middels de functie \"{{int:emailuser}}\" van {{SITENAME}}. {{GENDER:$2|Uw}} e-mail wordt direct naar de {{GENDER:$1|oorspronkelijke afzender}} verstuurd, waardoor {{GENDER:$2|uw}} e-mailadres aan {{GENDER:$1|hem|haar|hem of haar}} onthuld wordt.",
+       "emailuserfooter": "Deze e-mail is door $1 aan {{GENDER:$2|$2}} {{GENDER:$1|verstuurd}} middels de functie \"{{int:emailuser}}\" van {{SITENAME}}. Indien {{GENDER:$2|uw}} reageert op deze e-mail, wordt uw e-mail direct naar de {{GENDER:$1|oorspronkelijke afzender}} verstuurd, waardoor {{GENDER:$2|uw}} e-mailadres aan {{GENDER:$1|hem|haar|hem of haar}} onthuld wordt.",
        "usermessage-summary": "Systeembericht achtergelaten",
        "usermessage-editor": "Systeembericht",
        "watchlist": "Volglijst",
        "logentry-tag-update-logentry": "$1 heeft de labels van logboekregel $5 van pagina $3 {{GENDER:$2|bijgewerkt}} ($6 {{PLURAL:$7|toegevoegd}}; $8 {{PLURAL:$9|verwijderd}})",
        "rightsnone": "(geen)",
        "revdelete-summary": "bewerkingssamenvatting",
+       "rightslogentry-temporary-group": "$1 (tijdelijk, tot $2)",
        "feedback-adding": "Uw terugkoppeling wordt aan de pagina toegevoegd...",
        "feedback-back": "Terug",
        "feedback-bugcheck": "Geweldig! Controleer even of het niet al één van de [$1 bekende problemen] is.",
        "authmanager-provider-password": "Op wachtwoord gebaseerde authenticatie",
        "authmanager-provider-password-domain": "Wachtwoord- en domeingebaseerde authentificatie",
        "authmanager-provider-temporarypassword": "Tijdelijk wachtwoord",
+       "authprovider-confirmlink-request-label": "Accounts die aan elkaar moeten worden gekoppeld.",
        "authprovider-confirmlink-success-line": "$1: Succesvol gekoppeld.",
        "authprovider-resetpass-skip-label": "Overslaan",
        "authprovider-resetpass-skip-help": "Sla het resetten van het wachtwoord over.",
        "authform-notoken": "Ontbrekend token",
        "authform-wrongtoken": "Verkeerd token",
        "specialpage-securitylevel-not-allowed-title": "Niet toegestaan",
+       "authpage-cannot-create": "Kon het account aanmaken niet starten.",
        "cannotauth-not-allowed-title": "Geen toegang",
        "cannotauth-not-allowed": "U hebt geen toestemming om deze pagina te gebruiken",
        "changecredentials": "Authenticatiegegevens wijzigen",
        "changecredentials-submit": "Authenticatiegegevens wijzigen",
+       "changecredentials-invalidsubpage": "$1 is geen geldig identificatietype.",
        "changecredentials-success": "Uw authenticatiegegevens zijn gewijzigd.",
        "removecredentials": "Authenticatiegegevens verwijderen",
        "removecredentials-submit": "Authenticatiegegevens verwijderen",
+       "removecredentials-invalidsubpage": "$1 is geen geldig identificatietype.",
        "removecredentials-success": "Uw authenticatiegegevens zijn verwijderd.",
        "credentialsform-provider": "Soort authenticatiegegevens:",
        "credentialsform-account": "Gebruikersnaam:",
        "usercssispublic": "Let op: CSS deelpagina's moeten geen vertrouwelijke gegevens bevatten omdat ze kunnen worden bekeken door andere gebruikers.",
        "restrictionsfield-badip": "Ongeldig IP-adres of range: $1",
        "restrictionsfield-label": "Toegestane IP-ranges:",
+       "restrictionsfield-help": "Een IP-adres of CIDR bereik per lijn. Om alles toe te staan, gebruik:<pre>0.0.0.0/0\n::/0</pre>",
        "revid": "versie $1",
        "pageid": "Pagina-ID $1"
 }
index 6685817..c50b09e 100644 (file)
        "history-feed-description": "Endringshistorikk for denne sida på wikien",
        "history-feed-item-nocomment": "$1 på $2",
        "history-feed-empty": "Den etterspurde sida finst ikkje. Ho kan vere sletta frå wikien, eller vere flytta. Prøv å [[Special:Search|søke på wikien]] for relevante nye sider.",
+       "history-edit-tags": "Endra merka til dei valde versjonane",
        "rev-deleted-comment": "(endringssamandrag fjerna)",
        "rev-deleted-user": "(brukarnamnet er fjerna)",
        "rev-deleted-event": "(fjerna loggoppføring)",
        "feedback-thanks": "Takk! Attendemeldinga di er lagd inn på sida «[$2 $1]».",
        "searchsuggest-search": "Søk i {{SITENAME}}",
        "searchsuggest-containing": "som inneheld …",
-       "api-error-badaccess-groups": "Du har ikkje løyve til å lasta opp filer til wikien.",
        "api-error-badtoken": "Intern feil: ugild token.",
-       "api-error-copyuploaddisabled": "Opplasting etter URL er avslege på tenaren.",
-       "api-error-duplicate": "Det finst {{PLURAL:$1|ei anna fil|andre filer}} på nettstaden med same innhaldet.",
-       "api-error-duplicate-archive": "Det fanst {{PLURAL:$1|ei anna fi|andre file}} på nettstaden med det same innhaldet, men {{PLURAL:$1|ho|dei}} vart sletta.",
-       "api-error-empty-file": "Fila du sende var tom.",
        "api-error-emptypage": "Det er ikkje tillate å oppretta nye tomme sider.",
-       "api-error-fetchfileerror": "Intern feil: Noko gjekk gale då fila vart henta.",
-       "api-error-fileexists-forbidden": "Ei fil med namnet «$1» finst alt, og kan ikkje skrivast over.",
-       "api-error-fileexists-shared-forbidden": "Ei fil med namnet «$1» finst alt i den delte filsamlinga, og kan ikkje skrivast over.",
-       "api-error-file-too-large": "Fila du sende var for stor.",
-       "api-error-filename-tooshort": "Filnamnet er for stutt.",
-       "api-error-filetype-banned": "Denne filtypen er ikkje tillaten.",
-       "api-error-filetype-banned-type": "$1 er ikkje {{PLURAL:$4|ein tillaten filtype|tillatne filtypar}}. {{PLURAL:$3|Tillaten filtype|Tillatne filtypar}} er $2.",
-       "api-error-filetype-missing": "Fila saknar ei ending.",
-       "api-error-hookaborted": "Endringa du freista vart avbroten av ei utviding.",
-       "api-error-http": "Intern feil: kan ikkje kopla til tenaren.",
-       "api-error-illegal-filename": "Filnamnet er ikkje tillate.",
-       "api-error-internal-error": "Intern feil: Noko gjekk gale med handsaminga av opplastinga di til wikien.",
-       "api-error-invalid-file-key": "Intern feil: Fila vart ikkje funnen i mellombels lagringsplass.",
-       "api-error-missingparam": "Intern feil: det saknar parametrar i førespurnaden.",
-       "api-error-missingresult": "Intern feil: kunne ikkje avgjera om koperinga var vellukka.",
-       "api-error-mustbeloggedin": "Du lyt vera innlogga for å lasta opp filer.",
-       "api-error-mustbeposted": "Intern feil: førespurnad krev HTTP POST.",
-       "api-error-noimageinfo": "Opplastinga gjekk greitt, men tenaren gav oss ikkje noko informasjon om fila.",
-       "api-error-nomodule": "Intern feil: ingen opplastingsmodul er vald.",
-       "api-error-ok-but-empty": "Intern feil: ikkje noko svar frå tenaren.",
-       "api-error-overwrite": "Det er ikkje tillate å skriva over filer som alt finst.",
-       "api-error-stashfailed": "Intern feil: tenaren greidde ikkje å lagra ei mellombels fil.",
        "api-error-publishfailed": "Intern feil: tenaren greidde ikkje å publisera mellombels fil.",
-       "api-error-timeout": "Tenaren svara ikkje innan tida svar var venta.",
-       "api-error-unclassified": "Det oppstod ein ukjend feil.",
-       "api-error-unknown-code": "Ukjend feil: «$1»",
-       "api-error-unknown-error": "Intern feil: Noko gjekk gale då fila di vart freista lasta opp.",
+       "api-error-stashfailed": "Intern feil: tenaren greidde ikkje å lagra ei mellombels fil.",
        "api-error-unknown-warning": "Ukjend åtvaring: $1",
        "api-error-unknownerror": "Ukjend feil: «$1».",
-       "api-error-uploaddisabled": "Det er ikkje høve til å lasta opp filer til wikien.",
-       "api-error-verification-error": "Fila kan vera øydelagd eller ha rang filending.",
        "duration-seconds": "$1 {{PLURAL:$1|sekund|sekund}}",
        "duration-minutes": "$1 {{PLURAL:$1|minutt|minutt}}",
        "duration-hours": "$1 {{PLURAL:$1|time|timar}}",
index ea2bc9e..30bcfde 100644 (file)
        "changepassword-success": "Vòstre senhal es estat modificat !",
        "changepassword-throttled": "Avètz ensajat un tròp grand nombre de connexions darrièrament.\nEsperatz $1 abans d’ensajar tornarmai.",
        "botpasswords": "Senhals de robòts",
+       "botpasswords-disabled": "Los senhals robòts son desactivats.",
        "botpasswords-no-central-id": "Per intrar lo senhau d'un bot, devètz èsser connectat amb un còmpte globau.",
+       "botpasswords-existing": "Senhals de robòts existents",
        "botpasswords-createnew": "Crear un novèu senhau de bot",
        "botpasswords-editexisting": "Editar un senhau de bot existent",
        "botpasswords-label-appid": "Nom del robòt :",
        "passwordreset-emailelement": "Utilizaire: \n$1\n\nSenhal temporari: \n$2",
        "passwordreset-emailsentemail": "Se aquela adreiça de corrièr electrnic es associat ambé vòstre compte, un corrièr electronic de reïnicializacion de senhal es estat mandat.",
        "passwordreset-emailsentusername": "Se una adreiça de corrier electronic es associada amb aqueu còmpte d'utilizaire, un senhau de reïnicializacion serà mandat.",
+       "passwordreset-nosuchcaller": "L’apelant existís pas : $1",
        "passwordreset-invalidemail": "Adreiça electronica invalida",
        "changeemail": "Cambiar o suprimir l'adreça electronica",
        "changeemail-header": "Cambiar l'adreça electronica del compte",
        "mergehistory-done": "$3 version{{PLURAL:$3||s}} de $1 {{PLURAL:$3|es estada fusionada|son estada fusionadas}} dins [[:$2]].",
        "mergehistory-fail": "Impossible de procedir a la fusion dels istorics. Seleccionatz  tornamai la pagina e mai los paramètres de data.",
        "mergehistory-fail-bad-timestamp": "L’orodatatge es pas valid.",
+       "mergehistory-fail-invalid-source": "La pagina font es pas valida.",
        "mergehistory-fail-invalid-dest": "La pagina de destinacion es invalida",
        "mergehistory-fail-toobig": "Impossible d’efectuar la fusion de l’istoric perque un nombre de {{PLURAL:$1|revisions}} superior al limit de $1 deuriá èsser desplaçat.",
        "mergehistory-no-source": "La pagina d'origina $1 existís pas.",
        "right-sendemail": "Mandar un corrièl als autres utilizaires",
        "right-applychangetags": "Aplicar [[Special:Tags|las balisas]] amb sas pròprias modificacions",
        "grant-generic": "ensemble de dreits « $1 »",
+       "grant-group-page-interaction": "Interagir amb de paginas",
+       "grant-group-file-interaction": "Interagir amb de mèdias",
+       "grant-group-watchlist-interaction": "Interagir amb vòstra lista de seguiment",
        "grant-group-email": "Mandar un corrièr electronic",
        "grant-blockusers": "Blocar e desblocar d'utilizaires",
        "grant-createaccount": "Crear de comptes",
        "grant-uploadfile": "Telecargar un novèu fichier",
        "grant-basic": "Dreits de basa",
        "grant-viewdeleted": "Veire lei fichiers e lei paginas escafats",
+       "grant-viewmywatchlist": "Afichar vòstra lista de seguiment",
        "newuserlogpage": "Istoric de las creacions de comptes",
        "newuserlogpagetext": "Jornal de las creacions de comptes d'utilizaires.",
        "rightslog": "Istoric de las modificacions d'estatut",
        "action-upload_by_url": "importar aqueste fichièr a partir d’una adreça internet",
        "action-writeapi": "utilizar l‘API d’escritura",
        "action-delete": "suprimir aquesta pagina",
-       "action-deleterevision": "suprimir aquesta version",
+       "action-deleterevision": "suprimir las revisions",
        "action-deletelogentry": "Escafar lo jornau deis intradas",
-       "action-deletedhistory": "veire l’istoric suprimit d'aquesta pagina",
+       "action-deletedhistory": "veire l’istoric suprimit d'una pagina",
        "action-browsearchive": "recercar de paginas suprimidas",
-       "action-undelete": "restablir aquesta pagina",
-       "action-suppressrevision": "tornar veire e restablir aquesta version suprimida",
+       "action-undelete": "restablir de paginas",
+       "action-suppressrevision": "visionar e restablir de revisions suprimidas",
        "action-suppressionlog": "veire aqueste jornal privat",
        "action-block": "blocar aqueste utilizaire a l’edicion",
        "action-protect": "modificar los nivèls de proteccion per aquesta pagina",
        "recentchanges-legend-heading": "<strong>Legenda :</strong>",
        "recentchanges-legend-newpage": "{{int:recentchanges-label-newpage}} (veire tanben la [[Special:NewPages|lista de las paginas novèlas]]).",
        "recentchanges-submit": "Afichar",
+       "rcfilters-activefilters": "Filtres actius",
+       "rcfilters-invalid-filter": "Filtre pas valid",
+       "rcfilters-filterlist-title": "Filtres",
+       "rcfilters-filterlist-noresults": "Cap de filtre pas trobat",
+       "rcfilters-filtergroup-registration": "Inscripcion de l'utilizaire",
+       "rcfilters-filter-registered-label": "Enregistrat",
+       "rcfilters-filter-registered-description": "Editors connectats.",
+       "rcfilters-filter-unregistered-label": "Desinscrit",
+       "rcfilters-filter-unregistered-description": "Editors que son pas connectats.",
+       "rcfilters-filtergroup-authorship": "Modificar la paternitat",
+       "rcfilters-filter-editsbyself-label": "Vòstras pròprias modificacions",
+       "rcfilters-filter-editsbyself-description": "Vòstras modificacions.",
+       "rcfilters-filter-editsbyother-label": "Modificacions per d’autres.",
+       "rcfilters-filter-userExpLevel-newcomer-label": "Novèls arribants",
+       "rcfilters-filter-userExpLevel-learner-label": "Aprenents",
+       "rcfilters-filter-userExpLevel-experienced-label": "Utilizaires experimentats",
+       "rcfilters-filtergroup-automated": "Contribucions automatizadas",
+       "rcfilters-filter-bots-label": "Robòt",
+       "rcfilters-filter-humans-label": "Èsser uman (pas robòt)",
+       "rcfilters-filtergroup-significance": "Significacion",
+       "rcfilters-filter-minor-label": "Cambiaments menors",
+       "rcfilters-filter-major-label": "Modificacions pas menoras",
+       "rcfilters-filtergroup-changetype": "Tipe de cambiament",
+       "rcfilters-filter-pageedits-label": "Modificacions de pagina",
+       "rcfilters-filter-newpages-label": "Creacions de pagina",
+       "rcfilters-filter-categorization-label": "Cambiaments de categoria",
+       "rcfilters-filter-logactions-label": "Accions traçadas",
        "rcnotefrom": "Çaijós {{PLURAL:$5|la modificacion efectuada|las modificacions efectuadas}} dempuèi lo <strong>$3, $4</strong> (afichadas fins a <strong>$1</strong>).",
        "rclistfrom": "Afichar las modificacions novèlas dempuèi lo $3 $2",
        "rcshowhideminor": "$1 los cambiaments menors",
        "apisandbox-deprecated-parameters": "Paramètres obsolèts",
        "apisandbox-submit-invalid-fields-title": "De camps son invalides",
        "apisandbox-results": "Resultats",
+       "apisandbox-sending-request": "Mandadís de la requèsta a l'API...",
        "apisandbox-request-url-label": "Requèsta URL :",
        "apisandbox-request-time": "Durada de la demanda : {{PLURAL:$1|$1 ms}}",
        "apisandbox-continue": "Contunhar",
        "apisandbox-continue-clear": "Escafar",
+       "apisandbox-multivalue-all-namespaces": "$1 (totes los espacis de noms)",
+       "apisandbox-multivalue-all-values": "$1 (totas las valors)",
        "booksources": "Obratges de referéncia",
        "booksources-search-legend": "Recercar demest d'obratges de referéncia",
        "booksources-isbn": "ISBN :",
        "watchlistanontext": "Connectatz-vos per visualizar o modificar los elements de vòstra lista de seguiment.",
        "watchnologin": "Vos sètz pas identificat(ada)",
        "addwatch": "Apondre a la lista de seguiment",
-       "addedwatchtext": "La pagina « [[:$1]] » es estada aponduda a vòstra [[Special:Watchlist|lista de seguiment]]. Las modificacions venentas d'aquesta pagina e de la pagina de discussion associada i seràn repertoriadas.",
+       "addedwatchtext": "La pagina « [[:$1]] » e sa pagina de discussion son estadas apondudas a vòstra [[Special:Watchlist|lista de seguiment]].",
        "addedwatchtext-short": "La pagina « $1 » es estada aponduda a vòstra lista de seguiment.",
        "removewatch": "Suprimir de la lista de seguiment",
-       "removedwatchtext": "La pagina « [[:$1]] » es estada levada de vòstra [[Special:Watchlist|lista de seguiment]].",
+       "removedwatchtext": "La pagina « [[:$1]] » e sa pagina de discussion son estadas levadas de vòstra [[Special:Watchlist|lista de seguiment]].",
        "removedwatchtext-short": "La pagina « $1 » es estada suprimida de vòstra lista de seguiment.",
        "watch": "Seguir",
        "watchthispage": "Seguir aquesta pagina",
        "wlshowlast": "Far veire las darrièras $1 oras, los darrièrs $2 jorns",
        "watchlist-hide": "Amagar",
        "watchlist-submit": "Afichar",
+       "wlshowtime": "Periòde afichat :",
        "wlshowhideminor": "cambiaments menors",
        "wlshowhidebots": "Robòts",
        "wlshowhideliu": "utilizaires enregistrats",
        "wlshowhideanons": "utilizaires anonims",
        "wlshowhidepatr": "modificacions repassadas",
        "wlshowhidemine": "mas modificacions",
+       "wlshowhidecategorization": "categorizacion de la pagina",
        "watchlist-options": "Opcions de la lista de seguiment",
        "watching": "Seguit...",
        "unwatching": "Fin del seguit...",
        "sp-contributions-username": "Adreça IP o nom d’utilizaire :",
        "sp-contributions-toponly": "Mostrar sonque las contribucions que son las darrièras dels articles",
        "sp-contributions-newonly": "Afichar unicament las modificacions que son de creacions de pagina",
+       "sp-contributions-hideminor": "Amagar las modificacions menoras",
        "sp-contributions-submit": "Cercar",
        "whatlinkshere": "Paginas ligadas a aquesta",
        "whatlinkshere-title": "Paginas que puntan cap a « $1 »",
        "whatlinkshere-hidelinks": "$1 ligams",
        "whatlinkshere-hideimages": "$1 los ligams cap al fichièr",
        "whatlinkshere-filters": "Filtres",
+       "whatlinkshere-submit": "Validar",
        "autoblockid": "Blocatge automatic #$1",
        "block": "Blocar un utilizaire",
        "unblock": "Desblocar un utilizaire",
        "movenosubpage": "Aquesta pagina a pas cap de sospagina.",
        "movereason": "Motiu :",
        "revertmove": "anullar",
-       "delete_and_move_text": "==Supression requerida==\nL’article de destinacion « [[:$1]] » existís ja.\nLo volètz suprimir per permetre lo cambiament de nom ?",
+       "delete_and_move_text": "La pagina de destinacion « [[:$1]] » existís ja.\nSètz segur{{GENDER:||a|}} que la volètz suprimir pe permetre aqueste cambiament de nom ?",
        "delete_and_move_confirm": "Òc, accèpti de suprimir la pagina de destinacion per permetre lo cambiament de nom.",
        "delete_and_move_reason": "Pagina suprimida per permetre lo cambiament de nom dempuèi « [[$1]] »",
        "selfmove": "Los títols d’origina e de destinacion son los meteisses : impossible de tornar nomenar una pagina sus ela-meteissa.",
        "tooltip-ca-unprotect": "Cambiar la proteccion d'aquesta pagina",
        "tooltip-ca-delete": "Suprimir aquesta pagina",
        "tooltip-ca-undelete": "Restablir aquesta pagina",
-       "tooltip-ca-move": "Tornar nomenar aquesta pagina",
+       "tooltip-ca-move": "Renomenar aquesta pagina",
        "tooltip-ca-watch": "Apondètz aquesta pagina a vòstra lista de seguiment",
        "tooltip-ca-unwatch": "Levatz aquesta pagina de vòstra lista de seguiment",
        "tooltip-search": "Cercar dins {{SITENAME}}",
        "pageinfo-length": "Talha de la pagina (en octets)",
        "pageinfo-article-id": "Numèro de la pagina",
        "pageinfo-language": "Lenga del contengut de la pagina",
+       "pageinfo-language-change": "modificar",
        "pageinfo-content-model": "Modèl de contengut de la pagina",
        "pageinfo-content-model-change": "modificar",
        "pageinfo-robot-policy": "Indexacion per robòts",
        "newimages-legend": "Filtre",
        "newimages-label": "Nom del fichièr (o una partida d'aqueste) :",
        "newimages-showbots": "Afichar los impòrts per de robòts",
+       "newimages-hidepatrolled": "Amagar los telecargaments patrolhats",
        "noimages": "Cap d'imatge d'afichar pas.",
+       "gallery-slideshow-toggle": "Bascular las vinhetas",
        "ilsubmit": "Cercar",
        "bydate": "per data",
        "sp-newimages-showfrom": "Afichar los imatges novèls importats dempuèi lo $2, $1",
        "exif-compression-4": "CCITT Grop 4 encodatge del fax",
        "exif-copyrighted-true": "Somés al dreit d'autor",
        "exif-copyrighted-false": "Estat dels dreits d’autor pas definit",
+       "exif-photometricinterpretation-1": "Blanc e negre (0 pel negre)",
        "exif-unknowndate": "Data desconeguda",
        "exif-orientation-1": "Normala",
        "exif-orientation-2": "Inversada orizontalament",
        "confirmemail_body_set": "Qualqu’un, probablament vos, dempuèi l’adreça IP $1, a modificat l'adreça de corrièr electronic del compte « $2 » amb aquesta sul site {{SITENAME}}.\n\nPer confirmar qu'aqueste compte vos aparten vertadièrament e reactivar las foncions de messatjariá sus {{SITENAME}}, seguissètz lo ligam çaijós dins vòstre navigador :\n\n$3\n\nAqueste còdi de confirmacion expirarà lo $4.\n\nSe s’agís *pas* de vòstre compte, seguissètz aqueste ligam per anullar la confirmacion de l'adreça de corrièr electronic :\n\n$5",
        "confirmemail_invalidated": "Confirmacion de l’adreça de corrièr electronic anullada",
        "invalidateemail": "Anullar la confirmacion del corrièr electronic",
+       "notificationemail_subject_changed": "L'adreça de corrièr electronic enregistrada de {{SITENAME}} es estada cambiada",
+       "notificationemail_subject_removed": "L'adreça de corrièr electronic enregistrada de {{SITENAME}} es estada suprimida",
        "scarytranscludedisabled": "[La transclusion interwiki es desactivada]",
        "scarytranscludefailed": "[La recuperacion de modèl a pas capitat per $1]",
        "scarytranscludefailed-httpstatus": "[Fracàs de la recuperacion del modèl per  $1 : HTTP  $2 ]",
        "logentry-newusers-create2": "Lo compte d'utilizaire $3 {{GENDER:$2|es estat creat}} per $1",
        "logentry-newusers-byemail": "Lo compte d'utilizaire $3 {{GENDER:$2|es estat creat}} per $1 e lo senhal es estat mandat per corrièr electronic",
        "logentry-newusers-autocreate": "Lo compte $1 {{GENDER:$2|es estat creat}} automaticament",
-       "logentry-rights-rights": "$1 {{GENDER:$2|a modificat}} l'apartenéncia al grop per $3 de $4 a $5",
+       "logentry-rights-rights": "$1 a modificat l’apartenéncia al grop per {{GENDER:$6|$3}} de $4 a $5",
        "logentry-rights-rights-legacy": "$1 {{GENDER:$2|a modificat}} l'apartenéncia al grop per $3",
        "logentry-rights-autopromote": "$1 {{GENDER:$2|es estat promolgut}} automaticament de $4 a $5",
        "logentry-upload-upload": "$1 {{GENDER:$2|a mandat}} $3",
        "api-error-emptypage": "Creacion de paginas voidas pas autorizada.",
        "api-error-publishfailed": "Error intèrna: Lo servidor a pas pogut publicar lo fichièr temporari.",
        "api-error-stashfailed": "Error intèrna : lo servidor a pas pogut enregistrar lo fichièr temporari.",
-       "api-error-unknown-warning": "Avertiment desconegut : $1",
+       "api-error-unknown-warning": "Avertiment desconegut : « $1 ».",
        "api-error-unknownerror": "Error desconeguda : « $1 »",
        "duration-seconds": "$1 segonda{{PLURAL:$1||s}}",
        "duration-minutes": "$1 minuta{{PLURAL:$1||s}}",
        "pagelang-language": "Lenga",
        "pagelang-use-default": "Utilizar la lenga per defaut",
        "pagelang-select-lang": "Seleccionar la lenga",
+       "pagelang-reason": "Motiu",
        "pagelang-submit": "Validar",
+       "pagelang-nonexistent-page": "La pagina $1 existís pas.",
        "right-pagelang": "Cambiar la lenga de la pagina",
        "action-pagelang": "cambiar la lenga de la pagina",
        "log-name-pagelang": "Traçar los cambiaments de lenga",
        "special-characters-group-ipa": "API",
        "special-characters-group-symbols": "Simbòls",
        "special-characters-group-greek": "Grèc",
+       "special-characters-group-greekextended": "Grèc espandit",
        "special-characters-group-cyrillic": "Cirillic",
        "special-characters-group-arabic": "Arabi",
        "special-characters-group-arabicextended": "Arabi espandit",
        "special-characters-title-endash": "jonhent anglés",
        "special-characters-title-emdash": "jonhent em",
        "special-characters-title-minus": "signe mens",
+       "mw-widgets-dateinput-no-date": "Cap de data pas seleccionada",
+       "mw-widgets-mediasearch-input-placeholder": "Recercar de mèdias",
        "mw-widgets-mediasearch-noresults": "Ges de resultat trobat",
        "mw-widgets-categoryselector-add-category-placeholder": "Ajustar una categoria...",
        "sessionprovider-generic": "$1 sessions",
        "log-action-filter-patrol-autopatrol": "Patrolha automatica",
        "log-action-filter-protect-protect": "Proteccion",
        "log-action-filter-protect-modify": "Modificacion de proteccion",
+       "log-action-filter-protect-unprotect": "Desproteccion",
+       "log-action-filter-protect-move_prot": "Proteccion de renomenatge",
        "log-action-filter-rights-rights": "Cambiament manuau",
        "log-action-filter-rights-autopromote": "Cambiament automatic",
+       "log-action-filter-suppress-event": "Supression de jornal",
+       "log-action-filter-suppress-revision": "Supression de revision",
        "log-action-filter-suppress-delete": "Supression de pagina",
        "log-action-filter-upload-upload": "Telecargament novèu",
        "log-action-filter-upload-overwrite": "Retelecargament",
        "authprovider-confirmlink-success-line": "$1 : operacion capitada, lei còmptes son estats liats.",
        "authprovider-confirmlink-failed": "La temptativa de liar lei còmptes a pas capitat : $1",
        "authprovider-resetpass-skip-label": "Sautar",
+       "authform-newtoken": "Geton mancant. $1",
+       "authform-notoken": "Geton mancant",
+       "authform-wrongtoken": "Marrit geton",
        "specialpage-securitylevel-not-allowed-title": "Pas autorizat",
        "changecredentials": "Modificar las informacions d’identificacion",
+       "credentialsform-account": "Nom de compte :",
        "linkaccounts": "Liar lei còmptes",
        "linkaccounts-success-text": "Lo còmpte èra estat liat.",
        "linkaccounts-submit": "Liar lei còmptes",
index d96cf90..8f3f530 100644 (file)
@@ -25,6 +25,7 @@
        "tog-enotifusertalkpages": "Éspédier un imèle su em bouéte quante m'pache \"Dvise Uzeu\" est candgée.",
        "tog-enotifminoredits": "M'éspédier étou un imèle pou chés tiots canjemints d'chés paches o d'chés fichiés",
        "tog-shownumberswatching": "Aficher ch'nombe ed gins qu'ont vu.",
+       "tog-uselivepreview": "Implouéyer ch'rade intrévir",
        "tog-watchlisthideown": "Muche ems édicions dseur el lisse à suire",
        "tog-watchlisthidebots": "Muche chés édicions des robots su el lisse à suire",
        "tog-watchlisthideminor": "Muche chés tiotes édicions su el lisse à suire.",
        "oct": "Oct",
        "nov": "Nov",
        "dec": "Déc",
+       "january-date": "{{PLURAL:$1|1=1ᵉʳ|$1}} jinvié",
+       "february-date": "{{PLURAL:$1|1=1ᵉʳ|$1}} févrié",
+       "march-date": "{{PLURAL:$1|1=1ᵉʳ|$1}} marche",
+       "april-date": "{{PLURAL:$1|1=1ᵉʳ|$1}} avri",
+       "may-date": "{{PLURAL:$1|1=1ᵉʳ|$1}} moai",
+       "june-date": "{{PLURAL:$1|1=1ᵉʳ|$1}} join",
+       "july-date": "{{PLURAL:$1|1=1ᵉʳ|$1}} juilet",
+       "august-date": "{{PLURAL:$1|1=1ᵉʳ|$1}} eut",
+       "september-date": "{{PLURAL:$1|1=1ᵉʳ|$1}} siétimbe",
+       "october-date": "{{PLURAL:$1|1=1ᵉʳ|$1}} octobe",
+       "november-date": "{{PLURAL:$1|1=1ᵉʳ|$1}} novimbe",
+       "december-date": "{{PLURAL:$1|1=1ᵉʳ|$1}} déchimbe",
+       "period-am": "AM",
+       "period-pm": "PM",
        "pagecategories": "{{PLURAL:$1|Catégorie|Catégories}}",
        "category_header": "Paches in catégorie \"$1\"",
        "subcategories": "Dsoucatégories",
        "hidden-category-category": "Catégouries muchées",
        "category-subcat-count": "{{PLURAL:$2|Chol catégorie ale o seulemint el dsou-catégorie-lo:|Chol catégorie ale o  {{PLURAL:$1|l'dsou-catégorie-lo|chés $1 dsou-catégories suivantes}}, pou un total éd $2.}}",
        "category-subcat-count-limited": "L'catégorie-lo ale o {{PLURAL:$1|el dsous-catégorie|chés $1 dsous-catégories}} -lo:",
-       "category-article-count": "Chol catégorie ale o {{PLURAL:$2|seulemint l'pache-lo:|$2 paches, dont{{PLURAL:$1|chelle-chi:|chés $1 paches chi:}} }}",
+       "category-article-count": "Chol catégorie ale o {{PLURAL:$2|0= autchune pache|1=seulemint l'pache-lo:|$2 paches, dont{{PLURAL:$1|0=autchune|1=chelle-chi|chés $1 paches in-dsous}} }}:",
        "category-article-count-limited": "{{PLURAL:$1|L' pache d'apré ale est|Chés $1 paches d'apré sont}} dins l'catégorie-lo.",
        "category-file-count": "Chol catégorie ale o  {{PLURAL:$2|seulemint ech fichié-lo:|$2 fichiés dont chés $1 fichiés suivants:}}",
        "category-file-count-limited": "{{PLURAL:$1|Ech fichié d'apré est|Chés $1 fichiés d'apré sont}} dins l'catégorie-lo.",
        "listingcontinuesabbrev": "cont.",
+       "index-category": "Paches indécsées",
        "noindex-category": "Paches nin indécsées",
        "broken-file-category": "Paches aveuc des loïens d'fichiés bérzillés",
        "about": "À pérpos",
        "newwindow": "(ouvrir din eune nouvèle fernéte)",
        "cancel": "Canchler",
        "moredotdotdot": "Plu...",
+       "morenotlisted": "Chol lisse peut ète incomplète.",
        "mypage": "Pache",
        "mytalk": "Min bavouér",
-       "anontalk": "Bavouér pou chl'IP-lo",
+       "anontalk": "Bavouér",
        "navigation": "Navigachon",
        "and": "&#32;pi",
        "qbfind": "Trouvoèr",
        "actions": "Acchons",
        "namespaces": "Éspaces d'chés noms",
        "variants": "Ércanjantes",
+       "navigation-heading": "Menu éd navigacion",
        "errorpagetitle": "Bérlure",
        "returnto": "Értrouve $1.",
        "tagline": "Cha vient éd {{SITENAME}}",
        "searcharticle": "Aller",
        "history": "Historique deul pache",
        "history_short": "Histoère",
+       "history_small": "Histoère",
        "updatedmarker": "Cangé édpui em darinne visite",
        "printableversion": "Imprimabe vérchon",
        "permalink": "Loïen pérmanint",
        "print": "Imprimer",
        "view": "Vir",
+       "view-foreign": "Vir su $1",
        "edit": "Éditer",
+       "edit-local": "Modifier el déscripcion locale",
        "create": "Créer",
+       "create-local": "Ajouter ène déscripcion locale",
        "editthispage": "Éditer chl'pache-lo",
        "create-this-page": "Créer chl'pache lo",
        "delete": "Défacer",
        "deletethispage": "Défacer chl'pache lo",
+       "undeletethispage": "n'poin défacer chol pache",
        "undelete_short": "Déface poin {{PLURAL:$1|un édite|$1 édites}}",
        "viewdeleted_short": "{{PLURAL:$1|eune édition défacée|$1  éditions défacées}}",
        "protect": "Garantir",
        "talk": "distchuter",
        "views": "Vues",
        "toolbox": "Boéte à otis",
+       "tool-link-userrights": "Modifier chés groupes éd {{GENDER:$1|l’uzeu|l’uzeuse}}",
+       "tool-link-userrights-readonly": "Vir chés {{GENDER:$1|groupes d'uzeu}}",
+       "tool-link-emailuser": "Invouéyer un courriel à {{GENDER:$1|l’uzeu|l’uzeuse}}",
        "userpage": "Vir el pache dech uzeu",
        "projectpage": "Vir l'pache dech prodjé",
        "imagepage": "Vir el pache dech fichié",
        "otherlanguages": "Din d'eutes langaches",
        "redirectedfrom": "(Érdirection édpis $1)",
        "redirectpagesub": "Pache érdérivée",
+       "redirectto": "Ardiriger vers :",
        "lastmodifiedat": "L'pache-lo ale o té modifiée l'fouos darin l' $1, à $2.",
        "viewcount": "L' page-lo ale o té vue {{PLURAL:$1|1 foués|$1 foués}}.",
        "protectedpage": "Pache défènnée",
        "jumpto": "Aler à:",
        "jumptonavigation": "navigachon",
        "jumptosearch": "tracher",
+       "pool-errorunknown": "Bérlurage inconnu",
+       "poolcounter-usage-error": "Bérlurage d’utilisacion : $1",
        "aboutsite": "à pérpos éd {{SITENAME}}",
        "aboutpage": "Project:à pérpos",
-       "copyright": "Ch'contnu, il est disponipe dsou $1.",
+       "copyright": "Ch'contnu, il est disponipe dsou licince $1 sauf mincion invérse.",
        "copyrightpage": "{{ns:project}}:Copyrights",
        "currentevents": "Darinnetés picardes",
        "currentevents-url": "Project:Darinnetés picardes",
        "disclaimers": "Démintis",
        "disclaimerpage": "Project:Déminti général",
        "edithelp": "Éditer el aiyude",
+       "helppage-top-gethelp": "Aïude",
        "mainpage": "Moaite Pache",
        "mainpage-description": "Moaite Pache",
+       "policy-url": "Project:Régues",
        "portal": "Portal del conmeunauté",
        "portal-url": "Project:Accueul del conminnité",
        "privacy": "Politique d'éscrè",
        "ok": "OK",
        "retrievedfrom": "Érprind din  \"$1\"",
        "youhavenewmessages": "Os avez $1 ($2).",
+       "youhavenewmessagesmanyusers": "Os avez $1 granmint d'uzeus ($2).",
+       "newmessagesdifflinkplural": "$1 {{PLURAL:$1|darin cangemint|darins cangemints}}",
        "youhavenewmessagesmulti": "Os avez des nouvieus messaches su $1",
        "editsection": "éditer",
        "editold": "éditer",
        "toc": "Étnus",
        "showtoc": "Aficher",
        "hidetoc": "muche",
+       "collapsible-collapse": "Érplier",
+       "collapsible-expand": "diswalper",
+       "confirmable-confirm": "Ètes-vos seur{{GENDER:$1||e}} ?",
+       "confirmable-yes": "Oui",
+       "confirmable-no": "Non",
        "thisisdeleted": "Vir ou érfoaire $1?",
        "viewdeleted": "Vir $1?",
        "restorelink": "{{PLURAL:$1|eune édition défacée|$1 chés éditions défacées}}",
        "nstab-template": "Modéle",
        "nstab-help": "Pache d'aiyude",
        "nstab-category": "Catégorie",
+       "mainpage-nstab": "Moaite Pache",
        "nosuchspecialpage": "I n'y o poin chot éspéchiale pache-lo",
        "error": "Bérlurache",
        "databaseerror": "Bérlurache din l'database",
        "login": "Intrer",
        "nav-login-createaccount": "Intrer / créer vote conpte",
        "userlogin": "Intrer / créer vote conpte",
+       "userloginnocreate": "Intrer",
        "logout": "Sortir",
        "userlogout": "Sortir",
        "notloggedin": "Poin connékté",
+       "userlogin-noaccount": "os n'avez mie un conpte ?",
+       "userlogin-joinproject": "Érgaingnez {{SITENAME}}",
        "nologin": "os n'avez mie un conpte? '''$1'''.",
        "nologinlink": "Créer un conpte",
        "createaccount": "Créer un conpte",
        "gotaccount": "Jou qu'os avez piécha un conpte? '''$1'''.",
        "gotaccountlink": "Intrer",
        "userlogin-resetlink": "Vos avez oblié vous détals d'connécsion ?",
-       "createaccountmail": "par imèle",
+       "userlogin-resetpassword-link": "Mot d'passe obliè ?",
+       "userlogin-helplink2": "Éyude pour s' connécter",
+       "userlogin-loggedin": "Os ètes déjo connécté{{GENDER:$1||e|(e)}} conme $1.\nImplouéyez ch' formuloére in-d'sous pour vous connécter aveuc un eute compte d'uzeu.",
+       "userlogin-reauth": "Os d'vez vous arconnécter pour vérifier éq vos ètes {{GENDER:$1|$1}}.",
+       "userlogin-createanother": "Créer un eute compte",
+       "createacct-emailrequired": "Adrèche courriel",
+       "createacct-emailoptional": "Adrèche courriel (facultative)",
+       "createacct-email-ph": "Intrez vote adrèche courriel",
+       "createacct-another-email-ph": "Intrez l' adrèche courriel",
+       "createaccountmail": "Uzer un mot d' passe aléatoére timporoére pi l’invouéyer à l’adrèche ed courriel éspécifiée",
+       "createaccountmail-help": "Peut ète implouèyé pour créer un compte pour eune eute parsonne sans connouaite ch' mot d'passe.",
+       "createacct-realname": "Nom réél (facultatif)",
+       "createaccountreason": "Motif :",
+       "createacct-reason": "Motif",
+       "createacct-reason-ph": "Porquoé os créez un eute compte ?",
+       "createacct-reason-help": "Mot d'billet affiché dins ch' jornal éd créachon d'compte",
+       "createacct-submit": "Créez vote compte",
+       "createacct-another-submit": "Créer un compte",
+       "createacct-continue-submit": "Continuer el créachon du compte",
+       "createacct-another-continue-submit": "Continuer el créachon du compte",
+       "createacct-benefit-heading": "{{SITENAME}} est foait pèr des gins conme vous.",
+       "createacct-benefit-body1": "modificacion{{PLURAL:$1||s}}",
+       "createacct-benefit-body2": "pache{{PLURAL:$1||s}}",
+       "createacct-benefit-body3": "{{PLURAL:$1|contributeu nouvieu|contributeus nouvieus}}",
        "badretype": "Chés mots d'passe intrés, is sont poin bon.",
+       "usernameinprogress": "Ène créachon d' compte pour ch' nom d’uzeu est déjo in cours.\nVoulez attènne.",
        "userexists": "Nom d’utilisateur entré déjà utilisé.\nNom d’uzeu intré déjo donné.\ni feut prinde un eute nom.\nj'm'escuse mais i feut prinde un aute nom.",
        "loginerror": "Bérlurache del intrée",
+       "createacct-error": "Bérlurage pour l'créachon du compte",
+       "createaccounterror": "Impossibe ed créer ch' compte : $1",
+       "nocookiesnew": "Ch' compte d'uzeu il o té créé, mais os n’ètes poin connecté{{GENDER:||e|(e)}}.\n{{SITENAME}} doét implouéyer des ''cookies'' pour warder el connecsion mais os les avez désactivés.\nVoulez les activer pi vos arconnecter aveuc ch' meume nom et pi ch' meume mot d'passe.",
+       "nocookieslogin": "{{SITENAME}} doét implouéyer des ''cookies'' pour warder el connecsion mais os les avez désactivés.\nVoulez les activer pi vos arconnecter.",
+       "nocookiesfornew": "Ch' compte d'uzeu il n'o poin té créé, pasqué os n’avons poin pu idintifier esn origine.\n{{SITENAME}} doét implouéyer des ''cookies'', vérifiez qu'ils sont activés, arquétchez l' pache pi érquérminchez.",
        "noname": "Os n'avez poin donné un nom d'uzeu valabe.",
        "loginsuccess": "'''Achteur os ètes intré{{GENDER:||e|(e)}} din {{SITENAME}} conme \"$1\".'''",
        "nouserspecified": "Os dvez intrer un nom d'uzeu.",
index d369b8e..4016aac 100644 (file)
        "apisandbox-sending-request": "Wysyłanie zapytania API…",
        "apisandbox-loading-results": "Pobieranie wyników API...",
        "apisandbox-results-error": "Wystąpił błąd podczas pobierania odpowiedzi na zapytanie API: $1.",
-       "apisandbox-request-params-json": "Parametry JSON:",
        "apisandbox-request-url-label": "URL zapytania:",
        "apisandbox-request-time": "Czas przetwarzania zapytania: {{PLURAL:$1|$1 ms}}",
        "apisandbox-results-fixtoken": "Popraw token i wyślij ponownie",
        "emailccsubject": "Kopia Twojej wiadomości do $1: $2",
        "emailsent": "Wiadomość została wysłana",
        "emailsenttext": "Twoja wiadomość została wysłana.",
-       "emailuserfooter": "Ten e-mail został {{GENDER:$1|wysłany}} z {{GRAMMAR:D.lp|{{SITENAME}}}} do {{GENDER:$2|$2}} przez $1 przy użyciu funkcji „{{int:emailuser}}”. {{GENDER:$2|Twoja}} odpowiedź na ten e-mail zostanie wysłana do {{GENDER:$1|oryginalnego nadawcy}}, a {{GENDER:$2|Twój}} adres e-mail zostanie {{GENDER:$1|mu|jej}} ujawniony.",
+       "emailuserfooter": "Ten e-mail został {{GENDER:$1|wysłany}} z {{GRAMMAR:D.lp|{{SITENAME}}}} do {{GENDER:$2|$2}} przez $1 przy użyciu funkcji „{{int:emailuser}}”. Jeśli {{GENDER:$2|Twoja}} odpowiedź na ten e-mail zostanie wysłana do {{GENDER:$1|oryginalnego nadawcy}}, wówczas {{GENDER:$2|Twój}} adres e-mail zostanie {{GENDER:$1|mu|jej}} ujawniony.",
        "usermessage-summary": "Pozostawianie komunikatu systemowego.",
        "usermessage-editor": "Nadawca komunikatów systemowych",
        "watchlist": "Obserwowane",
index 7aa8b09..fcfa032 100644 (file)
        "recentchanges-legend-plusminus": "(''±123'')",
        "recentchanges-submit": "Exibir",
        "rcfilters-activefilters": "Filtros ativos",
+       "rcfilters-restore-default-filters": "Restaurar filtros padrão",
+       "rcfilters-clear-all-filters": "Limpar todos os filtros",
        "rcfilters-search-placeholder": "Filtrar alterações recentes (procurar ou começar a digitar)",
        "rcfilters-invalid-filter": "Filtro inválido",
+       "rcfilters-empty-filter": "Nenhum filtro ativo. Todas as contribuições são mostradas.",
        "rcfilters-filterlist-title": "Filtros",
        "rcfilters-filterlist-noresults": "Nenhum filtro encontrado",
+       "rcfilters-filtergroup-registration": "Registro de usuário",
+       "rcfilters-filter-registered-label": "Registrado",
+       "rcfilters-filter-registered-description": "Editores conectados.",
+       "rcfilters-filter-unregistered-label": "Não registrado",
+       "rcfilters-filter-unregistered-description": "Editores que não estão conectados.",
        "rcfilters-filtergroup-authorship": "Editar autoria",
        "rcfilters-filter-editsbyself-label": "Suas próprias edições",
        "rcfilters-filter-editsbyself-description": "Edições por você.",
        "rcfilters-filter-editsbyother-label": "Edições de outros",
        "rcfilters-filter-editsbyother-description": "Edições criadas por outros usuários (não você.)",
-       "rcfilters-filtergroup-userExpLevel": "Nível de experiência do usuário",
+       "rcfilters-filtergroup-userExpLevel": "Nível de experiência (apenas para usuário registados)",
        "rcfilters-filter-userExpLevel-newcomer-label": "Recém-chegados",
-       "rcfilters-filter-userExpLevel-newcomer-description": "Editores muito novos: menos de 10 edições e 4 dias de atividade.",
+       "rcfilters-filter-userExpLevel-newcomer-description": "Menos de 10 edições e 4 dias de atividade.",
        "rcfilters-filter-userExpLevel-learner-label": "Aprendizes",
        "rcfilters-filter-userExpLevel-learner-description": "Mais dias de atividade e edições do que \"Novatos\", mas menos do que \"Usuários experientes\".",
        "rcfilters-filter-userExpLevel-experienced-label": "Usuários experientes",
        "rcfilters-filter-userExpLevel-experienced-description": "Mais de 30 dias de atividade e 500 edições.",
+       "rcfilters-filtergroup-automated": "Contribuições automatizadas",
+       "rcfilters-filter-bots-label": "Robô",
+       "rcfilters-filter-bots-description": "Edições feitas por ferramentas automatizadas.",
+       "rcfilters-filter-humans-label": "Humano (não bot)",
+       "rcfilters-filter-humans-description": "Edições feitas por editores humanos.",
+       "rcfilters-filtergroup-significance": "Significado",
+       "rcfilters-filter-minor-label": "Edições menores",
+       "rcfilters-filter-minor-description": "Edita o autor rotulado como menor.",
+       "rcfilters-filter-major-label": "Edições não menores",
+       "rcfilters-filter-major-description": "Edições não rotuladas como menores.",
+       "rcfilters-filtergroup-changetype": "Tipo de mudança",
+       "rcfilters-filter-pageedits-label": "Edições da página",
+       "rcfilters-filter-pageedits-description": "Edições para conteúdo wiki, discussões, descrições de categorias ....",
+       "rcfilters-filter-newpages-label": "Criações de páginas",
+       "rcfilters-filter-newpages-description": "Edições que fazem novas páginas.",
+       "rcfilters-filter-categorization-label": "Mudanças de categoria",
+       "rcfilters-filter-categorization-description": "Registros de páginas que estão sendo adicionadas ou removidas de categorias.",
+       "rcfilters-filter-logactions-label": "Acções registadas",
+       "rcfilters-filter-logactions-description": "Ações administrativas, criação de contas, eliminação de páginas, carregamentos ...",
        "rcnotefrom": "Abaixo {{PLURAL:$5|é a mudança|são as mudanças}} desde <strong>$3, $4</strong> (up to <strong>$1</strong> shown).",
        "rclistfrom": "Mostrar as novas alterações a partir das $2 de $3",
        "rcshowhideminor": "$1 edições menores",
        "apisandbox-sending-request": "Enviando solicitação de API ...",
        "apisandbox-loading-results": "Recebendo resultados da API ...",
        "apisandbox-results-error": "Ocorreu um erro ao carregar a resposta de consulta da API: $1.",
-       "apisandbox-request-params-json": "parâmetros JSON:",
+       "apisandbox-request-selectformat-label": "Mostrar dados do pedido como:",
+       "apisandbox-request-format-url-label": "Sequência de consulta de URL",
        "apisandbox-request-url-label": "URL solicitante:",
+       "apisandbox-request-json-label": "Pedido JSON:",
        "apisandbox-request-time": "Tempo do pedido: {{PLURAL:$1|$1 ms}}",
        "apisandbox-results-fixtoken": "Corrigir token e reenviar",
        "apisandbox-results-fixtoken-fail": "Falha ao buscar token \"$1\".",
        "usercssispublic": "Observação: As subpáginas CSS não devem conter dados confidenciais, pois são visíveis por outros usuários.",
        "restrictionsfield-badip": "Endereço IP ou intervalo inválido: $1",
        "restrictionsfield-label": "Intervalos IP permitidos:",
-       "restrictionsfield-help": "Um endereço IP ou intervalo CIDR por linha. Para ativar tudo, use<br><code>0.0.0.0/0</code><br><code>::/0</code>",
+       "restrictionsfield-help": "Um endereço IP ou intervalo CIDR por linha. Para ativar tudo, use\n<pre>0.0.0.0/0\n::/0</pre>",
        "revid": "revisão $1",
        "pageid": "ID da página $1"
 }
index cca5fc1..eb93915 100644 (file)
        "youremail": "Correio eletrónico:",
        "username": "Nome de {{GENDER:$1|utilizador|utilizadora|utilizador(a)}}:",
        "prefs-memberingroups": "{{GENDER:$2|Membro}} {{PLURAL:$1|do grupo|dos grupos}}:",
+       "group-membership-link-with-expiry": "$1 (até $2)",
        "prefs-registration": "Hora de registo:",
        "yourrealname": "Nome verdadeiro:",
        "yourlanguage": "Língua:",
        "userrights-nodatabase": "A base de dados $1 não existe ou não é uma base de dados local.",
        "userrights-changeable-col": "Grupos que pode alterar",
        "userrights-unchangeable-col": "Grupos que não pode alterar",
+       "userrights-expiry-current": "Expira a $1",
+       "userrights-expiry-none": "Não expira",
+       "userrights-expiry": "Expira a:",
+       "userrights-expiry-existing": "Prazo de expiração: $3, $2",
+       "userrights-expiry-othertime": "Outra duração:",
+       "userrights-expiry-options": "1 dia:1 day,1 semana:1 week,1 mês:1 month,3 meses:3 months,6 meses:6 months,1 ano:1 year",
+       "userrights-invalid-expiry": "O tempo de expiração para o grupo \"$1\" é inválido.",
+       "userrights-expiry-in-past": "O tempo de expiração para o grupo \"$1\" está no passado.",
        "userrights-conflict": "Conflito entre alterações de privilégios de utilizador! Por favor, reveja e confirme as suas mudanças.",
        "group": "Grupo:",
        "group-user": "Utilizadores",
        "recentchanges-legend-plusminus": "(<em>±123</em>)",
        "recentchanges-submit": "Mostrar",
        "rcfilters-activefilters": "Filtros ativos",
+       "rcfilters-restore-default-filters": "Restaurar os filtros padrão",
+       "rcfilters-clear-all-filters": "Limpar todos os filtros",
        "rcfilters-search-placeholder": "Filtrar mudanças recentes (navegue ou começe a escrever)",
        "rcfilters-invalid-filter": "Filtro inválido",
+       "rcfilters-empty-filter": "Nenhum filtro ativo. Todas as contribuições são mostradas.",
        "rcfilters-filterlist-title": "Filtros",
        "rcfilters-filterlist-noresults": "Não foram encontrados filtros",
+       "rcfilters-filtergroup-registration": "Registo de utilizador",
+       "rcfilters-filter-registered-label": "Registado",
+       "rcfilters-filter-registered-description": "Editores autenticados.",
+       "rcfilters-filter-unregistered-label": "Não registado",
+       "rcfilters-filter-unregistered-description": " Editores que não estão autenticados.",
        "rcfilters-filtergroup-authorship": "Editar autoria",
        "rcfilters-filter-editsbyself-label": "As suas próprias edições",
        "rcfilters-filter-editsbyself-description": "Edições suas.",
        "rcfilters-filter-editsbyother-label": "Edições de outros",
        "rcfilters-filter-editsbyother-description": "Edições criadas por outros utilizadores (não por si).",
-       "rcfilters-filtergroup-userExpLevel": "Nível de experiência do utilizador",
+       "rcfilters-filtergroup-userExpLevel": "Nível de experiência (apenas para utilizadores registados)",
        "rcfilters-filter-userExpLevel-newcomer-label": "Novatos",
-       "rcfilters-filter-userExpLevel-newcomer-description": "Editores muito recentes: menos de 10 edições e 4 dias de atividade.",
+       "rcfilters-filter-userExpLevel-newcomer-description": "Menos de 10 edições e 4 dias de atividade.",
        "rcfilters-filter-userExpLevel-learner-label": "Aprendizes",
        "rcfilters-filter-userExpLevel-learner-description": "Mais dias de atividade e edições do que \"Novatos\", mas menos do que \"Utilizadores experientes\".",
        "rcfilters-filter-userExpLevel-experienced-label": "Utilizadores experientes",
        "rcfilters-filter-userExpLevel-experienced-description": "Mais de 30 dias de atividade e 500 edições.",
+       "rcfilters-filtergroup-automated": "Contribuições automatizadas",
+       "rcfilters-filter-bots-label": "Bot",
+       "rcfilters-filter-bots-description": "Edições efectuadas por ferramentas automatizadas.",
+       "rcfilters-filter-humans-label": "Humano (não bot)",
+       "rcfilters-filter-humans-description": "Edições efectuadas por editores humanos.",
+       "rcfilters-filtergroup-significance": "Significado",
+       "rcfilters-filter-minor-label": "Edições menores",
+       "rcfilters-filter-minor-description": "Edições marcadas pelo autor como menores.",
+       "rcfilters-filter-major-label": "Edições não-menores",
+       "rcfilters-filter-major-description": "Edições não marcadas como menores.",
+       "rcfilters-filtergroup-changetype": "Tipo de alteração",
+       "rcfilters-filter-pageedits-label": "Edições da página",
+       "rcfilters-filter-pageedits-description": "Edições do conteúdo wiki, discussões, descrições de categorias....",
+       "rcfilters-filter-newpages-label": "Criações de páginas",
+       "rcfilters-filter-newpages-description": "Edições que criam novas páginas.",
+       "rcfilters-filter-categorization-label": "Alterações de categoria",
+       "rcfilters-filter-categorization-description": "Registos de páginas que estão a ser adicionadas ou removidas das categorias.",
+       "rcfilters-filter-logactions-label": "Ações registadas",
+       "rcfilters-filter-logactions-description": "Ações administrativas, criação de contas, eliminação de páginas, carregamentos....",
        "rcnotefrom": "Abaixo {{PLURAL:$5|está a mudança|estão as mudanças}} desde <strong>$2</strong> (mostradas até <strong>$1</strong>).",
        "rclistfrom": "Mostrar as novas mudanças a partir das $2 de $3",
        "rcshowhideminor": "$1 edições menores",
        "apisandbox-sending-request": "A enviar solicitação de API...",
        "apisandbox-loading-results": "A receber resultados da API...",
        "apisandbox-results-error": "Ocorreu um erro ao carregar a resposta à consulta por API: $1",
-       "apisandbox-request-params-json": "Parâmetros JSON:",
+       "apisandbox-request-selectformat-label": "Mostrar dados do pedido como:",
+       "apisandbox-request-format-url-label": "Sequência de consulta da URL",
        "apisandbox-request-url-label": "URL do pedido:",
+       "apisandbox-request-json-label": "Pedido JSON:",
        "apisandbox-request-time": "Tempo de processamento: {{PLURAL:$1|$1 ms}}",
        "apisandbox-results-fixtoken": "Corrija o identificador e volte a submete-lo",
        "apisandbox-results-fixtoken-fail": "Não foi possível obter o identificador \"$1\".",
        "emailccsubject": "Cópia da sua mensagem para $1: $2",
        "emailsent": "Mensagem enviada",
        "emailsenttext": "A sua mensagem foi enviada.",
-       "emailuserfooter": "Esta mensagem foi enviada {{GENDER:$1|pelo utilizador|pela utilizadora}} $1 para {{GENDER:$2|$2}} através da opção \"{{int:emailuser}}\" da wiki {{SITENAME}}. {{GENDER:$2|A sua}} resposta será enviada diretamente para {{GENDER:$1|o|a}} remetente original, e irá revelar-lhe {{GENDER:$2|o seu}} endereço de correio eletrónico.",
+       "emailuserfooter": "Esta mensagem foi enviada {{GENDER:$1|pelo utilizador|pela utilizadora}} $1 para {{GENDER:$2|$2}} através da opção \"{{int:emailuser}}\" da wiki {{SITENAME}}. Se {{GENDER:$2|responder}} a esta mensagem, {{GENDER:$2|a sua}} resposta será enviada diretamente para {{GENDER:$1|o|a}} remetente original, e irá revelar-lhe {{GENDER:$2|o seu}} endereço de correio eletrónico.",
        "usermessage-summary": "Deixar mensagem de sistema.",
        "usermessage-editor": "Editor de mensagens de sistema",
        "watchlist": "Páginas vigiadas",
        "logentry-tag-update-logentry": "$1 {{GENDER:$2|atualizou}} as etiquetas na entrada de registo $5 da página $3 ($6 {{PLURAL:$7|adicionadas}}; $8 {{PLURAL:$9|removidas}})",
        "rightsnone": "(nenhum)",
        "revdelete-summary": "editar resumo",
+       "rightslogentry-temporary-group": "$1 (temporário, até $2)",
        "feedback-adding": "A acrescentar os comentários à página...",
        "feedback-back": "Retroceder",
        "feedback-bugcheck": "Perfeito! Verifique apenas que não é já um dos [$1 defeitos conhecidos].",
        "usercssispublic": "Nota: As subpáginas de CSS não devem conter dados confidenciais porque podem ser vistas por outros utilizadores.",
        "restrictionsfield-badip": "Endereço IP (ou gama de endereços IP) inválido: $1",
        "restrictionsfield-label": "Gamas de endereços IP permitidas:",
-       "restrictionsfield-help": "Um endereço IP ou uma gama CIDR por linha. Para ativar todos,\nuse<br><code>0.0.0.0/0</code><br><code>::/0</code>",
+       "restrictionsfield-help": "Um endereço IP ou uma gama CIDR por linha. Para ativar todos,\nuse: <pre>0.0.0.0/0\n::/0</pre>",
        "revid": "revisão $1",
        "pageid": "identificador de página $1"
 }
index d4364ff..2c5fdb4 100644 (file)
        "username": "Username field in [[Special:Preferences]]. $1 is the current user name for GENDER distinction (depends on sex setting).\n\n{{Identical|Username}}",
        "prefs-memberingroups": "This message is shown on [[Special:Preferences]], first tab.\n\nParameters:\n* $1 - number of user groups\n* $2 - the username for GENDER\nSee also:\n* {{msg-mw|Prefs-memberingroups-type}}",
        "prefs-memberingroups-type": "{{optional}}\nParameters:\n* $1 - list of group names\n* $2 - list of group member names. Label for these is {{msg-mw|Prefs-memberingroups}}",
+       "group-membership-link-with-expiry": "Used as part of a list of user groups, to show the time and date when a user's membership of a group expires. That is, they are a member of that group \"until\" the specified date and time.\n\nParameters:\n* $1 - group name\n* $2 - time and date of expiry\n* $3 - date of expiry\n* $4 - time of expiry",
        "prefs-registration": "Used in [[Special:Preferences]].",
        "prefs-registration-date-time": "{{optional}}\nUsed in [[Special:Preferences]]. Parameters are:\n* $1 date and time of registration\n* $2 date of registration\n* $3 time of registration",
        "yourrealname": "Used in [[Special:Preferences]], first tab.\n{{Identical|Real name}}",
        "userrights-changeable-col": "Used when editing user groups in [[Special:Userrights]].\n\nThe message is the head of a column of group assignments.\n\nParameters:\n* $1 - (Optional) for PLURAL use, the number of items in the column following the message. Avoid PLURAL, if your language can do without.",
        "userrights-unchangeable-col": "Used when editing user groups in [[Special:Userrights]]. The message is the head of a column of group assignments.\n\nParameters:\n* $1 - (Optional) for PLURAL use, the number of items in the column following the message. Avoid PLURAL, if your language allows that.",
        "userrights-irreversible-marker": "{{optional}}\nParameters:\n* $1 - group member",
+       "userrights-expiry-current": "Indicates when a user's membership of a user group expires.\n\nParameters:\n* $1 - time and date of expiry\n* $2 - date of expiry\n* $3 - time of expiry\n{{Identical|Expire}}",
+       "userrights-expiry-none": "Indicates that a user's membership of a user group lasts indefinitely, and does not expire.",
+       "userrights-expiry": "Used as a label for a form element which can be used to select an expiry date/time.\n{{Identical|Expire}}",
+       "userrights-expiry-existing": "Shows the existing expiry time in the drop down menu underneath the individual user right on Special:UserRights.\n\nParameters:\n* $1 - Date and time of the existing expiry\n* $2 - date of the existing expiry\n* $3 - time of the existing expiry\n\nSee also:\n* {{msg-mw|protect-existing-expiry}}",
+       "userrights-expiry-othertime": "{{Identical|Other time}}",
+       "userrights-expiry-options": "{{doc-important|Be careful: '''1 translation:1 english''', so the first part is the translation and the second part should stay in English.}}\nOptions for the duration of the user group membership. Example: See e.g. [[MediaWiki:Userrights-expiry-options/nl]] if you still don't know how to do it.\n\nSee also {{msg-mw|protect-expiry-options}}.",
+       "userrights-invalid-expiry": "Error message on [[Special:UserRights]].\n\nParameters:\n* $1 - group name",
+       "userrights-expiry-in-past": "Error message on [[Special:UserRights]] when the user types an expiry date that has already passed.\n\nParameters:\n* $1 - group name",
        "userrights-conflict": "Shown on [[Special:UserRights]] if the target's rights have been changed since the form was loaded.",
        "group": "{{Identical|Group}}",
        "group-user": "{{doc-group|user}}\n{{Identical|User}}",
        "recentchanges-legend-plusminus": "{{optional}}\nA plus/minus sign with a number for the legend.",
        "recentchanges-submit": "Label for submit button in [[Special:RecentChanges]]\n{{Identical|Show}}",
        "rcfilters-activefilters": "Title for the filters selection showing the active filters.",
+       "rcfilters-restore-default-filters": "Label for the button that resets filters to defaults",
+       "rcfilters-clear-all-filters": "Title for the button that clears all filters",
        "rcfilters-search-placeholder": "Placeholder for the filter search input.",
        "rcfilters-invalid-filter": "A label for an invalid filter.",
+       "rcfilters-empty-filter": "Placeholder for the filter list when no filters were chosen.",
        "rcfilters-filterlist-title": "Title for the filters list.\n{{Identical|Filter}}",
        "rcfilters-filterlist-noresults": "Message showing no results found for searching a filter.",
        "rcfilters-filtergroup-registration": "Title for the filter group for editor registration type.",
        "rcfilters-filter-bots-label": "Label for the filter for showing edits made by automated tools.\n{{Identical|Bot}}",
        "rcfilters-filter-bots-description": "Description for the filter for showing edits made by automated tools.",
        "rcfilters-filter-humans-label": "Label for the filter for showing edits made by human editors.",
-       "rcfilters-filter-humans-description": " Description for the filter for showing edits made by human editors.",
+       "rcfilters-filter-humans-description": "Description for the filter for showing edits made by human editors.",
        "rcfilters-filtergroup-significance": "Title for the filter group for edit significance.\n{{Identical|Significance}}",
        "rcfilters-filter-minor-label": "Label for the filter for showing edits marked as minor.",
        "rcfilters-filter-minor-description": "Description for the filter for showing edits marked as minor.",
        "upload-form-label-own-work-message-generic-foreign": "Message shown by default when a user affirms that they are allowed to upload a file to a remote wiki.",
        "upload-form-label-not-own-work-message-generic-foreign": "Message shown by default when a user cannot upload a file to a remote wiki.",
        "upload-form-label-not-own-work-local-generic-foreign": "Suggests uploading a file locally instead of to a remote wiki.",
-       "backend-fail-stream": "Parameters:\n* $1 - a filename",
-       "backend-fail-backup": "Parameters:\n* $1 - a filename",
-       "backend-fail-notexists": "Parameters:\n* $1 - a filename",
-       "backend-fail-hashes": "Definition of \"[[w:en:Hash_function|hashes]]\".",
-       "backend-fail-notsame": "Parametreler:\n* $1 bir dosya ismi.",
-       "backend-fail-invalidpath": "Parameters:\n* $1 - a storage path",
-       "backend-fail-delete": "Parameters:\n* $1 - a file path",
-       "backend-fail-describe": "Parameters:\n* $1 - a file path",
-       "backend-fail-alreadyexists": "Parameters:\n* $1 - a filename",
-       "backend-fail-store": "Parameters:\n* $1 - a filename\n* $2 - a storage path",
-       "backend-fail-copy": "Parameters:\n* $1 - a file path\n* $2 - a file path",
-       "backend-fail-move": "Parameters:\n* $1 - a file path\n* $2 - a file path",
+       "backend-fail-stream": "Parameters:\n* $1 - a filename\n{{Related|Backend-fail}}",
+       "backend-fail-backup": "Parameters:\n* $1 - a filename\n{{Related|Backend-fail}}",
+       "backend-fail-notexists": "Parameters:\n* $1 - a filename\n{{Related|Backend-fail}}",
+       "backend-fail-hashes": "Definition of \"[[w:en:Hash_function|hashes]]\".\n{{Related|Backend-fail}}",
+       "backend-fail-notsame": "Parameters:\n* $1 is a filename.\n{{Related|Backend-fail}}",
+       "backend-fail-invalidpath": "Parameters:\n* $1 - a storage path\n{{Related|Backend-fail}}",
+       "backend-fail-delete": "Parameters:\n* $1 - a file path\n{{Related|Backend-fail}}",
+       "backend-fail-describe": "Parameters:\n* $1 - a file path\n{{Related|Backend-fail}}",
+       "backend-fail-alreadyexists": "Parameters:\n* $1 - a filename\n{{Related|Backend-fail}}",
+       "backend-fail-store": "Parameters:\n* $1 - a filename\n* $2 - a storage path\n{{Related|Backend-fail}}",
+       "backend-fail-copy": "Parameters:\n* $1 - a file path\n* $2 - a file path\n{{Related|Backend-fail}}",
+       "backend-fail-move": "Parameters:\n* $1 - a file path\n* $2 - a file path\n{{Related|Backend-fail}}",
        "backend-fail-opentemp": "Used as error message.\n{{Related|Backend-fail}}",
        "backend-fail-writetemp": "Used as error message.\n{{Related|Backend-fail}}",
        "backend-fail-closetemp": "Used as error message.\n{{Related|Backend-fail}}",
        "backend-fail-read": "Used as error message. Parameters:\n* $1 - filename\n{{Related|Backend-fail}}",
-       "backend-fail-create": "Parameters:\n* $1 - a filename",
-       "backend-fail-maxsize": "Parameters:\n* $1 - destination storage path\n* $2 - max file size (in bytes)",
-       "backend-fail-readonly": "A \"[[:wikipedia:Front and back ends|backend]]\" is a system or component that ordinary users don't interact with directly and don't need to know about, and that is responsible for a distinct task or service - for example, a storage back-end is a generic system for storing data which other applications can use. Possible alternatives for back-end are \"system\" or \"service\", or (depending on context and language) even leave it untranslated.\n\nParameters:\n* $1 - name\n* $2 - reason for being read-only",
-       "backend-fail-synced": "Used as fatal error message.\n\nParameters:\n* $1 - file path\n\nA \"[[:wikipedia:Front and back ends|backend]]\" is a system or component that ordinary users don't interact with directly and don't need to know about, and that is responsible for a distinct task or service - for example, a storage back-end is a generic system for storing data which other applications can use. Possible alternatives for back-end are \"system\" or \"service\", or (depending on context and language) even leave it untranslated.",
-       "backend-fail-connect": "Used as fatal error message. Parameters:\n* $1 - backend name\n\nA \"[[:wikipedia:Front and back ends|backend]]\" is a system or component that ordinary users don't interact with directly and don't need to know about, and that is responsible for a distinct task or service - for example, a storage back-end is a generic system for storing data which other applications can use. Possible alternatives for back-end are \"system\" or \"service\", or (depending on context and language) even leave it untranslated.",
-       "backend-fail-internal": "Used as fatal error message. Parameters:\n* $1 - backend name\n\nA \"[[:wikipedia:Front and back ends|backend]]\" is a system or component that ordinary users don't interact with directly and don't need to know about, and that is responsible for a distinct task or service - for example, a storage back-end is a generic system for storing data which other applications can use. Possible alternatives for back-end are \"system\" or \"service\", or (depending on context and language) even leave it untranslated.",
-       "backend-fail-contenttype": "Used as fatal error message. Parameters:\n* $1 - a storage (file) path",
-       "backend-fail-batchsize": "Error message when the limit of operations to be done at once in the file backend was reached.\nParameters:\n* $1 - the number of operations attempted at once in this case\n* $2 - the maximum number of operations that can be attempted at once\n\nA \"[[:wikipedia:Front and back ends|backend]]\" is a system or component that ordinary users don't interact with directly and don't need to know about, and that is responsible for a distinct task or service - for example, a storage back-end is a generic system for storing data which other applications can use. Possible alternatives for back-end are \"system\" or \"service\", or (depending on context and language) even leave it untranslated.",
-       "backend-fail-usable": "Parameters:\n* $1 - the file name, including the path, formatted for the storage backend used",
+       "backend-fail-create": "Parameters:\n* $1 - a filename\n{{Related|Backend-fail}}",
+       "backend-fail-maxsize": "Parameters:\n* $1 - destination storage path\n* $2 - max file size (in bytes)\n{{Related|Backend-fail}}",
+       "backend-fail-readonly": "A \"[[:wikipedia:Front and back ends|backend]]\" is a system or component that ordinary users don't interact with directly and don't need to know about, and that is responsible for a distinct task or service - for example, a storage back-end is a generic system for storing data which other applications can use. Possible alternatives for back-end are \"system\" or \"service\", or (depending on context and language) even leave it untranslated.\n\nParameters:\n* $1 - name\n* $2 - reason for being read-only\n{{Related|Backend-fail}}",
+       "backend-fail-synced": "Used as fatal error message.\n\nParameters:\n* $1 - file path\n\nA \"[[:wikipedia:Front and back ends|backend]]\" is a system or component that ordinary users don't interact with directly and don't need to know about, and that is responsible for a distinct task or service - for example, a storage back-end is a generic system for storing data which other applications can use. Possible alternatives for back-end are \"system\" or \"service\", or (depending on context and language) even leave it untranslated.\n{{Related|Backend-fail}}",
+       "backend-fail-connect": "Used as fatal error message. Parameters:\n* $1 - backend name\n\nA \"[[:wikipedia:Front and back ends|backend]]\" is a system or component that ordinary users don't interact with directly and don't need to know about, and that is responsible for a distinct task or service - for example, a storage back-end is a generic system for storing data which other applications can use. Possible alternatives for back-end are \"system\" or \"service\", or (depending on context and language) even leave it untranslated.\n{{Related|Backend-fail}}",
+       "backend-fail-internal": "Used as fatal error message. Parameters:\n* $1 - backend name\n\nA \"[[:wikipedia:Front and back ends|backend]]\" is a system or component that ordinary users don't interact with directly and don't need to know about, and that is responsible for a distinct task or service - for example, a storage back-end is a generic system for storing data which other applications can use. Possible alternatives for back-end are \"system\" or \"service\", or (depending on context and language) even leave it untranslated.\n{{Related|Backend-fail}}",
+       "backend-fail-contenttype": "Used as fatal error message. Parameters:\n* $1 - a storage (file) path\n{{Related|Backend-fail}}",
+       "backend-fail-batchsize": "Error message when the limit of operations to be done at once in the file backend was reached.\nParameters:\n* $1 - the number of operations attempted at once in this case\n* $2 - the maximum number of operations that can be attempted at once\nBoth parameters are PLURAL supported\n\nA \"[[:wikipedia:Front and back ends|backend]]\" is a system or component that ordinary users don't interact with directly and don't need to know about, and that is responsible for a distinct task or service - for example, a storage back-end is a generic system for storing data which other applications can use. Possible alternatives for back-end are \"system\" or \"service\", or (depending on context and language) even leave it untranslated.\n{{Related|Backend-fail}}",
+       "backend-fail-usable": "Parameters:\n* $1 - the file name, including the path, formatted for the storage backend used\n{{Related|Backend-fail}}",
        "filejournal-fail-dbconnect": "Parameters:\n* $1 is the name of the \"[[:wikipedia:Front and back ends|backend]]\" that the file journal logs changes for.",
        "filejournal-fail-dbquery": "Parameters:\n* $1 is the name of the \"[[:wikipedia:Front and back ends|backend]]\" that the file journal logs changes for.",
        "lockmanager-notlocked": "Parameters:\n* $1 is a resource path (e.g. \"mwstore://media-public/a/ab/file.jpg\").",
        "wantedcategories": "{{doc-special|WantedCategories}}",
        "wantedcategories-summary": "{{doc-specialpagesummary|wantedcategories}}",
        "wantedpages": "{{doc-special|WantedPages}}\n{{Identical|Wanted page}}",
-       "wantedpages-summary": "{{doc-specialpagesummary|wantedpages}}",
+       "wantedpages-summary": "ఇతర పేజీల నుండి అనేక లింకులు ఉండి కూడా \"ఉనికిలో లేని పేజీల\" జాబితా ఇది. దారిమార్పు పేజీల నుండి మాత్రమే లింకులు ఉన్న పేజీలు ఇందులో ఉండవు. ఆ పేజీ పేర్ల జాబితా కోసం [[{{#special:BrokenRedirects}}|తెగిపోయిన దారిమార్పుల జాబితా]] చూడండి.",
        "wantedpages-badtitle": "Error message shown when [[Special:WantedPages]] is listing a page with a title that shouldn't exist.\n\nParameters:\n* $1 - a page title",
        "wantedfiles": "{{doc-special|WantedFiles}}",
        "wantedfiles-summary": "{{doc-specialpagesummary|wantedfiles}}",
        "apisandbox-sending-request": "JavaScript message displayed while the request is being sent.",
        "apisandbox-loading-results": "JavaScript message displayed while the response is being read.",
        "apisandbox-results-error": "Displayed as an error message from JavaScript when the request failed.\n\nParameters:\n* $1 - Error message",
-       "apisandbox-request-params-json": "Label for text field display the request parameters as JSON.",
-       "apisandbox-request-url-label": "Label for the text field displaying the URL used to make this request.",
+       "apisandbox-request-selectformat-label": "Label for the format selector on the results page.",
+       "apisandbox-request-format-url-label": "Label for the menu item to select URL format.\n\nSee also:\n* {{msg-mw|apisandbox-request-selectformat-label}}\n* {{msg-mw|apisandbox-request-url-label}}",
+       "apisandbox-request-url-label": "Label for the text field displaying the URL used to make this request.\n\nSee also:\n* {{msg-mw|apisandbox-request-format-url-label}}",
+       "apisandbox-request-format-json-label": "Label for the menu item to select JSON format.\n\nSee also:\n* {{msg-mw|apisandbox-request-selectformat-label}}\n* {{msg-mw|apisandbox-request-json-label}}",
+       "apisandbox-request-json-label": "Label for text field display the request parameters as JSON.\n\nSee also:\n* {{msg-mw|apisandbox-request-format-json-label}}",
        "apisandbox-request-time": "Label and value for displaying the time taken by the request.\n\nParameters:\n* $1 - Time taken in milliseconds",
        "apisandbox-results-fixtoken": "JavaScript button label",
        "apisandbox-results-fixtoken-fail": "Displayed as an error message from JavaScript when a CSRF token could not be fetched.\n\nParameters:\n* $1 - Token type",
        "newuserlog-autocreate-entry": "This message is used in the [[:mw:Extension:Newuserlog|new user log]] to mark an account that was created by MediaWiki as part of a [[:mw:Extension:CentralAuth|CentralAuth]] global account.",
        "rightslogentry": "This message is displayed in the [[Special:Log/rights|User Rights Log]] when a bureaucrat changes the user groups for a user.\n\nParameters:\n* $1 - the username\n* $2 - list of user groups or {{msg-mw|Rightsnone}}\n* $3 - list of user groups or {{msg-mw|Rightsnone}}\n\nThe name of the bureaucrat who did this task appears before this message.\n\nSimilar to {{msg-mw|Gur-rightslog-entry}}",
        "rightslogentry-autopromote": "This message is displayed in the [[Special:Log/rights|User Rights Log]] when a user is automatically promoted to a user group.\n\nParameters:\n* $1 - (Unused)\n* $2 - a comma separated list of old user groups or {{msg-mw|Rightsnone}}\n* $3 - a comma separated list of new user groups",
+       "rightslogentry-temporary-group": "This message is displayed in the [[Special:Log/rights|User Rights Log]] to show that a user group has been allocated temporarily.\n\nParameters:\n* $1 - group name\n* $2 - date and time of expiry\n* $3 - date of expiry\n* $4 - time of expiry",
        "feedback-adding": "Progress notice",
        "feedback-back": "Button to go back to the previous action in the feedback dialog.\n{{Identical|Back}}",
        "feedback-bugcheck": "Message that appears before the user submits a bug, reminding them to check for known bugs.\n\nParameters:\n* $1 - bug list page URL",
index c5cd170..ee344e6 100644 (file)
        "nosuchuser": "Участника с именем «$1» не существует.\nИмена участников чувствительны к регистру букв.\nПроверьте правильность написания имени или [[Special:CreateAccount|создайте новую учётную запись]].",
        "nosuchusershort": "Не существует участника с именем «$1». Проверьте написание имени.",
        "nouserspecified": "Вы должны указать имя участника.",
-       "login-userblocked": "ЭÑ\82оÑ\82 Ñ\83Ñ\87аÑ\81Ñ\82ник Ð·Ð°Ð±Ð»Ð¾ÐºÐ¸Ñ\80ован. Ð\92Ñ\85од Ð² Ñ\81иÑ\81Ñ\82емÑ\83 Ð½Ðµ Ñ\80азÑ\80еÑ\88Ñ\91н.",
+       "login-userblocked": "УÑ\87аÑ\81Ñ\82ник Ð·Ð°Ð±Ð»Ð¾ÐºÐ¸Ñ\80ован. Ð\92Ñ\85од Ð² Ñ\81иÑ\81Ñ\82емÑ\83 Ð·Ð°Ð¿Ñ\80еÑ\89ен.",
        "wrongpassword": "Введённый вами пароль неверен. Попробуйте ещё раз.",
        "wrongpasswordempty": "Пожалуйста, введите непустой пароль.",
        "passwordtooshort": "Пароль должен состоять не менее чем из $1 {{PLURAL:$1|символа|символов}}.",
        "subject-preview": "Заголовок будет выглядеть так:",
        "previewerrortext": "При попытке отобразить предварительный просмотр ваших изменений произошла ошибка.",
        "blockedtitle": "Участник заблокирован",
-       "blockedtext": "'''Ваша учётная запись или IP-адрес заблокированы.'''\n\nБлокировка произведена администратором $1.\nУказана следующая причина: «''$2''».\n\n* Начало блокировки: $8\n* Окончание блокировки: $6\n* Цель блокировки: $7\n\nВы можете связаться с $1 или любым другим [[{{MediaWiki:Grouppage-sysop}}|администратором]], чтобы обсудить блокировку.\nОбратите внимание, что не сможете использовать функцию «письмо участнику», если в своих [[Special:Preferences|персональных настройках]] не задали или не подтвердили корректный адрес электронной почты, или если ваша блокировка включает запрет отправки писем подобным образом.\nВаш IP-адрес — $3, идентификатор блокировки — $5.\nПожалуйста, указывайте эти сведения в любых своих обращениях.",
+       "blockedtext": "<strong>Ваша учётная запись или IP-адрес заблокированы.</strong>\n\nБлокировка произведена администратором $1.\nУказана следующая причина: «<em>$2</em>».\n\n* Начало блокировки: $8\n* Окончание блокировки: $6\n* Цель блокировки: $7\n\nВы можете связаться с $1 или любым другим [[{{MediaWiki:Grouppage-sysop}}|администратором]], чтобы обсудить блокировку.\nОбратите внимание, что не сможете использовать функцию «письмо участнику», если в своих [[Special:Preferences|персональных настройках]] не задали или не подтвердили корректный адрес электронной почты, или если ваша блокировка включает запрет отправки писем подобным образом.\nВаш IP-адрес — $3, идентификатор блокировки — $5.\nПожалуйста, указывайте эти сведения в любых своих обращениях.",
        "autoblockedtext": "Ваш IP-адрес автоматически заблокирован в связи с тем, что он ранее использовался кем-то из участников, заблокированных {{GENDER:$4|участником|участницей}} $1. \nБыла указана следующая причина блокировки:\n\n: «$2».\n\n* Начало блокировки: $8\n* Окончание блокировки: $6\n* Цель блокировки: $7\n\nВы можете связаться с $1 или любым другим [[{{MediaWiki:Grouppage-sysop}}|администратором]], чтобы обсудить блокировку.\n\nОбратите внимание, что не сможете использовать функцию «письмо участнику», если в своих [[Special:Preferences|персональных настройках]] не задали или не подтвердили корректный адрес электронной почты, или если ваша блокировка включает запрет отправки писем подобным образом.\n\nВаш IP-адрес — $3, идентификатор блокировки — #$5.\nПожалуйста, указывайте эти сведения в любых своих обращениях.",
        "systemblockedtext": "Ваше имя участника или IP-адрес были автоматически заблокированы MediaWiki.\nУказана следующая причина:\n\n:<em>$2</em>\n\n* Начало блокировки: $8\n* Окончание блокировки: $6\n* Цель блокировки: $7\n\nВаш текущий IP-адрес $3.\nПожалуйста, указывайте все эти сведения в любых своих обращениях.",
        "blockednoreason": "причина не указана",
        "undo-nochange": "Правка, похоже, уже была отменена.",
        "undo-summary": "Отмена правки $1, сделанной [[Special:Contributions/$2|$2]] ([[User talk:$2|обсуждение]])",
        "undo-summary-username-hidden": "Отмена правки $1, сделанной участником, чьё имя скрыто",
-       "cantcreateaccount-text": "Создание учётных записей с этого IP-адреса ('''$1''') было заблокировано {{GENDER:$3|участником|участницей|}} [[User:$3|$3]].\n\n$3 {{GENDER:$3|указал|указала}} следующую причину: ''$2''.",
-       "cantcreateaccount-range-text": "{{GENDER:$3|УÑ\87аÑ\81Ñ\82ник|УÑ\87аÑ\81Ñ\82ниÑ\86а}} [[User:$3|$3]] {{GENDER:$3|Ñ\83Ñ\81Ñ\82ановил|Ñ\83Ñ\81Ñ\82ановила}} Ð·Ð°Ð¿Ñ\80еÑ\82 Ð½Ð° Ñ\81оздание Ñ\83Ñ\87Ñ\91Ñ\82нÑ\8bÑ\85 Ð·Ð°Ð¿Ð¸Ñ\81ей Ð¸Ð· Ð´Ð¸Ð°Ð¿Ð°Ð·Ð¾Ð½Ð° IP-адÑ\80еÑ\81ов <strong>$1</strong>, Ð²ÐºÐ»Ñ\8eÑ\87аÑ\8eÑ\89его Ð²Ð°Ñ\88 IP-адÑ\80еÑ\81 (<strong>$4</strong>). \n\nÐ\91Ñ\8bла Ñ\83казана Ñ\81ледÑ\83Ñ\8eÑ\89аÑ\8f Ð¿Ñ\80иÑ\87ина: $2.",
+       "cantcreateaccount-text": "Создание учётных записей с этого IP-адреса (<strong>$1</strong>) было заблокировано {{GENDER:$3|участником|участницей|}} [[User:$3|$3]].\n\n$3 {{GENDER:$3|указал|указала}} следующую причину: <em>$2</em>.",
+       "cantcreateaccount-range-text": "{{GENDER:$3|УÑ\87аÑ\81Ñ\82ник|УÑ\87аÑ\81Ñ\82ниÑ\86а}} [[User:$3|$3]] {{GENDER:$3|Ñ\83Ñ\81Ñ\82ановил|Ñ\83Ñ\81Ñ\82ановила}} Ð·Ð°Ð¿Ñ\80еÑ\82 Ð½Ð° Ñ\81оздание Ñ\83Ñ\87Ñ\91Ñ\82нÑ\8bÑ\85 Ð·Ð°Ð¿Ð¸Ñ\81ей Ð´Ð»Ñ\8f Ð´Ð¸Ð°Ð¿Ð°Ð·Ð¾Ð½Ð° IP-адÑ\80еÑ\81ов <strong>$1</strong>, Ð²ÐºÐ»Ñ\8eÑ\87аÑ\8eÑ\89его Ð²Ð°Ñ\88 IP-адÑ\80еÑ\81 (<strong>$4</strong>). \n\nÐ\91Ñ\8bла Ñ\83казана Ñ\81ледÑ\83Ñ\8eÑ\89аÑ\8f Ð¿Ñ\80иÑ\87ина: <em>$2</em>.",
        "viewpagelogs": "Показать журналы для этой страницы",
        "nohistory": "Для этой страницы история изменений отсутствует.",
        "currentrev": "Текущая версия",
        "youremail": "Электронная почта:",
        "username": "{{GENDER:$1|Имя участника|Имя участницы}}:",
        "prefs-memberingroups": "{{GENDER:$2|Член|Член}} {{PLURAL:$1|1=группы|групп}}:",
+       "group-membership-link-with-expiry": "$1 (до $2)",
        "prefs-registration": "Время регистрации:",
        "yourrealname": "Настоящее имя:",
        "yourlanguage": "Язык интерфейса:",
        "badsig": "Неверная подпись. Проверьте корректность HTML-тегов.",
        "badsiglength": "Слишком длинная подпись.\nПодпись не должна превышать $1 {{PLURAL:$1|символа|символа|символов}}.",
        "yourgender": "Какое описание вам более подходит?",
-       "gender-unknown": "При упоминании вас программное обеспечение, когда это возможно, будет использовать гендерно-нейтральные слова",
+       "gender-unknown": "При упоминании вас, программное обеспечение, когда это возможно, будет использовать гендерно-нейтральные слова",
        "gender-male": "Он редактирует страницы вики",
        "gender-female": "Онa редактирует страницы вики",
        "prefs-help-gender": "Этот параметр задавать необязательно.\nДвижок использует это значение, чтобы обращаться к вам и упоминать вас в правильном грамматическом роде.\nЭта информация будет общедоступной.",
        "saveusergroups": "Сохранить группы {{GENDER:$1|участника|участницы}}",
        "userrights-groupsmember": "Состоит в группах:",
        "userrights-groupsmember-auto": "Неявно состоит в группах:",
-       "userrights-groups-help": "Вы можете изменить группы, в которые входит этот участник.\n* Если около названия группы стоит отметка, значит участник входит в эту группу.\n* Если отметка не стоит — участник не относится к соответствующей группе.\n* Знак * отмечает, что вы не сможете удалить участника из группы, если добавите его в неё, или наоборот.",
+       "userrights-groups-help": "Вы можете изменить группы, в которые входит этот участник.\n* Если около названия группы стоит отметка — участник входит в эту группу.\n* Если отметка не стоит — участник не входит в эту группу.\n* Знак * отмечает, что вы не сможете удалить участника из группы, если добавите его в неё, или наоборот.",
        "userrights-reason": "Причина:",
        "userrights-no-interwiki": "У вас нет разрешения изменять права участников в других вики.",
        "userrights-nodatabase": "База данных $1 не существует или расположена не локально.",
        "userrights-changeable-col": "Группы, которые вы можете изменять",
        "userrights-unchangeable-col": "Группы, которые вы не можете изменять",
+       "userrights-expiry-current": "Истекает $1",
+       "userrights-expiry-none": "Никогда",
+       "userrights-expiry": "Права истекают:",
+       "userrights-expiry-existing": "$2, $3",
+       "userrights-expiry-othertime": "Другое время:",
+       "userrights-expiry-options": "1 день:1 day,1 неделя:1 week,1 месяц:1 mopnth,3 месяца:3 months,6 месяцев:6 months,1 год:1 year",
+       "userrights-invalid-expiry": "Время истечения для группы «$1» задано неверно.",
        "userrights-conflict": "Конфликт изменения прав участника! Пожалуйста, проверьте и примените изменения заново.",
        "group": "Группа:",
        "group-user": "Участники",
        "recentchanges-legend-plusminus": "(''±123'')",
        "recentchanges-submit": "Показать",
        "rcfilters-activefilters": "Активные фильтры",
+       "rcfilters-restore-default-filters": "Восстановить фильтры по умолчанию",
+       "rcfilters-clear-all-filters": "Очистить все фильтры",
        "rcfilters-search-placeholder": "Последние изменения фильтров (просмотрите или начните вводить)",
        "rcfilters-invalid-filter": "Недопустимый фильтр",
+       "rcfilters-empty-filter": "Нет активных фильтров. Показываются все правки.",
        "rcfilters-filterlist-title": "Фильтры",
        "rcfilters-filterlist-noresults": "Фильтры не найдены",
        "rcfilters-filtergroup-registration": "Регистрация участников",
        "upload_directory_missing": "Директория для загрузок ($1) отсутствует и не может быть создана веб-сервером.",
        "upload_directory_read_only": "Веб-сервер не имеет прав записи в папку ($1), в которой предполагается хранить загружаемые файлы.",
        "uploaderror": "Ошибка загрузки файла",
-       "upload-recreate-warning": "'''Внимание: файл с таким именем был удален или переименован.'''\n\nНиже представлены журналы удалений и переименований этой страницы:",
-       "uploadtext": "Воспользуйтесь этой формой для загрузки файлов на сервер.\nЧтобы просмотреть ранее загруженные файлы, обратитесь к [[Special:FileList|списку загруженных файлов]]. Загрузка файлов также записывается в [[Special:Log/upload|журнал загрузок]], данные об удалённых файлах можно найти в [[Special:Log/delete|журнале удалений]].\n\nДля включения файла в статью вы можете использовать строки вида:\n* '''<code><nowiki>[[</nowiki>{{ns:file}}<nowiki>:File.jpg]]</nowiki></code>''' для вставки полной версии файла;\n* '''<code><nowiki>[[</nowiki>{{ns:file}}<nowiki>:File.png|200px|thumb|left|описание]]</nowiki></code>''' для вставки слева от текста уменьшенной до 200 пикселей по ширине версии файла с выводом под ним указанного описания;\n* '''<code><nowiki>[[</nowiki>{{ns:media}}<nowiki>:File.ogg]]</nowiki></code>''' для вставки ссылки на файл, без отображения его содержимого на странице.",
+       "upload-recreate-warning": "<strong>Внимание: файл с таким именем был удален или переименован.</strong>\n\nНиже представлены журналы удалений и переименований этой страницы:",
+       "uploadtext": "Воспользуйтесь этой формой для загрузки файлов на сервер.\nЧтобы просмотреть ранее загруженные файлы, обратитесь к [[Special:FileList|списку загруженных файлов]]. Загрузка файлов также записывается в [[Special:Log/upload|журнал загрузок]]; данные об удалённых файлах можно найти в [[Special:Log/delete|журнале удалений]].\n\nДля включения файла в статью вы можете использовать строки вида:\n* <strong><code><nowiki>[[</nowiki>{{ns:file}}<nowiki>:File.jpg]]</nowiki></code></strong> для вставки полной версии файла;\n* <strong><code><nowiki>[[</nowiki>{{ns:file}}<nowiki>:File.png|200px|thumb|left|описание]]</nowiki></code></strong> для вставки слева от текста уменьшенной до 200 пикселей по ширине версии файла с выводом под ним указанного описания;\n* <strong><code><nowiki>[[</nowiki>{{ns:media}}<nowiki>:File.ogg]]</nowiki></code></strong> для вставки ссылки на файл, без отображения его содержимого на странице.",
        "upload-permitted": "{{PLURAL:$2|Разрешённый тип|Разрешённые типы}} файлов: $1.",
        "upload-preferred": "{{PLURAL:$2|Предпочтительный тип|Предпочтительные типы}} файлов: $1.",
        "upload-prohibited": "{{PLURAL:$2|Запрещённый тип|Запрещённые типы}} файлов: $1.",
        "lockmanager-fail-deletelock": "Не удалось удалить файл блокировки для «$1».",
        "lockmanager-fail-acquirelock": "Не удалось добиться блокировки «$1».",
        "lockmanager-fail-openlock": "Не удалось открыть файл блокировки для «$1».",
-       "lockmanager-fail-releaselock": "Не удалось разблокировать \"$1\".",
+       "lockmanager-fail-releaselock": "Не удалось разблокировать «$1».",
        "lockmanager-fail-db-bucket": "Не удалось связаться с достаточным количеством баз блокировок в сегменте $1.",
        "lockmanager-fail-db-release": "Не удалось снять блокировку базы данных  $1 .",
        "lockmanager-fail-svr-acquire": "Не удалось получить блокировку на сервере  $1.",
        "upload-curl-error6": "Невозможно обратить по указанному адресу.",
        "upload-curl-error6-text": "Невозможно обратить по указанному адресу. Пожалуйста, проверьте, что адрес верен, а сайт доступен.",
        "upload-curl-error28": "Время, отведённое на загрузку, истекло",
-       "upload-curl-error28-text": "Сайт слишком долго не отвечает. Пожалуйста, проверьте что сайт работоспособен и после небольшого перерыва попробуйте ещё раз. Возможно, операцию следует провести в другое время, когда сайт менее нагружен.",
+       "upload-curl-error28-text": "Сайт слишком долго не отвечает. \nПожалуйста, проверьте что сайт работоспособен и после небольшого перерыва попробуйте ещё раз. Возможно, операцию следует провести в другое время, когда сайт менее нагружен.",
        "license": "Лицензирование:",
        "license-header": "Лицензирование",
        "nolicense": "Ничего не выбрано",
        "apisandbox-sending-request": "Отправка API-запроса…",
        "apisandbox-loading-results": "Получение API-результатов…",
        "apisandbox-results-error": "Произошла ошибка при загрузке API-ответа на запрос: $1.",
-       "apisandbox-request-params-json": "JSON-параметры:",
+       "apisandbox-request-selectformat-label": "Показать данные запроса, как:",
+       "apisandbox-request-format-url-label": "Строка URL-запроса",
        "apisandbox-request-url-label": "URL-адрес запроса:",
+       "apisandbox-request-json-label": "Запросить JSON:",
        "apisandbox-request-time": "Время запроса: {{PLURAL:$1|$1 мс}}",
        "apisandbox-results-fixtoken": "Исправьте токен и повторите отправку",
        "apisandbox-results-fixtoken-fail": "Не удалось вызвать токен «$1».",
        "emailccsubject": "Копия вашего сообщения для $1: $2",
        "emailsent": "Письмо отправлено",
        "emailsenttext": "Ваше электронное сообщение отправлено.",
-       "emailuserfooter": "Это письмо было отправлено {{GENDER:$2|участнику|участнице}} $2 от {{GENDER:$1|участника|участницы}} $1 с помощью функции «{{int:emailuser}}» проекта {{SITENAME}}.\n{{GENDER:$2|Письмо}} будет отослано напрямую {{GENDER:$1|отправителю}}, так что {{GENDER:$2|ваш}} адрес электронной почты станет известен {{GENDER:$1|ему|ей}}.",
+       "emailuserfooter": "Это письмо было отправлено {{GENDER:$2|участнику|участнице}} $2 от {{GENDER:$1|участника|участницы}} $1 с помощью функции «{{int:emailuser}}» проекта {{SITENAME}}. Если {{GENDER:$2|вы}} ответите на это письмо, оно будет отослано напрямую {{GENDER:$1|отправителю}}, так что {{GENDER:$2|ваш}} адрес электронной почты станет известен {{GENDER:$1|ему|ей}}.",
        "usermessage-summary": "Оставить системное сообщение.",
        "usermessage-editor": "Системная доставка",
        "watchlist": "Список наблюдения",
        "deletecomment": "Причина:",
        "deleteotherreason": "Другая причина/дополнение:",
        "deletereasonotherlist": "Другая причина",
-       "deletereason-dropdown": "* Типовые причины удаления\n** спам\n** вандализм\n** нарушение авторских прав\n** по запросу автора\n** неработающее перенаправление",
+       "deletereason-dropdown": "* Типовые причины удаления\n** Спам\n** Вандализм\n** Нарушение авторских прав\n** По запросу автора\n** Неработающее перенаправление",
        "delete-edit-reasonlist": "Править список причин",
        "delete-toobig": "У этой страницы очень длинная история изменений, более $1 {{PLURAL:$1|версии|версий}}.\nУдаление таких страниц было запрещено во избежание нарушений в работе сайта «{{SITENAME}}».",
        "delete-warning-toobig": "У этой страницы очень длинная история изменений, более $1 {{PLURAL:$1|версии|версий}}.\nЕё удаление может привести к нарушению нормальной работы базы данных сайта «{{SITENAME}}»;\nдействуйте с осторожностью.",
        "sorbs_create_account_reason": "Ваш IP-адрес числится как открытый прокси в DNSBL. Вы не можете создать учётную запись.",
        "softblockrangesreason": "Анонимные правки не разрешены с вашего IP-адреса ($1). Пожалуйста, войдите в систему.",
        "xffblockreason": "Был заблокирован IP-адрес, присутствующий в заголовке X-Forwarded-For и принадлежащий либо вам, либо используемому вами прокси-серверу. Первоначальная причина блокировки была следующей: $1",
-       "cant-see-hidden-user": "Участник, которого вы пытаетесь заблокировать, уже заблокирован и скрыт. Поскольку у вас нет разрешения на работу по сокрытию участников, вы не можете просмотреть или изменить данную блокировку.",
+       "cant-see-hidden-user": "Участник, которого вы пытаетесь заблокировать, уже заблокирован и скрыт. Поскольку у вас недостаточно прав, вы не можете просмотреть детали.",
        "ipbblocked": "Вы не можете блокировать или разблокировать других участников, так как вы сами заблокированы",
        "ipbnounblockself": "Вы не можете разблокировать самого себя",
        "lockdb": "Сделать базу данных доступной только для чтения",
        "movepagetext": "Воспользовавшись нижеприведённой формой, вы переименуете страницу, одновременно переместив на новое место её журнал изменений.\nСтарое название станет перенаправлением на новое.\nВы можете автоматически обновить перенаправления, которые вели на старое название.\nЕсли вы этого не сделаете, пожалуйста, проверьте наличие [[Special:DoubleRedirects|двойных]] и [[Special:BrokenRedirects|разорванных перенаправлений]].\nВы отвечаете за то, чтобы ссылки продолжали и далее указывать туда, куда предполагалось.\n\nОбратите внимание, что страница <strong>не будет</strong> переименована, если уже существует страница с названием, идентичным выбранному, кроме случаев, когда такая страница пуста или представляет собой перенаправление, и при этом не имеет истории правок.\nЭто означает, что сделав ошибочное переименование, вы можете переименовать страницу обратно в то название, которое у неё только что было, но не можете случайно затереть существующую страницу.\n\n<strong>Примечание:</strong>\nПереименование популярных страниц может привести к масштабным и неожиданным изменениям.\nПожалуйста, прежде чем продолжать, убедитесь, что понимаете все возможные последствия.",
        "movepagetext-noredirectfixer": "Воспользовавшись формой ниже, вы переименуете страницу, одновременно переместив на новое место её журнал изменений.\nСтарое название станет перенаправлением на новое название.\nПожалуйста, проверьте наличие [[Special:DoubleRedirects|двойных]] и [[Special:BrokenRedirects|разорванных перенаправлений]].\nВы отвечаете за то, чтобы ссылки продолжали и далее указывать туда, куда предполагалось.\n\nОбратите внимание, что страница <strong>не будет</strong> переименована, если страница с новым названием уже существует, кроме случаев, если она пуста или представляет собой перенаправление, и при этом не имеет истории правок.\nЭто означает, что сделав ошибочное переименование, вы сможете переименовать страницу обратно в то название, которое у неё только что было, но не сможете случайно затереть существующую страницу.\n\n<strong>Примечание:</strong>\nПереименование может привести к масштабным и неожиданным изменениям для популярных страниц.\nПожалуйста, прежде чем продолжить, убедитесь, что понимаете все возможные последствия.",
        "movepagetalktext": "Если вы отметите этот пункт, связанная с ней страница обсуждения будет также автоматически переименована, если только уже не существует непустая страница обсуждения с таким же названием.\n\nВ этом случае вам нужно будет переименовать или объединить страницы вручную, если это необходимо.",
-       "moveuserpage-warning": "'''Внимание.''' Вы собираетесь переименовать страницу участника. Пожалуйста, обратите внимание, что переименована будет только страница, участник '''не''' будет переименован.",
+       "moveuserpage-warning": "<strong>Внимание:</strong> вы собираетесь переименовать страницу участника. Пожалуйста, обратите внимание, что переименована будет только страница, участник <strong>не</strong> будет переименован.",
        "movecategorypage-warning": "<strong>Предупреждение:</strong> Вы собираетесь переименовать страницу категории. Пожалуйста, обратите внимание, что будет переименована только эта страница, а все страницы старой категории <em>не</em> будут перекатегоризованы в новую.",
        "movenologintext": "Вы должны [[Special:UserLogin|представиться системе]],\nчтобы иметь возможность переименовать страницы.",
        "movenotallowed": "У вас нет разрешения переименовывать страницы.",
        "file-info-png-looped": "закольцованный",
        "file-info-png-repeat": "проигрывается $1 {{PLURAL:$1|раз|раза|раз}}",
        "file-info-png-frames": "$1 {{PLURAL:$1|кадр|кадра|кадров}}",
-       "file-no-thumb-animation": "'''Примечание. По техническим причинам миниатюры этого файла не будет анимироваться.'''",
-       "file-no-thumb-animation-gif": "'''Примечание. По техническим причинам миниатюры подобных GIF-изображений высокого разрешения не анимируются.'''",
+       "file-no-thumb-animation": "<strong>Примечание: по техническим причинам миниатюры этого файла не будет анимироваться.</strong>",
+       "file-no-thumb-animation-gif": "<strong>Примечание: По техническим причинам миниатюры подобных GIF-изображений высокого разрешения не анимируются.</strong>",
        "newimages": "Галерея новых файлов",
        "imagelisttext": "Ниже представлен список из '''$1''' {{PLURAL:$1|файла|файлов}}, отсортированных $2.",
        "newimages-summary": "На этой служебной странице показаны недавно загруженные файлы.",
        "bitrate-gigabits": "$1 Гб/с",
        "bitrate-terabits": "$1 Тб/с",
        "lag-warn-normal": "Изменения, сделанные менее {{PLURAL:$1|$1 секунды|$1 секунд|1=секунды}} назад, могут не отображаться в этом списке.",
-       "lag-warn-high": "Из-за большого отставания в синхронизации серверов баз данных изменения, сделанные менее {{PLURAL:$1|$1 секунды|$1 секунд|1=секунды}} назад, могут не отображаться в этом списке.",
+       "lag-warn-high": "Из-за большого отставания в синхронизации серверов, изменения, сделанные менее {{PLURAL:$1|$1 секунды|$1 секунд|1=секунды}} назад, могут не отображаться в этом списке.",
        "watchlistedit-normal-title": "Изменение списка наблюдения",
        "watchlistedit-normal-legend": "Удаление записей из списка наблюдения",
        "watchlistedit-normal-explain": "Ниже перечислены страницы, находящиеся в вашем списке наблюдения.\nДля удаления записей отметьте соответствующие позиции и нажмите кнопку «{{int:Watchlistedit-normal-submit}}».\nВы также можете [[Special:EditWatchlist/raw|править список как текст]].",
        "logentry-tag-update-logentry": "$1 обновил{{GENDER:$2||а}} метки у записи журнала $5 страницы $3 (добавлен{{PLURAL:$7|а|ы}} $6; удален{{PLURAL:$9|а|ы}} $8)",
        "rightsnone": "(нет)",
        "revdelete-summary": "описание изменений",
+       "rightslogentry-temporary-group": "$1 (временно, до $4, $3)",
        "feedback-adding": "Добавление отзыва на страницу…",
        "feedback-back": "Назад",
        "feedback-bugcheck": "Прекрасно! Только проверьте, что в списке [$1 известных ошибок] нет подобной записи.",
index c1a718f..4a5ce17 100644 (file)
        "createacct-another-username-ph": "Ааккын суруй",
        "yourpassword": "Киирии тыла:",
        "userlogin-yourpassword": "Аһарык",
-       "userlogin-yourpassword-ph": "Ð\9aииÑ\80ии Ñ\82Ñ\8bлгын суруй",
-       "createacct-yourpassword-ph": "Ð\9aииÑ\80ии Ñ\82Ñ\8bлгын суруй",
-       "yourpasswordagain": "Ð\9aииÑ\80ии Ñ\82Ñ\8bлгын хатылаа:",
-       "createacct-yourpasswordagain": "Ð\9aииÑ\80ии Ñ\82Ñ\8bлгын бигэргэт",
-       "createacct-yourpasswordagain-ph": "Ð\9aииÑ\80ии Ñ\82Ñ\8bлгын хатылаа",
+       "userlogin-yourpassword-ph": "Ð\90һаÑ\80Ñ\8bккын суруй",
+       "createacct-yourpassword-ph": "Ð\90һаÑ\80Ñ\8bккын суруй",
+       "yourpasswordagain": "Ð\90һаÑ\80Ñ\8bккын хатылаа:",
+       "createacct-yourpasswordagain": "Ð\90һаÑ\80Ñ\8bккын бигэргэт",
+       "createacct-yourpasswordagain-ph": "Ð\90һаÑ\80Ñ\8bккын хатылаа",
        "userlogin-remembermypassword": "Тиһиликтэн тахсыма",
        "userlogin-signwithsecure": "Бигэ холбонуу",
        "cannotlogin-title": "Киирэр сатаммат",
        "gotaccount": "Бэлиэтэммитиҥ дуо? '''$1'''.",
        "gotaccountlink": "Аатыҥ",
        "userlogin-resetlink": "Киирэр тылгын умнубуккун дуо?",
-       "userlogin-resetpassword-link": "Ð\9aииÑ\80ии тылгын санаттараҕын дуо?",
+       "userlogin-resetpassword-link": "Ð\90һаÑ\80Ñ\8bк тылгын санаттараҕын дуо?",
        "userlogin-helplink2": "Киирэргэ көмө",
        "userlogin-loggedin": "Маннык аатынан киирбиккин {{GENDER:$1|$1}}.\nАтын аатынан киирэргэ аллара көстөр форманы туһан.",
        "userlogin-reauth": "Тиһиккэ хат киирэн {{GENDER:$1|$1}} буоларгын бигэргэтиэхтээххин.",
        "nouserspecified": "Кыттааччы аатын киллэриэхтээххин.",
        "login-userblocked": "Бу кыттааччы бобуллубут. Тиһиккэ киирии көҥүллэммэт.",
        "wrongpassword": "Киирии тылыҥ сыыһалаах. Өссө киллэрэн көр.",
-       "wrongpasswordempty": "Ð\9aииÑ\80ии Ñ\82Ñ\8bлгÑ\8bн Ñ\81Ñ\83Ñ\80Ñ\83йбаÑ\82аÑ\85Ñ\85Ñ\8bн. Ó¨Ñ\81Ñ\81Ó© киирэн көр.",
+       "wrongpasswordempty": "Ð\90һаÑ\80Ñ\8bккÑ\8bн Ñ\81Ñ\83Ñ\80Ñ\83йбаÑ\82аÑ\85Ñ\85Ñ\8bн. Ð¥Ð°Ñ\82 киирэн көр.",
        "passwordtooshort": "Киирии тылыҥ наһаа кылгас.\nКырата {{PLURAL:$1|1 бэлиэлээх|$1 бэлиэлээх}} буолуохтаах.",
        "passwordtoolong": "Аһарык {{PLURAL:$1|1 бэлиэттэн|$1 бэлиэттэн}} уһун буолуо суохтаах.",
        "passwordtoopopular": "Элбэхтэ туттуллар аһарыктары туттар сатаммат. Бука диэн атын аһарыкта тал.",
        "password-name-match": "Аһарыгыҥ ааккыттан атын буолуохтаах.",
        "password-login-forbidden": "Маннык ааты уонна киирии тылы туһаныы бобуллар.",
        "mailmypassword": "Киирии тылы саҥардыы",
-       "passwordremindertitle": "{{SITENAME}} ÐºÐ¸Ð¸Ñ\80ии тылын санатыы",
-       "passwordremindertext": "Ким эрэ (бадаҕа эн бу IP-аадырыстан: $1), {{SITENAME}} ($4) аһарыгын саҥаттан ыытыҥ диэбит.\n\"$2\" кыттааччы быстах аһарыга билигин маннык: \"$3\".\nӨскө маны эн чахчы көрдөөбүт буоллаххына, систиэмэҕэ саҥаттан киирэҥҥин аһарыккын уларытыаххын сөп.\nБыстах аһарык {{PLURAL:$5|биир хонук|$5 хонук устата}} үлэлиир.\n\nӨскөтүн аһарыгы саҥаттан көрдөөбөтөх буоллаххына,\nэбэтэр урукку аһарыккн өйдөөн кэлбит буоллаххына,\nбу суругу ааххайыма уонна урукку аһарыккын салгыы туһан.",
+       "passwordremindertitle": "{{SITENAME}} Ð°Ò»Ð°Ñ\80Ñ\8bк тылын санатыы",
+       "passwordremindertext": "Ким эрэ (бадаҕа Эн бу IP-аадырыстан: $1), {{SITENAME}} ($4) аһарыгын саҥаттан ыытыҥ диэбит.\n\"$2\" кыттааччы быстах аһарыга билигин маннык: \"$3\".\nӨскө маны эн чахчы көрдөөбүт буоллаххына, систиэмэҕэ саҥаттан киирэҥҥин аһарыккын уларытыаххын сөп.\nБыстах аһарык {{PLURAL:$5|биир хонук|$5 хонук устата}} үлэлиир.\n\nӨскөтүн аһарыгы саҥаттан көрдөөбөтөх буоллаххына,\nэбэтэр урукку аһарыккын өйдөөн кэлбит буоллаххына,\nбу суругу ааххайыма уонна урукку аһарыккын салгыы туһан.",
        "noemail": "\"$1\" ааттаах киһиэхэ эл. почтата ыйыллыбатах.",
        "noemailcreate": "Электроннай почтаҥ сөптөөх аадырыһын суруйуохтааххын",
        "passwordsent": "Саҥа аһарык тыл \"$1\" эл. почтатыгар ыытылынна.\nТиһиккэ киирэргэ саҥа аһарыгы туһан.",
        "accountcreated": "Саҥа аат иҥэрилиннэ",
        "accountcreatedtext": "[[{{ns:User}}:$1|$1]] ([[{{ns:User talk}}:$1|ыр.]]) бэлиэ аат оҥоһулунна.",
        "createaccount-title": "{{SITENAME}} бырайыакка саҥа аат оҥоруу",
-       "createaccount-text": "Ð\9aим Ñ\8dÑ\80Ñ\8d {{SITENAME}} Ð±Ñ\8bÑ\80айÑ\8bакка ($4) Ñ\81аҥа $2 Ð°Ð°Ñ\82Ñ\8b Ð±Ñ\8dлиÑ\8dÑ\82Ñ\8dÑ\8dбиÑ\82. \"$2\" ÐºÐ¸Ð¸Ñ\80ии Ñ\82Ñ\8bла \"$3\". Ð\91илигин ÐºÐ¸Ð¸Ñ\80Ñ\8dн ÐºÐ¸Ð¸Ñ\80ии Ñ\82Ñ\8bлгÑ\8bн Ñ\83лаÑ\80Ñ\8bÑ\82Ñ\8bаÑ\85Ñ\85Ñ\8bн Ð½Ð°Ð°Ð´Ð°.\n\nСаҥа аат сыыһа оҥоһуллубут буоллаҕына тугу да гыныа суоххун сөп.",
+       "createaccount-text": "Ð\9aим Ñ\8dÑ\80Ñ\8d {{SITENAME}} Ð±Ñ\8bÑ\80айÑ\8bакка ($4) Ñ\81аҥа $2 Ð°Ð°Ñ\82Ñ\8b Ð±Ñ\8dлиÑ\8dÑ\82Ñ\8dÑ\8dбиÑ\82. \"$2\" Ð°Ò»Ð°Ñ\80Ñ\8bга \"$3\". Ð\91илигин ÐºÐ¸Ð¸Ñ\80Ñ\8dн Ð°Ò»Ð°Ñ\80Ñ\8bк Ñ\82Ñ\8bлгÑ\8bн Ñ\83лаÑ\80Ñ\8bÑ\82Ñ\8bаÑ\85Ñ\82ааÑ\85 Ñ\8dбиккин.\n\nСаҥа аат сыыһа оҥоһуллубут буоллаҕына тугу да гыныа суоххун сөп.",
        "login-throttled": "Ааккын аһара элбэхтик билиһиннэрэ сатаатыҥ.\nБука диэн $1 буолан баран өссө киирэн көрөөр.",
        "login-abort-generic": "Бу аатынан сатаан киирбэтиҥ - быһынна",
        "login-migrated-generic": "Эн бэлиэ-аатыҥ көһөрүллүбүт, онон урукку аатыҥ бу биикигэ суох буолбут эбит.",
        "changepassword": "Киирии тылы уларытарга",
        "resetpass_announce": "Түмүктүүргэ саҥа киирии тылла суруй.",
        "resetpass_text": "<!-- Тиэкиһи манна эбэн суруйуҥ -->",
-       "resetpass_header": "Ð\90аÑ\82 ÐºÐ¸Ð¸Ñ\80ии тылын уларытыы",
+       "resetpass_header": "Ð\91Ñ\8dлиÑ\8d-ааÑ\82 Ð°Ò»Ð°Ñ\80Ñ\8bк тылын уларытыы",
        "oldpassword": "Эргэ аһарык:",
        "newpassword": "Саҥа аһарык:",
        "retypenew": "Саҥа киирии тылы хатылаа:",
        "passwordreset-domain": "Домен:",
        "passwordreset-email": "Электроннай почтата:",
        "passwordreset-emailtitle": "{{SITENAME}} бырайыакка аатын туһунан",
-       "passwordreset-emailtext-ip": "Ким эрэ (баҕар эн буолуо, бу IP-ттан $1)  {{SITENAME}} ($4) бырайыакка киирии тылы уларытар туһунан ыйытык биэрбит.\nБу электрон аадырыһы кытта бу {{PLURAL:$3|аат ситимнээх|ааттар ситимнээхтэр}}:\n\n$2\n\nБу быстах кэмҥэ аналлаах {{PLURAL:$3|киирии тыл|кирии тыллар}} {{PLURAL:$5|биир күн үлэлиэҕэ|$5 күн үлэлиэхтэрэ}}.\nЭн тиһиликкэ ааккын этэн саҥа киирии тылы киллэриэхтээххин.\nӨскө бу ыйытыгы ыыппатах буоллаххына, эбэтэр урукку киирии тылгын өйдөөн кэлбит буоллаххына \nбу биллэриини ааххайыа суоххун сөп.\nОччоҕо урукку киирии тылыҥ оннунан хаалыа.",
-       "passwordreset-emailtext-user": "$1 Ð´Ð¸Ñ\8dн ÐºÑ\8bÑ\82Ñ\82ааÑ\87Ñ\87Ñ\8b  {{SITENAME}} ($4) Ð±Ñ\8bÑ\80айÑ\8bакка ÐºÐ¸Ð¸Ñ\80ии Ñ\82Ñ\8bлгÑ\8bн Ñ\83лаÑ\80Ñ\8bÑ\82аÑ\80 Ñ\82Ñ\83Ò»Ñ\83нан Ñ\8bйÑ\8bÑ\82Ñ\8bк Ñ\8bÑ\8bппÑ\8bÑ\82.\nÐ\91Ñ\83 Ñ\8dлекÑ\82Ñ\80он Ð°Ð°Ð´Ñ\8bÑ\80Ñ\8bÒ»Ñ\8b ÐºÑ\8bÑ\82Ñ\82а Ð±Ñ\83 {{PLURAL:$3|ааÑ\82 Ñ\81иÑ\82имнÑ\8dÑ\8dÑ\85|ааÑ\82Ñ\82аÑ\80 Ñ\81иÑ\82имнÑ\8dÑ\8dÑ\85Ñ\82Ñ\8dÑ\80}}\n\n$2\n\nÐ\91Ñ\83 Ð±Ñ\8bÑ\81Ñ\82аÑ\85 ÐºÑ\8dмҥÑ\8d Ð°Ð½Ð°Ð»Ð»Ð°Ð°Ñ\85 {{PLURAL:$3|кииÑ\80ии Ñ\82Ñ\8bл|киÑ\80ии Ñ\82Ñ\8bллаÑ\80}} {{PLURAL:$5|бииÑ\80 ÐºÒ¯Ð½ Ò¯Ð»Ñ\8dлиÑ\8dÒ\95Ñ\8d|$5 ÐºÒ¯Ð½ Ò¯Ð»Ñ\8dлиÑ\8dÑ\85Ñ\82Ñ\8dÑ\80Ñ\8d}}.\nЭн Ñ\82иһиликкÑ\8d Ð°Ð°ÐºÐºÑ\8bн Ñ\8dÑ\82Ñ\8dн Ñ\81аҥа ÐºÐ¸Ð¸Ñ\80ии Ñ\82Ñ\8bлÑ\8b ÐºÐ¸Ð»Ð»Ñ\8dÑ\80иÑ\8dÑ\85Ñ\82Ñ\8dÑ\8dÑ\85Ñ\85ин.\nÓ¨Ñ\81кө Ð±Ñ\83 Ñ\8bйÑ\8bÑ\82Ñ\8bгÑ\8b Ñ\8bÑ\8bппаÑ\82аÑ\85 Ð±Ñ\83оллаÑ\85Ñ\85Ñ\8bна, Ñ\8dбÑ\8dÑ\82Ñ\8dÑ\80 Ñ\83Ñ\80Ñ\83ккÑ\83 ÐºÐ¸Ð¸Ñ\80ии Ñ\82Ñ\8bлгÑ\8bн Ó©Ð¹Ð´Ó©Ó©Ð½ ÐºÑ\8dлбиÑ\82 Ð±Ñ\83оллаÑ\85Ñ\85Ñ\8bна \nбÑ\83 Ð±Ð¸Ð»Ð»Ñ\8dÑ\80иини Ð°Ð°Ñ\85Ñ\85айÑ\8bа Ñ\81Ñ\83оÑ\85Ñ\85Ñ\83н Ñ\81өп.\nÐ\9eÑ\87Ñ\87оÒ\95о Ñ\83Ñ\80Ñ\83ккÑ\83 ÐºÐ¸Ð¸Ñ\80ии Ñ\82Ñ\8bлыҥ оннунан хаалыа.",
+       "passwordreset-emailtext-ip": "Ким эрэ (баҕар Эн буолуо, бу IP-ттан $1)  {{SITENAME}} ($4) бырайыакка аһарык тылы уларытар туһунан ыйытык биэрбит.\nБу электрон аадырыһы кытта бу {{PLURAL:$3|аат ситимнээх|ааттар ситимнээхтэр}}:\n\n$2\n\nБу быстах кэмҥэ аналлаах {{PLURAL:$3|аһарык|аһарык тыллар}} {{PLURAL:$5|биир күн үлэлиэҕэ|$5 күн үлэлиэхтэрэ}}.\nЭн тиһиликкэ ааккын этэн саҥа аһарык тылы киллэриэхтээххин.\nӨскө бу ыйытыгы ыыппатах буоллаххына, эбэтэр урукку аһарык тылгын өйдөөн кэлбит буоллаххына \nбу биллэриини ааххайыа суоххун сөп.\nОччоҕо урукку аһарык тылыҥ оннунан хаалыа.",
+       "passwordreset-emailtext-user": "$1 Ð´Ð¸Ñ\8dн ÐºÑ\8bÑ\82Ñ\82ааÑ\87Ñ\87Ñ\8b  {{SITENAME}} ($4) Ð±Ñ\8bÑ\80айÑ\8bакка Ð°Ò»Ð°Ñ\80Ñ\8bккÑ\8bн Ñ\83лаÑ\80Ñ\8bÑ\82аÑ\80 Ñ\82Ñ\83Ò»Ñ\83нан Ñ\8bйÑ\8bÑ\82Ñ\8bк Ñ\8bÑ\8bппÑ\8bÑ\82.\nÐ\91Ñ\83 Ñ\8dлекÑ\82Ñ\80он Ð°Ð°Ð´Ñ\8bÑ\80Ñ\8bÒ»Ñ\8b ÐºÑ\8bÑ\82Ñ\82а Ð±Ñ\83 {{PLURAL:$3|ааÑ\82 Ñ\81иÑ\82имнÑ\8dÑ\8dÑ\85|ааÑ\82Ñ\82аÑ\80 Ñ\81иÑ\82имнÑ\8dÑ\8dÑ\85Ñ\82Ñ\8dÑ\80}}\n\n$2\n\nÐ\91Ñ\83 Ð±Ñ\8bÑ\81Ñ\82аÑ\85 ÐºÑ\8dмҥÑ\8d Ð°Ð½Ð°Ð»Ð»Ð°Ð°Ñ\85 {{PLURAL:$3|аһаÑ\80Ñ\8bк|аһаÑ\80Ñ\8bкÑ\82аÑ\80}} {{PLURAL:$5|бииÑ\80 ÐºÒ¯Ð½ Ò¯Ð»Ñ\8dлиÑ\8dÒ\95Ñ\8d|$5 ÐºÒ¯Ð½ Ò¯Ð»Ñ\8dлиÑ\8dÑ\85Ñ\82Ñ\8dÑ\80Ñ\8d}}.\nЭн Ñ\82иһиликкÑ\8d Ð°Ð°ÐºÐºÑ\8bн Ñ\8dÑ\82Ñ\8dн Ñ\81аҥа ÐºÐ¸Ð¸Ñ\80ии Ñ\82Ñ\8bлÑ\8b ÐºÐ¸Ð»Ð»Ñ\8dÑ\80иÑ\8dÑ\85Ñ\82Ñ\8dÑ\8dÑ\85Ñ\85ин.\nÓ¨Ñ\81кө Ð±Ñ\83 Ñ\8bйÑ\8bÑ\82Ñ\8bгÑ\8b Ñ\8bÑ\8bппаÑ\82аÑ\85 Ð±Ñ\83оллаÑ\85Ñ\85Ñ\8bна, Ñ\8dбÑ\8dÑ\82Ñ\8dÑ\80 Ñ\83Ñ\80Ñ\83ккÑ\83 Ð°Ò»Ð°Ñ\80Ñ\8bккÑ\8bн Ó©Ð¹Ð´Ó©Ó©Ð½ ÐºÑ\8dлбиÑ\82 Ð±Ñ\83оллаÑ\85Ñ\85Ñ\8bна \nбÑ\83 Ð±Ð¸Ð»Ð»Ñ\8dÑ\80иини Ð°Ð°Ñ\85Ñ\85айÑ\8bа Ñ\81Ñ\83оÑ\85Ñ\85Ñ\83н Ñ\81өп.\nÐ\9eÑ\87Ñ\87оÒ\95о Ñ\83Ñ\80Ñ\83ккÑ\83 Ð°Ò»Ð°Ñ\80Ñ\8bгыҥ оннунан хаалыа.",
        "passwordreset-emailelement": "Кыттааччы: \n$1\n\nБыстах аһарык тыл: \n$2",
        "passwordreset-emailsentemail": "Өскө бу Эн ааккар баайыллыбыт аадырыс буоллаҕына, аһарык тылы уларытар туһунан сурук барыа.",
        "passwordreset-emailsentusername": "Өскө бу аакка баайыллыбыт аадырыс баар буоллаҕына, аһарык тылы уларытар туһунан сурук онно барыа.",
        "prefs-help-gender": "Маны туруорар булгуччута суох. \nБырагыраамма сорох дьоҥҥо туһаайыллыбыт биллэриилэригэр эбэтэр кинилэргэ сыһыаннаах этиилэригэр кытааччы дьахтарыттан эбэтэр эр киһититтэн көрөн этии тутулун уларытан биэриэн сөп. \nТуора дьоҥҥо көстөр бэлиэтээһин.",
        "email": "Почта",
        "prefs-help-realname": "Сурукка киирбит аатыҥ булгуччута суох. Суруйдаххына ааптар быһыытынан ыйыллар буолуоҥ.",
-       "prefs-help-email": "ЭлекÑ\82Ñ\80оннай Ð°Ð°Ð´Ñ\8bÑ\80Ñ\8bÒ»Ñ\8b Ñ\81Ñ\83Ñ\80Ñ\83йаÑ\80 Ð±Ñ\83лгÑ\83Ñ\87Ñ\87Ñ\83Ñ\82а Ñ\81Ñ\83оÑ\85, Ð¾Ð» Ñ\8dÑ\80Ñ\8dÑ\8dÑ\80и ÐºÐ¸Ð¸Ñ\80ии тылгын умуннаххына санатарга көмөлөһүө.",
+       "prefs-help-email": "ЭлекÑ\82Ñ\80оннай Ð°Ð°Ð´Ñ\8bÑ\80Ñ\8bÒ»Ñ\8b Ñ\81Ñ\83Ñ\80Ñ\83йаÑ\80 Ð±Ñ\83лгÑ\83Ñ\87Ñ\87Ñ\83Ñ\82а Ñ\81Ñ\83оÑ\85, Ð¾Ð» Ñ\8dÑ\80Ñ\8dÑ\8dÑ\80и Ð°Ò»Ð°Ñ\80Ñ\8bк тылгын умуннаххына санатарга көмөлөһүө.",
        "prefs-help-email-others": "Эбии. Атын кыттааччылар Эйигин кытта электроннай почтаҕын билбэккэ эрэ суруйсар кыахтаныахтара.",
        "prefs-help-email-required": "E-mail баар буолуохтаах.",
        "prefs-info": "Сүрүн сибидиэнньэлэр",
index 037258d..ba5685a 100644 (file)
        "prefs-rendering": "حليو",
        "saveprefs": "سانڍيو",
        "prefs-editing": "سنوارڻ",
-       "rows": "قطارون:",
-       "columns": "ڪالمَ:",
        "searchresultshead": "ڳولا",
        "stub-threshold-sample-link": "نمونو",
        "stub-threshold-disabled": "غيرفعال",
        "sharedupload-desc-here": "ھي فائيل $1 مان آھي ۽ ٻين رٿائن پاران پڻ استعمال ٿي سگھي ٿو. تشريح انجي [[$2 جو تشريحي صفحو]] ھيٺان ڏنل آھي.",
        "uploadnewversion-linktext": "هن فائيل جو نئون پرت چاڙهيو",
        "shared-repo-from": "$1 کان",
+       "shared-repo-name-wikimediacommons": "وڪيميڊيا ڪامنز",
        "upload-disallowed-here": "توھان ھن فائيل مٿان لکي نہ ٿا سگھو.",
        "filerevert-comment": "سبب:",
        "filerevert-submit": "واپس ورايو",
        "feedback-submit": "جمع ڪرايو",
        "feedback-thanks-title": "توهان جي مهرباني!",
        "searchsuggest-search": "ڳوليو {{SITENAME}}",
-       "api-error-filename-tooshort": "فائيل‌نانءَُ هيڪاندو ننڍو آهي.",
-       "api-error-unclassified": "ڪا اڻجاتل چُڪَ واقع ٿي.",
-       "api-error-unknown-code": "اڻڄاتل چُڪَ: \"$1\".",
        "api-error-unknown-warning": "اڻڄاتل چتاءُ: \"$1\".",
        "api-error-unknownerror": "اڻڄاتل چُڪَ: \"$1\".",
        "expand_templates_output": "نتيجو",
index 259bbe2..389398d 100644 (file)
        "badsig": "Loš sirovi potpis.\nProvjerite HTML tagove.",
        "badsiglength": "Vaš potpis je predug.\nMora biti manji od $1 {{PLURAL:$1|znaka|znaka|znakova}}.",
        "yourgender": "Kako želite da se predstavite?",
-       "gender-unknown": "Kad vas spominje, softver će pokušati koristiti srednji rod kad god je to moguće",
+       "gender-unknown": "Kad Vas spominje, softver će pokušati izbjegavati rod kad god je to moguće",
        "gender-male": "On uređuje wiki stranice",
        "gender-female": "Ona uređuje wiki stranice",
        "prefs-help-gender": "Postavljanje ove preferencije nije obavezno.\nSoftver koristi ovu vrijednost kako bi vam se obratio i spomenuo vas drugima koristeći vaš gramatički rod.\nOva informacija će biti javna.",
index eafaea6..1204519 100644 (file)
        "passwordreset-emaildisabled": "ၽၢင်ႁဵတ်းၵၢၼ် ဢီးမေးလ် ထုၵ်ႇဢိုတ်းဝႆႉ ၵႃႈတီႈ ဝီႇၶီႇၼႆႉ။",
        "passwordreset-username": "ၸိုဝ်ႈၽူႈၸႂ်ႉတိုဝ်း",
        "passwordreset-domain": "တူဝ်ႇမဵင်း :",
-       "passwordreset-capture": "တေတူၺ်း ဢီးမေးလ်ၽွၼ်းလႆႈ?",
-       "passwordreset-capture-help": "ပေႃးၸဝ်ႈၵဝ်ႇ ၶိုၼ်ႇလွၵ်ႈၼႆႉၼႆ ဢီးမေးလ် (ဢၼ်ၸႂ်ႉၶေႃႈလပ်ႉၸူဝ်ႈၵႅပ်ႉ) တေၼႄဝႆႉဝႃႈ  မၼ်းသူင်ႇၸူး ၽူႈၸႂ်ႉတိုဝ်း ဝႆႉယဝ်ႉ ၼႆဢေႃႈ.",
        "passwordreset-email": "ႁဵင်းလိၵ်ႈ ဢီးမေးလ် :",
        "passwordreset-emailtitle": "လွင်ႈႁူဝ်ယွႆႈ ဢၶွင်ႉ ၵႃႈတီႈ {{SITENAME}}",
        "passwordreset-emailelement": "ၸိုဝ်ႈၽူႈၸႂ်ႉတိုဝ်း:\n$1\n\nၶေႃႈလပ်ႉ ၸူဝ်ႈၵႅပ်ႉ:\n$2",
        "searchprofile-everything-tooltip": "သွၵ်ႈႁႃလမ်းၼႂ်းတင်းမူတ်း (ဢိၵ်ႇပႃးၼႃႈလိၵ်ႈ ဢုပ်ႇဢူဝ်း)",
        "searchprofile-advanced-tooltip": "သွၵ်ႈႁႃတီႈၼႂ်း ဢွင်ႈတီႈၸိုဝ်ႈႁင်းတူဝ်",
        "search-result-size": "$1 ({{PLURAL:$2|1 ၶေႃႈ|$2 ၶေႃႈ}})",
-       "search-redirect": "(á\80\95á\80­á\81¼á\80ºá\82\87á\80\9eá\80µá\81¼á\80ºá\82\88á\80\90á\81¢á\80\84á\80ºá\80¸á\81¸á\80°á\80¸ $1)",
+       "search-redirect": "(á\80\95á\80­á\81¼á\80ºá\82\87á\80\9dá\81¢á\82\86á\82\87á\80\99á\82\83á\80¸á\80\90á\80®á\82\88 $1)",
        "search-section": "(တွၼ်ႈၵၼ် $1)",
        "search-category": "(တွၼ်ႈၵၼ် $1)",
        "search-suggest": "ၶႂ်ႈဝႃႈ $1 - ၼႆႁႃႉ",
        "saveprefs": "ၵဵပ်းသိမ်း",
        "restoreprefs": "ၶိုၼ်းတမ်း ၵၢၼ်တင်ႈတင်းမူတ်း ႁႂ်ႈမိူၼ်ၵဝ်ႇၶိုၼ်း (ၵႃႈတီႈ တွၼ်ႈၵၼ်ၵူႈဢၼ်)",
        "prefs-editing": "တိုၵ်ႉမႄးထတ်းယူႇ",
-       "rows": "သၢႆတမ်း :",
-       "columns": "သၢႆၸုၵ်း :",
        "searchresultshead": "ၶူၼ်ႉႁႃ",
        "stub-threshold-sample-link": "တူဝ်ယၢင်ႇ",
        "stub-threshold-disabled": "ဢိုတ်းဝႆႉ",
        "userrights-reason": "လွင်ႈတၢင်း :",
        "userrights-no-interwiki": "ၸဝ်ႈၵဝ်ႇ ဢမ်ႇမီးသုၼ်ႇၶႂၢင်းပၼ် တွၼ်ႈတႃႇ မႄးထတ်း သုၼ်ႇၽူႈၸႂ်ႉတိုဝ်းၵႃႈတီႈဝီႇၶီႇ တၢင်ႇဢၼ်။",
        "userrights-nodatabase": "ယွင်ၶေႃႈမုၼ်း $1 ၼႆႉဢမ်ႇမီး ဢမ်ႇၼၼ် မၼ်းဢမ်ႇၸႂ်ႈ လူဝ်ႇၵႄႇ။",
-       "userrights-notallowed": "ၸဝ်ႈၵဝ်ႇဢမ်ႇလႆႈမီးသုၼ်ႇၶႂၢင်းပၼ် တွၼ်ႈတႃႇ တေထႅမ်သႂ်ႇ ဢမ်ႇၼၼ် ထွၼ်ပႅတ်ႈ သုၼ်ႇလႆႈ ၽူႈၸႂ်ႉတိုဝ်း",
        "userrights-changeable-col": "ၸုမ်း ၸိူဝ်းၸဝ်ႈၵဝ်ႇ ၸၢင်ႈလႅၵ်ႈလၢႆႈ",
        "userrights-unchangeable-col": "ၸုမ်း ၸိူဝ်းၸဝ်ႈၵဝ်ႇ ဢမ်ႇၸၢင်ႈလႅၵ်ႈလၢႆႈ",
        "userrights-conflict": "လွင်ႈလႅၵ်ႈလၢႆႈ သုၼ်ႇၽူႈၸႂ်ႉတိုဝ်းၼၼ်ႉ မီးလွင်ႈယုင်ႈယၢင်ႈဝႆႉ။ ၶႅၼ်းတေႃႈ ၶိုၼ်းထတ်းတူၺ်းပၼ် သေ ၶိုၼ်းၼႄႉၼွၼ်းပၼ် လွင်ႈလႅၵ်ႈလၢႆႈၸဝ်ႈၵဝ်ႇလႄႈ။",
-       "userrights-removed-self": "ၸဝ်ႈၵဝ်ႇထွၼ်ပႅတ်ႇ သုၼ်ႇလႆႈတူဝ်ၸဝ်ႈၵဝ်ႇ။ ယွၼ်ႉၼၼ်လႄႈ ၸဝ်ႈၵဝ်ႇ တေဢမ်ႇၸၢင်ႈၶဝ်ႈၸႂ်ႉ ၼႃႈလိၵ်ႈၼႆႉလႆႈယဝ်ႉ။",
        "group": "ၸုမ်း :",
        "group-user": "ၽူႈၸႂ်ႉတိုဝ်း",
        "group-autoconfirmed": "ၽူႈၸႂ်ႉတိုဝ်း ၸိူဝ်းၼႄႉၼွၼ်းတူဝ်ႁင်းၵူၺ်း",
        "right-userrights-interwiki": "မႄးထတ်း သုၼ်ႇလႆႈ ၽူႈၸႂ်ႉတိုဝ်း ၸိူဝ်းပဵၼ် ၽူႈၸႂ်ႉတိုဝ်း ဢၼ်မီးဝႆႉယူႇ ၵႃႈတီႈၼိူဝ် ဝီႇၶီႇတၢင်ႇၸိူဝ်း",
        "right-siteadmin": "ၶတ်းသေႃး လႄႈ ဢမ်ႇၶတ်းသေႃး ယွင်ၶေႃႈမုၼ်း",
        "right-sendemail": "သူင်ႇဢီးမေးလ်ၸူး ၽူႈၸႂ်ႉတိုဝ်း တၢင်ႇၸိူဝ်း",
-       "right-passwordreset": "တူၺ်း ဢီးမေး တင်ႈၶိုၼ်း ၶေႃႈလပ်ႉ",
        "right-managechangetags": "ၵေႃႇသၢင်ႈ လႄႈ (ဢမ်ႇ) တူင်ႉတိုၼ်ႇ  [[Special:Tags|tags]]",
        "right-deletechangetags": "မွတ်ႇပႅတ်ႈ  [[Special:Tags|tags]] ၵႃႈတီႈ ယွင်ၶေႃႈမုၼ်း",
        "grant-generic": "\"$1\" ထုပ်ႉႁေႃႇ သုၼ်ႇလႆႈ",
        "logentry-move-move": "$1 {{GENDER:$2|ၶၢႆႉယဝ်ႉ}} ၼႃႈလိၵ်ႈ $3 တေႃႇ $4",
        "logentry-newusers-create": "ဢၶွင်ႉၽူႈၸႂ်ႉတိုဝ်း $1 ၼႆႉ လႆႈ  {{GENDER:$2|ၵေႃႇသၢင်ႈယဝ်ႉ}}",
        "logentry-upload-upload": "$1 {{GENDER:$2|လူတ်ႇၶိုၼ်ႈၵႂႃႇယဝ်ႉ}} $3",
-       "searchsuggest-search": "ၶူၼ်ႉႁႃ",
+       "searchsuggest-search": "ၶူၼ်ႉႁႃ {{SITENAME}}",
        "mw-widgets-dateinput-no-date": "ပႆႇလိူၵ်ႈဝၼ်းယၢမ်း"
 }
index d4e182b..5bda1ac 100644 (file)
        "username": "{{GENDER:$1|Uporabniško|Uporabničino}} ime:",
        "prefs-memberingroups": "{{GENDER:$2|Član|Članica}} {{PLURAL:$1|naslednje skupine|naslednjih skupin}}:",
        "prefs-memberingroups-type": "$1",
+       "group-membership-link-with-expiry": "$1 (do $2)",
        "prefs-registration": "Registriran od:",
        "yourrealname": "Pravo ime:",
        "yourlanguage": "Jezik:",
        "userrights-nodatabase": "Podatkovna baza $1 ne obstaja ali ni lokalna.",
        "userrights-changeable-col": "Skupine, ki jih lahko spremenite",
        "userrights-unchangeable-col": "Skupine, ki jih ne morete spremeniti",
+       "userrights-expiry-current": "Poteče $1",
+       "userrights-expiry-none": "Ne poteče",
+       "userrights-expiry": "Poteče:",
+       "userrights-expiry-existing": "Obstoječ čas poteka: $3, $2",
+       "userrights-expiry-othertime": "Drug čas:",
+       "userrights-expiry-options": "1 dan:1 day,1 teden:1 week,1 mesec:1 month,3 mesece:3 months,6 mesecev:6 months,1 leto:1 year",
+       "userrights-invalid-expiry": "Čas poteka skupine »$1« ni veljaven.",
+       "userrights-expiry-in-past": "Čas poteka skupine »$1« je v preteklosti.",
        "userrights-conflict": "Spor sprememb uporabniških pravic! Prosimo, da pregledate in potrdite svoje spremembe.",
        "group": "Skupina:",
        "group-user": "Uporabniki",
        "recentchanges-summary": "Na tej strani lahko spremljate najnovejše spremembe wikija.",
        "recentchanges-noresult": "V podanem obdobju nobena sprememba ne ustreza tem merilom.",
        "recentchanges-feed-description": "Spremljajte zadnje spremembe wikija prek tega vira.",
-       "recentchanges-label-newpage": "s tem urejanjem je uporabnik ustvaril novo stran",
-       "recentchanges-label-minor": "manjše urejanje",
+       "recentchanges-label-newpage": "nova stran",
+       "recentchanges-label-minor": "[[w:sl:Pomoč:Manjše urejanje|manjše urejanje]]",
        "recentchanges-label-bot": "urejanje je izvedel bot",
-       "recentchanges-label-unpatrolled": "Urejanje še ni bilo pregledano",
-       "recentchanges-label-plusminus": "uporabnik je velikost strani spremenil za tolikšno število bajtov",
+       "recentchanges-label-unpatrolled": "nepreverjeno urejanje",
+       "recentchanges-label-plusminus": "razlika v številu znakov (krepko, če 500 ali več)",
        "recentchanges-legend-heading": "<strong>Legenda:</strong>",
        "recentchanges-legend-newpage": "{{int:recentchanges-label-newpage}} (glej tudi [[Special:NewPages|seznam novih strani]])",
        "recentchanges-submit": "Prikaži",
        "rcfilters-activefilters": "Dejavni filtri",
+       "rcfilters-restore-default-filters": "Obnovi privzete filtre",
+       "rcfilters-clear-all-filters": "Počisti vse filtre",
        "rcfilters-search-placeholder": "Zadnje spremembe filtrov (prebrskajte ali začnite vnašati)",
        "rcfilters-invalid-filter": "Neveljaven filter",
+       "rcfilters-empty-filter": "Ni dejavnih filtrov. Prikazani so vsi prispevki.",
        "rcfilters-filterlist-title": "Filtri",
        "rcfilters-filterlist-noresults": "Nismo našli nobenega filtra",
+       "rcfilters-filtergroup-registration": "Registracija uporabnika",
+       "rcfilters-filter-registered-label": "Registriran",
+       "rcfilters-filter-registered-description": "Prijavljeni uredniki.",
+       "rcfilters-filter-unregistered-label": "Neregistriran",
+       "rcfilters-filter-unregistered-description": "Uredniki, ki niso prijavljeni.",
        "rcfilters-filtergroup-authorship": "Uredi avtorstvo",
        "rcfilters-filter-editsbyself-label": "Vaša lastna urejanja",
        "rcfilters-filter-editsbyself-description": "Vaša urejanja.",
        "rcfilters-filter-editsbyother-label": "Urejanja drugih",
        "rcfilters-filter-editsbyother-description": "Urejanja, ki so jih naredili drugi uporabniki (ne vi).",
-       "rcfilters-filtergroup-userExpLevel": "Stopnja uporabnikove izkušenosti",
+       "rcfilters-filtergroup-userExpLevel": "Stopnja izkušenosti (samo za registrirane uporabnike)",
        "rcfilters-filter-userExpLevel-newcomer-label": "Novinci",
-       "rcfilters-filter-userExpLevel-newcomer-description": "Zelo novi sodelavci: manj kot 10 urejanj in 4 dni dejavnosti.",
+       "rcfilters-filter-userExpLevel-newcomer-description": "Manj kot 10 urejanj in 4 dni dejavnosti.",
        "rcfilters-filter-userExpLevel-learner-label": "Učenci",
        "rcfilters-filter-userExpLevel-learner-description": "Več dni dejavnosti in urejanj kot »Novinci«, vendar manj kot »Izkušeni uporabniki«.",
        "rcfilters-filter-userExpLevel-experienced-label": "Izkušeni uporabniki",
        "rcfilters-filter-userExpLevel-experienced-description": "Več kot 30 dni dejavnosti in 500 urejanj.",
+       "rcfilters-filtergroup-automated": "Samodejni prispevki",
+       "rcfilters-filter-bots-label": "Bot",
+       "rcfilters-filter-bots-description": "Urejanja, narejena s samodejnimi orodji.",
+       "rcfilters-filter-humans-label": "Človek (ne bot)",
+       "rcfilters-filter-humans-description": "Urejanja, ki so jih izvedli uredniki ljudje.",
+       "rcfilters-filtergroup-significance": "Pomembnost",
+       "rcfilters-filter-minor-label": "Manjše urejanje",
+       "rcfilters-filter-minor-description": "Urejanja, ki jih je avtor označil kot manjša.",
+       "rcfilters-filter-major-label": "Nemanjša urejanja",
+       "rcfilters-filter-major-description": "Urejanja, ki niso označena kot manjša.",
+       "rcfilters-filtergroup-changetype": "Vrsta spremembe",
+       "rcfilters-filter-pageedits-label": "Urejanja strani",
+       "rcfilters-filter-pageedits-description": "Urejanja vsebine wikija, razprave, opisi kategorij ...",
+       "rcfilters-filter-newpages-label": "Ustvarjanja strani",
+       "rcfilters-filter-newpages-description": "Urejanja, ki ustvarijo nove strani.",
+       "rcfilters-filter-categorization-label": "Spremembe kategorij",
+       "rcfilters-filter-categorization-description": "Zapisi o straneh, ki so bila dodana ali odstranjena iz kategorij.",
+       "rcfilters-filter-logactions-label": "Zabeležena dejanja",
+       "rcfilters-filter-logactions-description": "Administrativna dejanja, ustvarjanja računov, izbrisi strani, nalaganja ...",
        "rcnotefrom": "{{PLURAL:$5|Navedena je sprememba|Navedeni sta spremembi|Navedene so spremembe}} od <strong>$3 $4</strong> dalje (prikazujem jih do <strong>$1</strong>).",
        "rclistfrom": "Prikaži spremembe od $3 $2 naprej",
        "rcshowhideminor": "$1 manjša urejanja",
        "apisandbox-sending-request": "Pošiljanje zahteve API ...",
        "apisandbox-loading-results": "Prejemanje zahteve API ...",
        "apisandbox-results-error": "Med nalaganjem odgovora poizvedbe API je prišlo do napake: $1.",
-       "apisandbox-request-params-json": "Parametri JSON:",
+       "apisandbox-request-selectformat-label": "Prikaži zahtevane podatke kot:",
+       "apisandbox-request-format-url-label": "Niz poizvedbe URL",
        "apisandbox-request-url-label": "URL zahteve:",
+       "apisandbox-request-json-label": "Zahteva JSON:",
        "apisandbox-request-time": "Trajanje zahteve: {{PLURAL:$1|$1 ms}}",
        "apisandbox-results-fixtoken": "Popravite žeton in ponovno pošljite",
        "apisandbox-results-fixtoken-fail": "Pridobivanje žetona »$1« je spodletelo.",
        "emailccsubject": "Kopija tvojega sporočila iz $1: $2",
        "emailsent": "E-pismo je poslano!",
        "emailsenttext": "E-pismo je poslano.",
-       "emailuserfooter": "To e-poštno sporočilo je {{GENDER:$1|poslal|poslala|poslal(-a)}} $1 uporabniku {{GENDER:$2|$2}} s funkcijo »{{int:emailuser}}« na {{GRAMMAR:dative|{{SITENAME}}}}. {{GENDER:$2|Vaše}} e-poštno sporočilo bo poslano neposredno {{GENDER:$1|izvornemu pošiljatelju|izvorni pošiljateljici}}, kar {{GENDER:$1|mu|ji}} bo razkrilo {{GENDER:$2|vaš}} e-poštni naslov.",
+       "emailuserfooter": "To e-poštno sporočilo je {{GENDER:$1|poslal|poslala|poslal(-a)}} $1 uporabniku {{GENDER:$2|$2}} s funkcijo »{{int:emailuser}}« na {{GRAMMAR:dative|{{SITENAME}}}}. Če odgovorite na to sporočilo, bo {{GENDER:$2|vaše}} e-poštno sporočilo poslano neposredno {{GENDER:$1|izvornemu pošiljatelju|izvorni pošiljateljici}}, kar {{GENDER:$1|mu|ji}} bo razkrilo {{GENDER:$2|vaš}} e-poštni naslov.",
        "usermessage-summary": "Pusti sistemsko sporočilo.",
        "usermessage-editor": "Sistemski sporočevalec",
        "watchlist": "Spisek nadzorov",
        "logentry-tag-update-logentry": "$1 je {{GENDER:$2|posodobil|posodobila|posodobil(-a)}} oznake dnevniškega vnosa $5 strani $3 ({{PLURAL:$7|dodano}} $6; {{PLURAL:$9|odstranjeno}} $8)",
        "rightsnone": "(nobeno)",
        "revdelete-summary": "povzetek urejanja",
+       "rightslogentry-temporary-group": "$1 (začasno, do $2)",
        "feedback-adding": "Dodajanje povratne informacije na stran ...",
        "feedback-back": "Nazaj",
        "feedback-bugcheck": "Izvrstno! Samo preverite, da ne gre za enega od [$1 že znanih hroščev].",
index 464a470..6e457e0 100644 (file)
@@ -31,7 +31,8 @@
                        "Macofe",
                        "Сербијана",
                        "Xð",
-                       "Matma Rex"
+                       "Matma Rex",
+                       "Zoranzoki21"
                ]
        },
        "tog-underline": "Подвлачење веза:",
        "recentchanges-legend-heading": "<strong>Легенда:</strong>",
        "recentchanges-legend-newpage": "{{int:recentchanges-label-newpage}} ([[Special:NewPages|списак нових страница]])",
        "recentchanges-submit": "Прикажи",
+       "rcfilters-restore-default-filters": "Враћање подразумеваних филтера",
+       "rcfilters-clear-all-filters": "Уклони све филтере",
+       "rcfilters-empty-filter": "Нема активних филтера. Сви доприноси су приказани.",
        "rcfilters-filter-userExpLevel-newcomer-label": "Новајлије",
        "rcfilters-filter-userExpLevel-experienced-label": "Искусни корисници",
        "rcnotefrom": "Испод {{PLURAL:$5|је измена|су измене}} од <strong>$3, $4</strong> (до <strong>$1</strong> приказано).",
        "autoredircomment": "Преусмерење на [[$1]]",
        "autosumm-new": "Нова страница: $1",
        "autosumm-newblank": "Направљена празна страница",
-       "size-bytes": "$1 B",
+       "size-bytes": "$1 {{PLURAL:$1|бајт|бајта|бајтова}}",
        "size-kilobytes": "$1 kB",
        "size-megabytes": "$1 MB",
        "size-gigabytes": "$1 GB",
index 735e419..fc2858e 100644 (file)
        "saveprefs": "Sačuvaj",
        "restoreprefs": "Vrati sve na podrazumevano (u svim odeljcima)",
        "prefs-editing": "Uređivanje",
-       "rows": "Redova:",
-       "columns": "Kolona",
        "searchresultshead": "Pretraga",
        "stub-threshold": "Prag za oblikovanje veze kao klice ($1):",
        "stub-threshold-sample-link": "primer",
        "autoredircomment": "Preusmerenje na [[$1]]",
        "autosumm-new": "Nova stranica: $1",
        "autosumm-newblank": "Napravljena prazna stranica",
-       "size-bytes": "$1 B",
+       "size-bytes": "$1 {{PLURAL:$1|bajt|bajta|bajtova}}",
        "size-kilobytes": "$1 kB",
        "size-megabytes": "$1 MB",
        "size-gigabytes": "$1 GB",
        "feedback-thanks-title": "Hvala vam!",
        "searchsuggest-search": "Pretraga",
        "searchsuggest-containing": "sadrži...",
-       "api-error-badaccess-groups": "Nije vam dozvoljeno da otpremate datoteke na ovaj viki.",
        "api-error-badtoken": "Unutrašnja greška: neispravan žeton.",
-       "api-error-copyuploaddisabled": "Otpremanje putem adrese je onemogućeno na ovom serveru.",
-       "api-error-duplicate": "Već {{PLURAL:$1|1=postoji druga datoteka|postoje druge datoteke}} s istim sadržajem.",
-       "api-error-duplicate-archive": "{{PLURAL:$1|Postojala je druga datoteka|Postojale su druge datoteke}} s istim sadržajem, ali {{PLURAL:$1|je obrisana|su obrisane}}.",
-       "api-error-empty-file": "Poslata datoteka je prazna.",
        "api-error-emptypage": "Stvaranje novih praznih stranica nije dozvoljeno.",
-       "api-error-fetchfileerror": "Unutrašnja greška: došlo je do greške pri dobavljanju datoteke.",
-       "api-error-fileexists-forbidden": "Već postoji datoteka s imenom „$1“ i ne može da se zameni.",
-       "api-error-fileexists-shared-forbidden": "Već postoji datoteka s imenom „$1“ u zajedničkoj riznici i ne može da se zameni.",
-       "api-error-file-too-large": "Poslata datoteka je prevelika.",
-       "api-error-filename-tooshort": "Naziv datoteke je prekratak.",
-       "api-error-filetype-banned": "Ova vrsta datoteke je zabranjena.",
-       "api-error-filetype-banned-type": "$1 {{PLURAL:$4|je zabranjena vrsta datoteke|su zabranjene vrste datoteka}}. {{PLURAL:$3|Dozvoljena je|Dozvoljene su}} $2.",
-       "api-error-filetype-missing": "Datoteci nedostaje nastavak.",
-       "api-error-hookaborted": "Izmena je odbačena od kuke za proširenja.",
-       "api-error-http": "Unutrašnja greška: ne mogu da se povežem sa serverom.",
-       "api-error-illegal-filename": "Naziv datoteke je zabranjen.",
-       "api-error-internal-error": "Unutrašnja greška: došlo je do greške pri obrađivanju datoteke na vikiju.",
-       "api-error-invalid-file-key": "Unutrašnja greška: ne mogu da pronađem datoteku u privremenom skladištu.",
-       "api-error-missingparam": "Unutrašnja greška: nedostaju parametri u zahtevu.",
-       "api-error-missingresult": "Unutrašnja greška: ne mogu da utvrdim da li je umnožavanje uspelo.",
-       "api-error-mustbeloggedin": "Morate biti prijavljeni da biste otpremali datoteke.",
-       "api-error-mustbeposted": "Unutrašnja greška: ne koristi se ispravan HTTP metod.",
-       "api-error-noimageinfo": "Otpremanje je uspelo, ali server nije dao nikakav podatak o datoteci.",
-       "api-error-nomodule": "Unutrašnja greška: nije postavljen modul za otpremanje.",
-       "api-error-ok-but-empty": "Unutrašnja greška: server ne odgovara.",
-       "api-error-overwrite": "Zamenjivanje postojeće datoteke je zabranjeno.",
-       "api-error-stashfailed": "Unutrašnja greška: server ne može da sačuva privremenu datoteku.",
        "api-error-publishfailed": "Unutrašnja greška: server nije uspeo da objavi privremenu datoteku.",
-       "api-error-timeout": "Server nije odgovorio u očekivano vreme.",
-       "api-error-unclassified": "Došlo je do nepoznate greške",
-       "api-error-unknown-code": "Nepoznata greška: „$1“",
-       "api-error-unknown-error": "Unutrašnja greška: došlo je do greške pri otpremanju datoteke.",
+       "api-error-stashfailed": "Unutrašnja greška: server ne može da sačuva privremenu datoteku.",
        "api-error-unknown-warning": "Nepoznato upozorenje: $1",
        "api-error-unknownerror": "Nepoznata greška: „$1“.",
-       "api-error-uploaddisabled": "Otpremanje je onemogućeno na ovom vikiju.",
-       "api-error-verification-error": "Datoteka je oštećena ili ima neispravan nastavak.",
        "duration-seconds": "$1 {{PLURAL:$1|sekund|sekunde|sekundi}}",
        "duration-minutes": "$1 {{PLURAL:$1|minut|minuta|minuta}}",
        "duration-hours": "$1 {{PLURAL:$1|sat|sata|sati}}",
index a972790..bff2aab 100644 (file)
        "searcharticle": "Gå till",
        "history": "Sidhistorik",
        "history_short": "Historik",
+       "history_small": "historik",
        "updatedmarker": "uppdaterad sedan senaste besöket",
        "printableversion": "Utskriftsvänlig version",
        "permalink": "Permanent länk",
        "youremail": "E-post:",
        "username": "{{GENDER:$1|Användarnamn}}:",
        "prefs-memberingroups": "{{GENDER:$2|Medlem}} av {{PLURAL:$1|gruppen|grupperna}}:",
+       "group-membership-link-with-expiry": "$1 (tills $2)",
        "prefs-registration": "Registreringstid:",
        "yourrealname": "Riktigt namn:",
        "yourlanguage": "Språk:",
        "userrights-nodatabase": "Databasen $1 finns inte eller så är den inte lokal.",
        "userrights-changeable-col": "Grupper du kan ändra",
        "userrights-unchangeable-col": "Grupper du inte kan ändra",
+       "userrights-expiry-current": "Förfaller $1",
+       "userrights-expiry-none": "Förfaller inte",
+       "userrights-expiry": "Förfaller:",
+       "userrights-expiry-existing": "Befintlig förfallotid: $3, $2",
+       "userrights-expiry-othertime": "Annan tid:",
+       "userrights-expiry-options": "1 dag:1 dag,1 vecka:1 vecka,1 månad:1 månad,3 månader:3 månader,6 månader:6 månader,1 år:1 år",
+       "userrights-invalid-expiry": "Förfallotiden för gruppen \"$1\" är ogiltig.",
+       "userrights-expiry-in-past": "Förfallotiden för gruppen \"$1\" är i det förflutna.",
        "userrights-conflict": "Konflikt vid ändringar av användarrättigheter! Var god granska och bekräfta dina ändringar.",
        "group": "Grupp:",
        "group-user": "Användare",
        "recentchanges-legend-plusminus": "(''±123'')",
        "recentchanges-submit": "Visa",
        "rcfilters-activefilters": "Aktiva filter",
+       "rcfilters-restore-default-filters": "Återställ standardfilter",
+       "rcfilters-clear-all-filters": "Rensa alla filter",
        "rcfilters-search-placeholder": "Filtrera senaste ändringar (bläddra eller börja skriva)",
        "rcfilters-invalid-filter": "Ogiltigt filter",
+       "rcfilters-empty-filter": "Inga aktiva filter. Alla bidrag visas.",
        "rcfilters-filterlist-title": "Filter",
        "rcfilters-filterlist-noresults": "Inga filter hittades",
+       "rcfilters-filtergroup-registration": "Användarregistrering",
+       "rcfilters-filter-registered-label": "Registrerade",
+       "rcfilters-filter-registered-description": "Inloggade redigerare.",
+       "rcfilters-filter-unregistered-label": "Oregistrerade",
+       "rcfilters-filter-unregistered-description": "Redigerare som inte är inloggade.",
        "rcfilters-filtergroup-authorship": "Redigera författarskap",
        "rcfilters-filter-editsbyself-label": "Dina egna redigeringar",
        "rcfilters-filter-editsbyself-description": "Redigeringar av dig.",
        "rcfilters-filter-editsbyother-label": "Redigeringar av andra",
-       "rcfilters-filter-editsbyother-description": "Redigeringar som har skapats av andra användare (inte dig.)",
-       "rcfilters-filtergroup-userExpLevel": "Erfarenhetsnivå för användare",
+       "rcfilters-filter-editsbyother-description": "Redigeringar som har skapats av andra användare (inte dig).",
+       "rcfilters-filtergroup-userExpLevel": "Erfarenhetsnivå (endast för registrerade användare)",
        "rcfilters-filter-userExpLevel-newcomer-label": "Nykomlingar",
-       "rcfilters-filter-userExpLevel-newcomer-description": "Väldigt nya redigerare: färre än 10 redigeringar och 4 dagars aktivitet.",
+       "rcfilters-filter-userExpLevel-newcomer-description": "Färre än 10 redigeringar och 4 dagars aktivitet.",
        "rcfilters-filter-userExpLevel-learner-label": "Nybörjare",
        "rcfilters-filter-userExpLevel-learner-description": "Fler dagars aktivitet och redigeringar än \"Nybörjare\" men färre än \"Erfarna användare\".",
        "rcfilters-filter-userExpLevel-experienced-label": "Erfarna användare",
        "rcfilters-filter-userExpLevel-experienced-description": "Fler än 30 dagars aktivitet och 500 redigeringar.",
+       "rcfilters-filtergroup-automated": "Automatiserade bidrag",
+       "rcfilters-filter-bots-label": "Bot",
+       "rcfilters-filter-bots-description": "Redigeringar gjorda av automatiserade verktyg.",
+       "rcfilters-filter-humans-label": "Människa (inte bot)",
+       "rcfilters-filter-humans-description": "Redigeringar gjorda av mänskliga redigerare.",
+       "rcfilters-filtergroup-significance": "Betydelse",
+       "rcfilters-filter-minor-label": "Mindre redigeringar",
+       "rcfilters-filter-minor-description": "Redigeringar som är märkta som mindre.",
+       "rcfilters-filter-major-label": "Icke-mindre redigeringar",
+       "rcfilters-filter-major-description": "Redigeringar som inte är märkta som mindre.",
+       "rcfilters-filtergroup-changetype": "Typ av ändring",
+       "rcfilters-filter-pageedits-label": "Sidredigeringar",
+       "rcfilters-filter-pageedits-description": "Redigeringar till wikiinnehåll, diskussioner, kategoribeskrivningar...",
+       "rcfilters-filter-newpages-label": "Sidskapande",
+       "rcfilters-filter-newpages-description": "Redigeringar som skapade nya sidor.",
+       "rcfilters-filter-categorization-label": "Kategoriändringar",
+       "rcfilters-filter-categorization-description": "Poster av sidor som läggs till eller tas bort från kategorier.",
+       "rcfilters-filter-logactions-label": "Loggade åtgärder",
+       "rcfilters-filter-logactions-description": "Administrativa åtgärder, kontoskapande, sidraderingar, uppladdningar....",
        "rcnotefrom": "Nedan visas {{PLURAL:$5|ändringen|ändringar}} sedan <strong>$3, $4</strong> (upp till <strong>$1</strong> ändringar visas).",
        "rclistfrom": "Visa nya ändringar från och med $2 $3",
        "rcshowhideminor": "$1 mindre ändringar",
        "apisandbox-sending-request": "Skickar API-begäran...",
        "apisandbox-loading-results": "Hämtar API-resultat...",
        "apisandbox-results-error": "Ett fel uppstod när API-förfrågans svar lästes in: $1.",
-       "apisandbox-request-params-json": "JSON-parametrar:",
+       "apisandbox-request-selectformat-label": "Visa begärd data som:",
+       "apisandbox-request-format-url-label": "URL-frågesträng",
        "apisandbox-request-url-label": "Begärd URL:",
+       "apisandbox-request-json-label": "Begär JSON:",
        "apisandbox-request-time": "Tid för begäran: {{PLURAL:$1|$1 ms}}",
        "apisandbox-results-fixtoken": "Korrigera nyckeln och skicka igen",
        "apisandbox-results-fixtoken-fail": "Misslyckades att hämta nyckeln \"$1\".",
        "emailccsubject": "Kopia av ditt meddelande till $1: $2",
        "emailsent": "E-post har nu skickats",
        "emailsenttext": "Ditt e-postmeddelande har skickats",
-       "emailuserfooter": "Detta e-postmeddelande {{GENDER:$1|skickades}} av $1 till {{GENDER:$2|$2}} med funktionen \"{{int:emailuser}}\" på {{SITENAME}}. {{GENDER:$2|Ditt}} e-postmeddelande kommer att skickas direkt till {{GENDER:$1|den ursprungliga avsändaren}}, vilket kommer avslöja {{GENDER:$2|din}} e-postadress för {{GENDER:$1|honom|henne|hen}}.",
+       "emailuserfooter": "Detta e-postmeddelande {{GENDER:$1|skickades}} av $1 till {{GENDER:$2|$2}} med funktionen \"{{int:emailuser}}\" på {{SITENAME}}. Om {{GENDER:$2|du}} svarar på detta e-postmeddelande kommer {{GENDER:$2|ditt}} e-postmeddelande att skickas direkt till {{GENDER:$1|den ursprungliga avsändaren}}, vilket kommer avslöja {{GENDER:$2|din}} e-postadress för {{GENDER:$1|honom|henne|hen}}.",
        "usermessage-summary": "Lämnar systemmeddelande.",
        "usermessage-editor": "Systemmeddelare",
        "watchlist": "Bevakningslista",
        "logentry-tag-update-logentry": "$1 {{GENDER:$2|uppdaterade}} märken på loggposten $5 för sidan $3 ({{PLURAL:$7|lade till}} $6; {{PLURAL:$9|tog bort}} $8)",
        "rightsnone": "(inga)",
        "revdelete-summary": "sammanfattning",
+       "rightslogentry-temporary-group": "$1 (temporärt, tills $2)",
        "feedback-adding": "Ge feedback till sida...",
        "feedback-back": "Tillbaka",
        "feedback-bugcheck": "Jättebra! Bara kontrollera att det inte är en av de [$1 kända buggarna].",
        "feedback-useragent": "Användaragent:",
        "searchsuggest-search": "Sök på {{SITENAME}}",
        "searchsuggest-containing": "innehåller...",
-       "api-error-autoblocked": "Din IP-adress har blockerats automatiskt eftersom den har använts av en blockerad användare.",
-       "api-error-badaccess-groups": "Du får inte ladda upp filer till denna wiki.",
        "api-error-badtoken": "Internt fel: felaktig nyckel.",
-       "api-error-blocked": "Du har blockerats från att redigera.",
-       "api-error-copyuploaddisabled": "Uppladdning via URL är inaktiverat på den här servern.",
-       "api-error-duplicate": "Det finns redan {{PLURAL:$1|en annan fil|andra filer}} på webbplatsen med samma innehåll.",
-       "api-error-duplicate-archive": "Det fanns redan {{PLURAL:$1|en annan fil|några andra filer}} på webbplatsen med samma innehåll, men {{PLURAL:$1|den har|de har}} raderats.",
-       "api-error-empty-file": "Filen du skickade var tom.",
        "api-error-emptypage": "Det är inte tillåtet att skapa nya, tomma sidor.",
-       "api-error-fetchfileerror": "Internt fel: något gick fel vid hämtningen av filen.",
-       "api-error-fileexists-forbidden": "En fil med namnet \"$1\" finns redan och kan inte skrivas över.",
-       "api-error-fileexists-shared-forbidden": "En fil med namnet \"$1\" finns redan i det delade filarkivet och kan inte skrivas över.",
-       "api-error-file-too-large": "Filen du skickade var för stor.",
-       "api-error-filename-tooshort": "Filnamnet är för kort.",
-       "api-error-filetype-banned": "Denna typ av fil är förbjuden.",
-       "api-error-filetype-banned-type": "$1 är inte {{PLURAL:$4|en tillåten filtyp|tillåtna filtyper}}. {{PLURAL:$3|Tillåten filtyp|Tillåtna filtyper}} är $2.",
-       "api-error-filetype-missing": "Filnamnet saknar en filändelse.",
-       "api-error-hookaborted": "Ändringen du försökte göra avbröts av en extension hook.",
-       "api-error-http": "Internt fel: Det gick inte att ansluta till servern.",
-       "api-error-illegal-filename": "Filnamnet är inte tillåtet.",
-       "api-error-internal-error": "Internt fel: Något gick fel med bearbetningen av din uppladdning på wikin.",
-       "api-error-invalid-file-key": "Internt fel: filen hittades inte i tillfällig lagring.",
-       "api-error-missingparam": "Internt fel: Det saknas parametrar i begäran.",
-       "api-error-missingresult": "Internt fel: Kunde inte avgöra om kopieringen lyckades.",
-       "api-error-mustbeloggedin": "Du måste vara inloggad för att kunna ladda upp filer.",
-       "api-error-mustbeposted": "Det finns en bugg i detta program, det använder inte rätt HTTP-metod.",
-       "api-error-noimageinfo": "Uppladdningen lyckades, men servern gav oss inte någon information om filen.",
-       "api-error-nomodule": "Internt fel: Ingen uppladdningsmodul uppsatt.",
-       "api-error-ok-but-empty": "Internt fel: Inget svar från servern.",
-       "api-error-overwrite": "Det är inte tillåtet att skriva över en befintlig fil.",
-       "api-error-ratelimited": "Du försöker ladda upp fler filer inom en kortare tidsrymd än denna wiki tillåter.\nFörsök igen om några minuter.",
-       "api-error-stashfailed": "Internt fel: servern kunde inte lagra temporär fil.",
        "api-error-publishfailed": "Internt fel: Servern kunde inte publicera temporär fil.",
-       "api-error-stasherror": "Ett fel uppstod under uppladdningen av filen till mellanlagringsfilen.",
-       "api-error-stashedfilenotfound": "Den temporära filen kunde inte hittas när den skulle laddas upp från den temporära lagringsytan.",
-       "api-error-stashpathinvalid": "Den sökväg där den temporära filen skulle ha hittats var ogiltig.",
-       "api-error-stashfilestorage": "Ett fel uppstod under lagringen av filen i den temporära lagringsytan.",
-       "api-error-stashzerolength": "Servern kunde inte lagra filen temporärt eftersom den har noll längd.",
-       "api-error-stashnotloggedin": "Du måste vara inloggad för att spara filer till den temporära ytan för uppladdningar.",
-       "api-error-stashwrongowner": "Filen du försöker komma åt i det temporära lagringsutrymmet tillhör inte dig.",
-       "api-error-stashnosuchfilekey": "Filnyckeln som du försökte komma åt i den temporära lagringsytan existerar inte.",
-       "api-error-timeout": "Servern svarade inte inom förväntad tid.",
-       "api-error-unclassified": "Ett okänt fel uppstod.",
-       "api-error-unknown-code": "Okänt fel: \"$1\".",
-       "api-error-unknown-error": "Internt fel: något gick fel när vi försökte ladda upp din fil.",
+       "api-error-stashfailed": "Internt fel: servern kunde inte lagra temporär fil.",
        "api-error-unknown-warning": "Okänd varning: \"$1\".",
        "api-error-unknownerror": "Okänt fel: \"$1\".",
-       "api-error-uploaddisabled": "Uppladdning är inaktiverad på denna wiki.",
-       "api-error-verification-error": "Denna fil kan vara skadad eller har fel filändelse.",
-       "api-error-was-deleted": "En fil med detta namn har tidigare laddats upp och sedan raderats.",
        "duration-seconds": "$1 {{PLURAL:$1|sekund|sekunder}}",
        "duration-minutes": "$1 {{PLURAL:$1|minut|minuter}}",
        "duration-hours": "$1 {{PLURAL:$1|timme|timmar}}",
        "usercssispublic": "Observera: CSS-undersidor bör inte innehålla konfidentiella uppgifter eftersom de kan ses av andra användare.",
        "restrictionsfield-badip": "Ogiltig IP-adress eller intervall: $1",
        "restrictionsfield-label": "Tillåtna IP-intervall:",
-       "restrictionsfield-help": "En IP-adress eller CIDR-intervall per rad. För att aktivera allting, använd<br><code>0.0.0.0/0</code><br><code>::/0</code>",
+       "restrictionsfield-help": "En IP-adress eller CIDR-intervall per rad. För att aktivera allting, använd<br /><code>0.0.0.0/0</code><br /><code>::/0</code>",
        "revid": "sidversion $1",
        "pageid": "sid-ID $1"
 }
index 8d17d4d..bf05552 100644 (file)
        "searcharticle": "செல்",
        "history": "பக்க வரலாறு",
        "history_short": "வரலாறு",
+       "history_small": "வரலாறு",
        "updatedmarker": "எனது கடைசி வருகைக்குப் பின் இற்றைப்படுத்தப்பட்டது",
        "printableversion": "அச்சுக்குகந்த பதிப்பு",
        "permalink": "நிலையான இணைப்பு",
        "saveprefs": "சேமி",
        "restoreprefs": "எல்லோருக்கும் பொதுவான வடிவமைப்பைத் திரும்பக்கொண்டுவரவும் (எல்லா பிரிவுகளிலும்).",
        "prefs-editing": "தொகுத்தல்",
-       "rows": "நிரைகள் (கிடை வரிசைகள்):",
-       "columns": "நிரல்கள்",
        "searchresultshead": "தேடுக",
        "stub-threshold": "<a href=\"#\" class=\"stub\">stub link</a> சீர்படுத்தலுக்கான எல்லை (பைட்டுகள்):",
        "stub-threshold-sample-link": "மாதிரி",
        "recentchanges-legend-heading": "<strong>குறியீட்டு விளக்கம்:</strong>",
        "recentchanges-legend-newpage": "{{int:recentchanges-label-newpage}} ([[Special:NewPages|புதிய பக்கங்கள் பட்டியலையும்]] காணவும்)",
        "recentchanges-submit": "காட்டு",
+       "rcfilters-filterlist-title": "வடிப்பான்கள்",
+       "rcfilters-filtergroup-registration": "பயனர் பதிகை",
+       "rcfilters-filter-registered-label": "பதிவுசெய்யப்பட்டது",
+       "rcfilters-filter-unregistered-label": "பதிவு நீக்கம் செய்யப்பட்டது",
+       "rcfilters-filter-editsbyself-label": "தங்களின் சொந்த தொகுப்புகள்",
+       "rcfilters-filter-userExpLevel-newcomer-label": "புது வரவுகள்",
+       "rcfilters-filter-userExpLevel-learner-label": "கற்போர்",
+       "rcfilters-filter-bots-label": "தானியங்கி",
+       "rcfilters-filter-humans-label": "மனிதன் (தானியங்கி அல்ல)",
+       "rcfilters-filtergroup-changetype": "மாற்ற வகை",
+       "rcfilters-filter-newpages-label": "பக்க உருவாக்கங்கள்",
        "rcnotefrom": "கீழே காணப்படுவது <strong>$3, $4</strong> இலிருந்து செய்யப்பட்ட (<strong>$1</strong> வரைக் காட்டப்பட்டுள்ளது) {{PLURAL:$5|மாற்றமாகும்.|மாற்றங்களாகும்.}}",
        "rclistfrom": "$2, $3 முதல் இன்று வரை செய்யப்பட்ட புதிய மாற்றங்களைக் காட்டவும்",
        "rcshowhideminor": "சிறிய தொகுப்புகளை $1",
        "feedback-useragent": "பயனர் முகவர்:",
        "searchsuggest-search": "தேடு",
        "searchsuggest-containing": "கொண்டுள்ளது...",
-       "api-error-badaccess-groups": "இந்த விக்கிக்குக் கோப்புகளைப் பதிவேற்றுவதற்கு நீங்கள் அனுமதிக்கப்படவில்லை.",
        "api-error-badtoken": "உள்ளகப் பிழை: தவறான அடையாளம்.",
-       "api-error-copyuploaddisabled": "உரலி மூலம் பதிவேற்றுவது இந்த வழங்கியில் செயலிழக்கச் செய்யப்பட்டுள்ளது.",
-       "api-error-duplicate": "There {{PLURAL:$1|is another file|are some other files}} already on the site with the same content.",
-       "api-error-duplicate-archive": "ஏற்கனவே இத்தளத்தில் இதே உள்ளடக்கத்தைக் கொண்ட {{PLURAL:$1|கோப்பு இருந்தது|கோப்புகள் இருந்தன}}, ஆனால் {{PLURAL:$1|அது நீக்கப்பட்டுவிட்டது|அவை நீக்கப்பட்டுவிட்டன.}}",
-       "api-error-empty-file": "நீங்கள் அளித்த கோப்பு காலியாக உள்ளது.",
        "api-error-emptypage": "புதிய, காலி பக்கங்கள் உருவாக்கல் அனுமதிக்கப்படவில்லை.",
-       "api-error-fetchfileerror": "உள்ளகப் பிழை: கோப்பைப் பெறுகையில் ஏதோ தவறு நேர்ந்துவிட்டது.",
-       "api-error-fileexists-forbidden": "\"$1\" என்ற பெயருள்ள கோப்பு ஏற்கனவே உள்ளது.  மேலெழுத முடியாது.",
-       "api-error-fileexists-shared-forbidden": "\"$1\" என்ற பெயருள்ள கோப்பு ஏற்கனவே கோப்பு பகிர்மானப் பெட்டகத்தில்  உள்ளது. மேலெழுத முடியாது.",
-       "api-error-file-too-large": "நீங்கள் அளித்த கோப்பு மிகவும் பெரியதாக உள்ளது.",
-       "api-error-filename-tooshort": "கோப்புப் பெயர் மிகவும் சிறியதாக உள்ளது.",
-       "api-error-filetype-banned": "இக்கோப்பு வகை தடைசெய்யப்பட்டுள்ளது.",
-       "api-error-filetype-banned-type": "$1  {{PLURAL:$4|அனுமதிக்கப்படாத கோப்பு வகையாகும் | அனுமதிக்கப்படாத கோப்பு வகைகளாகும்}}.. அனுமதிக்கப்பட்ட {{PLURAL:$3|கோப்புவகை|கோப்புவகைகள்}} $2 என்பது(வை) ஆகும்.",
-       "api-error-filetype-missing": "கோப்பில் ஒரு விரிவு விடுபடுகிறது.",
-       "api-error-hookaborted": "நீங்கள் செய்ய முயன்ற மாற்றம் ஒரு விரிவாக்கத்தால் புறக்கணிக்கப்பட்டது.",
-       "api-error-http": "உள்ளகப் பிழை: வழங்கியுடன் இணைக்க முடியவில்லை",
-       "api-error-illegal-filename": "இக்கோப்புப் பெயர் அனுமதிக்கப்படமாட்டாது.",
-       "api-error-internal-error": "உள்ளகப் பிழை: உங்கள் பதிவேற்றத்தை விக்கியில் செயல்படுத்தும்போது ஏதோ தவறு நேர்ந்துவிட்டது.",
-       "api-error-invalid-file-key": "உள்ளகப் பிழை: தற்காலிகச் சேமிப்பில் கோப்பு காணப்படவில்லை.",
-       "api-error-missingparam": "உள்ளகப் பிழை: கோரிக்கையில் அளபுருக்கள் விடுபடுகின்றன.",
-       "api-error-missingresult": "உள்ளகப் பிழை: நகல் வெற்றியடைந்ததா என்று தீர்மாணிக்க முடியவில்லை.",
-       "api-error-mustbeloggedin": "கோப்புகளைப் பதிவேற்ற நீங்கள் கண்டிப்பாகப் புகுபதிகை செய்திருக்க வேண்டும்.",
-       "api-error-mustbeposted": "உள்ளகப் பிழை: கோரிக்கைக்கு HTTP POST தேவை.",
-       "api-error-noimageinfo": "பதிவேற்றம் வெற்றியடைந்தது, ஆனால் வழங்கி கோப்பைப் பற்றிய எந்த ஒரு தகவலையும் எங்களுக்குத் தரவில்லை.",
-       "api-error-nomodule": "உள்ளகப் பிழை: பதிவேற்றப் பகுதி அமைக்கப்படவில்லை.",
-       "api-error-ok-but-empty": "உள்ளகப் பிழை: வழங்கியிலிருந்து பதில் வரவில்லை",
-       "api-error-overwrite": "ஏற்கனவே உள்ள கோப்பின் மேலெழுதுவது அனுமதிக்கப்படமாட்டாது.",
-       "api-error-stashfailed": "உள்ளகப் பிழை: வழங்கி தற்காலிகக் கோப்பைத் தேக்கத் தவறிவிட்டது.",
        "api-error-publishfailed": "உள்ளகப் பிழை: வழங்கி தற்காலிகக் கோப்பைத் பதிப்பிக்க தவறிவிட்டது.",
-       "api-error-stasherror": "பரணில் ஒரு கோப்பை ஏற்றும் போது பிழை ஏற்பட்டது.",
-       "api-error-stashedfilenotfound": "பரணிலிருந்து கோப்பே ஏற்றும் போது பரணேற்றப்பட்ட கோப்பை காணவில்லை.",
-       "api-error-stashpathinvalid": "பரணேற்றபட்ட கோப்பு காணப்பட வேண்டிய பாதை செல்லாதது.",
-       "api-error-stashfilestorage": "பரணில் ஒரு கோப்பை சேமிக்கும் போது பிழை ஏற்பட்டது.",
-       "api-error-stashzerolength": "வழங்கி கோப்பை பரணேற்ற இயலாது, ஏனெனில் அது சுழி நீளம் கொண்டது.",
-       "api-error-stashnotloggedin": "ஏற்று பரணில் கோப்பை சேமிக்க நீங்கள் புகுபதிய வேண்டும்.",
-       "api-error-stashwrongowner": "நீங்கள் பரணில் அணுக முயற்சிக்கும் கோப்பு உங்களுக்கு உரியதல்ல.",
-       "api-error-stashnosuchfilekey": "நீங்கள் பரணில் அணுக முயற்சிக்கும் கோப்புக் குறி காணக்கிடைக்கவில்லை.",
-       "api-error-timeout": "எதிர்பார்க்கப்பட்ட நேரத்தில் வழங்கி பதிலளிக்கவில்லை.",
-       "api-error-unclassified": "அறியாப் பிழை ஏற்பட்டது",
-       "api-error-unknown-code": "அறியாப் பிழை: \"$1\"",
-       "api-error-unknown-error": "உள்ளகப் பிழை: உங்கள் கோப்பைப் பதிவேற்ற முயல்கையில் ஏதோ தவறு நேர்ந்துவிட்டது.",
+       "api-error-stashfailed": "உள்ளகப் பிழை: வழங்கி தற்காலிகக் கோப்பைத் தேக்கத் தவறிவிட்டது.",
        "api-error-unknown-warning": "அறியப்படா எச்சரிக்கை: \"$1\".",
        "api-error-unknownerror": "அறியப்படாத பிழை: \"$1\".",
-       "api-error-uploaddisabled": "இந்த விக்கியில் பதிவேற்றல் செயலிழக்கச் செய்யப்பட்டுள்ளது.",
-       "api-error-verification-error": "இக்கோப்பு பிழையுடனோ தவறான விரிவுடனோ இருக்கலாம்.",
        "duration-seconds": "$1 {{PLURAL:$1|நொடி|நொடிகள்}}",
        "duration-minutes": "{{PLURAL:$1|நிமிடம்|நிமிடங்கள்}}",
        "duration-hours": "$1 {{PLURAL:$1|மணி|மணிகள்}} முன்பு",
        "pagelang-language": "மொழி",
        "pagelang-use-default": "இயல்பு நிலை மொழி",
        "pagelang-select-lang": "மொழியைத் தேர்ந்தெடு",
+       "pagelang-reason": "காரணம்",
        "pagelang-submit": "சமர்ப்பி",
        "right-pagelang": "பக்க மொழியை மாற்றுக",
        "action-pagelang": "பக்க மொழியை மாற்றுக",
index 2ab4a98..8eb7790 100644 (file)
        "may_long": "మే",
        "june": "జూన్",
        "july": "జూలై",
-       "august": "à°\86à°\97à°·్టు",
+       "august": "à°\86à°\97à°¸్టు",
        "september": "సెప్టెంబరు",
        "october": "అక్టోబరు",
        "november": "నవంబరు",
        "broken-file-category": "తెగిపోయిన ఫైలులింకులు గల పేజీలు",
        "about": "గురించి",
        "article": "విషయపు పేజీ",
-       "newwindow": "(à°\95à±\8aà°¤à±\8dà°¤ à°\95à°¿à°\9fà°¿à°\95à±\80లో వస్తుంది)",
+       "newwindow": "(à°\95à±\8aà°¤à±\8dà°¤ à°µà°¿à°\82à°¡à±\8bలో వస్తుంది)",
        "cancel": "రద్దుచేయి",
        "moredotdotdot": "ఇంకా...",
        "morenotlisted": "బహుశా ఈ జాబితా అసంపూర్ణం.",
        "searcharticle": "వెళ్లు",
        "history": "పేజీ చరిత్ర",
        "history_short": "చరిత్ర",
+       "history_small": "చరిత్ర",
        "updatedmarker": "నేను కిందటిసారి వచ్చిన తరువాత జరిగిన మార్పులు",
        "printableversion": "అచ్చుతీయదగ్గ కూర్పు",
        "permalink": "శాశ్వత లంకె",
        "view": "చూపు",
        "view-foreign": "$1 లో చూడండి",
        "edit": "సవరించు",
-       "edit-local": "à°ªà±\8dà°°à°¾à°\82à°¤à±\80à°¯ వివరణని మార్చు",
+       "edit-local": "à°¸à±\8dథానిà°\95 వివరణని మార్చు",
        "create": "సృష్టించు",
        "create-local": "ప్రాంతీయ వివరణని చేర్చు",
        "editthispage": "ఈ పేజీని సవరించండి",
        "delete": "తొలగించు",
        "deletethispage": "ఈ పేజీని తొలగించండి",
        "undeletethispage": "ఈ పేజీ తొలగింపును ఆపు",
-       "undelete_short": "{{PLURAL:$1|ఒక్క రచన|$1 రచనల}} తొలగింపును రద్దుచెయ్యి",
+       "undelete_short": "{{PLURAL:$1|ఒక మార్పు|$1 మార్పుల}} తొలగింపును రద్దుచెయ్యి",
        "viewdeleted_short": "{{PLURAL:$1|తొలగించిన ఒక మార్పు|$1 తొలగించిన మార్పుల}}ను చూడండి",
        "protect": "సంరక్షించు",
        "protect_change": "మార్చు",
        "tool-link-userrights-readonly": "{{GENDER:$1|వాడుకరి}} గుంపులను చూడండి",
        "tool-link-emailuser": "ఈ {{GENDER:$1|వాడుకరికి}} ఈమెయిలు పంపు",
        "userpage": "వాడుకరి పేజీని చూడండి",
-       "projectpage": "à°ªà±\8dà°°à°¾à°\9cà±\86à°\95à±\8dà°\9fà±\81 à°ªà±\87à°\9cà±\80ని à°\9aà±\82à°¡à±\81",
+       "projectpage": "à°ªà±\8dà°°à°¾à°\9cà±\86à°\95à±\8dà°\9fà±\81 à°ªà±\87à°\9cà±\80ని à°\9aà±\82à°¡à°\82à°¡à°¿",
        "imagepage": "ఫైలు పేజీని చూడండి",
-       "mediawikipage": "à°¸à°\82à°¦à±\87à°¶à°\82 à°ªà±\87à°\9cà±\80ని à°\9aà±\82à°¡à±\81",
-       "templatepage": "à°®à±\82à°¸ à°ªà±\87à°\9cà±\80ని à°\9aà±\82à°¡à±\81",
-       "viewhelppage": "సహాయà°\82 à°ªà±\87à°\9cà±\80ని à°\9aà±\82à°¡à±\81",
-       "categorypage": "వరà±\8dà°\97à°\82 à°ªà±\87à°\9cà±\80ని à°\9aà±\82à°¡à±\81",
-       "viewtalkpage": "à°\9aà°°à±\8dà°\9aà°¨à±\81 à°\9aà±\82à°¡à±\81",
+       "mediawikipage": "à°¸à°\82à°¦à±\87à°¶à°\82 à°ªà±\87à°\9cà±\80ని à°\9aà±\82à°¡à°\82à°¡à°¿",
+       "templatepage": "à°®à±\82à°¸ à°ªà±\87à°\9cà±\80ని à°\9aà±\82à°¡à°\82à°¡à°¿",
+       "viewhelppage": "సహాయà°\82 à°ªà±\87à°\9cà±\80ని à°\9aà±\82à°¡à°\82à°¡à°¿",
+       "categorypage": "వరà±\8dà°\97à°ªà±\81 à°ªà±\87à°\9cà±\80 à°\9aà±\82à°¡à°\82à°¡à°¿",
+       "viewtalkpage": "à°\9aà°°à±\8dà°\9aà°¨à±\81 à°\9aà±\82à°¡à°\82à°¡à°¿",
        "otherlanguages": "ఇతర భాషలలో",
        "redirectedfrom": "($1 నుండి మళ్ళించబడింది)",
        "redirectpagesub": "దారిమార్పు పేజీ",
        "privacy": "గోప్యతా విధానం",
        "privacypage": "Project:గోప్యతా విధానం",
        "badaccess": "అనుమతి లోపం",
-       "badaccess-group0": "à°®à±\80à°°à±\81 à°\9aà±\87యతలపà±\86à°\9fà±\8dà°\9fà°¿à°¨ à°ªà°¨à°¿à°\95à°¿ à°®à±\80à°\95à±\81 à°¹à°\95à±\8dà°\95à±\81à°²à±\81 à°²à±\87à°µు.",
+       "badaccess-group0": "à°®à±\80à°°à°¡à°¿à°\97à°¿à°¨ à°ªà°¨à°¿ à°\9aà±\87à°¸à±\87à°\82à°¦à±\81à°\95à±\81 à°®à±\80à°\95à±\81 à°\85à°¨à±\81మతి à°²à±\87à°¦ు.",
        "badaccess-groups": "మీరు చేయతలపెట్టిన పని ఈ {{PLURAL:$2|గుంపు|గుంపులలో ఒకదాని}} లోని వాడుకర్లకు మాత్రమే పరిమితం: $1.",
        "versionrequired": "మీడియావికీ సాఫ్టువేరు వెర్షను $1 కావాలి",
        "versionrequiredtext": "ఈ పేజీని వాడటానికి మీకు మీడియావికీ సాఫ్టువేరు వెర్షను $1 కావాలి. [[Special:Version|వెర్షను పేజీ]]ని చూడండి.",
        "myprivateinfoprotected": "మీ అంతరంగిక సమాచారాన్ని సవరించేందుకు మీకు అనుమతి లేదు.",
        "mypreferencesprotected": "మీ అభీష్టాలను సవరించేందుకు మీకు అనుమతి లేదు.",
        "ns-specialprotected": "ప్రత్యేక పేజీలపై దిద్దుబాట్లు చేయలేరు.",
-       "titleprotected": "[[User:$1|$1]] ఈ శీర్షికని సృష్టించకుండా ఇది సంరక్షించబడింది.\nఅందుకు ఇచ్చిన కారణం: <em>$2</em>.",
+       "titleprotected": "ఈ శీర్షికను [[User:$1|$1]] సృష్టించకుండా సంరక్షించబడింది.\nఅందుకు ఇచ్చిన కారణం: <em>$2</em>.",
        "filereadonlyerror": "ఫైలు ఖజానా \"$2\" రీడ్-ఓన్లీ స్థితిలో ఉండటం చేత \"$1\" ఫైలులో మార్పులు చెయ్యలేకపోయాం.\n\nదానికి తాళం వేసిన సిస్టము నిర్వాహకుడు ఇచ్చిన వివరణ ఇది: \"$3\".",
        "invalidtitle-knownnamespace": "పేరుబరి \"$2\", పాఠ్యము \"$3\" తో కూడిన ఈ శీర్షిక చెల్లనిది",
        "invalidtitle-unknownnamespace": "అపరిచితమైన పేరుబరి సంఖ్య \"$1\", పాఠ్యము \"$2\" తో కూడిన ఈ శీర్షిక చెల్లనిది",
        "createacct-email-ph": "మీ ఈమెయిలు చిరునామాను ఇవ్వండి",
        "createacct-another-email-ph": "ఈమెయిలు చిరునామాను ఇవ్వండి",
        "createaccountmail": "ఏదో ఒక తాత్కాలిక సంకేతపదాన్ని వాడి దాన్ని పేర్కొన్న ఈమెయిలు చిరునామాకు పంపించు",
+       "createaccountmail-help": "సంకేతపదం తెలుసుకోనవసరం లేకుండా వేరొకరి కోసం ఖాతా సృష్టించేందుకు వాడవచ్చు.",
        "createacct-realname": "అసలు పేరు (ఐచ్చికం)",
        "createaccountreason": "కారణం:",
        "createacct-reason": "కారణం",
        "resetpass_submit": "సంకేతపదాన్ని మార్చి లాగినవండి",
        "changepassword-success": "మీ సంకేతపదం మార్చబడింది!",
        "changepassword-throttled": "కొద్దిసేపటిగా మీరు చాలా లాగిన్ ప్రయత్నాలు చేసారు.\nమళ్ళీ ప్రయత్నించే ముందు $1 ఆగండి.",
+       "botpasswords": "బాట్ సంకేతపదాలు",
        "botpasswords-label-appid": "బాట్ పేరు:",
        "botpasswords-label-create": "సృష్టించు",
        "botpasswords-label-update": "తాజాకరించు",
        "botpasswords-updated-body": "వాడుకరి \"$2\" కు చెందిన \"$1\" అనే బాట్‌ యొక్క బాట్ సంకేతపదాన్ని తాజాకరించాం.",
        "botpasswords-deleted-title": "బాట్ సంకేతపదాన్ని తొలగించాం",
        "botpasswords-deleted-body": "వాడుకరి \"$2\" కు చెందిన \"$1\" అనే బాట్‌ యొక్క బాట్ సంకేతపదాన్ని తొలగించాం.",
-       "botpasswords-newpassword": "<strong>$1</strong> తో లాగినయేందుకు కొత్త సంకేతపదం <strong>$2</strong>. <em>భావి ఉపయోగం కోసం దీన్ని జాగ్రత్త చేసుకోండి.</em>",
+       "botpasswords-newpassword": "<strong>$1</strong> తో లాగినయేందుకు కొత్త సంకేతపదం <strong>$2</strong>. <em>భావి ఉపయోగం కోసం దీన్ని జాగ్రత్త చేసుకోండి.</em><br> (లాగిన్ పేరుగా వాడుకరిపేరే ఉండాల్సిన పాత బాట్‌ల విషయంలో <strong>$3</strong> ను వాడుకరిపేరుగాను, <strong>$4</strong> ను సంకేతపదంగానూ వాడుకోవచ్చు.)",
        "botpasswords-not-exist": "వాడుకరి \"$1\" కి \"$2\" అనే బాట్ సంకేతపదం లేదు.",
        "resetpass_forbidden": "సంకేతపదాలను మార్చటం కుదరదు",
        "resetpass_forbidden-reason": "సంకేతపదాలు మార్చజాలరు: $1",
        "action-upload_by_url": "ఈ ఫైలుని URL చిరునామా నుండి ఎగుమతి చేసే",
        "action-writeapi": "వ్రాసే APIని ఉపయోగించే",
        "action-delete": "ఈ పేజీని తొలగించే",
-       "action-deleterevision": "à°\88 à°\95à±\82à°°à±\8dà°ªà±\81ని తొలగించే",
+       "action-deleterevision": "à°\95à±\82à°°à±\8dà°ªà±\81లనà±\81 తొలగించే",
        "action-deletelogentry": "చిట్టా పద్దులను తొలగించే",
        "action-deletedhistory": "పేజీల తొలగించిన చరిత్రని చూసే",
        "action-deletedtext": "తొలగించిన కూర్పుల పాఠ్యాన్ని చూసే",
        "action-browsearchive": "తొలగించిన పేజీలలో వెతికే",
        "action-undelete": "పేజీలను పునఃస్థాపించే",
-       "action-suppressrevision": "à°\88 à°¦à°¾à°\9aà°¿à°¨ à°\95à±\82à°°à±\8dà°ªà±\81ని à°¸à°®à±\80à°\95à±\8dà°·à°¿à°\82à°\9aà°¿ పునఃస్థాపించే",
+       "action-suppressrevision": "దాà°\9aà°¿à°¨ à°\95à±\82à°°à±\8dà°ªà±\81లనà±\81 à°¸à°®à±\80à°\95à±\8dà°·à°¿à°\82à°\9aà°¿, పునఃస్థాపించే",
        "action-suppressionlog": "ఈ అంతరంగిక చిట్టాను చూసే",
        "action-block": "ఈ వాడుకరిని మార్పులు చేయడం నుండి నిరోధించే",
        "action-protect": "ఈ పేజీకి సంరక్షణా స్థాయిని మార్చే",
        "recentchanges-legend-heading": "<strong>సూచిక :</strong>",
        "recentchanges-legend-newpage": "{{int:recentchanges-label-newpage}} ([[Special:NewPages|కొత్త పేజీల జాబితా]]ను కూడా చూడండి)",
        "recentchanges-submit": "చూపించు",
+       "rcfilters-filter-editsbyself-label": "మీ స్వంత దిద్దుబాట్లు",
+       "rcfilters-filter-editsbyself-description": "మీ దిద్దుబాట్లు.",
+       "rcfilters-filter-editsbyother-label": "ఇతరుల దిద్దుబాట్లు",
+       "rcfilters-filter-editsbyother-description": "ఇతరులు (మీరు కాదు) చేసిన దిద్దుబాట్లు.",
+       "rcfilters-filtergroup-userExpLevel": "అనుభవ స్థాయి (నమోదైన వాడుకరులకు మాత్రమే)",
+       "rcfilters-filter-userExpLevel-newcomer-label": "కొత్తవారు",
+       "rcfilters-filter-userExpLevel-newcomer-description": "10 కంటే తక్కువ దిద్దుబాట్లు, 4 రోజుల కంటే తక్కువ పని.",
+       "rcfilters-filter-userExpLevel-learner-label": "నేర్చుకుంటున్నవారు",
+       "rcfilters-filter-userExpLevel-learner-description": "\"కొత్తవారి\" కంటే ఎక్కువ, \"అనుభవజ్ఞులైన వాడుకరుల\" కంటే తక్కువ పనిరోజులు.",
+       "rcfilters-filter-userExpLevel-experienced-label": "అనుభవజ్ఞులైన వాడుకరులు",
+       "rcfilters-filter-userExpLevel-experienced-description": "30 రోజుల కంటే ఎక్కువ పని, 500 పైచిలుకు దిద్దుబాట్లు.",
+       "rcfilters-filtergroup-significance": "ప్రాముఖ్యం",
+       "rcfilters-filter-minor-label": "చిన్న మార్పులు",
+       "rcfilters-filter-minor-description": "రచయిత చిన్నవిగా గుర్తు పెట్టిన దిద్దుబాట్లు.",
+       "rcfilters-filter-major-label": "చిన్నవి కాని దిద్దుబాట్లు",
+       "rcfilters-filter-major-description": "చిన్నవిగా గుర్తు పెట్టని దిద్దుబాట్లు.",
+       "rcfilters-filtergroup-changetype": "దిద్దుబాటు రకం",
+       "rcfilters-filter-pageedits-label": "పేజీ దిద్దుబాట్లు",
+       "rcfilters-filter-newpages-label": "పేజీల సృష్టి",
+       "rcfilters-filter-newpages-description": "కొత్త పేజీలను సృష్టించే దిద్దుబాట్లు.",
+       "rcfilters-filter-categorization-label": "వర్గాల దిద్దుబాట్లు",
+       "rcfilters-filter-logactions-description": "నిర్వాహక పనులు, ఖాతా పనులు, పేజీ తొలగింపులు, ఎక్కింపులు....",
        "rcnotefrom": "<strong>$3, $4</strong> తరువాత జరిగిన {{PLURAL:$5|మార్పు|మార్పులు}} కింద ఇచ్చాం (<strong>$1</strong> దాకా చూపించాం).",
        "rclistfrom": "$3, $2 కు ముందు  జరిగిన మార్పులను చూపించు",
        "rcshowhideminor": "చిన్న మార్పులను $1",
        "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* ఎడమ వైపు మార్జినులో 200 పిక్సెళ్ళ వెడల్పుగల బొమ్మ  మరియు 'ప్రత్యామ్నాయ పాఠ్యం' అన్న వివరణతో గల పెట్టె కోసం  '''<code><nowiki>[[</nowiki>{{ns:file}}<nowiki>:File.png|200px|thumb|left|ప్రత్యామ్నాయ పాఠ్యం]]</nowiki></code>'''\n* దస్త్రాన్ని చూపించకుండా నేరుగా లింకు ఇవ్వడానికి '''<code><nowiki>[[</nowiki>{{ns:media}}<nowiki>:File.ogg]]</nowiki></code>'''",
        "upload-permitted": "అనుమతించబడిన ఫైలు {{PLURAL:$2|రకం|రకాలు}}: $1.",
-       "upload-preferred": "అనుమతించే ఫైలు రకాలు: $1.",
+       "upload-preferred": "అనుమతించే ఫైలు {{PLURAL:$2|రకం|రకాలు}}: $1.",
        "upload-prohibited": "నిషేధించబడిన ఫైలు {{PLURAL:$2|రకం|రకాలు}}: $1.",
        "uploadlogpage": "ఎక్కింపుల చిట్టా",
        "uploadlogpagetext": "ఇటీవల జరిగిన ఫైలు అప్‌లోడుల జాబితా ఇది.\nమరింత దృశ్యాత్మకంగా చూడటం కోసం [[Special:NewFiles|కొత్త ఫైళ్ళ కొలువు]]కు వెళ్ళండి.",
        "file-thumbnail-no": "ఫైలు పేరు <strong>$1</strong> తో మొదలవుతోంది.\nఅది పరిమాణం తగ్గించిన ''(నఖచిత్రం)'' లాగా అనిపిస్తోంది.\nఈ బొమ్మ యొక్క పూర్తి స్పష్టత కూర్పు ఉంటే, దాన్ని ఎగుమతి చెయ్యండి. లేదా ఫైలు పేరును మార్చండి.",
        "fileexists-forbidden": "ఈ పేరుతో ఇప్పటికే ఒక ఫైలు ఉంది, దాన్ని తిరగరాయలేరు.\nమీరు ఇప్పటికీ ఈ ఫైలుని ఎగుమతి చేయాలనుకుంటే, వెనక్కి వెళ్ళి మరో పేరుతో ఎగుమతి చేయండి. [[File:$1|thumb|center|$1]]",
        "fileexists-shared-forbidden": "ఈ పేరుతో ఇప్పటికే ఒక ఫైలు అందరి ఫైళ్ళ ఖజానాలో ఉంది.\nఇప్పటికీ మీ ఫైలుని ఎగుమతి చేయాలనుకుంటే, వెనక్కివెళ్ళి మరో పేరు వాడండి. [[File:$1|thumb|center|$1]]",
+       "fileexists-no-change": "ఈ ఎక్కింపు, <strong>[[:$1]]</strong> యొక్క ప్రస్తుత కూర్పుకు సరిగ్గా సరిపోలిన కచ్చితమైన నకలు.",
+       "fileexists-duplicate-version": "ఈ ఎక్కింపు, <strong>[[:$1]]</strong> యొక్క {{PLURAL:$2|పాత కూర్పు ఒకదానికి|పాత కూర్పులకు}} సరిగ్గా సరిపోలిన కచ్చితమైన నకలు.",
        "file-exists-duplicate": "ఈ ఫైలు క్రింద పేర్కొన్న {{PLURAL:$1|ఫైలుకు|ఫైళ్ళకు}} నకలు:",
        "file-deleted-duplicate": "గతంలో ఈ ఫైలు లాంటిదే ఒక ఫైలుని ([[:$1]]) తొలగించివున్నారు. మీరు దీన్ని తిరిగి ఎక్కించే ముందు ఆ ఫైలు యొక్క తొలగింపు చరిత్రను చూడండి.",
        "file-deleted-duplicate-notitle": "సరిగ్గా ఈ ఫైలునే పోలిన మరో ఫైలును గతంలో తొలగించాం. దాని పేరును అణచిపెట్టాం.\nదాన్ని తిరిగి ఎక్కించే ముందు, పరిస్థితిని సమీక్షించేందుకు గాను, అణచబడిన ఫైళ్ళ డేటాను చూడగలిగే వారిని అడగండి.",
        "reblock-logentry": "[[$1]] కై నిరోధపు అమరికలను $2 $3 గడువుతో మార్చారు",
        "blocklogtext": "వాడుకరుల నిరోధాలు, పునస్థాపనల చిట్టా ఇది. \nఆటోమాటిక్‌గా నిరోధానికి గురైన ఐ.పి. చిరునామాలు ఈ జాబితాలో ఉండవు. \nప్రస్తుతం అమల్లో ఉన్న నిరోధాలు, నిషేధాల కొరకు [[Special:BlockList|నిరోధాల జాబితా]]ను చూడండి.",
        "unblocklogentry": "$1పై నిరోధం తొలగించబడింది",
-       "block-log-flags-anononly": "à°\85à°\9cà±\8dà°\9eాత à°µà°¾à°¡à±\81à°\95à°°à±\8dలు మాత్రమే",
+       "block-log-flags-anononly": "à°\85à°\9cà±\8dà°\9eాత à°µà°¾à°¡à±\81à°\95à°°à±\81లు మాత్రమే",
        "block-log-flags-nocreate": "ఖాతా సృష్టించడాన్ని అశక్తం చేసాం",
        "block-log-flags-noautoblock": "ఆటోమాటిక్ నిరోధాన్ని అశక్తం చేసాం",
        "block-log-flags-noemail": "ఈ-మెయిలుని నిరోధించాం",
        "cant-move-to-user-page": "మీకు ఒక పేజీని వాడుకరి పేజీగా (వాడుకరి ఉపపేజీగా తప్ప) తరలించే అనుమతి లేదు.",
        "cant-move-category-page": "వర్గాల పేజీలను తరలించే అనుమతి మీకు లేదు.",
        "cant-move-to-category-page": "పేజీలను వర్గాల పేజీలుగా మార్చే అనుమతి మీకు లేదు.",
+       "cant-move-subpages": "ఉపపేజీలను తరలించడానికి మీకు అనుమతి లేదు.",
+       "namespace-nosubpages": "పేరుబరి \"$1\", ఉపపేజీలను అనుమతించదు.",
        "newtitle": "కొత్త శీర్షిక:",
        "move-watch": "ఈ పేజీని గమనించు",
        "movepagebtn": "పేజీని తరలించు",
        "movelogpagetext": "కింద తరలించిన పేజీల జాబితా ఉన్నది.",
        "movesubpage": "{{PLURAL:$1|ఉపపేజీ|ఉపపేజీలు}}",
        "movesubpagetext": "ఈ పేజీకి క్రింద చూపించిన $1 {{PLURAL:$1|ఉపపేజీ ఉంది|ఉపపేజీలు ఉన్నాయి}}.",
+       "movesubpagetalktext": "సంబంధిత చర్చా పేజీకి కింద చూపిన $1 {{PLURAL:$1|ఉపపేజీ ఉంది|ఉపపేజీలున్నాయి}}.",
        "movenosubpage": "ఈ పేజీకి ఉపపేజీలు ఏమీ లేవు.",
        "movereason": "కారణం:",
        "revertmove": "వెనక్కు తిప్పు",
-       "delete_and_move_text": "==తొలగింపు అవసరం==\n\nఉద్దేశించిన వ్యాసం \"[[:$1]]\" ఇప్పటికే ఉనికిలో ఉంది. ప్రస్తుత తరలింపుకు వీలుగా దాన్ని తొలగించేయమంటారా?",
+       "delete_and_move_text": "గమ్యపు పేజీ \"[[:$1]]\" ఇప్పటికే ఉనికిలో ఉంది. \nప్రస్తుత తరలింపుకు వీలుగా దాన్ని తొలగించేయమంటారా?",
        "delete_and_move_confirm": "అవును, పేజీని తొలగించు",
        "delete_and_move_reason": "\"[[$1]]\"ను తరలించడానికి వీలుగా తొలగించారు",
        "selfmove": "మూలం, గమ్యం పేర్లు ఒకటే; పేజీని దాని పైకే తరలించడం కుదరదు.",
        "move-leave-redirect": "పాత పేజీని దారిమార్పుగా ఉంచు",
        "protectedpagemovewarning": "'''హెచ్చరిక:''' ఈ పేజీని సంరక్షించారు కనుక నిర్వాహక హక్కులు కలిగిన వాడుకరులు మాత్రమే దీన్ని తరలించగలరు.\nమీ సమాచారం కోసం చివరి చిట్టా పద్దుని ఇక్కడ ఇస్తున్నాం:",
        "semiprotectedpagemovewarning": "'''గమనిక:''' ఈ పేజీని సంరక్షించారు కనుక నమోదైన వాడుకరులు మాత్రమే దీన్ని తరలించగలరు.\nమీ సమాచారం కోసం చివరి చిట్టా పద్దుని ఇక్కడ ఇస్తున్నాం:",
-       "move-over-sharedrepo": "== ఫైలు ఉంది ==\n[[:$1]] సామూహిక నిక్షేపంలో ఉంది. ఈ పేరుతో మరొక ఫైలును తరలిస్తే అది ఆ సామూహిక ఫైలును ఓవర్‌రైడు చేస్తుంది.",
+       "move-over-sharedrepo": "[[:$1]] సామూహిక నిక్షేపంలో ఉంది. ఈ పేరుకు మరొక ఫైలును తరలిస్తే అది ఆ సామూహిక ఫైలును ఓవర్‌రైడు చేస్తుంది.",
        "file-exists-sharedrepo": "ఎంచుకున్న ఫైలు పేరు ఇప్పటికే సామాన్య భాండాగారంలో వాడుకలో ఉంది.\nదయచేసి మరొక పేరుని ఎంచుకోండి.",
        "export": "పేజీల ఎగుమతి",
        "exporttext": "ఎంచుకున్న పేజీ లేదా పేజీలలోని వ్యాసం మరియు పేజీ చరితం లను XML లో ఎగుమతి చేసుకోవచ్చు. MediaWiki ని ఉపయోగించి Special:Import page ద్వారా దీన్ని వేరే వికీ లోకి దిగుమతి చేసుకోవచ్చు.\n\nపేజీలను ఎగుమతి చేసందుకు, కింద ఇచ్చిన టెక్స్టు బాక్సులో పేజీ పేర్లను లైనుకో పేరు చొప్పున ఇవ్వండి. ప్రస్తుత కూర్పుతో పాటు పాత కూర్పులు కూడా కావాలా, లేక ప్రస్తుత కూర్పు మాత్రమే చాలా అనే విషయం కూడా ఇవ్వవచ్చు.\n\nరెండో పద్ధతిలో అయితే, పేజీ యొక్క లింకును కూడా వాడవచ్చు. ఉదాహరణకు, \"[[{{MediaWiki:Mainpage}}]]\" కోసమైతే [[{{#Special:Export}}/{{MediaWiki:Mainpage}}]] అని ఇవ్వవచ్చు.",
        "export-download": "ఫైలుగా భద్రపరచు",
        "export-templates": "మూసలను కలుపు",
        "export-pagelinks": "ఈ లోతు వరకు లింకై ఉన్న పేజీలను చేర్చు:",
+       "export-manual": "పేజీలను మానవికంగా చేర్చండి:",
        "allmessages": "అన్ని సిస్టం సందేశాలు",
        "allmessagesname": "పేరు",
        "allmessagesdefault": "అప్రమేయ సందేశపు పాఠ్యం",
        "import-upload": "XML డేటాను అప్‌లోడు చెయ్యి",
        "import-token-mismatch": "సెషను భోగట్టా పోయింది. దయచేసి మళ్ళీ ప్రయత్నించండి.",
        "import-invalid-interwiki": "మీరు చెప్పిన వికీనుండి దిగుమతి చేయలేము.",
-       "import-error-edit": "పేజీ \"$1\" లో మార్పుచేర్పులు చేసే అనుమతి మీకు లేదు కాబట్టి దాన్ని దిగుమతి చెయ్యలేదు.",
-       "import-error-create": "పేజీ \"$1\" ను సృష్టించే అనుమతి మీకు లేదు కాబట్టి దాన్ని దిగుమతి చెయ్యలేదు.",
+       "import-error-edit": "\"$1\" పేజీలో మార్పుచేర్పులు చేసే అనుమతి మీకు లేదు కాబట్టి, దాన్ని దిగుమతి చెయ్యలేదు.",
+       "import-error-create": "\"$1\" పేజీని సృష్టించే అనుమతి మీకు లేదు కాబట్టి దాన్ని దిగుమతి చెయ్యలేదు.",
        "import-error-interwiki": "పేజీ \"$1\" యొక్క పేరు బయటి లింకుల (అంతరవికీ) కోసం అట్టేపెట్టబడింది కాబట్టి దాన్ని దిగుమతి చెయ్యలేదు.",
        "import-error-special": "పేజీ \"$1\" ప్రత్యేక పేరుబరికి చెందినది. ఈ పేరుబరిలో పేజీలు సృష్టించే అనుమతి లేదు. అందుచేత దాన్ని దిగుమతి చెయ్యలేదు.",
        "import-error-invalid": "పేజీ \"$1\" పేరు సరైనది కాదు కాబట్టి దాన్ని దిగుమతి చెయ్యలేదు.",
        "import-rootpage-nosubpage": "మూలపేజీ యొక్క పేరుబరి \"$1\" ఉపపేజీలను అనుమతించదు.",
        "importlogpage": "దిగుమతుల చిట్టా",
        "importlogpagetext": "ఇతర వికీల నుండీ మార్పుల చరిత్రతోసహా తెచ్చిన నిర్వహణా దిగుమతులు.",
-       "import-logentry-upload-detail": "$1 {{PLURAL:$1|కూర్పు|కూర్పులు}}",
-       "import-logentry-interwiki-detail": "$2 à°¨à±\81à°\82à°¡à°¿ {{PLURAL:$1|à°\92à°\95 à°\95à±\82à°°à±\8dà°ªà±\81|$1 à°\95à±\82à°°à±\8dà°ªà±\81à°²à±\81}}",
+       "import-logentry-upload-detail": "$1 {{PLURAL:$1|కూర్పును|కూర్పులను}} దిగుమతి చేసాం",
+       "import-logentry-interwiki-detail": "$2 à°¨à±\81à°\82à°¡à°¿ {{PLURAL:$1|à°\95à±\82à°°à±\8dà°ªà±\81à°¨à±\81|à°\95à±\82à°°à±\8dà°ªà±\81లనà±\81}} à°¦à°¿à°\97à±\81మతి à°\9aà±\87సాà°\82",
        "javascripttest": "జావాస్క్రిప్ట్ పరీక్ష",
        "javascripttest-pagetext-unknownaction": "తెలియని చర్య \"$1\".",
        "javascripttest-qunit-intro": "mediawiki.org లోని [$1 పరీక్షా డాక్యుమెంటేషన్] చూడండి.",
        "tooltip-pt-anontalk": "ఈ ఐపీ చిరునామా నుండి చేసిన మార్పుల గురించి చర్చ",
        "tooltip-pt-preferences": "{{GENDER:|మీ}} అభిరుచులు",
        "tooltip-pt-watchlist": "మీరు మార్పుల కొరకు గమనిస్తున్న పేజీల జాబితా",
-       "tooltip-pt-mycontris": "{{GENDER:|మీ}} యోగదానములు",
+       "tooltip-pt-mycontris": "{{GENDER:|మీ}} మార్పుచేర్పుల జాబితా",
+       "tooltip-pt-anoncontribs": "ఈ IP అడ్రసు నుండి చేసిన దిద్దుబాట్ల జాబితా",
        "tooltip-pt-login": "మిమ్మల్ని లాగినవమని ప్రోత్సహిస్తున్నాం; కానీ అది తప్పనిసరేమీ కాదు.",
        "tooltip-pt-logout": "లాగౌటవండి",
        "tooltip-pt-createaccount": "మీరొక ఖాతాని సృష్టించుకొని ప్రవేశించటాన్ని సమర్ధిస్తున్నాము; కానీ, అది అవసరం కాదు, ఐచ్ఛికం మాత్రమే.",
        "tooltip-t-recentchangeslinked": "ఈ పేజీకి లింకై ఉన్న పేజీల్లో జరిగిన ఇటీవలి మార్పులు",
        "tooltip-feed-rss": "ఈ పేజీకి RSS ఫీడు",
        "tooltip-feed-atom": "ఈ పేజీకి Atom ఫీడు",
-       "tooltip-t-contributions": "యోగదానములు జాబితా‌ {{GENDER:$1|ఈ వాడుకరి}}",
-       "tooltip-t-emailuser": "ఈ వాడుకరికి ఓ ఈమెయిలు పంపండి",
+       "tooltip-t-contributions": "{{GENDER:$1|ఈ వాడుకరి}} మార్పుచేర్పుల జాబితా‌",
+       "tooltip-t-emailuser": "ఈ {{GENDER:$1|వాడుకరికి}} ఓ ఈమెయిలు పంపండి",
        "tooltip-t-info": "ఈ పేజీ గురించి మరింత సమాచారం",
        "tooltip-t-upload": "దస్త్రాలను ఎక్కించండి",
        "tooltip-t-specialpages": "అన్ని ప్రత్యేక పుటల జాబితా",
        "tooltip-ca-nstab-category": "వర్గపు పేజీ చూడండి",
        "tooltip-minoredit": "దీన్ని చిన్న మార్పుగా గుర్తించు",
        "tooltip-save": "మీ మార్పులను భద్రపరచండి",
+       "tooltip-publish": "మీ మార్పులను ప్రచురించండి",
        "tooltip-preview": "మీ మార్పులను మునుజూడండి, భద్రపరిచేముందు ఇది వాడండి!",
        "tooltip-diff": "పాఠానికి మీరు ఏ మార్పులు చేసారో చూపిస్తుంది",
        "tooltip-compareselectedversions": "ఈ పేజీలో ఎంచుకున్న రెండు కూర్పులకు మధ్య తేడాలను చూడండి",
        "lastmodifiedatby": "ఈ పేజీకి $3 $2, $1న చివరి మార్పు చేసారు.",
        "othercontribs": "$1 యొక్క కృతిపై ఆధారితం.",
        "others": "ఇతరాలు",
-       "siteusers": "{{SITENAME}} {{PLURAL:$2|వాడుకరి|వాడుకరులు}} $1",
+       "siteusers": "{{SITENAME}} {{PLURAL:$2|{{GENDER:$1|వాడుకరి}}|వాడుకరులు}} $1",
        "anonusers": "{{SITENAME}} అజ్ఞాత {{PLURAL:$2|వాడుకరి|వాడుకరులు}} $1",
        "creditspage": "పేజీ క్రెడిట్లు",
        "nocredits": "ఈ పేజీకి క్రెడిట్ల సమాచారం అందుబాటులో లేదు.",
        "pageinfo-language": "పేజీ విషయపు భాష",
        "pageinfo-language-change": "మార్చు",
        "pageinfo-content-model": "పేజీ కంటెంటు మోడల్",
+       "pageinfo-content-model-change": "మార్చు",
        "pageinfo-robot-policy": "రోబోట్లచే ఇండెక్సింగు",
        "pageinfo-robot-index": "అనుమతించబడింది",
        "pageinfo-robot-noindex": "అనుమతించబడలేదు",
        "exif-xresolution": "క్షితిజసమాంతర స్పష్టత",
        "exif-yresolution": "లంబ స్పష్టత",
        "exif-stripoffsets": "బొమ్మ డేటా ఉన్న స్థలం",
-       "exif-rowsperstrip": "à°\92à°\95à±\8dà°\95à±\8b à°ªà°\9fà±\8dà°\9fà°¿కి ఉన్న అడ్డువరుసలు",
+       "exif-rowsperstrip": "à°\92à°\95à±\8dà°\95à±\8b à°ªà°\9fà±\8dà°\9fà±\80కి ఉన్న అడ్డువరుసలు",
        "exif-stripbytecounts": "ఒక్కో కుదించిన పట్టీలో ఉన్న బైట్లు",
        "exif-jpeginterchangeformat": "JPEG SOI కి ఆఫ్‌సెట్",
        "exif-jpeginterchangeformatlength": "JPEG డాటా యొక్క బైట్లు",
        "watchlistedit-raw-removed": "{{PLURAL:$1|1 శీర్షికను|$1 శీర్షికలను}} తీసివేశాం:",
        "watchlistedit-clear-title": "వీక్షణజాబితా చెరిపివేయి",
        "watchlistedit-clear-legend": "వీక్షణజాబితా చెరిపివేయి",
+       "watchlistedit-clear-explain": "ఈ శీర్షికలన్నిటినీ మీ వీక్షణ జాబితా నుండి తీసేస్తాం",
        "watchlistedit-clear-titles": "శీర్షికలు:",
        "watchlistedit-clear-submit": "వీక్షణ జాబితా శుభ్రం చేయి (ఇది శాశ్వతం!)",
        "watchlistedit-clear-done": "మీ వీక్షణ జాబితాను శుభ్రం చేశాం.",
        "watchlistedit-clear-removed": "{{PLURAL:$1|1 శీర్షికను|$1 శీర్షికలను}} తీసివేశాం:",
+       "watchlistedit-too-many": "ఇక్కడ చూపించలేనన్ని పేజీలున్నాయి.",
        "watchlisttools-clear": "వీక్షణజాబితాను శుభ్రం చేయి",
        "watchlisttools-view": "సంబంధిత మార్పులను చూడండి",
        "watchlisttools-edit": "వీక్షణ జాబితాను చూడండి లేదా మార్చండి",
        "specialpages-group-login": "ప్రవేశించండి / ఖాతాను సృష్టించుకోండి",
        "specialpages-group-changes": "ఇటీవలి మార్పులు మరియు దినచర్యలు",
        "specialpages-group-media": "మాధ్యమ నివేదికలు మరియు ఎగుమతులు",
-       "specialpages-group-users": "వాడà±\81à°\95à°°à±\8dà°²à±\81 à°®à°°à°¿à°¯à±\81 హక్కులు",
+       "specialpages-group-users": "వాడà±\81à°\95à°°à±\81à°²à±\81, హక్కులు",
        "specialpages-group-highuse": "అధిక వాడుక పేజీలు",
        "specialpages-group-pages": "పేజీల యొక్క జాబితాలు",
        "specialpages-group-pagetools": "పేజీ పనిముట్లు",
        "feedback-useragent": "వాడుకరి ఏజెంటు:",
        "searchsuggest-search": "{{SITENAME}}‌లో వెతకండి",
        "searchsuggest-containing": "కలిగియున్న...",
-       "api-error-badaccess-groups": "ఈ వికీ లోనికి దస్త్రాలను ఎక్కించే అనుమతి మీకు లేదు.",
        "api-error-badtoken": "అంతర్గత లోపం: చెడు టోకెన్.",
-       "api-error-copyuploaddisabled": "URL ద్వారా ఎక్కించడం ఈ సర్వరులో అశక్తం చెయ్యబడింది.",
-       "api-error-duplicate": "ఇదే విషయ పాఠ్యంతో ఈ సైటులో ఈసరికే {{PLURAL:$1|మరో ఫైలు ఉంది|ఇతర ఫైళ్ళు ఉన్నాయి}}.",
-       "api-error-duplicate-archive": "ఇదే విషయ పాఠ్యంతో ఈ సైటులో ఈసరికే {{PLURAL:$1|మరో ఫైలు ఉండేది|ఇతర ఫైళ్ళు ఉండేవి}}. అయితే {{PLURAL:$1|అది తొలగించబడింది|అవి తొలగించబడ్డాయి}}.",
-       "api-error-empty-file": "మీరు దాఖలుచేసిన ఫైల్ ఖాళీది.",
        "api-error-emptypage": "కొత్త మరియు ఖాళీ పేజీలను సృష్టించడానికి అనుమతి లేదు.",
-       "api-error-fetchfileerror": "అంతర్గత లోపం: ఈ ఫైలును తేవడంలో ఏదో తప్పు జరిగింది.",
-       "api-error-fileexists-forbidden": "\"$1\" పేరుతో ఓ ఫైలు ఈసరికే ఉంది. దాన్ని తిరగరాయడం కుదరదు.",
-       "api-error-fileexists-shared-forbidden": "\"$1\" పేరుతో ఓ ఫైలు ఈసరికే ఈ సహ ఫైలు ఖజానా (షేర్‍డ్ ఫైల్ రిపాజిటరీ)లో ఉంది. దాన్ని తిరగరాయడం కుదరదు.",
-       "api-error-file-too-large": "మీరు సమర్పించిన దస్త్రం చాలా పెద్దగా ఉంది.",
-       "api-error-filename-tooshort": "దస్త్రపు పేరు మరీ చిన్నగా ఉంది.",
-       "api-error-filetype-banned": "ఈ రకపు దస్త్రాలని నిషేధించారు.",
-       "api-error-filetype-banned-type": "$1, అనుమతించబడిన {{PLURAL:$4|ఫైలు రకం కాదు|ఫైలు రకాలు కాదు}}. అనుమతించబడిన {{PLURAL:$3|ఫైలు రకం|ఫైలు రకాలు}}: $2.",
-       "api-error-filetype-missing": "ఫైలుపేరులో ఓ ఎక్స్టెన్షను లేదు.",
-       "api-error-hookaborted": "మీరు చేయ ప్రయత్నించిన మార్పును ఓ పొడిగింత అడ్డుకుంది.",
-       "api-error-http": "అంతర్గత దోషము: సేవకానికి అనుసంధానమవలేకపోతున్నది.",
-       "api-error-illegal-filename": "ఆ పైల్ పేరు అనుమతించబడదు.",
-       "api-error-internal-error": "అంతర్గత లోపం: ఈ వికీలో మీ ఎక్కింపును ప్రాసెసు చెయ్యడంలో ఎదో తప్పు జరిగింది.",
-       "api-error-invalid-file-key": "అంతర్గత దోషము: తాత్కాలిక నిల్వలో ఫైల్ కనపడలేదు.",
-       "api-error-missingparam": "అంతర్గత దోషం: అభ్యర్ధనలో పరామితులు అన్నీ లేవు.",
-       "api-error-missingresult": "అంతర్గత లోపం: నకలు తీయడం సఫలమైందో లేదో తెలియడం లేదు.",
-       "api-error-mustbeloggedin": "దస్త్రాలను ఎక్కించడానికి మీరు ప్రవేశించివుండాలి.",
-       "api-error-mustbeposted": "అంతర్గత లోపం: అభ్యర్థనకు HTTP POST అవసరం.",
-       "api-error-noimageinfo": "ఎక్కింపు జయప్రదమైంది. కానీ సర్వరు, ఆ ఫైలు గురించిన సమాచారమేమీ ఇవ్వలేదు.",
-       "api-error-nomodule": "అంతర్గత దోషము: ఎక్కింపు పర్వికము అమర్చబడలేదు.",
-       "api-error-ok-but-empty": "అంతర్గత దోషము: సేవకము నుండి ఎటువంటి స్పందనా లేదు.",
-       "api-error-overwrite": "ఈసరికే ఉన్న ఫైలును తిరగరాయడానికి అనుమతి లేదు.",
-       "api-error-stashfailed": "అంతర్గత లోపం: తాత్కాలిక దస్త్రాన్ని భద్రపరచడంలో సేవకి విఫలమైంది.",
        "api-error-publishfailed": "అంతర్గత లోపం: తాత్కాలిక ఫైలును ప్రచురించడంలో సర్వరు విఫలమైంది.",
-       "api-error-stasherror": "ఫైలును ఖాజానాకు ఎక్కించడంలో లోపం దొర్లింది.",
-       "api-error-timeout": "సర్వరు ఆశించిన సమయం లోపు స్పందించలేదు.",
-       "api-error-unclassified": "ఒక తెలియని దోషము సంభవించినది",
-       "api-error-unknown-code": "తెలియని పొరపాటు: \"$1\".",
-       "api-error-unknown-error": "అంతర్గత పొరపాటు: మీ దస్త్రాన్ని ఎక్కించేప్పుడు ఏదో పొరపాటు జరిగింది.",
+       "api-error-stashfailed": "అంతర్గత లోపం: తాత్కాలిక దస్త్రాన్ని భద్రపరచడంలో సేవకి విఫలమైంది.",
        "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|గంట|గంటలు}}",
index 15341c8..fb73ae7 100644 (file)
        "nstab-mediawiki": "Mensajen",
        "nstab-help": "Pájina ajuda",
        "nstab-category": "Kategoria",
+       "mainpage-nstab": "Pájina Mahuluk",
        "nosuchspecialpage": "Pájina espesiál ne'e la iha",
        "nospecialpagetext": "<strong>Pájina espesiál ne'e la iha.</strong>\n\nLista ida pájina espesiál nian [[Special:SpecialPages|iha ne'e]].",
        "error": "Sala",
        "watchthis": "Hateke pájina ne'e",
        "savearticle": "Muda pájina",
        "showdiff": "Hatudu diferensa sira",
-       "anoneditwarning": "Ó lá'os \"log-in\" iha momentu.",
+       "anoneditwarning": "<strong>Warning:</strong> You are not logged in. Your IP address will be publicly visible if you make any edits. If you <strong>[$1 log in]</strong> or <strong>[$2 create an account]</strong>, your edits will be attributed to your username, along with other benefits.",
        "blockedtitle": "Uza-na'in la bele edita (blokeiu)",
        "blockednoreason": "laiha motivu",
        "whitelistedittext": "Ó tenke $1 ba edita pájina sira.",
        "loginreqpagetext": "Ó tenke $1 ba haree pájina seluk.",
        "newarticle": "(Foun)",
-       "noarticletext": "Iha momentu lá'os testu iha pájina ne'e, bele [[Special:Search/{{PAGENAME}}|buka naran pájina nian]] iha pájina seluk, <span class=\"plainlinks\">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} search the related logs], ka [{{fullurl:{{FULLPAGENAME}}|action=edit}} edita pájina ne'e]</span>.",
+       "noarticletext": "Iha momentu lá'os testu iha pájina ne'e, bele [[Special:Search/{{PAGENAME}}|buka naran pájina nian]] iha pájina seluk, <span class=\"plainlinks\">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} search the related logs], ka [{{fullurl:{{FULLPAGENAME}}|action=edit}} kria pájina ne'e]</span>.",
        "previewnote": "'''Ne'e de'it pájina ba kontrola.'''\nIta-nia mudansa la armazenadu seidauk!",
        "editing": "Edita $1",
        "editingsection": "Edita $1 (seksaun)",
        "permissionserrorstext": "Ó la bele halo ne'e; {{PLURAL:$1|motivu|motivu sira}}:",
        "permissionserrorstext-withaction": "Ita la bele $2. {{PLURAL:$1|Razaun|Razaun sira}}:",
        "currentrev": "Versaun atuál",
+       "currentrev-asof": "Versaun atuál $1 nian",
        "revisionasof": "Versaun $1 nian",
-       "revision-info": "Revisaun loron $4, tempu $5, husi $2",
+       "revision-info": "Revisaun loron $4, tempu $5, husi {{GENDER:$6|$2}}$7",
        "previousrevision": "←Versaun tuan liu",
        "nextrevision": "Versaun foun liu→",
        "currentrevisionlink": "Versaun atuál",
        "import-comment": "Komentáriu:",
        "import-revision-count": "{{PLURAL:$1|versaun ida|versaun $1}}",
        "import-logentry-interwiki-detail": "$1 {{PLURAL:$1|versaun|versaun}} husi $2",
-       "tooltip-pt-userpage": "Ó-nia pájina uza-na'in",
-       "tooltip-pt-mytalk": "Ó-nia pájina diskusaun",
-       "tooltip-pt-preferences": "Ha'u-nia preferénsia",
-       "tooltip-pt-mycontris": "Ó-nia kontribuisaun (lista)",
+       "tooltip-pt-userpage": "{{GENDER:|Ó-nia}} pájina uza-na'in",
+       "tooltip-pt-mytalk": "{{GENDER:|Ó-nia}} pájina diskusaun",
+       "tooltip-pt-preferences": "{{GENDER:|Ó}}-nia preferénsia",
+       "tooltip-pt-mycontris": "{{GENDER:|Ó-nia}} kontribuisaun (lista)",
        "tooltip-pt-login": "Ami rekomenda identifikasaun (\"log in\"), maibé Ita-Boot la presiza halo ne'e",
        "tooltip-pt-logout": "Husik",
        "tooltip-ca-talk": "Diskusaun kona-ba konteúdu pájina nian",
-       "tooltip-ca-edit": "Ita bele edita pájina ne'e. Please use the preview button before saving.",
+       "tooltip-ca-edit": "Edita pájina ne'e",
        "tooltip-ca-addsection": "Tau tan seksaun foun ida.",
        "tooltip-ca-viewsource": "Ema ruma proteje tiha pájina ne'e.\nÓ bele lee testu.",
        "tooltip-ca-history": "Versaun tuan pájina nian",
        "tooltip-n-randompage": "Hola pájina ruma",
        "tooltip-n-help": "Hatudu pájina ajuda.",
        "tooltip-t-whatlinkshere": "Lista pájina nian ne'ebé bá iha ne'e",
-       "tooltip-t-contributions": "Haree lista kontribuisaun uza-na'in ne'e nian",
+       "tooltip-t-contributions": "Haree lista kontribuisaun {{GENDER:$1|uza-na'in ne'e nian}}",
        "tooltip-t-emailuser": "Haruka korreiu eletróniku",
        "tooltip-t-upload": "Tau iha arkivu laran",
        "tooltip-t-specialpages": "Lista pájina espesiál hotu nian",
        "siteusers": "{{PLURAL:$2|uza-na'in|uza-na'in}} {{SITENAME}} nian $1",
        "previousdiff": "←Versaun molok",
        "nextdiff": "Versaun oinmai→",
-       "show-big-image": "Boot liu",
+       "show-big-image": "Fixeiru original",
        "ilsubmit": "Buka",
        "bad_image_list": "Formatu:\n\nLiña hotu tenke komesa ho *\nLigasaun uluk iha liña tenke ligasaun bá imajen aat.\nLigasaun seluk iha liña - ne'e pájina sira iha ne'ebé bele inklui imajen aat.",
        "exif-make": "Fabrikante kámara nian",
        "compare-rev2": "Versaun 2",
        "compare-submit": "Halo komparasaun",
        "rightsnone": "(mamuk)",
-       "searchsuggest-search": "Buka",
+       "searchsuggest-search": "Buka iha {{SITENAME}}",
        "expand_templates_ok": "OK"
 }
index ea4519d..7e77d4d 100644 (file)
        "changepassword-success": "เปลี่ยนรหัสผ่านของคุณสำเร็จ!",
        "changepassword-throttled": "ล่าสุดคุณพยายามล็อกอินมากครั้งเกินไป\nกรุณารอ $1 ก่อนลองอีกครั้ง",
        "botpasswords": "รหัสผ่านบอต",
+       "botpasswords-summary": "<em>รหัสผ่านบอต</em>อนุญาตการเข้าถึงให้กับบัญชีผู้ใช้ผ่านทาง API โดยไม่ต้องใช้ใบรับรองการล็อกอินหลักของบัญชีนี้ สิทธิผู้ใช้เมื่อล็อกอินด้วยรหัสผ่านบอตอาจถูกจำกัด\n\nถ้าคุณไม่ทราบว่าทำไมคุณอาจต้องการดำเนินการนี้ คุณไม่ควรดำเนินการนี้ และไม่ควรให้ผู้ใดขอให้คุณสร้างรหัสผ่านไว้ให้พวกเขาเหล่านั้น",
+       "botpasswords-disabled": "รหัสผ่านสำหรับบอตถูกปิดใช้",
+       "botpasswords-no-central-id": "หากต้องการใช้รหัสผ่านบอต คุณต้องล็อกอินในชื่อบัญชีผู้ใช้ที่เป็นกลาง",
+       "botpasswords-existing": "รหัสผ่านบอตที่มีอยู่",
+       "botpasswords-createnew": "สร้างรหัสผ่านบอตใหม่",
+       "botpasswords-editexisting": "แก้ไขรหัสผ่านบอตที่มีอยู่เดิม",
        "botpasswords-label-appid": "ชื่อบอต:",
        "botpasswords-label-create": "สร้าง",
        "botpasswords-label-update": "อัปเดต",
        "botpasswords-label-cancel": "ยกเลิก",
        "botpasswords-label-delete": "ลบ",
        "botpasswords-label-resetpassword": "ตั้งรหัสผ่านใหม่",
+       "botpasswords-label-grants": "การอนุญาตที่นำไปใช้ได้:",
+       "botpasswords-label-grants-column": "อนุญาตแล้ว",
+       "botpasswords-bad-appid": "ชื่อบอต \"$1\" ไม่ถูกต้อง",
+       "botpasswords-insert-failed": "การเพิ่มชื่อบอต \"$1\" ล้มเหลว คุณได้เพิ่มมันไว้แล้วหรือเปล่า?",
+       "botpasswords-update-failed": "การอัปเดตชื่อบอต \"$1\" ล้มเหลว คุณลบมันออกไปหรือเปล่า?",
+       "botpasswords-created-title": "สร้างรหัสผ่านบอตแล้ว",
+       "botpasswords-created-body": "รหัสผ่านบอตสำหรับชื่อบอต \"$1\" ของผู้ใช้ชื่อ \"$2\" ถูกสร้างขึ้นแล้ว",
+       "botpasswords-updated-title": "อัปเดตรหัสผ่านบอตแล้ว",
+       "botpasswords-updated-body": "รหัสผานบอตสำหรับชื่อบอต \"$1\" ของผู้ใช้ \"$2\" ถูกอัปเดตแล้ว",
+       "botpasswords-deleted-title": "ลบรหัสผ่านบอตแล้ว",
+       "botpasswords-deleted-body": "รหัสผ่านบอตสำหรับชื่อบอต \"$1\" ของผู้ใช้ชื่อ \"$2\" ถูกลบออกแล้ว",
+       "botpasswords-no-provider": "BotPasswordsSessionProvider ไม่พร้อมใช้งาน",
+       "botpasswords-restriction-failed": "ข้อจำกัดของรหัสผ่านบอตห้ามไม่ให้ล็อกอินครั้งนี้",
+       "botpasswords-invalid-name": "ชื่อผู้ใช้ที่ระบุไม่มีเครื่องหมายคั่นในรหัสผ่านบอต (\"$1\")",
+       "botpasswords-not-exist": "ผู้ใช้ \"$1\" ไม่มีรหัสผ่านบอต \"$2\".",
        "resetpass_forbidden": "ไม่สามารถเปลี่ยนรหัสผ่านได้",
+       "resetpass_forbidden-reason": "ไม่สามารถเปลี่ยนรหัสผ่านได้: $1",
        "resetpass-no-info": "คุณต้องล็อกอินเพื่อเข้าถึงหน้านี้โดยตรง",
        "resetpass-submit-loggedin": "เปลี่ยนรหัสผ่าน",
        "resetpass-submit-cancel": "ยกเลิก",
        "passwordreset-emailelement": "ชื่อผู้ใช้: \n$1\n\nรหัสผ่านชั่วคราว: \n$2",
        "passwordreset-emailsentemail": "หากที่อยู่อีเมลนี้สัมพันธ์กับบัญชีของคุณ เช่นนั้นจะส่งอีเมลตั้งรหัสผ่านใหม่",
        "passwordreset-emailsentusername": "หากมีที่อยู่อีเมลที่ลงทะเบียนไว้ด้วยกับชื่อผู้ใช้นี้ เช่นนั้นจะส่งอีเมลตั้งรหัสผ่านใหม่",
+       "passwordreset-invalidemail": "ที่อยู่อีเมลไม่ถูกต้อง",
+       "passwordreset-nodata": "ไม่ได้ระบุชื่อผู้ใช้และรหัสผ่านไว้",
        "changeemail": "เปลี่ยนหรือลบที่อยู่อีเมล",
        "changeemail-header": "กรอกแบบนี้เพื่อเปลี่ยนที่อยู่อีเมลของคุณ หากคุณต้องการลบการเชื่อมโยงของที่อยู่อีเมลใด ๆ จากบัญชีของคุณ ให้เว้นที่อยู่อีเมลใหม่ว่างเมื่อส่งแบบ",
        "changeemail-no-info": "คุณจำต้องล็อกอินเพื่อเข้าถึงหน้านี้โดยตรง",
        "savearticle": "บันทึกหน้า",
        "savechanges": "บันทึกการเปลี่ยนแปลง",
        "publishpage": "เผยแพร่หน้า",
+       "publishchanges": "เผยแพร่การเปลี่ยนแปลง",
        "preview": "ตัวอย่าง",
        "showpreview": "แสดงตัวอย่าง",
        "showdiff": "แสดงการเปลี่ยนแปลง",
        "blockedtitle": "ผู้ใช้ถูกบล็อก",
        "blockedtext": "<strong>ชื่อผู้ใช้หรือเลขที่อยู่ไอพีของคุณถูกบล็อก</strong>\n\nการบล็อกนี้ดำเนินการโดย $1\nซึ่งให้เหตุผลว่า ''$2''\n\n* เริ่มการบล็อก: $8\n* หมดเขตการบล็อก: $6\n* ผู้ถูกบล็อกที่เจตนา: $7\n\nคุณสามารถติดต่อ $1 หรือ[[{{MediaWiki:Grouppage-sysop}}|ผู้ดูแลระบบ]]คนอื่นเพื่ออภิปรายการบล็อกนี้ได้\nคุณไม่สามารถใช้คุณลักษณะ \"ส่งอีเมลหาผู้ใช้รายนี้ได้\" จนกว่าจะระบุที่อยู่อีเมลให้ถูกต้องใน[[Special:Preferences|การตั้งค่าบัญชี]]ของคุณ และคุณมิได้ถูกห้ามใช้ความสามารถนี้\nเลขที่อยู่ไอพีปัจจุบันของคุณคือ $3 และหมายเลขการบล็อกคือ #$5 \nโปรดแสดงรายละเอียดข้างต้นทั้งหมดในการสอบถามใด ๆ",
        "autoblockedtext": "เลขที่อยู่ไอพีของคุณถูกบล็อกอัตโนมัติ เพราะเคยมีผู้ใช้อื่นใช้ ซึ่งถูกบล็อกโดย $1\nโดยให้เหตุผลว่า\n\n:<em>$2</em>\n\n* เริ่มการบล็อก: $8\n* สิ้นสุดการบล็อก: $6\n* ผู้ถูกบล็อกที่เจตนา: $7\n\nคุณสามารถติดต่อ $1 หรือ[[{{MediaWiki:Grouppage-sysop}}|ผู้ดูแลระบบ]]คนอื่นเพื่ออภิปรายการบล็อกนี้ \nคุณไม่สามารถใช้คุณลักษณะ \"ส่งอีเมลหาผู้ใช้รายนี้ได้\" จนกว่าจะระบุที่อยู่อีเมลที่ถูกต้องใน[[Special:Preferences|การตั้งค่าบัญชี]]ของคุณ และคุณมิได้ถูกห้ามใช้\nเลขที่อยู่ไอพีปัจจุบันของคุณคือ $3 และหมายเลขการบล็อกคือ #$5 \nโปรดรวมรายละเอียดข้างต้นทั้งหมดในการสอบถามใด ๆ",
+       "systemblockedtext": "ชื่อผู้ใช้หรือที่อยู่ไอพีของคุณถูกบล็อกอัตโนมัติโดยมีเดียวิกิ\nเหตุผลสำหรับการบล็อกคือ:\n\n:<em>$2</em>\n\n* เริ่มการบล็อก: $8\n* สิ้นสุดการบล็อก: $6\n* ผู้ดำเนินการบล็อก: $7\n\nไอพีแอดเดรสปัจจุบันของคุณคือ $3\nโปรดแจ้งรายละเอียดทั้งหมดข้างต้น ถ้าคุณมีข้อสงสัยใด ๆ",
        "blockednoreason": "ไม่ได้ให้เหตุผล",
        "whitelistedittext": "คุณต้อง$1เพื่อแก้ไขหน้า",
        "confirmedittext": "คุณต้องยืนยันที่อยู่อีเมลของคุณก่อนแก้ไขหน้า \nโปรดตั้งและตรวจสอบความสมเหตุสมผลของที่อยู่อีเมลของคุผ่าน[[Special:Preferences|การตั้งค่าผู้ใช้]]",
        "content-model-text": "ข้อความธรรมดา",
        "content-model-javascript": "จาวาสคริปต์",
        "content-model-css": "CSS",
+       "content-json-empty-object": "วัตถุเปล่า",
+       "content-json-empty-array": "แถวเปล่า",
        "duplicate-args-category": "หน้าที่ใช้อาร์กิวเมนต์ซ้ำในการเรียกแม่แบบ",
        "expensive-parserfunction-warning": "<strong>คำเตือน:</strong> หน้านี้มีการเรียกใช้ฟังก์ชันแจงส่วนมากเกินไป\n\nหน้านี้ควรมีการเรียกใช้น้อยกว่า $2  ครั้ง แต่ปัจจุบันมีการเรียกใช้ $1 ครั้ง",
        "expensive-parserfunction-category": "หน้าที่มีการเรียกใช้ฟังก์ชันแจงส่วนมากเกินไป",
        "mergehistory-empty": "ไม่มีรุ่นปรับปรุงที่รวมได้",
        "mergehistory-done": "รวม $3 รุ่นปรับปรุงของ $1 เข้ากับ [[:$2]] แล้ว",
        "mergehistory-fail": "ไม่สามารถรวมประวัติได้ โปรดตรวจสอบตัวแปรเสริมหน้าและเวลาอีกครั้ง",
+       "mergehistory-fail-bad-timestamp": "สแตมป์เวลาไม่ถูกต้อง",
+       "mergehistory-fail-invalid-source": "หน้าต้นทางไม่ถูกต้อง",
+       "mergehistory-fail-invalid-dest": "หน้าปลายทางไม่ถูกต้อง",
+       "mergehistory-fail-permission": "มีสิทธิไม่เพียงพอที่จะผสานประวัติ",
+       "mergehistory-fail-self-merge": "หน้าต้นทางและปลายทางเป็นหน้าเดียวกัน",
+       "mergehistory-fail-toobig": "ไม่สามารถผสานประวัติได้ เนื่องจาก $1 รุ่นแก้ไขเก่าที่เกินขีดจำกัดสูงสุดจะต้องถูกย้ายไปก่อน",
        "mergehistory-no-source": "ไม่มีหน้าต้นทาง $1",
        "mergehistory-no-destination": "ไม่มีหน้าปลายทาง $1",
        "mergehistory-invalid-source": "ชื่อเรื่องหน้าต้นทางต้องสมเหตุสมผล",
        "search-external": "ค้นหาภายนอก",
        "searchdisabled": "การค้นหา {{SITENAME}} ถูกปิดใช้งาน \nคุณสามารถค้นหาโดยทางกูเกิลในระหว่างนั้น\nโปรดทราบว่าดัชนีเนื้อหา {{SITENAME} อาจล้าสมัย",
        "search-error": "มีข้อผิดพลาดขณะค้นหา: $1",
+       "search-warning": "มีคำเตือนขณะค้นหา: $1",
        "preferences": "การตั้งค่า",
        "mypreferences": "การตั้งค่า",
        "prefs-edits": "จำนวนการแก้ไข:",
        "userrights-user-editname": "ใส่ชื่อผู้ใช้:",
        "editusergroup": "โหลดกลุ่มผู้ใช้",
        "editinguser": "กำลังเปลี่ยนสิทธิผู้ใช้ของผู้ใช้ <strong>[[User:$1|$1]]</strong> $2",
+       "viewinguserrights": "กำลังดูสิทธิผู้ใช้ของผู้ใช้ <strong>[[User:$1|$1]]</strong> $2",
        "userrights-editusergroup": "แก้ไขกลุ่มผู้ใช้",
+       "userrights-viewusergroup": "ดูกลุ่มผู้ใช้",
        "saveusergroups": "บันทึกกลุ่ม{{GENDER:$1|ผู้ใช้}}",
        "userrights-groupsmember": "สมาชิกของ:",
        "userrights-groupsmember-auto": "สมาชิกโดยปริยายของ:",
        "right-createpage": "สร้างหน้า (ที่ไม่ใช่หน้าอภิปราย)",
        "right-createtalk": "สร้างหน้าอภิปราย",
        "right-createaccount": "สร้างบัญชีผู้ใช้ใหม่",
+       "right-autocreateaccount": "ล็อกอินโดยใช้บัญชีผู้ใช้ภายนอกอัตโนมัติ",
        "right-minoredit": "ทำเครื่องหมายการแก้ไขเป็นการแก้ไขเล็กน้อย",
        "right-move": "ย้ายหน้า",
        "right-move-subpages": "ย้ายหน้าพร้อมหน้าย่อย",
        "right-siteadmin": "ล็อกและปลดล็อกฐานข้อมูล",
        "right-override-export-depth": "ส่งออกหน้า รวมหน้าที่เชื่อมโยงกับหน้านี้สูงสุด 5 ลำดับชั้น",
        "right-sendemail": "ส่งอีเมลหาผู้ใช้อื่น",
+       "right-managechangetags": "สร้างและเปิด/ปิดใช้งาน[[Special:Tags|ป้ายชื่อ]]",
+       "right-deletechangetags": "ลบ[[Special:Tags|ป้ายชื่อ]]ออกจากฐานข้อมูล",
+       "grant-group-page-interaction": "โต้ตอบกับหน้า",
+       "grant-group-file-interaction": "โต้ตอบกับสื่อ",
+       "grant-group-watchlist-interaction": "โต้ตอบกับรายการเฝ้าดูของคุณ",
        "grant-group-email": "ส่งอีเมล",
+       "grant-group-customization": "การปรับแต่งและการตั้งค่า",
+       "grant-group-other": "กิจกรรมเบ็ดเตล็ด",
+       "grant-blockusers": "บล็อกและปลดบล็อกผู้ใช้ต่าง ๆ",
        "grant-createaccount": "สร้างบัญชี",
        "grant-createeditmovepage": "สร้าง แก้ไข และย้ายหน้า",
+       "grant-delete": "ลบหน้า รุ่นแก้ไขเก่า และรายการบันทึก",
+       "grant-editinterface": "แก้ไขเนมสเปซของมีเดียวิกิและ CSS/JavaScript ของผู้ใช้",
+       "grant-editmycssjs": "แก้ไข CSS/JavaScript ผู้ใช้ของคุณ",
+       "grant-editmyoptions": "แก้ไขการตั้งค่าผู้ใช้ของคุณ",
        "grant-editmywatchlist": "แก้ไขรายการเฝ้าดูของคุณ",
        "grant-editpage": "แก้ไขหน้านี้",
+       "grant-editprotected": "แก้ไขหน้าที่ถูกล็อก",
+       "grant-highvolume": "การแก้ไขในปริมาณสูง",
+       "grant-patrol": "ลาดตระเวนตรวจการเปลี่ยนแปลงหน้าต่าง ๆ",
+       "grant-privateinfo": "เข้าถึงข้อมูลส่วนบุคคล",
+       "grant-protect": "ล็อกและปลดล็อกหน้าต่าง ๆ",
+       "grant-rollback": "ทำกลับการเปลี่ยนแปลงในหน้า",
+       "grant-sendemail": "ส่งอีเมลหาผู้ใช้อื่น",
        "grant-uploadeditmovefile": "อัปโหลด แทนที่ และย้ายไฟล์",
        "grant-uploadfile": "อัปโหลดไฟล์ใหม่",
+       "grant-basic": "สิทธิพื้นฐาน",
+       "grant-viewdeleted": "ดูไฟล์และหน้าที่ถูกลบ",
        "grant-viewmywatchlist": "ดูรายการเฝ้าดูของคุณ",
+       "grant-viewrestrictedlogs": "ดูรายการบันทึกที่ถูกจำกัดไว้",
        "newuserlogpage": "ปูมการสร้างผู้ใช้",
        "newuserlogpagetext": "นี่คือปูมการสร้างผู้ใช้",
        "rightslog": "ปูมสิทธิผู้ใช้",
        "action-createpage": "สร้างหน้านี้",
        "action-createtalk": "สร้างหน้าอภิปรายนี้",
        "action-createaccount": "สร้างบัญชีผู้ใช้นี้",
+       "action-autocreateaccount": "สร้างบัญชีผู้ใช้ภายนอกนี้อัตโนมัติ",
        "action-history": "ดูประวัติหน้านี้",
        "action-minoredit": "ทำเครื่องหมายการแก้ไขนี้เป็นการแก้ไขเล็กน้อย",
        "action-move": "ย้ายหน้านี้",
        "action-writeapi": "ใช้การเขียนเอพีไอ",
        "action-delete": "ลบหน้านี้",
        "action-deleterevision": "ลบรุ่นปรับปรุง",
+       "action-deletelogentry": "ลบรายการบันทึก",
        "action-deletedhistory": "ดูประวัติที่ถูกลบของหน้าใดหน้าหนึ่ง",
+       "action-deletedtext": "ดูข้อความรุ่นแก้ไขเก่าที่ถูกลบ",
        "action-browsearchive": "ค้นหาหน้าที่ถูกลบ",
        "action-undelete": "กู้คืนหน้า",
        "action-suppressrevision": "ตรวจทานและกู้คืนรุ่นปรับปรุงที่ซ่อนอยู่",
        "action-userrights-interwiki": "แก้ไขสิทธิผู้ใช้ของผู้ใช้บนวิกิอื่น",
        "action-siteadmin": "ล็อกหรือปลดล็อกฐานข้อมูล",
        "action-sendemail": "ส่งอีเมล",
+       "action-editmyoptions": "แก้ไขการตั้งค่าของคุณ",
        "action-editmywatchlist": "แก้ไขรายการเฝ้าดูของคุณ",
        "action-viewmywatchlist": "ดูรายการเฝ้าดูของคุณ",
        "action-viewmyprivateinfo": "ดูสารสนเทศส่วนตัวของคุณ",
        "action-editmyprivateinfo": "แก้ไขสารสนเทศส่วนตัวของคุณ",
        "action-editcontentmodel": "แก้ไขตัวแบบเนื้อหาของหน้า",
+       "action-deletechangetags": "ลบป้ายชื่อออกจากฐานข้อมูล",
+       "action-purge": "ล้างหน้านี้",
        "nchanges": "$1 การเปลี่ยนแปลง",
        "enhancedrc-since-last-visit": "$1 {{PLURAL:$1|ตั้งแต่การเยี่ยมชมครั้งสุดท้าย}}",
        "enhancedrc-history": "ประวัติ",
        "recentchanges-legend-heading": "<strong>คำอธิบายสัญลักษณ์:</strong>",
        "recentchanges-legend-newpage": "{{int:recentchanges-label-newpage}} (ดูเพิ่มที่ [[Special:NewPages|รายชื่อหน้าใหม่]])",
        "recentchanges-submit": "แสดง",
+       "rcfilters-activefilters": "ตัวกรองที่ทำงาน",
+       "rcfilters-restore-default-filters": "คืนค่าตัวกรองปริยาย",
+       "rcfilters-clear-all-filters": "ล้างตัวกรองทั้งหมด",
+       "rcfilters-invalid-filter": "ตัวกรองไม่ถูกต้อง",
+       "rcfilters-filterlist-title": "ตัวกรอง",
+       "rcfilters-filterlist-noresults": "ไม่พบตัวกรองใด ๆ",
+       "rcfilters-filtergroup-registration": "การลงทะเบียนผู้ใช้",
+       "rcfilters-filter-registered-label": "ลงทะเบียน",
+       "rcfilters-filter-registered-description": "ผู้แก้ไขที่ล็อกอินแล้ว",
+       "rcfilters-filter-unregistered-label": "ไม่ได้ลงทะเบียน",
+       "rcfilters-filter-unregistered-description": "ผู้แก้ไขที่ไม่ได้ล็อกอิน",
+       "rcfilters-filter-editsbyself-label": "การแก้ไขของคุณเอง",
+       "rcfilters-filter-editsbyself-description": "การแก้ไขต่าง ๆ ที่คุณทำ",
+       "rcfilters-filter-editsbyother-label": "การแก้ไขต่าง ๆ ที่ผู้อื่นทำ",
+       "rcfilters-filter-editsbyother-description": "การแก้ไขต่าง ๆ ที่ผู้ใช้อื่นทำ (ไม่ใช่คุณ)",
+       "rcfilters-filtergroup-userExpLevel": "ระดับผู้เชี่ยวชาญ (สำหรับผู้ใช้ที่ลงทะเบียนเท่านั้น)",
+       "rcfilters-filter-userExpLevel-newcomer-label": "ผู้ที่มาใหม่",
+       "rcfilters-filter-userExpLevel-experienced-label": "ผู้ใช้ที่มีความเชี่ยวชาญ",
        "rcnotefrom": "ด้านล่างเป็นการเปลี่ยนแปลงตั้งแต่ <strong>$3, $4</strong> (แสดงมากสุด <strong>$1</strong>)",
        "rclistfrom": "แสดงการเปลี่ยนแปลงใหม่เริ่มตั้งแต่ $2, $3",
        "rcshowhideminor": "$1การแก้ไขเล็กน้อย",
index 405d823..d89ce49 100644 (file)
        "passwordreset-emaildisabled": "Hindi pinagana ang email features sa wiking ito.",
        "passwordreset-username": "Pangalan ng tagagamit:",
        "passwordreset-domain": "Nasasakupan:",
-       "passwordreset-capture": "Tingnan ang lumabas na e-liham?",
-       "passwordreset-capture-help": "Kapag tsetsekan mo ang kahong ito, ang email (may pansamantalang password) ay ipapakita sa iyo at ipapadala rin sa tagagamit.",
        "passwordreset-email": "Direksiyong e-liham:",
        "passwordreset-emailtitle": "Mga detalye ng account sa {{SITENAME}}",
        "passwordreset-emailtext-ip": "Isang tao (marahil ay ikaw, mula sa IP address na $1) ang humiling ng isang paalala sa iyong mga detalye ng account para sa {{SITENAME}} ($4). Ang sumusunod na {{PLURAL:$3|account ng tagagamit ay|mga account ng tagagamit ay}} may kaugnayan sa email address na ito:\n\n$2\n\n{{PLURAL:$3|Ang pansamantalang password na ito|Ang mga pansamantalang password na ito}} ay mawawalan ng bisa sa loob ng {{PLURAL:$5|isang araw|$5 araw}}.\nDapat kang mag-login at pumili ng isang bagong password ngayon. Kung ibang tao ang gumawa ng kahilingang ito, o kung naalala mo na ang orihinal mong password, at hindi mo na nais palitan ito, maaari mong huwag nang pansinin ang mensaheng ito at magpatuloy sa paggamit ng luma mong password.",
        "saveprefs": "Itala",
        "restoreprefs": "Ibalik ang lahat ng likas na mga pagtatakda",
        "prefs-editing": "May binabago",
-       "rows": "Mga pahalang na hanay:",
-       "columns": "Mga pahabang hanay:",
        "searchresultshead": "Hanapin",
        "stub-threshold": "Kakayanan para sa pagpopormat ng <a href=\"#\" class=\"usbong\">kawing ng usbong</a> (mga ''byte''):",
        "stub-threshold-disabled": "Hindi pinagagana",
        "username": "{{GENDER:$1|Bansag}}:",
        "prefs-memberingroups": "{{GENDER:$2|Kasapi}} ng {{PLURAL:$1|na pangkat|na mga pangkat}}:",
        "prefs-memberingroups-type": "$1",
+       "group-membership-link-with-expiry": "$1 (hanggang $2)",
        "prefs-registration": "Oras ng pagtatala:",
        "prefs-registration-date-time": "$1",
        "yourrealname": "Tunay na pangalan:",
        "userrights-reason": "Dahilan:",
        "userrights-no-interwiki": "Wala kang pahintulot na baguhin ang mga karapatan ng tagagamit sa ibang mga wiki.",
        "userrights-nodatabase": "Hindi umiiral o hindi lokal ang kalipunan ng datos na $1",
-       "userrights-nologin": "Kailangang [[Special:UserLogin|nakalagda ka]] bilang tagapangasiwa upang maitalaga ang mga karapatan ng tagagamit.",
-       "userrights-notallowed": "Wala kang pahintulot na magdagdag o magtanggal ng mga karapatan ng tagagamit.",
        "userrights-changeable-col": "Mga pangkat na maaari mong baguhin",
        "userrights-unchangeable-col": "Mga pangkat na hindi mo mababago",
        "userrights-irreversible-marker": "$1*",
+       "userrights-expiry-current": "Mapapaso sa $1",
+       "userrights-expiry-none": "Hindi napapaso",
+       "userrights-expiry": "Mapapaso ng:",
+       "userrights-expiry-existing": "Sa kaunting oras na: $3, $2",
+       "userrights-expiry-options": "Isang araw:1 day,Isang linggo:1 week,Isang buwan:1 month,Tatlong buwan:3 months,Anim na buwan:6 months,Isang taon:1 year",
+       "userrights-invalid-expiry": "Sa oras na mapaso ang grupong \"$1\" ay hindi na magagamit.",
+       "userrights-expiry-in-past": "Sa oras na mapaso ang grupong \"$1\" ay hindi na magagamit.",
        "group": "Pangkat:",
        "group-user": "Mga tagagamit",
        "group-autoconfirmed": "Mga tagagamit na nakompirma sa kusang paraan (autokompirmasyon)",
        "right-siteadmin": "Ikandado at alisin ang pagkakakandado ng kalipunan ng dato",
        "right-override-export-depth": "Iluwas ang mga pahina na kabilang ang mga pahinang nakakawing magpahanggang sa isang lalim na 5",
        "right-sendemail": "Magpadala ng e-liham sa ibang mga tagagamit",
-       "right-passwordreset": "Tingnan ang mga email ng muling pagtatakda ng password",
        "newuserlogpage": "Talaan ng paglikha ng tagagamit",
        "newuserlogpagetext": "Isa itong talaan ng mga paglikha ng tagagamit.",
        "rightslog": "Tala ng mga karapatan ng tagagamit",
        "recentchanges-label-plusminus": "Nagbago ang laki ng pahina sa ganitong bilang ng mga byte",
        "recentchanges-legend-heading": "<strong>Gabay:</strong>",
        "recentchanges-legend-newpage": "{{int:recentchanges-label-newpage}} (tingnan din [[Special:NewPages|ang talaan ng mga bagong pahina]])",
+       "rcfilters-restore-default-filters": "Ibalik ang mga napagkaukulang 'filters'",
+       "rcfilters-clear-all-filters": "Burahin lahat ng mga 'filters'",
+       "rcfilters-empty-filter": "Walang aktibong panangga. Lahat ay ipinamalas.",
        "rcnotefrom": "Nasa ibaba ang mga pagbabago mula pa noong '''$2''' (ipinapakita ang magpahanggang sa '''$1''').",
        "rclistfrom": "Ipakita ang bagong mga pagbabago simula sa $3 $2",
        "rcshowhideminor": "$1 ang mga maliliit na pagbabago",
        "apisandbox-reset": "Hawiin",
        "apisandbox-examples": "Halimbawa",
        "apisandbox-results": "Kinalabasan",
+       "apisandbox-request-selectformat-label": "Pakitang inihinging-datos gamit ang:",
        "apisandbox-request-url-label": "Hilingin ang URL:",
        "apisandbox-request-time": "Oras ng paghiling: $1",
        "apisandbox-continue": "Ipagpatuloy",
        "feedback-useragent": "Ahente ng tagagamit:",
        "searchsuggest-search": "Maghanap",
        "searchsuggest-containing": "naglalaman ng ...",
-       "api-error-badaccess-groups": "Hindi ka pinapayagang makapagkarga ng mga talaksan papunta sa wiking ito.",
        "api-error-badtoken": "Panloob na kamalian: masamang kahalip.",
-       "api-error-copyuploaddisabled": "Ang pagkakarga ng URL ay hindi pinagagana sa tagapaghaing ito.",
-       "api-error-duplicate": "May {{PLURAL:$1|ibang talaksang|ibang ilang mga talaksang}} nasa wiki na na may katulad na nilalaman",
-       "api-error-duplicate-archive": "Nagkaroon {{PLURAL:$1|dati ng iba pang talaksan|dati ng mga ilang iba pang mga talaksan}} na umiiral na sa sityo na may katulad na nilalaman, ngunit {{PLURAL:$1|ito ay|ito ay mga}} nabura na.",
-       "api-error-empty-file": "Walang laman ang ipinasa mong talaksan.",
        "api-error-emptypage": "Lumilikha ng bago, hindi pinapayagan ang mga pahinang walang laman.",
-       "api-error-fetchfileerror": "Panloob na kamalian: may naganap na pagkakamali habang kinukuha ang talaksan.",
-       "api-error-fileexists-forbidden": "Isang talaksan na may pangalang \"$1\" ang umiiral na, at hindi maaaring patungan ng muling pagsusulat.",
-       "api-error-fileexists-shared-forbidden": "Isang talaksang may pangalang \"$1\" ang umiiral na sa loob ng repository ng pinagsasaluhang talaksan, at hindi maaaring patungan ng muling pagsusulat.",
-       "api-error-file-too-large": "Napakalaki ng talaksang ipinasa mo.",
-       "api-error-filename-tooshort": "Napakaiksi ng pangalan ng talaksan.",
-       "api-error-filetype-banned": "Ipinagbabawal ang ganitong uri ng talaksan.",
-       "api-error-filetype-banned-type": "Ang $1 {{PLURAL:$4|ay isang hindi pinapahintulutang uri ng talaksan|ay hindi pinapahintulutang mga uri ng talaksan}}. Ang pinapayagang {{PLURAL:$3|uri ng talaksan ay ang|mga uri ng talaksan ay ang mga}} $2.",
-       "api-error-filetype-missing": "Kulang ng karugtong ang talaksan.",
-       "api-error-hookaborted": "Ang pagbabagong sinubok mong gawin ay hindi itinuloy ng isang kawil ng dugtong.",
-       "api-error-http": "Panloob na kamalian: hindi makaugnay sa tagahain.",
-       "api-error-illegal-filename": "Hindi pinapayagan ang pangalan ng talaksan.",
-       "api-error-internal-error": "Panloob na kamalian: may naganap na kamalian habang pinoproseso ang pagkakarga mo sa wiki.",
-       "api-error-invalid-file-key": "Panloob na kamalian: hindi matagpuan ang talaksan sa loob ng pansamantalang taguan.",
-       "api-error-missingparam": "Panloob na kamalian: nawawala ang mga parametro ng kahilingan.",
-       "api-error-missingresult": "Panloob na kamalian: hindi matukoy kung nagtagumpay ang kopya.",
-       "api-error-mustbeloggedin": "Dapat na nakalagda ka upang makapagkarga ng mga talaksan.",
-       "api-error-mustbeposted": "Panloob na kamalian: ang kahilingan ay nangangailangan ng HTTP POST.",
-       "api-error-noimageinfo": "Nagtagumpay ang pagkakarga, subalit hindi nakapagbigay ng anumang kabatiran ang tagapaghain hinggil sa talaksan.",
-       "api-error-nomodule": "Panloob na kamalian: walang pangkat ng modyul na pangkarga.",
-       "api-error-ok-but-empty": "Panloob na kamalian: walang tugon mula sa tagapaghain.",
-       "api-error-overwrite": "Hindi pinapayagan ang pagsusulat sa ibabaw ng isang umiiral na talaksan.",
        "api-error-stashfailed": "Panloob na kamalian: nabigo ang tagapaghain na magtabi ng pansamantalang talaksan.",
-       "api-error-timeout": "Hindi tumugon ang tagapaghain sa loob ng inaasahang panahon.",
-       "api-error-unclassified": "Naganap ang isang hindi nalalamang kamalian",
-       "api-error-unknown-code": "Hindi malamang kamalian: \"$1\"",
-       "api-error-unknown-error": "Panloob na kamalian: may nangyaring kamalian habang sinusubok mong ikarga ang talaksan mo.",
        "api-error-unknown-warning": "Hindi nalalamang babala: $1",
        "api-error-unknownerror": "Hindi malamang kamalian: \"$1\".",
-       "api-error-uploaddisabled": "Hindi pinapagana ang pagkakargang paitaas sa wiking ito.",
-       "api-error-verification-error": "Maaaring sira ang talaksang ito, o may maling karugtong.",
        "duration-seconds": "$1 {{PLURAL:$1|segundo|mga segundo}}",
        "duration-minutes": "$1 {{PLURAL:$1|minuto|mga minuto}}",
        "duration-hours": "$1 {{PLURAL:$1|oras|mga oras}}",
        "special-characters-group-khmer": "Khmer",
        "mw-widgets-dateinput-placeholder-day": "TTTT-BB-AA",
        "mw-widgets-dateinput-placeholder-month": "TTTT-BB",
-       "randomrootpage": "Alin mang pinag-ugatang/pinagmulang pahina",
-       "edit-error-long": "Mga kamalian:"
+       "randomrootpage": "Alin mang pinag-ugatang/pinagmulang pahina"
 }
index 8a61fb5..673c030 100644 (file)
        "cancel": "Берытсконо",
        "mypage": "Бам",
        "mytalk": "Викиавтор сярысь вераськон",
-       "anontalk": "СÑ\8fÑ\80Ñ\8bÑ\81Ñ\8c Ð²ераськон",
+       "anontalk": "Ð\92ераськон",
        "navigation": "Навигация",
        "and": "&#32;но",
        "qbfind": "Утчан",
        "protectedinterface": "Та бам возе интерфейс текстэз та викилэн программной обеспечениезлы. Вандализмез палэнтон понна со утемын воштонъёслэсь.\nВань викиослы берыктэмъёсты ватсалляны яке вошъяны вылысь, тауна, MediaWiki локализацияя сайтэ выжелэ — [https://translatewiki.net/ translatewiki.net].",
        "editinginterface": "<strong>Сак луэ:</strong> Тӥ тупатӥськоды бамез, кудӥз возе программной обеспеченилэсь интерфейс текстсэ.\nТа бамез тупатон воштоз интерфейсэз возьматонэз мукет викиавторъёслы та викиын.",
        "namespaceprotected": "Тон дорын редактировать карыны бам ӧвӧл юаське <кужмо>$1</strong> инты нимъёс.",
-       "exception-nologin": "Тон эн тусбуяськыны сӧзнэтэз",
+       "exception-nologin": "Ӧд пыре системае",
        "logouttext": "<strong>Тӥ ужан сеансэз йылпумъяды.</strong>\n\nКуд-огез бамъёс возьматӥськыны на быгато озьы, тӥ авторизовать каремын на кадь. Талы пумит нюръяськон понна бушатэ браузерлэсь кэшсэ.",
        "welcomeuser": "Гажаса ӧтиськом, $1!",
        "welcomecreation-msg": "Тӥляд учётной записьты кылдытэмын.\nТӥ быгатӥськоды воштыны асьтэлэсь [[Special:Preferences|настройкаостэс]] {{SITENAME}} сайтлы, потэ ке.",
        "yourname": "Учётной записьлэн нимыз:",
        "userlogin-yourname": "Викиавтор ним",
        "userlogin-yourname-ph": "Гожтэ учётной записьтылэсь нимзэ",
-       "createacct-another-username-ph": "Ð\92ики-авÑ\82оÑ\80лÑ\8dн Ð½Ð¸Ð¼Ñ\8aÑ\91Ñ\81 Ð¿Ñ\8bÑ\80Ñ\82Ñ\8dмÑ\8bн",
+       "createacct-another-username-ph": "Ð\93ожÑ\82Ñ\8d Ñ\83Ñ\87Ñ\91Ñ\82ной Ð·Ð°Ð¿Ð¸Ñ\81Ñ\8cлÑ\8dÑ\81Ñ\8c Ð½Ð¸Ð¼Ð·Ñ\8d",
        "yourpassword": "Лушкемкыл:",
        "userlogin-yourpassword": "Лушкемкыл",
        "userlogin-yourpassword-ph": "Гожтэ асьтэлэсь парольдэс",
        "createacct-yourpassword-ph": "Гожтэ паролез",
-       "createacct-yourpasswordagain": "Ð\9fаÑ\80олÑ\8c Ñ\8eнмаÑ\82Ñ\8d",
+       "createacct-yourpasswordagain": "ЮнмаÑ\82Ñ\8d Ð¿Ð°Ñ\80олез",
        "createacct-yourpasswordagain-ph": "Гожтэ паролез эшшо одӥг пол",
        "userlogin-remembermypassword": "Кылем сӧзнэтэз",
        "cannotcreateaccount-title": "Учётной записьёсты кылдытыны уг луы",
        "userloginnocreate": "Пырыны",
        "logout": "Кошкыны",
        "userlogout": "Потыны",
-       "notloggedin": "Тон эн тусбуяськыны сӧзнэтэз",
+       "notloggedin": "Ӧд пыре системае",
        "userlogin-noaccount": "Ас учётной записьты ӧвӧл?",
        "userlogin-joinproject": "Проектэ пыриськоно",
        "nologin": "Учётной запись ӧвӧл? $1.",
        "nologinlink": "Учётной записез кылдытыны",
-       "createaccount": "Выль вики-авторлэн регистрациез",
+       "createaccount": "Выль викиавторлэн регистрациез",
        "gotaccountlink": "Пырелэ",
        "userlogin-resetpassword-link": "Тӥлесьтыд парольдэс куштыны?",
        "userlogin-helplink2": "Пыронъя юрттэт",
        "createacct-emailrequired": "Электрон почталэн адресэз",
-       "createacct-emailoptional": "Электронной почтаезлэн адресэз (необязательное)",
+       "createacct-emailoptional": "Электрон почталэн адресэз (одно ик ӧвӧл)",
        "createacct-email-ph": "Гожтэ асьтэлэн электрон почтадылэсь адрессэ",
-       "createaccountmail": "Ð\90дÑ\80еÑ\81 Ñ\8dлекÑ\82Ñ\80онной Ð¿Ð¾Ñ\87Ñ\82а Ð¾Ð³Ð´Ñ\8bÑ\80лÑ\8b ÐºÑ\83Ñ\82Ó¥ Ð²Ñ\8bлÑ\8bн Ð²Ð¾Ð·Ñ\8cмаÑ\82Ñ\8dм Ð¾Ð±Ñ\80азÑ\8aÑ\91Ñ\81Ñ\8bнÑ\8bз Ð½Ð¾ Ñ\81ооÑ\81лÑ\8dн Ñ\81лÑ\83Ñ\87айной Ñ\81генеÑ\80иÑ\80оваÑ\82Ñ\8c Ð¿Ð°Ñ\80олÑ\8c Ñ\8bÑ\81Ñ\82Ñ\8bнÑ\8b",
+       "createaccountmail": "ЭÑ\80каз Ð¼Ð°Ð»Ð¿Ð°Ñ\81Ñ\8cкÑ\8bÑ\82Ñ\8dк ÐºÑ\8bлдÑ\8bÑ\82Ñ\8bнÑ\8b Ð¾Ð³Ð´Ñ\8bÑ\80лÑ\8b Ð¿Ð°Ñ\80олез Ð½Ð¾ Ñ\8bÑ\81Ñ\82Ñ\8bнÑ\8b Ñ\81ое Ñ\8dлекÑ\82Ñ\80он Ð¿Ð¾Ñ\87Ñ\82алÑ\8dн Ð³Ð¾Ð¶Ñ\82Ñ\8dм Ð°Ð´Ñ\80еÑ\81аз",
        "createacct-submit": "Учётной записьтэс кылдытоно",
        "createacct-another-submit": "Учётной записез кылдытоно",
        "createacct-benefit-heading": "{{SITENAME}} — тӥ выллем адямиослэн валче ужамзы.",
        "loginlanguagelabel": "Кыл: $1",
        "pt-login": "Пырыны",
        "pt-login-button": "Пырыны",
-       "pt-createaccount": "Выль вики-авторлэн регистрациез",
+       "pt-createaccount": "Выль викиавторлэн регистрациез",
        "pt-userlogout": "Потыны",
        "oldpassword": "Вуж лушкемкыл:",
        "newpassword": "Выль лушкемкыл:",
        "blockedtext": "<strong>Тӥляд учётной записьты яке IP-адресты заблокировать каремын вал.</strong>\n\nБлокировкаез лэсьтӥз $1.\nПусъем мугез: <em>$2</em>.\n\n* Блокировка кутскиз: $8\n* Блокировка йылпумъяськоз: $6\n* Блокировкалэн ужпумез: $7\n\nТӥ блокировка сярысь вераськыны быгатӥськоды $1 яке котькин мукет [[{{MediaWiki:Grouppage-sysop}}|администратор]] доры герӟаськыса.\n[[Special:Preferences|Настройкаосады]] электрон почталэн ужась адресэз ӧвӧл дыръя, тӥ «Викиавторлы гожтэт» функциез уже кутыны уд быгатӥське, сое тӥленыды уже кутон дугдытэмын ӧвӧл ке.\nТӥляд али IP-адресты луэ $3, но блокировка идентификатор — #$5.\nТауна пыртэ вань та пыр-поч сведениосыз асьтэлэн куронъёсады.",
        "autoblockedtext": "Тӥляд IP-адресты автоматически заблокировать каремын вал, малы ке шуоно со кутӥськиз вал мукет викиавторен, кинзэ $1 заблокировать кариз.\nБлокировкалэн пусъем мугез:\n\n:<em>$2</em>\n\n* Блокировка кутскиз: $8\n* Блокировка йылпумъяськоз: $6\n* Блокировкалэн ужпумез: $7\n\nТӥ блокировка сярысь вераськыны быгатӥськоды $1 яке мукет [[{{MediaWiki:Grouppage-sysop}}|администраторъёс]] пӧлысь огез доры герӟаськыса.\n\nСак луэ, тӥ «Викиавторлы гожтэт» функциез уже кутыны уд быгатӥське [[Special:Preferences|асьтэлэн настройкаосады]] электрон почталэсь шонер адрессэ гожтытозь яке юнматытозь, либо блокировкады сыӵе амалэн гожтэтъёсыз ыстыны уг лэзьы ке.\n\nТӥляд али IP-адресты луэ $3, но блокировка идентификатор — #$5.\nТауна пыртэ вань та пыр-поч сведениосыз асьтэлэн куронъёсады.",
        "blockednoreason": "пуктэм муг ӧвӧл",
-       "whitelistedittext": "Тон ÐºÑ\83лÑ\8d $1 Ð±Ð°Ð¼ Ð²Ð¾Ñ\88Ñ\82он Ð¿Ð¾Ð½Ð½Ð°.",
-       "loginreqtitle": "Ð\90вÑ\82оÑ\80изаÑ\86иÑ\8f ÐºÑ\83лÑ\8d",
+       "whitelistedittext": "Ð\91амÑ\8aÑ\91Ñ\81Ñ\82Ñ\8b Ð²Ð¾Ñ\88Ñ\8aÑ\8fнÑ\8b Ð²Ñ\8bлÑ\8bÑ\81Ñ\8c $1 ÐºÑ\83лÑ\8d.",
+       "loginreqtitle": "СиÑ\81Ñ\82емае Ð¿Ñ\8bÑ\80оно",
        "loginreqlink": "пырыны",
-       "loginreqpagetext": "Тон ÐºÑ\83лÑ\8d $1-Ñ\8bÑ\81Ñ\8c, Ñ\81ое Ð¼Ñ\83кеÑ\82 Ð±Ð°Ð¼ÐµÐ· Ñ\83Ñ\87кÑ\8bнÑ\8b Ñ\88Ñ\83Ñ\8bÑ\81а.",
-       "newarticletext": "Тон бам ссылкаос вылэ выжыса, со кема уз улы.\nСоос мед кылдозы, текст бичась укноос, улазы интыяськемын (умой-умой см. [$1 бам справочной]).\nЯнгыш-а тон татын луысалыд ке, кнопказэ зӥбиз гинэ <strong>берлань</strong> асьтэлэсь браузеръёстэс.",
+       "loginreqpagetext": "Ð\9cÑ\83кеÑ\82 Ð±Ð°Ð¼Ñ\8aÑ\91Ñ\81Ñ\82Ñ\8b Ñ\83Ñ\87кÑ\8bнÑ\8b Ð²Ñ\8bлÑ\8bÑ\81Ñ\8c $1 ÐºÑ\83лÑ\8d.",
+       "newarticletext": "Тӥ чӧлсконэтӥ ортчиды баме, кудӥз ӧвӧл на.\nСое кылдытыны вылысь, печатлалэ текст улӥ возьматэм укное (пыр-почгес учке [$1 юрттэт бамын]).\nТӥ вуиды татчы янгыш луэмен ке, зӥбе тӥляд браузердылэсь <strong>берлань</strong> кнопказэ.",
        "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}}|шедьтыны со сярысь кыӵе ке ивор]] мукет бамъёсысь, яке <span class=\"plainlinks\">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} шедьтыны журналъёсысь гожъямъёсыз]</span>, нош та бамез кылдытыны тӥляд лэзёнды ӧвӧл.",
        "blocked-notice-logextract": "Та викиавтор али заблокировать каремын.\nБлокировкаосын журналысь берпум гожъям улӥ возьматэмын:",
        "template-protected": "(утемын)",
        "template-semiprotected": "(ӧжытак утемын)",
        "hiddencategories": "Та бам пыре {{PLURAL:$1|$1 ватэм категорие}}:",
-       "nocreatetext": "Та сайтлэн бамаз выль сюбегатэм луонлыкъёсын кылдытон.\nТон улыса, берлань вуэ быгатэ бам отредактировать, [[Special:UserLogin|тусбуяськыны книгае яке выль система кылдыто учётной]].",
+       "nocreatetext": "{{SITENAME}} сюбегомытӥз луонлыкез выль бамъёсты кылдытъяны.\nТӥ быгатӥськоды берытскыны но азьло кылдытэм бам тупатыны, [[Special:UserLogin|системае пырыны яке выль аккаунт кылдытыны]].",
        "nocreate-loggedin": "Выль бамъёсты кылдытъяны тӥляд лэзёнды ӧвӧл.",
        "permissionserrors": "Лэзён янгыш",
        "permissionserrorstext": "Тӥляд тае быдэстыны лэзёнды ӧвӧл та {{PLURAL:$1|1=муген|мугъёсын}} сэрен:",
        "recentchangeslinked-page": "Бамлэн нимыз:",
        "recentchangeslinked-to": "Мыддоринтыны: та бамез чӧлскись бамъёсыз воштонъёсыз возьматыны",
        "upload": "Файл поныны",
-       "uploadnologin": "Тон эн тусбуяськыны сӧзнэтэз",
-       "uploadnologintext": "Тон ÐºÑ\83лÑ\8d $1, Ð¼ÐµÐ´Ð°Ð· Ð·Ð°Ð³Ñ\80Ñ\83зка Ñ\84айл Ñ\81еÑ\80веÑ\80.",
+       "uploadnologin": "Ӧд пыре системае",
+       "uploadnologintext": "ФайлÑ\8aÑ\91Ñ\81Ñ\82Ñ\8b Ñ\81еÑ\80веÑ\80е Ð¿Ð¾Ð½Ñ\8bнÑ\8b Ð²Ñ\8bлÑ\8bÑ\81Ñ\8c $1 ÐºÑ\83лÑ\8d.",
        "filedesc": "Вакчияк описаниез",
-       "uploaddisabled": "Ð\97агÑ\80Ñ\83зка Ð°Ð»Ó¥Ð·Ñ\8b",
-       "copyuploaddisabled": "Ð\97агÑ\80Ñ\83зка URL disconnect.",
-       "uploaddisabledtext": "Ð\97агÑ\80Ñ\83зка Ñ\84айл disconnect.",
+       "uploaddisabled": "ФайлÑ\8aÑ\91Ñ\81Ñ\8bз Ð²Ð°Ñ\82Ñ\81ан Ñ\83г Ð»Ñ\8dзиÑ\81Ñ\8cкÑ\8b.",
+       "copyuploaddisabled": "ФайлÑ\8aÑ\91Ñ\81Ñ\8bз Ð²Ð°Ñ\82Ñ\81ан URL Ð¿Ñ\8bÑ\80 Ñ\83г Ð»Ñ\8dзиÑ\81Ñ\8cкÑ\8b.",
+       "uploaddisabledtext": "Файл Ð¿Ð¾Ð½Ñ\8bнÑ\8b Ð»Ñ\83онлÑ\8bк Ó§Ð²Ó§Ð».",
        "upload-dialog-button-cancel": "Берытсконо",
        "license-header": "Лицензия",
        "nolicense": "Ӧвӧл",
        "blockip": "{{GENDER:$1|Викиавторез}} заблокировать карыны",
        "blockip-legend": "Блокировка пыриськисьёс",
        "blockiptext": "Формазэ уже кутыса, кулэ луэмезъя мед заблокировать гожъян IP-адрес яке пыриськисьёслэн нимъёссы.\nТа понна гинэ но соя гинэ лэсьтэмын луыны быгатоз вандализм предотвращение с [[{{MediaWiki:Policy-url}}|правилоосты]].\nМугез возьматись улӥзы членъёсын (кылсярысь, куд-ог тодметъёссэ вандализм цитировать кароно бам).\nТӥ быгатӥськоды диапазонэз заблокировать IP-адрес, уже кутыны [https://en.wikipedia.org/wiki/Classless_Inter-Domain_Routing CIDR]-синтаксис. Максимально диапазонэз допустимый — /$1 протокол понна IPv4 но /$2 протокол понна IPv6.",
-       "ipbreason-dropdown": "* Блокировка мугез кабес\n** Полы информациез оскизы\n** Вордскем палэнэ бам\n** Спам-сайтъя педпал чӧлскон\n** Текстлэсь визьем ватсан/жуг-жаг\n** Кышкытлыклэсь, пыриськыны уйиськон\n** Злоупотребление кӧня ке книга учётной\n** Пыриськисьёслэн нимъёссы пыриськисьёс",
+       "ipbreason-dropdown": "*Блокировкаослэн огшоры мугъёссы\n** Ӧрекчась информациез ватсан\n** Бамъёслэсь текстсэс быдтон\n** Спам-чӧлсконъёс педпал сайтъёс вылэ\n** Валантэм/жаг текстэз бамъёсы ватсан\n** Викиавторъёсыз кышкатъян/ултӥяллян\n** Лэзёнтэм ужан трос аккаунтъёсын\n** Викиавторлэн ярантэм нимыз",
        "ipbsubmit": "Адресъёсын та заблокировать/пыриськисьёс",
        "ipboptions": "2 час:2 hours,1 нунал:1 day,3 нунал:3 days,1 арня:1 week,2 арня:2 weeks,1 толэзь:1 month,3 толэзь:3 months,6 толэзь:6 months,1 ар:1 year,пырак азелы:infinite",
        "ipb-blocklist-contribs": "{{GENDER:$1|$1}} гожтэмъёсы",
index 0addcb6..de19903 100644 (file)
        "apisandbox-sending-request": "Надсилання запиту API…",
        "apisandbox-loading-results": "Отримання результатів API…",
        "apisandbox-results-error": "Сталася помилка при завантаженні відповіді на запит API: $1.",
-       "apisandbox-request-params-json": "Параметри JSON:",
        "apisandbox-request-url-label": "URL-адреса запиту:",
        "apisandbox-request-time": "Час запиту: {{PLURAL:$1|$1 мс}}",
        "apisandbox-results-fixtoken": "Виправте токен і надішліть ще раз",
index 9a4f66e..9ca5fde 100644 (file)
        "nstab-template": "Batakan",
        "nstab-help": "Pakli hin pabulig",
        "nstab-category": "Kaarangay",
-       "mainpage-nstab": "Panguna nga pakli",
+       "mainpage-nstab": "Syahan nga Pakli",
        "nosuchaction": "Waray sugad nga buhat",
        "nosuchactiontext": "An buhat nga gin-ispisipikar han URL diri puyde.\nBangin la, nagsayop ka pagmakinilya han URL, o sinmunod hin sayop nga sumpay.\nBangin liwat ini usa nga bug dida han software nga ginagamit han {{SITENAME}}.",
        "nosuchspecialpage": "Waray sugad nga pinaurog nga pakli",
        "passwordreset-emaildisabled": "Mga mga higamit ha email in waray pinaandar hini nga wiki.",
        "passwordreset-username": "Agnay hiton gumaramit:",
        "passwordreset-domain": "Dominyo:",
-       "passwordreset-capture": "Kikitaon mo an resulta nga e-mail?",
-       "passwordreset-capture-help": "Kun imo igtsek ini nga kahon, an email (lakip an temporaryo nga tigaman-panakob) in igpapakita ha imo labot la han ginpadangat ha gumaramit.",
        "passwordreset-email": "E-mail adres:",
        "passwordreset-emailtitle": "Mga detalye han akawnt ha {{SITENAME}}",
        "passwordreset-emailtext-ip": "Mayda gumaramit (bangin hi ikaw, tikang han IP adres nga $1) nga naghangyo hin reset han imo tigaman-pansulod han {{SITENAME}} ($4). An nasunod nga gumaramit {{PLURAL:$3|nga akawnt|nga mga akawnt}} nahanungod hini nga email nga adres: \n\n$2\n\n{{PLURAL:$3|Iní nga temporaryo nga tigaman-pansulod|Iní nga mga temporaryo nga tigaman-pansulod}} ma-waray bali hin {{PLURAL:$5|usa ka adlaw|$5 nga mga adlaw}}.\nAngay ka sumakob ngan pumílì hin bag-o nga tigaman-pansulod ha yanâ.  Kun mayda lain nga naghatag hini nga hangyo, o kun nahinumdoman mo an imo orihinal nga tigaman-pansulod, ngan nadírì ka na pagbalyo hiní, puyde mo pasagdan ini nga sumat ngan magpadayon hin paggamit han imo daan nga tigaman-pansulod.",
        "searchprofile-advanced-tooltip": "Pamilnga ha mga nabatasan nga ngaran-lat'ang",
        "search-result-size": "$1 ({{PLURAL:$2|1 nga pulong|$2 nga mga pulong}})",
        "search-result-category-size": "{{PLURAL:$1|1 nga api|$1 nga mga api}} ({{PLURAL:$2|1 nga ubos-nga-kaarangay|$2 nga mga ubos-nga-kaarangay}}, {{PLURAL:$3| 1 nga fayl|$3 nga mga fayl}})",
-       "search-redirect": "(redirekta $1)",
+       "search-redirect": "(Ginredirekta tikang ha $1)",
        "search-section": "(bahin $1)",
        "search-category": "(kaarangay $1)",
        "search-suggest": "Buot sidngon mo ba: $1",
        "saveprefs": "Igtipig",
        "restoreprefs": "Igbalik an ngatanan ngada nga aada-nga-daan nga settings (ha ngatanan nga mga bahin)",
        "prefs-editing": "Ginliliwat",
-       "rows": "Mga rumbay pahigda:",
-       "columns": "Mga rumbay patindog:",
        "searchresultshead": "Bilnga",
        "stub-threshold-sample-link": "pananglitan",
        "stub-threshold-disabled": "Waray ginpagana",
        "userrights-reason": "Katadungan:",
        "userrights-no-interwiki": "\nDiri ka gintutugotan pagliwat han mga katungod han gumaramit ha iba nga mga wiki.",
        "userrights-nodatabase": "Waray kaaagii an Database $1 o diri ini aada ha lokal.",
-       "userrights-notallowed": "Waray nim pagtugot hin pagdugang o pagtanggal hin mga katungod han gumaramit.",
        "userrights-changeable-col": "Mga hugpo nga puydi mo labtan",
        "userrights-unchangeable-col": "Mga hugpo nga diri mo puydi labtan",
-       "userrights-removed-self": "Imo gintanggal an imo kalugaringon mga katungod. Tungod hito, diri kana makaka-access hinin nga pakli.",
        "group": "Hugpo:",
        "group-user": "Mga gumaramit",
        "group-autoconfirmed": "Mga gumaramit nga lugaring nakokonpirma",
        "right-userrights-interwiki": "Igliwat an mga katungod han gumaramit han mga gumaramit ha iba nga mga wiki",
        "right-siteadmin": "Igtrangka ngan igrangka an database",
        "right-sendemail": "Padad-i hin e-mail ngada ha iba nga mga gumaramit",
-       "right-passwordreset": "Pakit-a an mga password reset email",
        "right-deletechangetags": "Igpara an [[Special:Tags|tags]] tikang han database",
        "grant-generic": "mga katungod nga katitirok han \"$1\"",
        "grant-group-page-interaction": "Pakig-interact han mga pakli",
        "whatlinkshere-links": "← mga sumpay",
        "whatlinkshere-hideredirs": "$1 nga mga redirek",
        "whatlinkshere-hidetrans": "$1 nga mga transklusyon",
-       "whatlinkshere-hidelinks": "$1 an mga sumpay",
+       "whatlinkshere-hidelinks": "$1 nga mga sumpay",
        "whatlinkshere-hideimages": "$1 an mga sumpay han paypay",
        "whatlinkshere-filters": "Mga panara",
        "whatlinkshere-submit": "Kadto-a",
        "feedback-message": "Mensahe:",
        "feedback-subject": "Himangrawon:",
        "feedback-thanks-title": "Salamat!",
-       "searchsuggest-search": "Pamilnga",
+       "searchsuggest-search": "Bilnga ha {{SITENAME}}",
        "searchsuggest-containing": "nagsusulod. . .",
-       "api-error-badaccess-groups": "Diri ka gintutugotan pagkarga paigbaw ha dinhi nga wiki.",
        "api-error-badtoken": "Sayop ha sulod: Maraot nga token.",
-       "api-error-copyuploaddisabled": "Pagkarga paigbaw pinaagi han URL in diri mahihimo ha dinhi nga serbidor.",
-       "api-error-empty-file": "An paypay nga isinumite nimo in waray sulod.",
        "api-error-emptypage": "Naghihimo hin bag-o, diri gintutugotan an waray sulod nga mga pakli.",
-       "api-error-filename-tooshort": "An ngaran han paypay in halipot hin duro.",
-       "api-error-filetype-banned": "Diri gintutugotan ini nga klase nga paypay.",
-       "api-error-filetype-missing": "Ini nga ngaran han paypay in nawawad-an hin ekstensyon.",
-       "api-error-http": "Sayop ha sulod: Diri nakakasumpay ha serbidor.",
-       "api-error-illegal-filename": "Diri gintutugotan an ngaran-han-paypay.",
-       "api-error-mustbeloggedin": "Diri ka nakalog-in para makapagkarga-pasaka hin mga paypay.",
-       "api-error-mustbeposted": "Sayop ha sulod: Iton paalayon in nagkikinahanglan hin HTTP POST.",
-       "api-error-overwrite": "Pagsasapaw in aada nga paypay in diri gintutugotan.",
        "api-error-stashfailed": "Sayop ha sulod:  An serbidor in waray makatipig han temporaryo nga paypay.",
-       "api-error-timeout": "An serbidor in diri nabaton ha sulod han ginaasahan nga oras.",
-       "api-error-unclassified": "Nahitabo an waray kasabti nga sayop.",
-       "api-error-unknown-code": "Waray kasabti nga sayop: \"$1\".",
-       "api-error-unknown-error": "Sayop ha sulod: May-ada nagkasayop han pagkakarga paigbaw han imo paypay.",
        "api-error-unknown-warning": "Waray kasabti nga pahimatngon: \"$1\".",
        "api-error-unknownerror": "Waray kasabti nga sayop: \"$1\".",
-       "api-error-uploaddisabled": "Diri ginpapakarga paigbaw ha dinhi nga wiki.",
-       "api-error-verification-error": "Ini nga paypay in bangin naraot, o may-ada iba nga ekstensyon.",
        "duration-seconds": "$1 {{PLURAL:$1|segundo|mga segundo}}",
        "duration-minutes": "$1 {{PLURAL:$1|minuto|mga minuto}}",
        "duration-hours": "$1 {{PLURAL:$1|oras|mga oras}}",
index 10da157..03a882e 100644 (file)
        "previewnote": "<strong>请记住这只是预览。</strong>您的更改尚未保存!",
        "continue-editing": "前往编辑区",
        "previewconflict": "该预览反映了上面文字编辑区中的文字在你保存后的显示状况。",
-       "session_fail_preview": "对不起!由于会话数据丢失,我们无法处理您的编辑。\n\n您可能已经退出。<strong>请核实您是否仍在登录,并重试</strong>。\n如果仍然不能工作,尝试[[Special:UserLogout|退出]]并重新登录,并检查您的浏览器是否允许来自该网站的cookie。",
-       "session_fail_preview_html": "对不起!由于会话数据丢失,我们无法处理您的编辑,\n\n<em>因为{{SITENAME}}已启用原始HTML,为了预防JavaScript攻击,预览被隐藏。</em>\n\n<strong>如果该编辑尝试合法,请重试。</strong>\n如果仍然不能工作,尝试[[Special:UserLogout|退出]]并重新登录,并检查您的浏览器是否允许来自该网站的cookie。",
+       "session_fail_preview": "对不起!由于会话数据丢失,我们无法处理您的编辑。\n\n您可能已经退出。<strong>请核实您是否仍在登录,并重试</strong>。如果仍然不能工作,尝试[[Special:UserLogout|退出]]并重新登录,并检查您的浏览器是否允许来自该网站的cookie。",
+       "session_fail_preview_html": "对不起!由于会话数据丢失,我们无法处理您的编辑,\n\n<em>因为{{SITENAME}}已启用原始HTML,为了预防JavaScript攻击,预览被隐藏。</em>\n\n<strong>如果该编辑尝试合法,请重试。</strong>如果仍然不能工作,尝试[[Special:UserLogout|退出]]并重新登录,并检查您的浏览器是否允许来自该网站的cookie。",
        "token_suffix_mismatch": "<strong>由于您客户端中的编辑令牌毁损了一些标点符号字符,您的编辑已经被拒绝。</strong>\n此次编辑被拒绝以防止页面文本损坏。\n这种情况通常在您使用含有故障的网页式匿名代理服务的时候出现。",
        "edit_form_incomplete": "<strong>编辑表格的某些部分没有到达服务器,请检查您的编辑是否完整并重试。</strong>",
        "editing": "编辑“$1”",
        "youremail": "电子邮件:",
        "username": "{{GENDER:$1|用户名}}:",
        "prefs-memberingroups": "{{GENDER:$2|用户}}{{PLURAL:$1|组}}:",
+       "group-membership-link-with-expiry": "$1(直到$2)",
        "prefs-registration": "注册时间:",
        "yourrealname": "真实姓名:",
        "yourlanguage": "界面语言:",
        "userrights-nodatabase": "数据库$1不存在或并非为本地的。",
        "userrights-changeable-col": "您可以更改的用户组",
        "userrights-unchangeable-col": "您不能更改的用户组",
+       "userrights-expiry-current": "终止于$1",
+       "userrights-expiry-none": "不会终止",
+       "userrights-expiry": "终止时间:",
+       "userrights-expiry-existing": "现有的终止时间:$2 $3",
+       "userrights-expiry-othertime": "其它时间:",
+       "userrights-expiry-options": "1天:1 day,1周:1 week,1个月:1 month,3个月:3 months,6个月:6 months,1年:1 year",
+       "userrights-invalid-expiry": "组“$1”的终止时间无效。",
+       "userrights-expiry-in-past": "组“$1”的终止时间是在过去。",
        "userrights-conflict": "用户权限的更改存在冲突!请检查并确认您的更改。",
        "group": "用户组:",
        "group-user": "用户",
        "recentchanges-legend-plusminus": "(<em>±123</em>)",
        "recentchanges-submit": "显示",
        "rcfilters-activefilters": "活跃的过滤器",
+       "rcfilters-restore-default-filters": "恢复默认过滤器",
+       "rcfilters-clear-all-filters": "清空所有过滤器",
        "rcfilters-search-placeholder": "过滤器最近更改(浏览或开始输入)",
        "rcfilters-invalid-filter": "无效过滤器",
+       "rcfilters-empty-filter": "没有活跃的过滤器。已显示所有贡献。",
        "rcfilters-filterlist-title": "过滤器",
        "rcfilters-filterlist-noresults": "找不到过滤器",
        "rcfilters-filtergroup-registration": "用户注册",
        "fileexists": "已存在相同名称的文件,如果您无法确定您是否要改变它,请检查<strong>[[:$1]]</strong>。 [[$1|thumb]]",
        "filepageexists": "该文件的说明页面已经创建于<strong>[[:$1]]</strong>,但是目前没有名称为此的文件存在。您输入的摘要不会显示在说明页面上。要使你的摘要在那里显示,您需要手工编辑它。[[$1|thumb]]",
        "fileexists-extension": "一个相似名称的文件已经存在: [[$2|thumb]]\n* 上传文件的文件名:<strong>[[:$1]]</strong>\n* 现有文件的文件名:<strong>[[:$2]]</strong>\n请选择一个不同的名字。",
-       "fileexists-thumbnail-yes": "此文件可能是另一幅图像的缩小版本<em>(缩略图)</em>。 [[$1|thumb]]\n请仔细检查该文件<strong>[[:$1]]</strong>。\n如果被检查文件与原始大小的图像是同一幅图像,您无需上传多余的缩略图。",
+       "fileexists-thumbnail-yes": "此文件可能是另一幅图像的缩小版本<em>(缩略图)</em>。[[$1|thumb]]请仔细检查该文件<strong>[[:$1]]</strong>。如果被检查文件与原始大小的图像是同一幅图像,您无需上传多余的缩略图。",
        "file-thumbnail-no": "文件名以<strong>$1</strong>开始。它似乎是缩小的图像<em>(缩略图)</em>。如果您有完整分辨率的该图像,请上传它,否则请更改文件名。",
        "fileexists-forbidden": "已存在相同名称的文件,且不能覆盖;请返回并用一个新的名称来上传此文件。[[File:$1|thumb|center|$1]]",
        "fileexists-shared-forbidden": "共享文件库中存在该名称的文件。如果您仍想上传你的文件,请返回使用其他名称。[[File:$1|thumb|center|$1]]",
        "upload-form-label-own-work-message-generic-foreign": "我知道我正在上传此文件至一个共享的存储库。我确认我依据这里的服务条款和许可方针做此事。",
        "upload-form-label-not-own-work-message-generic-foreign": "如果您无法依据分享存储库的方针上传此文件,请关闭此对话框并尝试其他方法。",
        "upload-form-label-not-own-work-local-generic-foreign": "如果此文件可以依据他们的方针上传的话,您也可以尝试使用[[Special:Upload|{{SITENAME}}上的上传页面]]。",
-       "backend-fail-stream": "无法流传送文件$1。",
-       "backend-fail-backup": "无法备份文件$1。",
-       "backend-fail-notexists": "æ\9d¡ç\9b®$1不存在。",
-       "backend-fail-hashes": "æ¯\94è¾\83æ\97 æ³\95è\8e·å\8f\96æ\96\87件hashes",
-       "backend-fail-notsame": "$1已存在不同的文件。",
-       "backend-fail-invalidpath": "$1不是有效的存储路径。",
+       "backend-fail-stream": "无法流传送文件“$1”。",
+       "backend-fail-backup": "无法备份文件“$1”。",
+       "backend-fail-notexists": "æ\96\87件$1不存在。",
+       "backend-fail-hashes": "æ\97 æ³\95è\8e·å\8f\96æ\96\87件å\93\88å¸\8cç\94¨äº\8eæ¯\94è¾\83ã\80\82",
+       "backend-fail-notsame": "“$1”已存在不同的文件。",
+       "backend-fail-invalidpath": "“$1”不是有效的存储路径。",
        "backend-fail-delete": "无法删除文件“$1”。",
        "backend-fail-describe": "无法修改文件“$1”的元数据。",
-       "backend-fail-alreadyexists": "“$1”页面已存在",
-       "backend-fail-store": "无法在$2存储文件$1。",
-       "backend-fail-copy": "无法复制文件$1到$2。",
-       "backend-fail-move": "无法移动文件$1到$2。",
+       "backend-fail-alreadyexists": "“$1”文件已存在。",
+       "backend-fail-store": "无法在“$2”存储文件“$1”。",
+       "backend-fail-copy": "无法复制文件“$1”到“$2”。",
+       "backend-fail-move": "无法移动文件“$1”到“$2”。",
        "backend-fail-opentemp": "无法打开临时文件。",
        "backend-fail-writetemp": "无法写临时文件。",
-       "backend-fail-closetemp": "æ\97 æ³\95å\88\9b建临时文件。",
+       "backend-fail-closetemp": "æ\97 æ³\95å\85³é\97­临时文件。",
        "backend-fail-read": "找不到文件“$1”。",
-       "backend-fail-create": "无法写入文件 $1 。",
+       "backend-fail-create": "无法写入文件“$1”。",
        "backend-fail-maxsize": "无法写入文件“$1”,因为它大于$2字节。",
        "backend-fail-readonly": "“$1”存储后端目前在只读模式,因为:<em>$2</em>",
-       "backend-fail-synced": "文件\"$1\"在内部存储后端之中处于不一致状态",
+       "backend-fail-synced": "文件“$1”在内部存储后端之中处于不一致状态",
        "backend-fail-connect": "无法连接到存储后端“$1。",
        "backend-fail-internal": "存储后端“$1”发生了一个未知错误。",
        "backend-fail-contenttype": "无法判断文件的内容类型来储存于“$1”。",
        "apisandbox-sending-request": "正在发送API请求...",
        "apisandbox-loading-results": "正在接收API请求...",
        "apisandbox-results-error": "加载API查询响应时出错:$1。",
-       "apisandbox-request-params-json": "JSON参数:",
+       "apisandbox-request-selectformat-label": "显示请求数据为:",
+       "apisandbox-request-format-url-label": "URL查询字符串",
        "apisandbox-request-url-label": "请求的URL:",
+       "apisandbox-request-json-label": "请求JSON:",
        "apisandbox-request-time": "请求时间:{{PLURAL:$1|$1毫秒}}",
        "apisandbox-results-fixtoken": "改正令牌并重新提交",
        "apisandbox-results-fixtoken-fail": "检索“$1”令牌失败。",
        "emailccsubject": "您发送给$1的消息的副本:$2",
        "emailsent": "电子邮件已发送",
        "emailsenttext": "您的电子邮件已经发出。",
-       "emailuserfooter": "本电子邮件是通过{{SITENAME}}的“{{int:emailuser}}”功能被$1{{GENDER:$1|发送}}至{{GENDER:$2|$2}}的。{{GENDER:$2|您}}的电子邮件将直接发送至{{GENDER:$1|原始发送者}},并向{{GENDER:$1|其}}显示{{GENDER:$2|您}}的电子邮件地址。",
+       "emailuserfooter": "本电子邮件是通过{{SITENAME}}的“{{int:emailuser}}”功能被$1{{GENDER:$1|发送}}至{{GENDER:$2|$2}}的。如果{{GENDER:$2|您}}回复该电子邮件的话,{{GENDER:$2|您}}的电子邮件将直接发送至{{GENDER:$1|原始发送者}},并向{{GENDER:$1|其}}显示{{GENDER:$2|您}}的电子邮件地址。",
        "usermessage-summary": "留下系统消息。",
        "usermessage-editor": "系统信息编辑器",
        "watchlist": "监视列表",
        "import-nonewrevisions": "没有导入版本(所有都已存在或因错误跳过)。",
        "xml-error-string": "$1于行$2,列$3($4字节):$5",
        "import-upload": "上传XML数据",
-       "import-token-mismatch": "会话数据丢失。\n\n您可能已经退出。<strong>请核实您是否仍在登录,并重试</strong>。\n如果仍然不能工作,尝试[[Special:UserLogout|退出]]并重新登录,并检查您的浏览器是否允许来自该网站的cookie。",
+       "import-token-mismatch": "会话数据丢失。\n\n您可能已经退出。<strong>请核实您是否仍在登录,并重试</strong>。如果仍然不能工作,尝试[[Special:UserLogout|退出]]并重新登录,并检查您的浏览器是否允许来自该网站的cookie。",
        "import-invalid-interwiki": "不能从指定的wiki导入。",
        "import-error-edit": "页面“$1”未导入,因为您不被允许编辑它。",
        "import-error-create": "页面“$1”未导入,因为您不被允许创建它。",
        "previousdiff": "←上一编辑",
        "nextdiff": "下一编辑→",
        "mediawarning": "<strong>警告:</strong>该文件类型可能含有恶意代码。执行后您的系统可能受损。",
-       "imagemaxsize": "图像尺寸限制:<br />''(文件说明页面)''",
+       "imagemaxsize": "图像尺寸限制:<br /><em>(文件说明页面)</em>",
        "thumbsize": "缩略图尺寸:",
        "widthheightpage": "$1×$2,$3页",
        "file-info": "文件大小:$1,MIME类型:$2",
        "seconds": "$1秒",
        "minutes": "$1分",
        "hours": "$1小时",
-       "days": "$1天",
+       "days": "{{PLURAL:$1|$1天}}",
        "weeks": "$1周",
        "months": "$1个月",
        "years": "$1年",
        "logentry-tag-update-logentry": "$1在页面$3的日志记录$5中{{GENDER:$2|更新了}}标签({{PLURAL:$7|添加了}}$6;并{{PLURAL:$9|移除了}}$8)",
        "rightsnone": "(无)",
        "revdelete-summary": "编辑摘要",
+       "rightslogentry-temporary-group": "$1(临时,直到$2)",
        "feedback-adding": "正在添加反馈至页面...",
        "feedback-back": "返回",
        "feedback-bugcheck": "请检查本bug是否为[$1 已知bug]。",
        "expand_templates_generate_xml": "显示XML语法树",
        "expand_templates_generate_rawhtml": "显示原始HTML",
        "expand_templates_preview": "预览",
-       "expand_templates_preview_fail_html": "<em>因为{{SITENAME}}启用了Raw HTML并且丢失了会话数据,预览被隐藏以防止JavaScript攻击。</em>\n\n<strong>如果这是合法的预览尝试,请再次重试。</strong>\n如果仍然不能工作,尝试[[Special:UserLogout|退出]]并重新登录,并检查您的浏览器是否允许来自该网站的cookie。",
+       "expand_templates_preview_fail_html": "<em>因为{{SITENAME}}启用了Raw HTML并且丢失了会话数据,预览被隐藏以防止JavaScript攻击。</em>\n\n<strong>如果这是合法的预览尝试,请再次重试。</strong>如果仍然不能工作,尝试[[Special:UserLogout|退出]]并重新登录,并检查您的浏览器是否允许来自该网站的cookie。",
        "expand_templates_preview_fail_html_anon": "<em>因为{{SITENAME}}启用了Raw HTML并且丢失了会话数据,预览被隐藏以防止JavaScript攻击。</em>\n\n<strong>如果这是合法的预览尝试,请尝试[[Special:UserLogin|登录]]并重试。</strong>",
        "expand_templates_input_missing": "您需要提供至少一些输入文本。",
        "pagelanguage": "更改页面语言",
        "changecredentials": "更改凭据",
        "changecredentials-submit": "更改凭据",
        "changecredentials-invalidsubpage": "$1不是有效的凭据类型。",
-       "changecredentials-success": "您的证书已被更改。",
+       "changecredentials-success": "您的凭据已被更改。",
        "removecredentials": "移除凭据",
-       "removecredentials-submit": "移除证书",
+       "removecredentials-submit": "移除凭据",
        "removecredentials-invalidsubpage": "$1不是有效的凭据类型。",
        "removecredentials-success": "您的证书已被移除。",
        "credentialsform-provider": "凭据类型:",
index 7132ab6..e15367a 100644 (file)
        "rcfilters-filter-editsbyself-description": "您的編輯。",
        "rcfilters-filter-editsbyother-label": "其他人的編輯",
        "rcfilters-filter-editsbyother-description": "由其他使用者而非您所作的編輯。",
-       "rcfilters-filtergroup-userExpLevel": "使用者經驗等級",
+       "rcfilters-filtergroup-userExpLevel": "經驗等級 (僅限已註冊的使用者)",
        "rcfilters-filter-userExpLevel-newcomer-label": "新手",
-       "rcfilters-filter-userExpLevel-newcomer-description": "非常新的編輯者:編輯數低於 10 次,活躍低於 4 天。",
+       "rcfilters-filter-userExpLevel-newcomer-description": "編輯數低於 10 次,活躍低於 4 天。",
        "rcfilters-filter-userExpLevel-learner-label": "初學者",
        "rcfilters-filter-userExpLevel-learner-description": "活躍的天數以及編輯數比 '新手' 多,但比 '有經驗的使用者' 少。",
        "rcfilters-filter-userExpLevel-experienced-label": "有經驗的使用者",
        "apisandbox-sending-request": "傳送 API 請求中...",
        "apisandbox-loading-results": "接收 API 結果中...",
        "apisandbox-results-error": "讀取 API 查詢回應時發生錯誤:$1。",
-       "apisandbox-request-params-json": "JSON參數:",
        "apisandbox-request-url-label": "請求 URL:",
        "apisandbox-request-time": "請求時間:{{PLURAL:$1|$1 ms}}",
        "apisandbox-results-fixtoken": "更正密鑰並重新送出",
        "tags-edit-revision-legend": "加入或移除此標籤自{{PLURAL:$1|此修訂|全部 $1 筆修訂}}",
        "tags-edit-logentry-legend": "加入或移除此標籤自{{PLURAL:$1|此日誌項目|全部 $1 筆日誌項目}}",
        "tags-edit-existing-tags": "已存在的標籤:",
-       "tags-edit-existing-tags-none": "''無''",
+       "tags-edit-existing-tags-none": "<em>無</em>",
        "tags-edit-new-tags": "新標籤:",
        "tags-edit-add": "加入這些標籤:",
        "tags-edit-remove": "移除這些標籤:",
        "authmanager-authn-no-local-user": "提供的憑證沒有與任何在此 wiki 上的使用者相關聯。",
        "authmanager-authn-no-local-user-link": "提供的憑證有效但沒有與任何在此 wiki 上的使用者相關聯。請採用其他方式登入,或建立新使用者,您將會有選項可以連結您先前的憑證到新帳號。",
        "authmanager-authn-autocreate-failed": "自動建立本地帳號失敗:$1",
-       "authmanager-change-not-supported": "提供的證無法變更,因為尚無法使用。",
+       "authmanager-change-not-supported": "提供的證無法變更,因為尚無法使用。",
        "authmanager-create-disabled": "已關閉帳號自動建立。",
        "authmanager-create-from-login": "要建立您的帳號,請先填寫此欄位。",
        "authmanager-create-not-in-progress": "帳號建立尚未進行或連線階段資料已遺失,請重頭再開始。",
        "authpage-cannot-link-continue": "無法繼續帳號連結,您的連線階段似乎已逾時。",
        "cannotauth-not-allowed-title": "權限不足",
        "cannotauth-not-allowed": "您不被允許使用此頁面",
-       "changecredentials": "更改憑證",
-       "changecredentials-submit": "更改憑證",
+       "changecredentials": "變更認證",
+       "changecredentials-submit": "變更認證",
        "changecredentials-invalidsubpage": "$1 不是有效的憑証類型。",
-       "changecredentials-success": "已更改您的憑證。",
-       "removecredentials": "移除證",
-       "removecredentials-submit": "移除證",
+       "changecredentials-success": "已變更您的認證。",
+       "removecredentials": "移除證",
+       "removecredentials-submit": "移除證",
        "removecredentials-invalidsubpage": "$1 不是有效的憑証類型。",
        "removecredentials-success": "已移除您的憑證。",
-       "credentialsform-provider": "證類型:",
+       "credentialsform-provider": "證類型:",
        "credentialsform-account": "帳號名稱:",
        "cannotlink-no-provider-title": "沒有可連結的帳號",
        "cannotlink-no-provider": "沒有可連結的帳號。",
index dd5a3af..cb26337 100644 (file)
@@ -8,6 +8,8 @@
  *
  */
 
+$fallback = 'oc';
+
 $namespaceNames = [
        NS_MEDIA            => 'Media',
        NS_SPECIAL          => 'Especial',
@@ -158,6 +160,14 @@ $dateFormats = [
        'ymd both' => 'H:i, Y M j',
 ];
 
+$datePreferences = [
+       'default',
+       'dmy',
+       'ymd',
+       'ISO 8601',
+];
+$defaultDateFormat = 'dmy';
+
 $bookstoreList = [
        'Catàleg Col·lectiu de les Universitats de Catalunya' => 'http://ccuc.cbuc.es/cgi-bin/vtls.web.gateway?searchtype=control+numcard&searcharg=$1',
        'Totselsllibres.com' => 'http://www.totselsllibres.com/tel/publi/busquedaAvanzadaLibros.do?ISBN=$1',
index 1de22bd..1d9e0e5 100644 (file)
@@ -19,6 +19,8 @@
  * @author לערי ריינהארט
  */
 
+$fallback = 'ca';
+
 $bookstoreList = [
        'Amazon.fr' => 'https://www.amazon.fr/exec/obidos/ISBN=$1'
 ];
@@ -57,6 +59,8 @@ $namespaceAliases = [
        'Discussion_Imatge'    => NS_FILE_TALK,
 ];
 
+$namespaceGenderAliases = [];
+
 $specialPageAliases = [
        'Allmessages'               => [ 'Messatge_sistèma', 'Messatge_del_sistèma' ],
        'Allpages'                  => [ 'Totas_las_paginas' ],
index 3ee463e..8130978 100644 (file)
@@ -13,6 +13,8 @@
  * @author לערי ריינהארט
  */
 
+$fallback = 'bs, sr-el, hr';
+
 $namespaceNames = [
        NS_SPECIAL          => 'Posebno',
        NS_TALK             => 'Razgovor',
@@ -30,6 +32,23 @@ $namespaceNames = [
        NS_CATEGORY_TALK    => 'Razgovor_o_kategoriji',
 ];
 
+# Some dummy translations to prevent language fallback for now
+# @TODO: Check whether localising them is appropriate.
+$namespaceGenderAliases = [];
+$defaultDateFormat = 'dmy';
+$datePreferences = [
+       'default',
+       'dmy',
+       'ymd',
+       'ISO 8601',
+];
+$datePreferenceMigrationMap = [
+       'default',
+       'mdy',
+       'dmy',
+       'ymd'
+];
+
 $specialPageAliases = [
        'Activeusers'               => [ 'Aktivni_korisnici' ],
        'Allmessages'               => [ 'Sve_poruke' ],
diff --git a/maintenance/archives/patch-user_groups-ug_expiry.sql b/maintenance/archives/patch-user_groups-ug_expiry.sql
new file mode 100644 (file)
index 0000000..2ce2c9e
--- /dev/null
@@ -0,0 +1,7 @@
+-- Primary key and expiry column in user_groups table
+
+ALTER TABLE /*$wgDBprefix*/user_groups
+  DROP INDEX ug_user_group,
+  ADD PRIMARY KEY (ug_user, ug_group),
+  ADD COLUMN ug_expiry varbinary(14) NULL default NULL,
+  ADD INDEX ug_expiry (ug_expiry);
diff --git a/maintenance/manageJobs.php b/maintenance/manageJobs.php
new file mode 100644 (file)
index 0000000..9585ed8
--- /dev/null
@@ -0,0 +1,98 @@
+<?php
+/**
+ * Maintenance script that handles managing job queue admin tasks
+ *
+ * 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 Maintenance
+ * @author Aaron Schulz
+ */
+
+require_once __DIR__ . '/Maintenance.php';
+
+/**
+ * Maintenance script that handles managing job queue admin tasks (re-push, delete, ...)
+ *
+ * @ingroup Maintenance
+ */
+class ManageJobs extends Maintenance {
+       public function __construct() {
+               parent::__construct();
+               $this->addDescription( 'Perform administrative tasks on a job queue' );
+               $this->addOption( 'type', 'Job type', true, true );
+               $this->addOption( 'action', 'Queue operation ("delete", "repush-abandoned")', true, true );
+       }
+
+       public function execute() {
+               $type = $this->getOption( 'type' );
+               $action = $this->getOption( 'action' );
+
+               $group = JobQueueGroup::singleton();
+               $queue = $group->get( $type );
+
+               if ( $action === 'delete' ) {
+                       $this->delete( $queue );
+               } elseif ( $action === 'repush-abandoned' ) {
+                       $this->repushAbandoned( $queue );
+               } else {
+                       $this->error( "Invalid action '$action'.", 1 );
+               }
+       }
+
+       private function delete( JobQueue $queue ) {
+               $this->output( "Queue has {$queue->getSize()} job(s); deleting...\n" );
+               $queue->delete();
+               $this->output( "Done; current size is {$queue->getSize()} job(s).\n" );
+       }
+
+       private function repushAbandoned( JobQueue $queue ) {
+               $cache = ObjectCache::getInstance( CACHE_DB );
+               $key = $cache->makeGlobalKey( 'last-job-repush', $queue->getWiki(), $queue->getType() );
+
+               $now = wfTimestampNow();
+               $lastRepushTime = $cache->get( $key );
+               if ( $lastRepushTime === false ) {
+                       $lastRepushTime = wfTimestamp( TS_MW, 1 ); // include all jobs
+               }
+
+               $this->output( "Last re-push time: $lastRepushTime; current time: $now\n" );
+
+               $count = 0;
+               $skipped = 0;
+               foreach ( $queue->getAllAbandonedJobs() as $job ) {
+                       /** @var Job $job */
+                       if ( $job->getQueuedTimestamp() < $lastRepushTime ) {
+                               ++$skipped;
+                               continue; // already re-pushed in prior round
+                       }
+
+                       $queue->push( $job );
+                       ++$count;
+
+                       if ( ( $count % $this->mBatchSize ) == 0 ) {
+                               $queue->waitForBackups();
+                       }
+               }
+
+               $cache->set( $key, $now ); // next run will ignore these jobs
+
+               $this->output( "Re-pushed $count job(s) [$skipped skipped].\n" );
+       }
+}
+
+$maintClass = "ManageJobs";
+require_once RUN_MAINTENANCE_IF_MAIN;
diff --git a/maintenance/mssql/archives/patch-user_groups-ug_expiry.sql b/maintenance/mssql/archives/patch-user_groups-ug_expiry.sql
new file mode 100644 (file)
index 0000000..371d80b
--- /dev/null
@@ -0,0 +1,6 @@
+-- Primary key and expiry column in user_groups table
+
+DROP INDEX IF EXISTS /*i*/ug_user_group ON /*_*/user_groups;
+ALTER TABLE /*_*/tag_summary ADD CONSTRAINT pk_user_groups PRIMARY KEY(ug_user, ug_group);
+ALTER TABLE /*_*/tag_summary ADD ug_expiry varchar(14) DEFAULT NULL;
+CREATE INDEX /*i*/ug_expiry ON /*_*/user_groups(ug_expiry);
index ba1f752..1c633be 100644 (file)
@@ -64,9 +64,11 @@ INSERT INTO /*_*/mwuser (user_name) VALUES ('##Anonymous##');
 CREATE TABLE /*_*/user_groups (
    ug_user  INT     NOT NULL REFERENCES /*_*/mwuser(user_id) ON DELETE CASCADE,
    ug_group NVARCHAR(255) NOT NULL DEFAULT '',
+   ug_expiry varchar(14) DEFAULT NULL,
+   PRIMARY KEY(ug_user, ug_group)
 );
-CREATE UNIQUE clustered INDEX /*i*/ug_user_group ON /*_*/user_groups (ug_user, ug_group);
 CREATE INDEX /*i*/ug_group ON /*_*/user_groups(ug_group);
+CREATE INDEX /*i*/ug_expiry ON /*_*/user_groups(ug_expiry);
 
 -- Stores the groups the user has once belonged to.
 -- The user may still belong to these groups (check user_groups).
diff --git a/maintenance/oracle/archives/patch-user_groups-ug_expiry.sql b/maintenance/oracle/archives/patch-user_groups-ug_expiry.sql
new file mode 100644 (file)
index 0000000..d5376a3
--- /dev/null
@@ -0,0 +1,8 @@
+define mw_prefix='{$wgDBprefix}';
+
+ALTER TABLE &mw_prefix.user_groups ADD (
+ug_expiry TIMESTAMP(6) WITH TIME ZONE  NULL
+);
+DROP INDEX IF EXISTS &mw_prefix.user_groups_u01;
+ALTER TABLE &mw_prefix.user_groups ADD CONSTRAINT &mw_prefix.user_groups_pk PRIMARY KEY (ug_user,ug_group);
+CREATE INDEX &mw_prefix.user_groups_i02 ON &mw_prefix.user_groups (ug_expiry);
index edb3398..fc3c696 100644 (file)
@@ -33,11 +33,13 @@ INSERT INTO &mw_prefix.mwuser
 
 CREATE TABLE &mw_prefix.user_groups (
   ug_user   NUMBER      DEFAULT 0 NOT NULL,
-  ug_group  VARCHAR2(255)     NOT NULL
+  ug_group  VARCHAR2(255)     NOT NULL,
+  ug_expiry TIMESTAMP(6) WITH TIME ZONE NULL
 );
+ALTER TABLE &mw_prefix.user_groups ADD CONSTRAINT &mw_prefix.user_groups_pk PRIMARY KEY (ug_user,ug_group);
 ALTER TABLE &mw_prefix.user_groups ADD CONSTRAINT &mw_prefix.user_groups_fk1 FOREIGN KEY (ug_user) REFERENCES &mw_prefix.mwuser(user_id) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED;
-CREATE UNIQUE INDEX &mw_prefix.user_groups_u01 ON &mw_prefix.user_groups (ug_user,ug_group);
 CREATE INDEX &mw_prefix.user_groups_i01 ON &mw_prefix.user_groups (ug_group);
+CREATE INDEX &mw_prefix.user_groups_i02 ON &mw_prefix.user_groups (ug_expiry);
 
 CREATE TABLE &mw_prefix.user_former_groups (
   ufg_user   NUMBER      DEFAULT 0 NOT NULL,
index 61ad075..e19c447 100644 (file)
@@ -58,10 +58,13 @@ INSERT INTO mwuser
   VALUES (DEFAULT,'Anonymous','',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,now(),now());
 
 CREATE TABLE user_groups (
-  ug_user   INTEGER      NULL  REFERENCES mwuser(user_id) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED,
-  ug_group  TEXT     NOT NULL
+  ug_user    INTEGER          NULL  REFERENCES mwuser(user_id) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED,
+  ug_group   TEXT         NOT NULL,
+  ug_expiry  TIMESTAMPTZ  NULL,
+  PRIMARY KEY(ug_user, ug_group)
 );
-CREATE UNIQUE INDEX user_groups_unique ON user_groups (ug_user, ug_group);
+CREATE INDEX user_groups_group  ON user_groups (ug_group);
+CREATE INDEX user_groups_expiry ON user_groups (ug_expiry);
 
 CREATE TABLE user_former_groups (
   ufg_user   INTEGER      NULL  REFERENCES mwuser(user_id) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED,
index e7a4d06..fb24a1d 100644 (file)
@@ -29,6 +29,8 @@ require_once __DIR__ . '/Maintenance.php';
  * @ingroup Maintenance
  */
 class RefreshLinks extends Maintenance {
+       const REPORTING_INTERVAL = 100;
+
        /** @var int|bool */
        protected $namespace = false;
 
@@ -43,6 +45,8 @@ class RefreshLinks extends Maintenance {
                $this->addOption( 'dfn-chunk-size', 'Maximum number of existent IDs to check per ' .
                        'query, default 100000', false, true );
                $this->addOption( 'namespace', 'Only fix pages in this namespace', false, true );
+               $this->addOption( 'category', 'Only fix pages in this category', false, true );
+               $this->addOption( 'tracking-category', 'Only fix pages in this tracking category', false, true );
                $this->addArg( 'start', 'Page_id to start from, default 1', false );
                $this->setBatchSize( 100 );
        }
@@ -61,7 +65,15 @@ class RefreshLinks extends Maintenance {
                } else {
                        $this->namespace = (int)$ns;
                }
-               if ( !$this->hasOption( 'dfn-only' ) ) {
+               if ( ( $category = $this->getOption( 'category', false ) ) !== false ) {
+                       $title = Title::makeTitleSafe( NS_CATEGORY, $category );
+                       if ( !$title ) {
+                               $this->error( "'$category' is an invalid category name!\n", true );
+                       }
+                       $this->refreshCategory( $category );
+               } elseif ( ( $category = $this->getOption( 'tracking-category', false ) ) !== false ) {
+                       $this->refreshTrackingCategory( $category );
+               } elseif ( !$this->hasOption( 'dfn-only' ) ) {
                        $new = $this->getOption( 'new-only', false );
                        $redir = $this->getOption( 'redirects-only', false );
                        $oldRedir = $this->getOption( 'old-redirects-only', false );
@@ -89,7 +101,6 @@ class RefreshLinks extends Maintenance {
        private function doRefreshLinks( $start, $newOnly = false,
                $end = null, $redirectsOnly = false, $oldRedirectsOnly = false
        ) {
-               $reportingInterval = 100;
                $dbr = $this->getDB( DB_REPLICA, [ 'vslow' ] );
 
                if ( $start === null ) {
@@ -124,7 +135,7 @@ class RefreshLinks extends Maintenance {
                        $i = 0;
 
                        foreach ( $res as $row ) {
-                               if ( !( ++$i % $reportingInterval ) ) {
+                               if ( !( ++$i % self::REPORTING_INTERVAL ) ) {
                                        $this->output( "$i\n" );
                                        wfWaitForSlaves();
                                }
@@ -145,7 +156,7 @@ class RefreshLinks extends Maintenance {
 
                        $i = 0;
                        foreach ( $res as $row ) {
-                               if ( !( ++$i % $reportingInterval ) ) {
+                               if ( !( ++$i % self::REPORTING_INTERVAL ) ) {
                                        $this->output( "$i\n" );
                                        wfWaitForSlaves();
                                }
@@ -166,7 +177,7 @@ class RefreshLinks extends Maintenance {
 
                        for ( $id = $start; $id <= $end; $id++ ) {
 
-                               if ( !( $id % $reportingInterval ) ) {
+                               if ( !( $id % self::REPORTING_INTERVAL ) ) {
                                        $this->output( "$id\n" );
                                        wfWaitForSlaves();
                                }
@@ -179,7 +190,7 @@ class RefreshLinks extends Maintenance {
 
                                for ( $id = $start; $id <= $end; $id++ ) {
 
-                                       if ( !( $id % $reportingInterval ) ) {
+                                       if ( !( $id % self::REPORTING_INTERVAL ) ) {
                                                $this->output( "$id\n" );
                                                wfWaitForSlaves();
                                        }
@@ -379,6 +390,7 @@ class RefreshLinks extends Maintenance {
         * @param string $var Field name
         * @param mixed $start First value to include or null
         * @param mixed $end Last value to include or null
+        * @return string
         */
        private static function intervalCond( IDatabase $db, $var, $start, $end ) {
                if ( $start === null && $end === null ) {
@@ -391,6 +403,87 @@ class RefreshLinks extends Maintenance {
                        return "$var BETWEEN {$db->addQuotes( $start )} AND {$db->addQuotes( $end )}";
                }
        }
+
+       /**
+        * Refershes links for pages in a tracking category
+        *
+        * @param string $category Category key
+        */
+       private function refreshTrackingCategory( $category ) {
+               $cats = $this->getPossibleCategories( $category );
+
+               if ( !$cats ) {
+                       $this->error( "Tracking category '$category' is disabled\n" );
+                       // Output to stderr but don't bail out,
+               }
+
+               foreach ( $cats as $cat ) {
+                       $this->refreshCategory( $cat );
+               }
+       }
+
+       /**
+        * Refreshes links to a category
+        *
+        * @param Title $category
+        */
+       private function refreshCategory( Title $category ) {
+               $this->output( "Refreshing pages in category '{$category->getText()}'...\n" );
+
+               $dbr = $this->getDB( DB_REPLICA );
+               $conds = [
+                       'page_id=cl_from',
+                       'cl_to' => $category->getDBkey(),
+               ];
+               if ( $this->namespace !== false ) {
+                       $conds['page_namespace'] = $this->namespace;
+               }
+
+               $i = 0;
+               $timestamp = '';
+               $lastId = 0;
+               do {
+                       $finalConds = $conds;
+                       $timestamp = $dbr->addQuotes( $timestamp );
+                       $finalConds []=
+                               "(cl_timestamp > $timestamp OR (cl_timestamp = $timestamp AND cl_from > $lastId))";
+                       $res = $dbr->select( [ 'page', 'categorylinks' ],
+                               [ 'page_id', 'cl_timestamp' ],
+                               $finalConds,
+                               __METHOD__,
+                               [
+                                       'ORDER BY' => [ 'cl_timestamp', 'cl_from' ],
+                                       'LIMIT' => $this->mBatchSize,
+                               ]
+                       );
+
+                       foreach ( $res as $row ) {
+                               if ( !( ++$i % self::REPORTING_INTERVAL ) ) {
+                                       $this->output( "$i\n" );
+                                       wfWaitForSlaves();
+                               }
+                               $lastId = $row->page_id;
+                               $timestamp = $row->cl_timestamp;
+                               self::fixLinksFromArticle( $row->page_id );
+                       }
+
+               } while ( $res->numRows() == $this->mBatchSize );
+       }
+
+       /**
+        * Returns a list of possible categories for a given tracking category key
+        *
+        * @param string $categoryKey
+        * @return Title[]
+        */
+       private function getPossibleCategories( $categoryKey ) {
+               $trackingCategories = new TrackingCategories( $this->getConfig() );
+               $cats = $trackingCategories->getTrackingCategories();
+               if ( isset( $cats[$categoryKey] ) ) {
+                       return $cats[$categoryKey]['cats'];
+               }
+               $this->error( "Unknown tracking category {$categoryKey}\n", true );
+       }
 }
 
 $maintClass = 'RefreshLinks';
diff --git a/maintenance/sqlite/archives/patch-user_groups-ug_expiry.sql b/maintenance/sqlite/archives/patch-user_groups-ug_expiry.sql
new file mode 100644 (file)
index 0000000..7fc8941
--- /dev/null
@@ -0,0 +1,21 @@
+DROP TABLE IF EXISTS /*_*/user_groups_tmp;
+
+CREATE TABLE /*$wgDBprefix*/user_groups_tmp (
+  ug_user int unsigned NOT NULL default 0,
+  ug_group varbinary(255) NOT NULL default '',
+  ug_expiry varbinary(14) NULL default NULL,
+  PRIMARY KEY (ug_user, ug_group)
+);
+
+INSERT OR IGNORE INTO /*_*/user_groups_tmp (
+    ug_user, ug_group )
+    SELECT
+    ug_user, ug_group
+    FROM /*_*/user_groups;
+
+DROP TABLE /*_*/user_groups;
+
+ALTER TABLE /*_*/user_groups_tmp RENAME TO /*_*/user_groups;
+
+CREATE INDEX /*i*/ug_group ON /*_*/user_groups (ug_group);
+CREATE INDEX /*i*/ug_expiry ON /*_*/user_groups (ug_expiry);
index 2b6ea03..892f799 100644 (file)
@@ -160,11 +160,17 @@ CREATE TABLE /*_*/user_groups (
   -- with particular permissions. A user will have the combined
   -- permissions of any group they're explicitly in, plus
   -- the implicit '*' and 'user' groups.
-  ug_group varbinary(255) NOT NULL default ''
+  ug_group varbinary(255) NOT NULL default '',
+
+  -- Time at which the user group membership will expire. Set to
+  -- NULL for a non-expiring (infinite) membership.
+  ug_expiry varbinary(14) NULL default NULL,
+
+  PRIMARY KEY (ug_user, ug_group)
 ) /*$wgDBTableOptions*/;
 
-CREATE UNIQUE INDEX /*i*/ug_user_group ON /*_*/user_groups (ug_user,ug_group);
 CREATE INDEX /*i*/ug_group ON /*_*/user_groups (ug_group);
+CREATE INDEX /*i*/ug_expiry ON /*_*/user_groups (ug_expiry);
 
 -- Stores the groups the user has once belonged to.
 -- The user may still belong to these groups (check user_groups).
index 0c15dae..f14787f 100644 (file)
@@ -1354,13 +1354,6 @@ return [
                ],
                'targets' => [ 'desktop', 'mobile' ],
        ],
-       'mediawiki.reasonSuggest' => [
-               'scripts' => 'resources/src/mediawiki/mediawiki.reasonSuggest.js',
-               'dependencies' => [
-                       'jquery.suggestions',
-                       'mediawiki.api.messages'
-               ]
-       ],
        'mediawiki.userSuggest' => [
                'scripts' => 'resources/src/mediawiki/mediawiki.userSuggest.js',
                'dependencies' => [
@@ -1754,7 +1747,6 @@ return [
                        'resources/src/mediawiki.rcfilters/mw.rcfilters.init.js',
                ],
                'styles' => [
-                       'resources/src/mediawiki.rcfilters/styles/mw.rcfilters.less',
                        'resources/src/mediawiki.rcfilters/styles/mw.rcfilters.ui.FilterItemWidget.less',
                        'resources/src/mediawiki.rcfilters/styles/mw.rcfilters.ui.FilterGroupWidget.less',
                        'resources/src/mediawiki.rcfilters/styles/mw.rcfilters.ui.FiltersListWidget.less',
@@ -1763,8 +1755,11 @@ return [
                ],
                'messages' => [
                        'rcfilters-activefilters',
+                       'rcfilters-restore-default-filters',
+                       'rcfilters-clear-all-filters',
                        'rcfilters-search-placeholder',
                        'rcfilters-invalid-filter',
+                       'rcfilters-empty-filter',
                        'rcfilters-filterlist-title',
                        'rcfilters-filterlist-noresults',
                        'rcfilters-filtergroup-registration',
@@ -1807,6 +1802,7 @@ return [
                'dependencies' => [
                        'oojs-ui',
                        'mediawiki.Uri',
+                       'oojs-ui.styles.icons-moderation'
                ],
        ],
        'mediawiki.special' => [
@@ -1860,8 +1856,11 @@ return [
                        'apisandbox-sending-request',
                        'apisandbox-loading-results',
                        'apisandbox-results-error',
-                       'apisandbox-request-params-json',
+                       'apisandbox-request-selectformat-label',
+                       'apisandbox-request-format-url-label',
                        'apisandbox-request-url-label',
+                       'apisandbox-request-format-json-label',
+                       'apisandbox-request-json-label',
                        'apisandbox-request-time',
                        'apisandbox-results-fixtoken',
                        'apisandbox-results-fixtoken-fail',
@@ -1957,6 +1956,7 @@ return [
                ],
        ],
        'mediawiki.special.userrights' => [
+               'styles' => 'resources/src/mediawiki.special/mediawiki.special.userrights.css',
                'scripts' => 'resources/src/mediawiki.special/mediawiki.special.userrights.js',
                'dependencies' => [
                        'mediawiki.notification.convertmessagebox',
index 63db0ea..5dfb68d 100644 (file)
         * @cfg {string} [group] The group this item belongs to
         * @cfg {string} [label] The label for the filter
         * @cfg {string} [description] The description of the filter
-        * @cfg {boolean} [selected] Filter is selected
+        * @cfg {boolean} [active=true] The filter is active and affecting the result
+        * @cfg {string[]} [excludes=[]] A list of filter names this filter, if
+        *  selected, makes inactive.
+        * @cfg {boolean} [default] The default state of this filter
         */
        mw.rcfilters.dm.FilterItem = function MwRcfiltersDmFilterItem( name, config ) {
                config = config || {};
                this.group = config.group || '';
                this.label = config.label || this.name;
                this.description = config.description;
+               this.default = !!config.default;
 
-               this.selected = !!config.selected;
+               this.active = config.active === undefined ? true : !!config.active;
+               this.excludes = config.excludes || [];
+               this.selected = this.default;
        };
 
        /* Initialization */
                return this.description;
        };
 
+       /**
+        * Get the default value of this filter
+        *
+        * @return {boolean} Filter default
+        */
+       mw.rcfilters.dm.FilterItem.prototype.getDefault = function () {
+               return this.default;
+       };
+
        /**
         * Get the selected state of this filter
         *
                return this.selected;
        };
 
+       /**
+        * Check if this filter is active
+        *
+        * @return {boolean} Filter is active
+        */
+       mw.rcfilters.dm.FilterItem.prototype.isActive = function () {
+               return this.active;
+       };
+
+       /**
+        * Check if this filter has a list of excluded filters
+        *
+        * @return {boolean} Filter has a list of excluded filters
+        */
+       mw.rcfilters.dm.FilterItem.prototype.hasExcludedFilters = function () {
+               return !!this.excludes.length;
+       };
+
+       /**
+        * Get this filter's list of excluded filters
+        *
+        * @return {string[]} Array of excluded filter names
+        */
+       mw.rcfilters.dm.FilterItem.prototype.getExcludedFilters = function () {
+               return this.excludes;
+       };
+
+       /**
+        * Toggle the active state of the item
+        *
+        * @param {boolean} [isActive] Filter is active
+        * @fires update
+        */
+       mw.rcfilters.dm.FilterItem.prototype.toggleActive = function ( isActive ) {
+               isActive = isActive === undefined ? !this.active : isActive;
+
+               if ( this.active !== isActive ) {
+                       this.active = isActive;
+                       this.emit( 'update' );
+               }
+       };
+
        /**
         * Toggle the selected state of the item
         *
index 3217d0d..3f7fa53 100644 (file)
                OO.EmitterList.call( this );
 
                this.groups = {};
+               this.excludedByMap = {};
+               this.defaultParams = {};
+               this.defaultFiltersEmpty = null;
 
                // Events
-               this.aggregate( { update: 'itemUpdate' } );
+               this.aggregate( { update: 'filterItemUpdate' } );
+               this.connect( this, { filterItemUpdate: 'onFilterItemUpdate' } );
        };
 
        /* Initialization */
 
        /* Methods */
 
+       /**
+        * Respond to filter item change.
+        *
+        * @param {mw.rcfilters.dm.FilterItem} item Updated filter
+        * @fires itemUpdate
+        */
+       mw.rcfilters.dm.FiltersViewModel.prototype.onFilterItemUpdate = function ( item ) {
+               // Reapply the active state of filters
+               this.reapplyActiveFilters( item );
+
+               this.emit( 'itemUpdate', item );
+       };
+
+       /**
+        * Calculate the active state of the filters, based on selected filters in the group.
+        *
+        * @param {mw.rcfilters.dm.FilterItem} item Changed item
+        */
+       mw.rcfilters.dm.FiltersViewModel.prototype.reapplyActiveFilters = function ( item ) {
+               var selectedItemsCount,
+                       group = item.getGroup(),
+                       model = this;
+               if (
+                       !this.groups[ group ].exclusionType ||
+                       this.groups[ group ].exclusionType === 'default'
+               ) {
+                       // Default behavior
+                       // If any parameter is selected, but:
+                       // - If there are unselected items in the group, they are inactive
+                       // - If the entire group is selected, all are inactive
+
+                       // Check what's selected in the group
+                       selectedItemsCount = this.groups[ group ].filters.filter( function ( filterItem ) {
+                               return filterItem.isSelected();
+                       } ).length;
+
+                       this.groups[ group ].filters.forEach( function ( filterItem ) {
+                               filterItem.toggleActive(
+                                       selectedItemsCount > 0 ?
+                                               // If some items are selected
+                                               (
+                                                       selectedItemsCount === model.groups[ group ].filters.length ?
+                                                       // If **all** items are selected, they're all inactive
+                                                       false :
+                                                       // If not all are selected, then the selected are active
+                                                       // and the unselected are inactive
+                                                       filterItem.isSelected()
+                                               ) :
+                                               // No item is selected, everything is active
+                                               true
+                               );
+                       } );
+               } else if ( this.groups[ group ].exclusionType === 'explicit' ) {
+                       // Explicit behavior
+                       // - Go over the list of excluded filters to change their
+                       //   active states accordingly
+
+                       // For each item in the list, see if there are other selected
+                       // filters that also exclude it. If it does, it will still be
+                       // inactive.
+
+                       item.getExcludedFilters().forEach( function ( filterName ) {
+                               var filterItem = model.getItemByName( filterName );
+
+                               // Note to reduce confusion:
+                               // - item is the filter whose state changed and should exclude the other filters
+                               //   in its list of exclusions
+                               // - filterItem is the filter that is potentially being excluded by the current item
+                               // - anotherExcludingFilter is any other filter that excludes filterItem; we must check
+                               //   if that filter is selected, because if it is, we should not touch the excluded item
+                               if (
+                                       // Check if there are any filters (other than the current one)
+                                       // that also exclude the filterName
+                                       !model.excludedByMap[ filterName ].some( function ( anotherExcludingFilterName ) {
+                                               var anotherExcludingFilter = model.getItemByName( anotherExcludingFilterName );
+
+                                               return (
+                                                       anotherExcludingFilterName !== item.getName() &&
+                                                       anotherExcludingFilter.isSelected()
+                                               );
+                                       } )
+                               ) {
+                                       // Only change the state for filters that aren't
+                                       // also affected by other excluding selected filters
+                                       filterItem.toggleActive( !item.isSelected() );
+                               }
+                       } );
+               }
+       };
+
        /**
         * Set filters and preserve a group relationship based on
         * the definition given by an object
         * @param {Object} filters Filter group definition
         */
        mw.rcfilters.dm.FiltersViewModel.prototype.initializeFilters = function ( filters ) {
-               var i, filterItem,
+               var i, filterItem, selectedFilterNames, excludedFilters,
                        model = this,
-                       items = [];
+                       items = [],
+                       addToMap = function ( excludedFilters ) {
+                               excludedFilters.forEach( function ( filterName ) {
+                                       model.excludedByMap[ filterName ] = model.excludedByMap[ filterName ] || [];
+                                       model.excludedByMap[ filterName ].push( filterItem.getName() );
+                               } );
+                       };
 
                // Reset
                this.clearItems();
                this.groups = {};
+               this.excludedByMap = {};
 
                $.each( filters, function ( group, data ) {
                        model.groups[ group ] = model.groups[ group ] || {};
                        model.groups[ group ].title = data.title;
                        model.groups[ group ].type = data.type;
                        model.groups[ group ].separator = data.separator || '|';
+                       model.groups[ group ].exclusionType = data.exclusionType || 'default';
 
+                       selectedFilterNames = [];
                        for ( i = 0; i < data.filters.length; i++ ) {
+                               excludedFilters = data.filters[ i ].excludes || [];
+
                                filterItem = new mw.rcfilters.dm.FilterItem( data.filters[ i ].name, {
                                        group: group,
                                        label: data.filters[ i ].label,
                                        description: data.filters[ i ].description,
-                                       selected: data.filters[ i ].selected
+                                       selected: data.filters[ i ].selected,
+                                       excludes: excludedFilters,
+                                       'default': data.filters[ i ].default
                                } );
 
+                               // Map filters and what excludes them
+                               addToMap( excludedFilters );
+
+                               if ( data.type === 'send_unselected_if_any' ) {
+                                       // Store the default parameter state
+                                       // For this group type, parameter values are direct
+                                       model.defaultParams[ data.filters[ i ].name ] = Number( !!data.filters[ i ].default );
+                               } else if (
+                                       data.type === 'string_options' &&
+                                       data.filters[ i ].default
+                               ) {
+                                       selectedFilterNames.push( data.filters[ i ].name );
+                               }
+
                                model.groups[ group ].filters.push( filterItem );
                                items.push( filterItem );
                        }
+
+                       if ( data.type === 'string_options' ) {
+                               // Store the default parameter group state
+                               // For this group, the parameter is group name and value is the names
+                               // of selected items
+                               model.defaultParams[ group ] = model.sanitizeStringOptionGroup( group, selectedFilterNames ).join( model.groups[ group ].separator );
+                       }
                } );
 
                this.addItems( items );
+
                this.emit( 'initialize' );
        };
 
        };
 
        /**
-        * Get the current state of the filters
+        * Get the current state of the filters.
+        *
+        * Checks whether the filter group is active. This means at least one
+        * filter is selected, but not all filters are selected.
+        *
+        * @param {string} groupName Group name
+        * @return {boolean} Filter group is active
+        */
+       mw.rcfilters.dm.FiltersViewModel.prototype.isFilterGroupActive = function ( groupName ) {
+               var count = 0,
+                       filters = this.groups[ groupName ].filters;
+
+               filters.forEach( function ( filterItem ) {
+                       count += Number( filterItem.isSelected() );
+               } );
+
+               return (
+                       count > 0 &&
+                       count < filters.length
+               );
+       };
+
+       /**
+        * Update the representation of the parameters. These are the back-end
+        * parameters representing the filters, but they represent the given
+        * current state regardless of validity.
+        *
+        * This should only run after filters are already set.
+        *
+        * @param {Object} params Parameter state
+        */
+       mw.rcfilters.dm.FiltersViewModel.prototype.updateParameters = function ( params ) {
+               var model = this;
+
+               $.each( params, function ( name, value ) {
+                       // Only store the parameters that exist in the system
+                       if ( model.getItemByName( name ) ) {
+                               model.parameters[ name ] = value;
+                       }
+               } );
+       };
+
+       /**
+        * Get the value of a specific parameter
+        *
+        * @param {string} name Parameter name
+        * @return {number|string} Parameter value
+        */
+       mw.rcfilters.dm.FiltersViewModel.prototype.getParamValue = function ( name ) {
+               return this.parameters[ name ];
+       };
+
+       /**
+        * Get the current selected state of the filters
         *
-        * @return {Object} Filters current state
+        * @return {Object} Filters selected state
         */
-       mw.rcfilters.dm.FiltersViewModel.prototype.getState = function () {
+       mw.rcfilters.dm.FiltersViewModel.prototype.getSelectedState = function () {
                var i,
                        items = this.getItems(),
                        result = {};
                return result;
        };
 
+       /**
+        * Get the current full state of the filters
+        *
+        * @return {Object} Filters full state
+        */
+       mw.rcfilters.dm.FiltersViewModel.prototype.getFullState = function () {
+               var i,
+                       items = this.getItems(),
+                       result = {};
+
+               for ( i = 0; i < items.length; i++ ) {
+                       result[ items[ i ].getName() ] = {
+                               selected: items[ i ].isSelected(),
+                               active: items[ i ].isActive()
+                       };
+               }
+
+               return result;
+       };
+
+       /**
+        * Get the default parameters object
+        *
+        * @return {Object} Default parameter values
+        */
+       mw.rcfilters.dm.FiltersViewModel.prototype.getDefaultParams = function () {
+               return this.defaultParams;
+       };
+
+       /**
+        * Set all filter states to default values
+        */
+       mw.rcfilters.dm.FiltersViewModel.prototype.setFiltersToDefaults = function () {
+               var defaultFilterStates = this.getFiltersFromParameters( this.getDefaultParams() );
+
+               this.updateFilters( defaultFilterStates );
+       };
+
        /**
         * Analyze the groups and their filters and output an object representing
         * the state of the parameters they represent.
         *
+        * @param {Object} [filterGroups] An object defining the filter groups to
+        *  translate to parameters. Its structure must follow that of this.groups
+        *  see #getFilterGroups
         * @return {Object} Parameter state object
         */
-       mw.rcfilters.dm.FiltersViewModel.prototype.getParametersFromFilters = function () {
+       mw.rcfilters.dm.FiltersViewModel.prototype.getParametersFromFilters = function ( filterGroups ) {
                var i, filterItems, anySelected, values,
                        result = {},
-                       groupItems = this.getFilterGroups();
+                       groupItems = filterGroups || this.getFilterGroups();
 
                $.each( groupItems, function ( group, data ) {
                        filterItems = data.filters;
         * Remove duplicates and make sure to only use valid
         * values.
         *
+        * @private
         * @param {string} groupName Group name
         * @param {string[]} valueArray Array of values
         * @return {string[]} Array of valid values
                return result;
        };
 
+       /**
+        * Check whether the current filter state is set to all false.
+        *
+        * @return {boolean} Current filters are all empty
+        */
+       mw.rcfilters.dm.FiltersViewModel.prototype.areCurrentFiltersEmpty = function () {
+               var currFilters = this.getSelectedState();
+
+               return Object.keys( currFilters ).every( function ( filterName ) {
+                       return !currFilters[ filterName ];
+               } );
+       };
+
+       /**
+        * Check whether the default values of the filters are all false.
+        *
+        * @return {boolean} Default filters are all false
+        */
+       mw.rcfilters.dm.FiltersViewModel.prototype.areDefaultFiltersEmpty = function () {
+               var defaultFilters;
+
+               if ( this.defaultFiltersEmpty !== null ) {
+                       // We only need to do this test once,
+                       // because defaults are set once per session
+                       defaultFilters = this.getFiltersFromParameters();
+                       this.defaultFiltersEmpty = Object.keys( defaultFilters ).every( function ( filterName ) {
+                               return !defaultFilters[ filterName ];
+                       } );
+               }
+
+               return this.defaultFiltersEmpty;
+       };
+
        /**
         * This is the opposite of the #getParametersFromFilters method; this goes over
-        * the parameters and translates into a selected/unselected value in the filters.
+        * the given parameters and translates into a selected/unselected value in the filters.
         *
         * @param {Object} params Parameters query object
         * @return {Object} Filter state object
                var i, filterItem,
                        groupMap = {},
                        model = this,
-                       base = this.getParametersFromFilters(),
-                       // Start with current state
-                       result = this.getState();
+                       base = this.getDefaultParams(),
+                       result = {};
 
                params = $.extend( {}, base, params );
 
                } )[ 0 ];
        };
 
+       /**
+        * Set all filters to false or empty/all
+        * This is equivalent to display all.
+        */
+       mw.rcfilters.dm.FiltersViewModel.prototype.emptyAllFilters = function () {
+               var filters = {};
+
+               this.getItems().forEach( function ( filterItem ) {
+                       filters[ filterItem.getName() ] = false;
+               } );
+
+               // Update filters
+               this.updateFilters( filters );
+       };
+
        /**
         * Toggle selected state of items by their names
         *
index ea44b8b..28d9f28 100644 (file)
@@ -6,7 +6,6 @@
         */
        mw.rcfilters.Controller = function MwRcfiltersController( model ) {
                this.model = model;
-
                // TODO: When we are ready, update the URL when a filter is updated
                // this.model.connect( this, { itemUpdate: 'updateURL' } );
        };
        mw.rcfilters.Controller.prototype.initialize = function () {
                var uri = new mw.Uri();
 
+               // Give the model a full parameter state from which to
+               // update the filters
                this.model.updateFilters(
                        // Translate the url params to filter select states
                        this.model.getFiltersFromParameters( uri.query )
                );
        };
 
+       /**
+        * Reset to default filters
+        */
+       mw.rcfilters.Controller.prototype.resetToDefaults = function () {
+               this.model.setFiltersToDefaults();
+       };
+
+       /**
+        * Empty all selected filters
+        */
+       mw.rcfilters.Controller.prototype.emptyFilters = function () {
+               this.model.emptyAllFilters();
+       };
+
        /**
         * Update the state of a filter
         *
index 34df2f5..7b29d4b 100644 (file)
@@ -24,7 +24,7 @@
                                                        description: mw.msg( 'rcfilters-filter-registered-description' )
                                                },
                                                {
-                                                       name: 'hideanon',
+                                                       name: 'hideanons',
                                                        label: mw.msg( 'rcfilters-filter-unregistered-label' ),
                                                        description: mw.msg( 'rcfilters-filter-unregistered-description' )
                                                }
                                                {
                                                        name: 'hidebots',
                                                        label: mw.msg( 'rcfilters-filter-bots-label' ),
-                                                       description: mw.msg( 'rcfilters-filter-bots-description' )
+                                                       description: mw.msg( 'rcfilters-filter-bots-description' ),
+                                                       'default': true
                                                },
                                                {
                                                        name: 'hidehumans',
                                                        label: mw.msg( 'rcfilters-filter-humans-label' ),
-                                                       description: mw.msg( 'rcfilters-filter-humans-description' )
+                                                       description: mw.msg( 'rcfilters-filter-humans-description' ),
+                                                       'default': false
                                                }
                                        ]
                                },
                                                {
                                                        name: 'hidepageedits',
                                                        label: mw.msg( 'rcfilters-filter-pageedits-label' ),
-                                                       description: mw.msg( 'rcfilters-filter-pageedits-description' )
+                                                       description: mw.msg( 'rcfilters-filter-pageedits-description' ),
+                                                       'default': false
                                                },
                                                {
                                                        name: 'hidenewpages',
                                                        label: mw.msg( 'rcfilters-filter-newpages-label' ),
-                                                       description: mw.msg( 'rcfilters-filter-newpages-description' )
+                                                       description: mw.msg( 'rcfilters-filter-newpages-description' ),
+                                                       'default': false
                                                },
                                                {
                                                        name: 'hidecategorization',
                                                        label: mw.msg( 'rcfilters-filter-categorization-label' ),
-                                                       description: mw.msg( 'rcfilters-filter-categorization-description' )
+                                                       description: mw.msg( 'rcfilters-filter-categorization-description' ),
+                                                       'default': true
                                                },
                                                {
                                                        name: 'hidelog',
                                                        label: mw.msg( 'rcfilters-filter-logactions-label' ),
-                                                       description: mw.msg( 'rcfilters-filter-logactions-description' )
+                                                       description: mw.msg( 'rcfilters-filter-logactions-description' ),
+                                                       'default': false
                                                }
                                        ]
                                }
                        // Initialize values
                        controller.initialize();
 
+                       // HACK: Remove old-style filter links for filters handled by the widget
+                       // Ideally the widget would handle all filters and we'd just remove .rcshowhide entirely
+                       $( '.rcshowhide' ).children().each( function () {
+                               // HACK: Interpret the class name to get the filter name
+                               // This should really be set as a data attribute
+                               var i,
+                                       name = null,
+                                       // Some of the older browsers we support don't have .classList,
+                                       // so we have to interpret the class attribute manually.
+                                       classes = this.getAttribute( 'class' ).split( ' ' );
+                               for ( i = 0; i < classes.length; i++ ) {
+                                       if ( classes[ i ].substr( 0, 'rcshow'.length ) === 'rcshow' ) {
+                                               name = classes[ i ].substr( 'rcshow'.length );
+                                               break;
+                                       }
+                               }
+                               if ( name === null ) {
+                                       return;
+                               }
+                               if ( name === 'hidemine' ) {
+                                       // HACK: the span for hidemyself is called hidemine
+                                       name = 'hidemyself';
+                               }
+                               // This span corresponds to a filter that's in our model, so remove it
+                               if ( model.getItemByName( name ) ) {
+                                       // HACK: Remove the text node after the span.
+                                       // If there isn't one, we're at the end, so remove the text node before the span.
+                                       // This would be unnecessary if we added separators with CSS.
+                                       if ( this.nextSibling && this.nextSibling.nodeType === Node.TEXT_NODE ) {
+                                               this.parentNode.removeChild( this.nextSibling );
+                                       } else if ( this.previousSibling && this.previousSibling.nodeType === Node.TEXT_NODE ) {
+                                               this.parentNode.removeChild( this.previousSibling );
+                                       }
+                                       // Remove the span itself
+                                       this.parentNode.removeChild( this );
+                               }
+                       } );
+
                        $( '.rcoptions form' ).submit( function () {
                                var $form = $( this );
 
diff --git a/resources/src/mediawiki.rcfilters/styles/mw.rcfilters.less b/resources/src/mediawiki.rcfilters/styles/mw.rcfilters.less
deleted file mode 100644 (file)
index 7f71c0c..0000000
+++ /dev/null
@@ -1,5 +0,0 @@
-.rcshowhidemine {
-       // HACK: Hide this filter since it already appears in
-       // the new filter drop-down.
-       display: none;
-}
index 4e55add..2ff731c 100644 (file)
@@ -4,6 +4,31 @@
                color: #54595d;
        }
 
+       &-item-inactive {
+               opacity: 0.5;
+       }
+
+       &-emptyFilters {
+               color: #72777d;
+       }
+
+       &-table {
+               display: table;
+               width: 100%;
+       }
+
+       &-row {
+               display: table-row;
+       }
+
+       &-cell {
+               display: table-cell;
+
+               &:last-child {
+                       text-align: right;
+               }
+       }
+
        .oo-ui-capsuleItemWidget {
                color: #222;
                background-color: #fff;
index 70982d4..3723916 100644 (file)
@@ -8,6 +8,12 @@
                color: #555a5d;
        }
 
+       &-active {
+               .mw-rcfilters-ui-filterGroupWidget-title {
+                       font-weight: bold;
+               }
+       }
+
        &-invalid-notice {
                padding: 0.5em;
                font-style: italic;
index ad0b816..912e75c 100644 (file)
@@ -15,4 +15,8 @@
        .oo-ui-fieldLayout.oo-ui-fieldLayout-align-inline {
                margin-bottom: 0 !important;
        }
+
+       &-inactive {
+               opacity: 0.5;
+       }
 }
index a610e8f..f138d7e 100644 (file)
@@ -17,7 +17,7 @@
        &-popup {
                // We have to override OOUI's definition, which is set
                // on the inline style of the popup
-               margin-top: 2em !important;
+               margin-top: 2.4em !important;
                max-width: 650px;
        }
 
index db21542..c498ce9 100644 (file)
@@ -5,15 +5,19 @@
         * @extends OO.ui.CapsuleMultiselectWidget
         *
         * @constructor
+        * @param {mw.rcfilters.Controller} controller RCFilters controller
+        * @param {mw.rcfilters.dm.FiltersViewModel} model RCFilters view model
         * @param {OO.ui.InputWidget} filterInput A filter input that focuses the capsule widget
         * @param {Object} config Configuration object
         */
-       mw.rcfilters.ui.FilterCapsuleMultiselectWidget = function MwRcfiltersUiFilterCapsuleMultiselectWidget( filterInput, config ) {
+       mw.rcfilters.ui.FilterCapsuleMultiselectWidget = function MwRcfiltersUiFilterCapsuleMultiselectWidget( controller, model, filterInput, config ) {
                // Parent
                mw.rcfilters.ui.FilterCapsuleMultiselectWidget.parent.call( this, $.extend( {
                        $autoCloseIgnore: filterInput.$element
                }, config ) );
 
+               this.controller = controller;
+               this.model = model;
                this.filterInput = filterInput;
 
                this.$content.prepend(
                                .text( mw.msg( 'rcfilters-activefilters' ) )
                );
 
+               this.resetButton = new OO.ui.ButtonWidget( {
+                       icon: 'trash',
+                       framed: false,
+                       title: mw.msg( 'rcfilters-clear-all-filters' ),
+                       classes: [ 'mw-rcfilters-ui-filterCapsuleMultiselectWidget-resetButton' ]
+               } );
+
+               this.emptyFilterMessage = new OO.ui.LabelWidget( {
+                       label: mw.msg( 'rcfilters-empty-filter' ),
+                       classes: [ 'mw-rcfilters-ui-filterCapsuleMultiselectWidget-emptyFilters' ]
+               } );
+
                // Events
+               this.resetButton.connect( this, { click: 'onResetButtonClick' } );
+               this.model.connect( this, { itemUpdate: 'onModelItemUpdate' } );
                // Add the filterInput as trigger
                this.filterInput.$input
                        .on( 'focus', this.focus.bind( this ) );
 
+               // Initialize
+               this.$content.append( this.emptyFilterMessage.$element );
+               this.$handle
+                       .append(
+                               // The content and button should appear side by side regardless of how
+                               // wide the button is; the button also changes its width depending
+                               // on language and its state, so the safest way to present both side
+                               // by side is with a table layout
+                               $( '<div>' )
+                                       .addClass( 'mw-rcfilters-ui-filterCapsuleMultiselectWidget-table' )
+                                       .append(
+                                               $( '<div>' )
+                                                       .addClass( 'mw-rcfilters-ui-filterCapsuleMultiselectWidget-row' )
+                                                       .append(
+                                                               $( '<div>' )
+                                                                       .addClass( 'mw-rcfilters-ui-filterCapsuleMultiselectWidget-content' )
+                                                                       .addClass( 'mw-rcfilters-ui-filterCapsuleMultiselectWidget-cell' )
+                                                                       .append( this.$content ),
+                                                               $( '<div>' )
+                                                                       .addClass( 'mw-rcfilters-ui-filterCapsuleMultiselectWidget-cell' )
+                                                                       .append( this.resetButton.$element )
+                                                       )
+                                       )
+                       );
+
                this.$element
                        .addClass( 'mw-rcfilters-ui-filterCapsuleMultiselectWidget' );
+
+               this.reevaluateResetRestoreState();
        };
 
        /* Initialization */
 
        /* Methods */
 
+       mw.rcfilters.ui.FilterCapsuleMultiselectWidget.prototype.onModelItemUpdate = function () {
+               // Re-evaluate reset state
+               this.reevaluateResetRestoreState();
+       };
+
+       /**
+        * Respond to click event on the reset button
+        */
+       mw.rcfilters.ui.FilterCapsuleMultiselectWidget.prototype.onResetButtonClick = function () {
+               if ( this.model.areCurrentFiltersEmpty() ) {
+                       // Reset to default filters
+                       this.controller.resetToDefaults();
+               } else {
+                       // Reset to have no filters
+                       this.controller.emptyFilters();
+               }
+       };
+
+       /**
+        * Reevaluate the restore state for the widget between setting to defaults and clearing all filters
+        */
+       mw.rcfilters.ui.FilterCapsuleMultiselectWidget.prototype.reevaluateResetRestoreState = function () {
+               var defaultsAreEmpty = this.model.areDefaultFiltersEmpty(),
+                       currFiltersAreEmpty = this.model.areCurrentFiltersEmpty(),
+                       hideResetButton = currFiltersAreEmpty && defaultsAreEmpty;
+
+               this.resetButton.setIcon(
+                       currFiltersAreEmpty ? 'history' : 'trash'
+               );
+
+               this.resetButton.setLabel(
+                       currFiltersAreEmpty ? mw.msg( 'rcfilters-restore-default-filters' ) : ''
+               );
+
+               this.resetButton.toggle( !hideResetButton );
+               this.emptyFilterMessage.toggle( currFiltersAreEmpty );
+       };
+
        /**
         * @inheritdoc
         */
index 92ae4d1..2723258 100644 (file)
                return this.name;
        };
 
+       /**
+        * Toggle the active state of this group
+        *
+        * @param {boolean} isActive The group is active
+        */
+       mw.rcfilters.ui.FilterGroupWidget.prototype.toggleActiveState = function ( isActive ) {
+               this.$element.toggleClass( 'mw-rcfilters-ui-filterGroupWidget-active', isActive );
+       };
+
 }( mediaWiki, jQuery ) );
index b77df3b..f353051 100644 (file)
         */
        mw.rcfilters.ui.FilterItemWidget.prototype.onModelUpdate = function () {
                this.checkboxWidget.setSelected( this.model.isSelected() );
+
+               this.$element.toggleClass(
+                       'mw-rcfilters-ui-filterItemWidget-inactive',
+                       !this.model.isActive()
+               );
        };
 
        /**
index 3fcfc47..34cc240 100644 (file)
@@ -37,7 +37,7 @@
                        placeholder: mw.msg( 'rcfilters-search-placeholder' )
                } );
 
-               this.capsule = new mw.rcfilters.ui.FilterCapsuleMultiselectWidget( this.textInput, {
+               this.capsule = new mw.rcfilters.ui.FilterCapsuleMultiselectWidget( controller, this.model, this.textInput, {
                        popup: {
                                $content: this.filterPopup.$element,
                                classes: [ 'mw-rcfilters-ui-filterWrapperWidget-popup' ]
@@ -99,6 +99,7 @@
         */
        mw.rcfilters.ui.FilterWrapperWidget.prototype.onModelInitialize = function () {
                var items,
+                       wrapper = this,
                        filters = this.model.getItems();
 
                // Reset
                } );
 
                this.capsule.getMenu().addItems( items );
+
+               // Add defaults to capsule. We have to do this
+               // after we added to the capsule menu, since that's
+               // how the capsule multiselect widget knows which
+               // object to add
+               filters.forEach( function ( filterItem ) {
+                       if ( filterItem.isSelected() ) {
+                               wrapper.addCapsuleItemFromName( filterItem.getName() );
+                       }
+               } );
        };
 
        /**
         * @param {mw.rcfilters.dm.FilterItem} item Filter item that was updated
         */
        mw.rcfilters.ui.FilterWrapperWidget.prototype.onModelItemUpdate = function ( item ) {
+               var widget = this;
+
                if ( item.isSelected() ) {
-                       this.capsule.addItemsFromData( [ item.getName() ] );
+                       this.addCapsuleItemFromName( item.getName() );
                } else {
                        this.capsule.removeItemsFromData( [ item.getName() ] );
                }
+
+               // Toggle the active state of the group
+               this.filterPopup.getItems().forEach( function ( groupWidget ) {
+                       if ( groupWidget.getName() === item.getGroup() ) {
+                               groupWidget.toggleActiveState( widget.model.isFilterGroupActive( groupWidget.getName() ) );
+                       }
+               } );
+       };
+
+       /**
+        * Add a capsule item by its filter name
+        *
+        * @param {string} itemName Filter name
+        */
+       mw.rcfilters.ui.FilterWrapperWidget.prototype.addCapsuleItemFromName = function ( itemName ) {
+               var item = this.model.getItemByName( itemName );
+
+               this.capsule.addItemsFromData( [ itemName ] );
+
+               // Deal with active/inactive capsule filter items
+               this.capsule.getItemFromData( itemName ).$element
+                       .toggleClass( 'mw-rcfilters-ui-filterCapsuleMultiselectWidget-item-inactive', !item.isActive() );
        };
 }( mediaWiki ) );
index a62ef2e..87e209e 100644 (file)
@@ -123,7 +123,6 @@ table.toc td {
 /* Images */
 /* @noflip */div.floatright, table.floatright {
        margin: 0 0 .5em .5em;
-       border: 0;
 }
 
 div.floatright p {
@@ -132,7 +131,6 @@ div.floatright p {
 
 /* @noflip */div.floatleft, table.floatleft {
        margin: 0 .5em .5em 0;
-       border: 0;
 }
 
 div.floatleft p {
index 707a579..59a03f3 100644 (file)
@@ -87,7 +87,7 @@
 }
 
 .mw-apisandbox-textInputCode .oo-ui-inputWidget-input {
-       font-family: monospace, 'Courier';
+       font-family: monospace, monospace;
        font-size: 0.8125em;
        -moz-tab-size: 4;
        -o-tab-size: 4;
index fdb54cb..ad58583 100644 (file)
@@ -3,6 +3,7 @@
        'use strict';
        var ApiSandbox, Util, WidgetMethods, Validators,
                $content, panel, booklet, oldhash, windowManager, fullscreenButton,
+               formatDropdown,
                api = new mw.Api(),
                bookletPages = [],
                availableFormats = {},
                                .filter( '[href]:not([target])' )
                                .attr( 'target', '_blank' );
                        return $html;
+               },
+
+               /**
+                * Format a request and return a bunch of menu option widgets
+                *
+                * @param {Object} displayParams Query parameters, sanitized for display.
+                * @param {Object} rawParams Query parameters. You should probably use displayParams instead.
+                * @return {OO.ui.MenuOptionWidget[]} Each item's data should be an OO.ui.FieldLayout
+                */
+               formatRequest: function ( displayParams, rawParams ) {
+                       var jsonInput,
+                               items = [
+                                       new OO.ui.MenuOptionWidget( {
+                                               label: Util.parseMsg( 'apisandbox-request-format-url-label' ),
+                                               data: new OO.ui.FieldLayout(
+                                                       new OO.ui.TextInputWidget( {
+                                                               readOnly: true,
+                                                               value: mw.util.wikiScript( 'api' ) + '?' + $.param( displayParams )
+                                                       } ), {
+                                                               label: Util.parseMsg( 'apisandbox-request-url-label' )
+                                                       }
+                                               )
+                                       } ),
+                                       new OO.ui.MenuOptionWidget( {
+                                               label: Util.parseMsg( 'apisandbox-request-format-json-label' ),
+                                               data: new OO.ui.FieldLayout(
+                                                       jsonInput = new OO.ui.TextInputWidget( {
+                                                               classes: [ 'mw-apisandbox-textInputCode' ],
+                                                               readOnly: true,
+                                                               multiline: true,
+                                                               autosize: true,
+                                                               maxRows: 6,
+                                                               value: JSON.stringify( displayParams, null, '\t' )
+                                                       } ), {
+                                                               label: Util.parseMsg( 'apisandbox-request-json-label' )
+                                                       }
+                                               ).on( 'toggle', function ( visible ) {
+                                                       if ( visible ) {
+                                                               // Call updatePosition instead of adjustSize
+                                                               // because the latter has weird caching
+                                                               // behavior and the former bypasses it.
+                                                               jsonInput.updatePosition();
+                                                       }
+                                               } )
+                                       } )
+                               ];
+
+                       mw.hook( 'apisandbox.formatRequest' ).fire( items, displayParams, rawParams );
+
+                       return items;
+               },
+
+               /**
+                * Event handler for when formatDropdown's selection changes
+                */
+               onFormatDropdownChange: function () {
+                       var i,
+                               menu = formatDropdown.getMenu(),
+                               items = menu.getItems(),
+                               selectedField = menu.getSelectedItem() ? menu.getSelectedItem().getData() : null;
+
+                       for ( i = 0; i < items.length; i++ ) {
+                               items[ i ].getData().toggle( items[ i ].getData() === selectedField );
+                       }
                }
        };
 
                        }
 
                        $.when.apply( $, deferreds ).done( function () {
-                               var jsonInput;
+                               var formatItems, menu, selectedLabel;
 
                                if ( $.inArray( false, arguments ) !== -1 ) {
                                        windowManager.openWindow( 'errorAlert', {
 
                                query = $.param( displayParams );
 
+                               formatItems = Util.formatRequest( displayParams, params );
+
                                // Force a 'fm' format with wrappedhtml=1, if available
                                if ( params.format !== undefined ) {
                                        if ( availableFormats.hasOwnProperty( params.format + 'fm' ) ) {
                                page.setupOutlineItem = function () {
                                        this.outlineItem.setLabel( mw.message( 'apisandbox-results' ).text() );
                                };
+
+                               if ( !formatDropdown ) {
+                                       formatDropdown = new OO.ui.DropdownWidget( {
+                                               menu: { items: [] }
+                                       } );
+                                       formatDropdown.getMenu().on( 'choose', Util.onFormatDropdownChange );
+                               }
+
+                               menu = formatDropdown.getMenu();
+                               selectedLabel = menu.getSelectedItem() ? menu.getSelectedItem().getLabel() : '';
+                               if ( typeof selectedLabel !== 'string' ) {
+                                       selectedLabel = selectedLabel.text();
+                               }
+                               menu.clearItems().addItems( formatItems );
+                               menu.chooseItem( menu.getItemFromLabel( selectedLabel ) || menu.getFirstSelectableItem() );
+
+                               // Fire the event to update field visibilities
+                               Util.onFormatDropdownChange();
+
                                page.$element.empty()
                                        .append(
                                                new OO.ui.FieldLayout(
-                                                       new OO.ui.TextInputWidget( {
-                                                               readOnly: true,
-                                                               value: mw.util.wikiScript( 'api' ) + '?' + query
-                                                       } ), {
-                                                               label: Util.parseMsg( 'apisandbox-request-url-label' )
-                                                       }
-                                               ).$element,
-                                               new OO.ui.FieldLayout(
-                                                       jsonInput = new OO.ui.TextInputWidget( {
-                                                               classes: [ 'mw-apisandbox-textInputCode' ],
-                                                               readOnly: true,
-                                                               multiline: true,
-                                                               autosize: true,
-                                                               maxRows: 6,
-                                                               value: JSON.stringify( displayParams, null, '\t' )
-                                                       } ), {
-                                                               label: Util.parseMsg( 'apisandbox-request-params-json' )
+                                                       formatDropdown, {
+                                                               label: Util.parseMsg( 'apisandbox-request-selectformat-label' )
                                                        }
                                                ).$element,
+                                               $.map( formatItems, function ( item ) {
+                                                       return item.getData().$element;
+                                               } ),
                                                $result
                                        );
                                ApiSandbox.updateUI();
                                booklet.setPage( '|results|' );
 
-                               // Resize the multiline input once visible
-                               jsonInput.adjustSize();
-
                                location.href = oldhash = '#' + query;
 
                                api.post( params, {
diff --git a/resources/src/mediawiki.special/mediawiki.special.userrights.css b/resources/src/mediawiki.special/mediawiki.special.userrights.css
new file mode 100644 (file)
index 0000000..a4b4087
--- /dev/null
@@ -0,0 +1,12 @@
+/*!
+ * Styling for Special:UserRights
+ */
+.mw-userrights-nested {
+       margin-left: 1.2em;
+}
+
+.mw-userrights-nested span {
+       margin-left: 0.3em;
+       display: inline-block;
+       vertical-align: middle;
+}
index 0643988..3f864dd 100644 (file)
@@ -1,8 +1,18 @@
 /*!
  * JavaScript for Special:UserRights
  */
-( function () {
+( function ( $ ) {
        var convertmessagebox = require( 'mediawiki.notification.convertmessagebox' );
        // Replace successbox with notifications
        convertmessagebox();
-}() );
+
+       // Dynamically show/hide the expiry selection underneath each checkbox
+       $( '#mw-userrights-form2 input[type=checkbox]' ).on( 'change', function ( e ) {
+               $( '#mw-userrights-nested-' + e.target.id ).toggle( e.target.checked );
+       } ).trigger( 'change' );
+
+       // Also dynamically show/hide the "other time" input under each dropdown
+       $( '.mw-userrights-nested select' ).on( 'change', function ( e ) {
+               $( e.target.parentNode ).find( 'input' ).toggle( $( e.target ).val() === 'other' );
+       } ).trigger( 'change' );
+}( jQuery ) );
index 069fbbf..4930c4f 100644 (file)
@@ -26,7 +26,7 @@
                 * Any warnings returned by the API, including warnings about invalid option names or values,
                 * are ignored. However, do not rely on this behavior.
                 *
-                * If necessary, the options will be saved using several parallel API requests. Only one promise
+                * If necessary, the options will be saved using several sequential API requests. Only one promise
                 * is always returned that will be resolved when all requests complete.
                 *
                 * @param {Object} options Options as a `{ name: value, … }` object
@@ -35,7 +35,7 @@
                saveOptions: function ( options ) {
                        var name, value, bundleable,
                                grouped = [],
-                               deferreds = [];
+                               promise = $.Deferred().resolve();
 
                        for ( name in options ) {
                                value = options[ name ] === null ? null : String( options[ name ] );
                                        }
                                } else {
                                        if ( value !== null ) {
-                                               deferreds.push( this.postWithToken( 'csrf', {
-                                                       formatversion: 2,
-                                                       action: 'options',
-                                                       optionname: name,
-                                                       optionvalue: value
-                                               } ) );
+                                               promise = promise.then( function ( name, value ) {
+                                                       return this.postWithToken( 'csrf', {
+                                                               formatversion: 2,
+                                                               action: 'options',
+                                                               optionname: name,
+                                                               optionvalue: value
+                                                       } );
+                                               }.bind( this, name, value ) );
                                        } else {
                                                // Omitting value resets the option
-                                               deferreds.push( this.postWithToken( 'csrf', {
-                                                       formatversion: 2,
-                                                       action: 'options',
-                                                       optionname: name
-                                               } ) );
+                                               promise = promise.then( function ( name ) {
+                                                       return this.postWithToken( 'csrf', {
+                                                               formatversion: 2,
+                                                               action: 'options',
+                                                               optionname: name
+                                                       } );
+                                               }.bind( this, name ) );
                                        }
                                }
                        }
 
                        if ( grouped.length ) {
-                               deferreds.push( this.postWithToken( 'csrf', {
-                                       formatversion: 2,
-                                       action: 'options',
-                                       change: grouped
-                               } ) );
+                               promise = promise.then( function () {
+                                       return this.postWithToken( 'csrf', {
+                                               formatversion: 2,
+                                               action: 'options',
+                                               change: grouped
+                                       } );
+                               }.bind( this ) );
                        }
 
-                       return $.when.apply( $, deferreds );
+                       return promise;
                }
 
        } );
index 7a3fb0a..4849f5a 100644 (file)
@@ -71,7 +71,7 @@
                $notificationContent.appendTo( $notification );
 
                // Private state parameters, meant for internal use only
-               // autoHideSeconds: Number of seconds to wait before auto-hiding notifications.
+               // autoHideSeconds: String alias for number of seconds for timeout of auto-hiding notifications.
                // isOpen: Set to true after .start() is called to avoid double calls.
                //         Set back to false after .close() to avoid duplicating the close animation.
                // isPaused: false after .resume(), true after .pause(). Avoids duplicating or breaking the hide timeouts.
@@ -80,8 +80,9 @@
                //          to stop replacement of a tagged notification with another notification using the same message.
                // options: The options passed to the notification with a little sanitization. Used by various methods.
                // $notification: jQuery object containing the notification DOM node.
-               // Set hide delay
-               this.autoHideSeconds = options.autoHideSeconds;
+               this.autoHideSeconds = options.autoHideSeconds &&
+                       notification.autoHideSeconds[ options.autoHideSeconds ] ||
+                       notification.autoHideSeconds.short;
                this.isOpen = false;
                this.isPaused = true;
                this.message = message;
                 *   be hidden after shown. Or if it should persist.
                 *
                 * - autoHideSeconds:
-                *   Number of seconds to wait before auto-hiding notifications.
+                *   Key to #autoHideSeconds for number of seconds for timeout of auto-hide
+                *   notifications.
                 *
                 * - tag:
                 *   An optional string. When a notification is tagged only one message
                 */
                defaults: {
                        autoHide: true,
-                       autoHideSeconds: 5,
+                       autoHideSeconds: 'short',
                        tag: false,
                        title: undefined,
                        type: false
                },
 
+               /**
+                * @private
+                * @property {Object}
+                */
+               autoHideSeconds: {
+                       'short': 5,
+                       'long': 30
+               },
+
                /**
                 * @property {number}
-                * Maximum number of notifications to count down auto-hide timers for.
-                * Only the first #autoHideLimit notifications being displayed will
-                * auto-hide. Any notifications further down in the list will only start
-                * counting down to auto-hide after the first few messages have closed.
+                * Maximum number of simultaneous notifications to start auto-hide timers for.
+                * Only this number of notifications being displayed will be auto-hidden at one time.
+                * Any additional notifications in the list will only start counting their timeout for
+                * auto-hiding after the previous messages have been closed.
                 *
-                * This basically represents the number of notifications the user should
-                * be able to process in #autoHideSeconds time.
+                * This basically represents the minimal number of notifications the user should
+                * be able to process during the {@link #defaults default} #autoHideSeconds time.
                 */
                autoHideLimit: 3
        };
diff --git a/resources/src/mediawiki/mediawiki.reasonSuggest.js b/resources/src/mediawiki/mediawiki.reasonSuggest.js
deleted file mode 100644 (file)
index 71efdb0..0000000
+++ /dev/null
@@ -1,20 +0,0 @@
-/*!
-* Add autocomplete suggestions for action forms reasons.
-*/
-( function ( mw, $ ) {
-       $( function () {
-               var reasons = mw.config.get( 'reasons' );
-
-               // Add relevant suggestion
-               $( '#mwProtect-reason, #wpReason, #mw-input-wpReason-other' ).suggestions( {
-                       fetch: function () {
-                               var $this = $( this ), relevantSuggestions;
-                               relevantSuggestions = $.grep( reasons, function ( reason ) {
-                                       return ( reason.toLowerCase().indexOf( $this.val().toLowerCase() ) > -1 );
-                               } );
-                               $this.suggestions( 'suggestions', relevantSuggestions );
-                       },
-                       highlightInput: true
-               } );
-       } );
-}( mediaWiki, jQuery ) );
index c18f087..8922234 100644 (file)
@@ -11,11 +11,11 @@ Feature: Log in
 
   Scenario: Log in without entering credentials
     When I log in without entering credentials
-    Then error box should be visible
+    Then error message should be displayed for username
 
   Scenario: Log in without entering password
     When I log in without entering password
-    Then error box should be visible
+    Then error message should be displayed for password
 
   Scenario: Log in with incorrect username
     When I log in with incorrect username
index 9b35e99..14a2d76 100644 (file)
@@ -30,6 +30,14 @@ Then(/^error box should not be visible$/) do
   expect(on(LoginPage).error_message_element).not_to exist
 end
 
+Then(/^error message should be displayed for username$/) do
+  expect(on(LoginPage).username_error_element).to exist
+end
+
+Then(/^error message should be displayed for password$/) do
+  expect(on(LoginPage).password_error_element).to exist
+end
+
 Then(/^feedback should be (.+)$/) do |feedback|
   on(LoginPage) do |page|
     page.feedback_element.when_present.click
index 20e2744..de12aee 100644 (file)
@@ -4,5 +4,5 @@ class CreateAccountPage
   page_url '<%=params[:page_title]%>'
 
   button(:create_account, id: 'wpCreateaccount')
-  element(:error_message, css: 'div#userloginForm div.error')
+  element(:error_message, css: 'input#wpName2:required:invalid')
 end
index 4727318..c119b38 100644 (file)
@@ -10,10 +10,12 @@ class LoginPage
   button(:login, id: 'wpLoginAttempt')
   li(:logout, id: 'pt-logout')
   text_field(:password, id: 'wpPassword1')
+  element(:password_error, css: 'input#wpPassword1:required:invalid')
   a(:password_strength, text: 'password strength')
   a(:phishing, text: 'phishing')
   text_field(:username, id: 'wpName1')
   a(:username_displayed, title: /Your user page/)
+  element(:username_error, css: 'input#wpName1:required:invalid')
 
   def logged_in_as_element
     @browser.div(id: 'mw-content-text').p.b
index 281e1df..97e24b6 100644 (file)
@@ -974,7 +974,10 @@ class ParserTestRunner {
                        'wgEnableUploads' => self::getOptionValue( 'wgEnableUploads', $opts, true ),
                        'wgLanguageCode' => $langCode,
                        'wgRawHtml' => self::getOptionValue( 'wgRawHtml', $opts, false ),
-                       'wgNamespacesWithSubpages' => [ 0 => isset( $opts['subpage'] ) ],
+                       'wgNamespacesWithSubpages' => [
+                               0 => isset( $opts['subpage'] ),
+                               2 => isset( $opts['subpage'] ),
+                       ],
                        'wgMaxTocLevel' => $maxtoclevel,
                        'wgAllowExternalImages' => self::getOptionValue( 'wgAllowExternalImages', $opts, true ),
                        'wgThumbLimits' => [ self::getOptionValue( 'thumbsize', $opts, 180 ) ],
index 3853a12..46e1012 100644 (file)
@@ -933,6 +933,7 @@ Italics and bold: 5-quote opening sequence: (5,6)
 ###
 ### multiple quote sequences in a line
 ###
+
 !! test
 Italics and bold: multiple quote sequences: (2,4,2)
 !! options
@@ -942,8 +943,7 @@ parsoid=wt2html
 !! html/*
 <p><i>foo'<b>bar</b></i>
 </p>
-!!end
-
+!! end
 
 # same html as previous, but wikitext adjusted to match parsoid html2wt
 !! test
@@ -955,7 +955,6 @@ Italics and bold: multiple quote sequences: (2,4,2+3) w/ nowiki
 </p>
 !! end
 
-
 !! test
 Italics and bold: multiple quote sequences: (2,4,3)
 !! options
@@ -965,8 +964,7 @@ parsoid=wt2html
 !! html/*
 <p><i>foo'<b>bar</b></i>
 </p>
-!!end
-
+!! end
 
 # same html as previous, but wikitext adjusted to match parsoid html2wt
 !! test
@@ -978,7 +976,6 @@ Italics and bold: multiple quote sequences: (2,4,3+2) w/ nowiki
 </p>
 !! end
 
-
 !! test
 Italics and bold: multiple quote sequences: (2,4,4)
 !! options
@@ -988,8 +985,7 @@ parsoid=wt2html
 !! html/*
 <p><i>foo'<b>bar'</b></i>
 </p>
-!!end
-
+!! end
 
 # same html as previous, but wikitext adjusted to match parsoid html2wt
 !! test
@@ -1001,7 +997,6 @@ Italics and bold: multiple quote sequences: (2,4,4+2) w/ nowiki
 </p>
 !! end
 
-
 # The PHP parser strips the empty tags out for giggles; parsoid doesn't.
 !! test
 Italics and bold: multiple quote sequences: (3,4,2)
@@ -1015,24 +1010,21 @@ parsoid=wt2html
 !! html/parsoid
 <p><b>foo'</b>bar<i></i>
 </p>
-!!end
+!! end
 
 # same html as previous, but wikitext adjusted to match parsoid html2wt
 !! test
 Italics and bold: multiple quote sequences: (3,4,2+2) w/ nowiki
-!! options
-parsoid
 !! wikitext
-'''<nowiki>foo'</nowiki>'''bar''<nowiki/>''
+'''foo''''bar''<nowiki/>''
 !! html/php
 <p><b>foo'</b>bar
 </p>
 !! html/parsoid
-<p><b><span typeof="mw:Nowiki">foo'</span></b>bar<i></i>
+<p><b>foo'</b>bar<i></i>
 </p>
 !! end
 
-
 # The PHP parser strips the empty tags out for giggles; parsoid doesn't.
 !! test
 Italics and bold: multiple quote sequences: (3,4,3)
@@ -1046,18 +1038,18 @@ parsoid=wt2html
 !! html/parsoid
 <p><b>foo'</b>bar<b></b>
 </p>
-!!end
+!! end
 
 # same html as previous, but wikitext adjusted to match parsoid html2wt
 !! test
 Italics and bold: multiple quote sequences: (3,4,3+3) w/ nowiki
 !! wikitext
-'''<nowiki>foo'</nowiki>'''bar'''<nowiki/>'''
+'''foo''''bar'''<nowiki/>'''
 !! html/php
 <p><b>foo'</b>bar
 </p>
 !! html/parsoid
-<p><b><span typeof="mw:Nowiki">foo'</span></b>bar<b></b>
+<p><b>foo'</b>bar<b></b>
 </p>
 !! end
 
@@ -1135,7 +1127,7 @@ The ''[[Main Page]]'''s talk page.
 <p>The <i><a href="/wiki/Main_Page" title="Main Page">Main Page</a>'</i>s talk page.
 </p>
 !! html/parsoid
-<p>The <i><a rel="mw:WikiLink"  href="Main_Page" title="Main Page">Main Page</a>'</i>s talk page.</p>
+<p>The <i><a rel="mw:WikiLink" href="./Main_Page" title="Main Page">Main Page</a>'</i>s talk page.</p>
 !! end
 
 !! test
@@ -2861,9 +2853,9 @@ Parsoid: pipe in transclusion parameter
 !! html/php+tidy
 <p><a rel="nofollow" class="external free" href="http://foo.com/a%7Cb">http://foo.com/a%7Cb</a></p>
 !! html/parsoid
-<p><a rel="mw:ExtLink" href="http://foo.com/a|b" about="#mwt1"
+<p><a rel="mw:ExtLink" href="http://foo.com/a%7Cb" about="#mwt1"
 typeof="mw:Transclusion"
-data-mw='{"parts":[{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"http://foo.com/a&amp;#124;b"}},"i":0}}]}'>http://foo.com/a|b</a></p>
+data-mw='{"parts":[{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"http://foo.com/a&amp;#124;b"}},"i":0}}]}'>http://foo.com/a%7Cb</a></p>
 !! end
 
 !! test
@@ -4798,6 +4790,17 @@ news:'a'b''c''d e
 <p><a rel="mw:ExtLink" href="news:'a'b">news:'a'b</a><i>c</i>d e</p>
 !! end
 
+!! test
+External links: with entity
+!! wikitext
+[http://&#x20;www.librarieswithoutborders.org Libraries without borders]
+!! html/php
+<p><a rel="nofollow" class="external text" href="http://+www.librarieswithoutborders.org">Libraries without borders</a>
+</p>
+!! html/parsoid
+<p><a rel="mw:ExtLink" href="http://+www.librarieswithoutborders.org" data-parsoid='{"a":{"href":"http://+www.librarieswithoutborders.org"},"sa":{"href":"http://&amp;#x20;www.librarieswithoutborders.org"}}'>Libraries without borders</a></p>
+!! end
+
 !! test
 External links: Lone protocols are never linked (T105697)
 !! wikitext
@@ -5460,7 +5463,7 @@ http://example.com/index.php?foozoid&#x5B;&#x5D;=bar
 !! html/parsoid
 <p><a rel="mw:ExtLink" href="http://example.com/index.php?foozoid%5B%5D=bar">http://example.com/index.php?foozoid%5B%5D=bar</a></p>
 
-<p><a rel="mw:ExtLink" href="http://example.com/index.php?foozoid[]=bar">http://example.com/index.php?foozoid[]=bar</a></p>
+<p><a rel="mw:ExtLink" href="http://example.com/index.php?foozoid%5B%5D=bar" data-parsoid='{"stx":"url","a":{"href":"http://example.com/index.php?foozoid%5B%5D=bar"},"sa":{"href":"http://example.com/index.php?foozoid&amp;#x5B;&amp;#x5D;=bar"}}'>http://example.com/index.php?foozoid%5B%5D=bar</a></p>
 !! end
 
 !! test
@@ -6407,7 +6410,7 @@ parsoid=wt2html,html2html
 !! html/parsoid
 <table><tbody>
 <tr>
-<td data-parsoid='{"startTagSrc":"| ","attrSepSrc":"|","autoInsertedEnd":true}'><a rel="mw:ExtLink" href="ftp://|x||"></a>" onmouseover="alert(document.cookie)">test</td></tr></tbody></table>
+<td data-parsoid='{"startTagSrc":"| ","attrSepSrc":"|","autoInsertedEnd":true}'>[<a rel="mw:ExtLink" href="ftp://%7Cx" data-parsoid='{"stx":"url","a":{"href":"ftp://%7Cx"},"sa":{"href":"ftp://|x"}}'>ftp://%7Cx</a></td><td data-parsoid='{"stx_v":"row","autoInsertedEnd":true}'>]" onmouseover="alert(document.cookie)">test</td></tr></tbody></table>
 !! end
 
 !! test
@@ -7485,7 +7488,7 @@ Piped link with multiple pipe characters in link text
 <p><a href="/wiki/Main_Page" title="Main Page">|The|Main|Page|</a>
 </p>
 !! html/parsoid
-<p><a rel="mw:WikiLink" href="Main_Page" title="Main Page">|The|Main|Page|</a></p>
+<p><a rel="mw:WikiLink" href="./Main_Page" title="Main Page">|The|Main|Page|</a></p>
 !! end
 
 !! test
@@ -7841,6 +7844,17 @@ Link containing double-single-quotes '' (bug 4598)
 <p><a rel="mw:WikiLink" href="./Lista_d''e_paise_d''o_munno" title="Lista d''e paise d''o munno">Lista d''e paise d''o munno</a></p>
 !! end
 
+!! test
+Link containing double quotes and spaces
+!! wikitext
+[[Cool "Gator"]]
+!! html/php
+<p><a href="/index.php?title=Cool_%22Gator%22&amp;action=edit&amp;redlink=1" class="new" title="Cool &quot;Gator&quot; (page does not exist)">Cool "Gator"</a>
+</p>
+!! html/parsoid
+<p><a rel="mw:WikiLink" href="./Cool_%22Gator%22" title='Cool "Gator"'>Cool "Gator"</a></p>
+!! end
+
 !! test
 Link containing double-single-quotes '' in text (bug 4598 sanity check)
 !! wikitext
@@ -7849,7 +7863,7 @@ Some [[Link|pretty ''italics'' and stuff]]!
 <p>Some <a href="/index.php?title=Link&amp;action=edit&amp;redlink=1" class="new" title="Link (page does not exist)">pretty <i>italics</i> and stuff</a>!
 </p>
 !! html/parsoid
-<p>Some <a rel="mw:WikiLink" href="Link" title="Link">pretty <i>italics</i> and stuff</a>!</p>
+<p>Some <a rel="mw:WikiLink" href="./Link" title="Link">pretty <i>italics</i> and stuff</a>!</p>
 !! end
 
 !! test
@@ -7879,9 +7893,9 @@ Link with double quotes in title part (literal) and alternate part (interpreted)
 </p>
 !! html/parsoid
 <p><span class="mw-default-size" typeof="mw:Error mw:Image" data-mw='{"errors":[{"key":"missing-image","message":"This image does not exist."}]}'><a href="./File:Denys_Savchenko_''Pentecoste''.jpg"><img resource="./File:Denys_Savchenko_''Pentecoste''.jpg" src="./Special:FilePath/Denys_Savchenko_''Pentecoste''.jpg" height="220" width="220"/></a></span></p>
-<p><a rel="mw:WikiLink" href="''Pentecoste''" title="''Pentecoste''">''Pentecoste''</a></p>
-<p><a rel="mw:WikiLink" href="''Pentecoste''" title="''Pentecoste''">Pentecoste</a></p>
-<p><a rel="mw:WikiLink" href="''Pentecoste''" title="''Pentecoste''"><i>Pentecoste</i></a></p>
+<p><a rel="mw:WikiLink" href="./''Pentecoste''" title="''Pentecoste''">''Pentecoste''</a></p>
+<p><a rel="mw:WikiLink" href="./''Pentecoste''" title="''Pentecoste''">Pentecoste</a></p>
+<p><a rel="mw:WikiLink" href="./''Pentecoste''" title="''Pentecoste''"><i>Pentecoste</i></a></p>
 !! end
 
 !! test
@@ -7976,7 +7990,7 @@ Piped link to URL: [[http://www.example.com|an example URL]]
 <p>Piped link to URL: [<a rel="nofollow" class="external text" href="http://www.example.com%7Can">example URL</a>]
 </p>
 !! html/parsoid
-<p>Piped link to URL: [<a rel="mw:ExtLink" href="http://www.example.com|an">example URL</a>]</p>
+<p>Piped link to URL: [<a rel="mw:ExtLink" href="http://www.example.com%7Can" data-parsoid='{"a":{"href":"http://www.example.com%7Can"},"sa":{"href":"http://www.example.com|an"}}'>example URL</a>]</p>
 !! end
 
 !! test
@@ -8134,19 +8148,32 @@ Link with multiple ":" in a subpage-supporting namespace (bug 63636)
 Handle title parsing for subpages
 !! options
 title=[[/123123]]
+subpage
 !! wikitext
 123
+!! html/php
+<p>123
+</p>
 !! html/parsoid
 <p>123</p>
 !! end
 
-## FIXME: Add a working php section here
+!! article
+User:Test/123
+!! text
+test 123
+!! endarticle
+
 !! test
 Link to a subpage from a namespace other than main
 !! options
-title=[[User:test]]
+title=[[User:Test]]
+subpage
 !! wikitext
 [[/123]]
+!! html/php
+<p><a href="/wiki/User:Test/123" title="User:Test/123">/123</a>
+</p>
 !! html/parsoid
 <p><a rel="mw:WikiLink" href="./User:Test/123" title="User:Test/123" data-parsoid='{"stx":"simple","a":{"href":"./User:Test/123"},"sa":{"href":"/123"}}'>/123</a></p>
 !! end
@@ -8168,7 +8195,8 @@ parsoid=wt2html
 !! test
 Purely hash wikilink
 !! options
-title=[[User:test/123]]
+title=[[User:Test/123]]
+subpage
 !! wikitext
 [[#a|b]]
 !! html/php
@@ -8180,12 +8208,10 @@ title=[[User:test/123]]
 
 !! test
 1. Interaction of linktrail and template encapsulation
-!! options
-parsoid
 !! wikitext
 {{echo|[[Foo]]}}l
-!! html
-<p><a rel="mw:WikiLink" href="Foo" title="Foo" typeof="mw:Transclusion" data-mw='{"parts":[{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"[[Foo]]"}},"i":0}},"l"]}'>Fool</a></p>
+!! html/parsoid
+<p><a rel="mw:WikiLink" href="./Foo" title="Foo" typeof="mw:Transclusion" data-mw='{"parts":[{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"[[Foo]]"}},"i":0}},"l"]}'>Fool</a></p>
 !! end
 
 !! test
@@ -8255,7 +8281,7 @@ Parsoid link trail escaping
 !! options
 parsoid=html2wt,html2html
 !! html/parsoid
-<p><a rel="mw:WikiLink" href="Apple" title="Apple">apple</a>s</p>
+<p><a rel="mw:WikiLink" href="./Apple" title="Apple">apple</a>s</p>
 !! wikitext
 [[apple]]<nowiki/>s
 !! end
@@ -8266,7 +8292,7 @@ Parsoid link prefix escaping
 language=is
 parsoid=html2wt,html2html
 !! html/parsoid
-<p>Aðrir mótmælenda<a rel="mw:WikiLink" href="Söfnuður" title="Söfnuður">söfnuður</a></p>
+<p>Aðrir mótmælenda<a rel="mw:WikiLink" href="./Söfnuður" title="Söfnuður">söfnuður</a></p>
 !! wikitext
 Aðrir mótmælenda<nowiki/>[[söfnuður]]
 !! end
@@ -8291,12 +8317,10 @@ Parsoid-centric test: Whitespace in ext- and wiki-links should be preserved
 
 !! test
 Parsoid: Scoped parsing should handle mixed transclusions and plain text
-!! options
-parsoid
 !! wikitext
 [[Foo|{{echo|a}} b {{echo|c}}]]
-!! html
-<p><a rel="mw:WikiLink" href="Foo" title="Foo"><span about="#mwt2" typeof="mw:Transclusion" data-mw='{"parts":[{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"a"}},"i":0}}]}'>a</span> b <span about="#mwt3" typeof="mw:Transclusion" data-mw='{"parts":[{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"c"}},"i":0}}]}'>c</span></a></p>
+!! html/parsoid
+<p><a rel="mw:WikiLink" href="./Foo" title="Foo"><span about="#mwt2" typeof="mw:Transclusion" data-mw='{"parts":[{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"a"}},"i":0}}]}'>a</span> b <span about="#mwt3" typeof="mw:Transclusion" data-mw='{"parts":[{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"c"}},"i":0}}]}'>c</span></a></p>
 !! end
 
 !! test
@@ -8590,6 +8614,22 @@ Blah blah blah
 <link rel="mw:PageProp/Language" href="http://es.wikipedia.org/wiki/Foo_bar" />
 !! end
 
+!! test
+Escaping of interlanguage links
+!! wikitext
+Blah blah blah
+[[:es:Spanish]]
+[[ : zh : Chinese ]]
+!! html/php
+<p>Blah blah blah
+<a href="http://es.wikipedia.org/wiki/Spanish" class="extiw" title="es:Spanish">es:Spanish</a>
+<a href="http://zh.wikipedia.org/wiki/Chinese" class="extiw" title="zh:Chinese"> zh : Chinese </a>
+</p>
+!! html/parsoid
+<p><a rel="mw:ExtLink" href="http://es.wikipedia.org/wiki/Spanish" title="es:Spanish">es:Spanish</a>
+<a rel="mw:ExtLink" href="http://zh.wikipedia.org/wiki/Chinese" title="zh:Chinese"> zh : Chinese </a></p>
+!! end
+
 ## parsoid html2wt will normalize the space to _
 !! test
 Space and question mark encoding in interlanguage links (T95473)
@@ -8695,8 +8735,8 @@ Parsoid bug 53221: Wikilinks should be properly entity-escaped
 !! options
 parsoid={ "modes": ["html2wt"], "suppressErrors": true }
 !! html/parsoid
-<p>He&amp;nbsp;llo <a href="Foo" rel="mw:WikiLink">He&amp;nbsp;llo</a></p>
-<p>He&amp;nbsp;llo <a href="He&amp;nbsp;llo" rel="mw:WikiLink">He&amp;nbsp;llo</a></p>
+<p>He&amp;nbsp;llo <a href="./Foo" rel="mw:WikiLink">He&amp;nbsp;llo</a></p>
+<p>He&amp;nbsp;llo <a href="./He&amp;nbsp;llo" rel="mw:WikiLink">He&amp;nbsp;llo</a></p>
 !! wikitext
 He&amp;nbsp;llo [[Foo|He&amp;nbsp;llo]]
 
@@ -10345,7 +10385,7 @@ Parsoid: Page property magic word with magic word contents
 !! wikitext
 {{DISPLAYTITLE:''{{PAGENAME}}''}}
 !! html/parsoid
-<meta property="mw:PageProp/displaytitle" content="Main Page" about="#mwt2" typeof="mw:ExpandedAttrs" data-parsoid='{"src":"{{DISPLAYTITLE:&#39;&#39;{{PAGENAME}}&#39;&#39;}}"}' data-mw='{"attribs":[[{"txt":"content"},{"html":"&lt;i data-parsoid=&#39;{\"dsr\":[15,31,2,2]}&#39;>&lt;span about=\"#mwt1\" typeof=\"mw:Transclusion\" data-parsoid=&#39;{\"pi\":[[]],\"dsr\":[17,29,null,null]}&#39; data-mw=&#39;{\"parts\":[{\"template\":{\"target\":{\"wt\":\"PAGENAME\",\"function\":\"pagename\"},\"params\":{},\"i\":0}}]}&#39;>Main Page&lt;/span>&lt;/i>"}]]}'/>
+<meta property="mw:PageProp/displaytitle" content="Main Page" about="#mwt3" typeof="mw:ExpandedAttrs" data-parsoid='{"src":"{{DISPLAYTITLE:&#39;&#39;{{PAGENAME}}&#39;&#39;}}"}' data-mw='{"attribs":[[{"txt":"content"},{"html":"&lt;i data-parsoid=&#39;{\"dsr\":[15,31,2,2]}&#39;>&lt;span about=\"#mwt2\" typeof=\"mw:Transclusion\" data-parsoid=&#39;{\"pi\":[[]],\"dsr\":[17,29,null,null]}&#39; data-mw=&#39;{\"parts\":[{\"template\":{\"target\":{\"wt\":\"PAGENAME\",\"function\":\"pagename\"},\"params\":{},\"i\":0}}]}&#39;>Main Page&lt;/span>&lt;/i>"}]]}'/>
 !! end
 
 !! test
@@ -13561,7 +13601,7 @@ Image with link parameter, wiki target
 <p><a href="/wiki/Main_Page" title="Main Page"><img alt="Foobar.jpg" src="http://example.com/images/3/3a/Foobar.jpg" width="1941" height="220" /></a>
 </p>
 !! html/parsoid
-<p><span class="mw-default-size" typeof="mw:Image"><a href="Main_Page"><img resource="./File:Foobar.jpg" src="//example.com/images/3/3a/Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="220" width="1941"/></a></span></p>
+<p><span class="mw-default-size" typeof="mw:Image"><a href="./Main_Page"><img resource="./File:Foobar.jpg" src="//example.com/images/3/3a/Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="220" width="1941"/></a></span></p>
 !! end
 
 # parsoid bug 49293 (part 1)
@@ -13668,7 +13708,7 @@ Image with link parameter (wiki target) and unnamed parameter
 <p><a href="/wiki/Main_Page" title="Title"><img alt="Title" src="http://example.com/images/3/3a/Foobar.jpg" width="1941" height="220" /></a>
 </p>
 !! html/parsoid
-<p><span class="mw-default-size" typeof="mw:Image" data-mw='{"caption":"Title"}'><a href="Main_Page"><img resource="./File:Foobar.jpg" src="//example.com/images/3/3a/Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="220" width="1941"/></a></span></p>
+<p><span class="mw-default-size" typeof="mw:Image" data-mw='{"caption":"Title"}'><a href="./Main_Page"><img resource="./File:Foobar.jpg" src="//example.com/images/3/3a/Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="220" width="1941"/></a></span></p>
 !! end
 
 !! test
@@ -13720,7 +13760,7 @@ parsoid=wt2html,wt2wt,html2html
 <div class="thumb tright"><div class="thumbinner" style="width:137px;"><a href="/wiki/Main_Page" title="Main Page"><img alt="" src="http://example.com/images/e/ea/Thumb.png" width="135" height="135" class="thumbimage" /></a>  <div class="thumbcaption"><div class="magnify"><a href="/wiki/File:Foobar.jpg" class="internal" title="Enlarge"></a></div>Title</div></div></div>
 
 !! html/parsoid
-<figure class="mw-default-size" typeof="mw:Image/Thumb" data-mw='{"thumb":"Thumb.png"}'><a href="Main_Page"><img resource="./File:Foobar.jpg" src="//example.com/images/e/ea/Thumb.png" data-file-width="135" data-file-height="135" data-file-type="bitmap" height="135" width="135"/></a><figcaption>Title</figcaption></figure>
+<figure class="mw-default-size" typeof="mw:Image/Thumb" data-mw='{"thumb":"Thumb.png"}'><a href="./Main_Page"><img resource="./File:Foobar.jpg" src="//example.com/images/e/ea/Thumb.png" data-file-width="135" data-file-height="135" data-file-type="bitmap" height="135" width="135"/></a><figcaption>Title</figcaption></figure>
 !! end
 
 !! test
@@ -13762,7 +13802,7 @@ parsoid=wt2html,wt2wt,html2html
 <div class="thumb tright"><div class="thumbinner" style="width:137px;"><a href="/wiki/Main_Page" title="Main Page"><img alt="alttext" src="http://example.com/images/e/ea/Thumb.png" width="135" height="135" class="thumbimage" /></a>  <div class="thumbcaption"><div class="magnify"><a href="/wiki/File:Foobar.jpg" class="internal" title="Enlarge"></a></div>Title</div></div></div>
 
 !! html/parsoid
-<figure class="mw-default-size" typeof="mw:Image/Thumb" data-mw='{"thumb":"Thumb.png"}'><a href="Main_Page"><img alt="alttext" resource="./File:Foobar.jpg" src="//example.com/images/e/ea/Thumb.png" data-file-width="135" data-file-height="135" data-file-type="bitmap" height="135" width="135"/></a><figcaption>Title</figcaption></figure>
+<figure class="mw-default-size" typeof="mw:Image/Thumb" data-mw='{"thumb":"Thumb.png"}'><a href="./Main_Page"><img alt="alttext" resource="./File:Foobar.jpg" src="//example.com/images/e/ea/Thumb.png" data-file-width="135" data-file-height="135" data-file-type="bitmap" height="135" width="135"/></a><figcaption>Title</figcaption></figure>
 !! end
 
 !! test
@@ -13775,7 +13815,7 @@ parsoid=wt2html,wt2wt,html2html
 <div class="thumb tleft"><div class="thumbinner" style="width:1943px;"><a href="/wiki/File:Foobar.jpg" class="image"><img alt="" src="http://example.com/images/3/3a/Foobar.jpg" width="1941" height="220" class="thumbimage" /></a>  <div class="thumbcaption">This is a test image <a href="/wiki/Main_Page" title="Main Page">Main Page</a></div></div></div>
 
 !! html/parsoid
-<figure class="mw-default-size mw-halign-left" typeof="mw:Image/Frame"><a href="./File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/3/3a/Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="220" width="1941"/></a><figcaption>This is a test image <a rel="mw:WikiLink" href="Main_Page" title="Main Page">Main Page</a></figcaption></figure>
+<figure class="mw-default-size mw-halign-left" typeof="mw:Image/Frame"><a href="./File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/3/3a/Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="220" width="1941"/></a><figcaption>This is a test image <a rel="mw:WikiLink" href="./Main_Page" title="Main Page">Main Page</a></figcaption></figure>
 !! end
 
 !! test
@@ -13788,7 +13828,7 @@ parsoid=wt2html,wt2wt,html2html
 <div class="thumb tleft"><div class="thumbinner" style="width:1943px;"><a href="/wiki/File:Foobar.jpg" class="image"><img alt="Altitude" src="http://example.com/images/3/3a/Foobar.jpg" width="1941" height="220" class="thumbimage" /></a>  <div class="thumbcaption">This is a test image <a href="/wiki/Main_Page" title="Main Page">Main Page</a></div></div></div>
 
 !! html/parsoid
-<figure class="mw-default-size mw-halign-left" typeof="mw:Image/Frame"><a href="./File:Foobar.jpg"><img alt="Altitude" resource="./File:Foobar.jpg" src="//example.com/images/3/3a/Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="220" width="1941"/></a><figcaption>This is a test image <a rel="mw:WikiLink" href="Main_Page" title="Main Page">Main Page</a></figcaption></figure>
+<figure class="mw-default-size mw-halign-left" typeof="mw:Image/Frame"><a href="./File:Foobar.jpg"><img alt="Altitude" resource="./File:Foobar.jpg" src="//example.com/images/3/3a/Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="220" width="1941"/></a><figcaption>This is a test image <a rel="mw:WikiLink" href="./Main_Page" title="Main Page">Main Page</a></figcaption></figure>
 !! end
 
 !! test
@@ -14252,7 +14292,7 @@ parsoid=wt2html,wt2wt,html2html
 <p>[[Image:Foobar.jpg|thumb|This is a broken caption. But <a href="/wiki/Main_Page" title="Main Page">this</a> is just an ordinary link.
 </p>
 !! html/parsoid
-<p>[[Image:Foobar.jpg|thumb|This is a broken caption. But <a rel="mw:WikiLink" href="Main_Page" title="Main Page">this</a> is just an ordinary link.</p>
+<p>[[Image:Foobar.jpg|thumb|This is a broken caption. But <a rel="mw:WikiLink" href="./Main_Page" title="Main Page">this</a> is just an ordinary link.</p>
 !! end
 
 !! test
@@ -14365,7 +14405,7 @@ language=es
 <div class="thumb tleft"><div class="thumbinner" style="width:222px;"><a href="/wiki/Foo" title="Foo"><img alt="" src="http://example.com/images/thumb/3/3a/Foobar.jpg/220px-Foobar.jpg" width="220" height="25" class="thumbimage" srcset="http://example.com/images/thumb/3/3a/Foobar.jpg/330px-Foobar.jpg 1.5x, http://example.com/images/thumb/3/3a/Foobar.jpg/440px-Foobar.jpg 2x" /></a>  <div class="thumbcaption"><div class="magnify"><a href="/wiki/Archivo:Foobar.jpg" class="internal" title="Aumentar"></a></div>caption</div></div></div>
 
 !! html/parsoid
-<figure class="mw-default-size mw-halign-left" typeof="mw:Image/Thumb"><a href="Foo"><img resource="./Archivo:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/220px-Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="25" width="220"/></a><figcaption>caption</figcaption></figure>
+<figure class="mw-default-size mw-halign-left" typeof="mw:Image/Thumb"><a href="./Foo"><img resource="./Archivo:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/220px-Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="25" width="220"/></a><figcaption>caption</figcaption></figure>
 !! end
 
 !! test
@@ -14739,8 +14779,8 @@ subpage title=[[Subpage test/1/2/3/4]]
 </p><p><a href="/wiki/Subpage_test/1/2/subpage" title="Subpage test/1/2/subpage">Subpage test/1/2/subpage</a>
 </p>
 !! html/parsoid
-<p><a rel="mw:WikiLink" href="Subpage_test/1/2/subpage" title="Subpage test/1/2/subpage">subpage</a></p>
-<p><a rel="mw:WikiLink" href="Subpage_test/1/2/subpage" title="Subpage test/1/2/subpage">Subpage_test/1/2/subpage</a></p>
+<p><a rel="mw:WikiLink" href="./Subpage_test/1/2/subpage" title="Subpage test/1/2/subpage">subpage</a></p>
+<p><a rel="mw:WikiLink" href="./Subpage_test/1/2/subpage" title="Subpage test/1/2/subpage">Subpage_test/1/2/subpage</a></p>
 !! end
 
 !! test
@@ -15030,12 +15070,12 @@ Bar
 Bar
 </p>
 !! html/parsoid
-<p>Foo <link rel="mw:PageProp/Category" href="Category:Baz"/> Bar</p>
-<p>Foo <link rel="mw:PageProp/Category" href="Category:Baz"/> Bar</p>
-<p>Foo <link rel="mw:PageProp/Category" href="Category:Baz"/> Bar</p>
-<p>Foo <link rel="mw:PageProp/Category" href="Category:Baz"/> Bar</p>
-<p>Foo <link rel="mw:PageProp/Category" href="Category:Baz"/> <link rel="mw:PageProp/Category" href="Category:Baz"/> <link rel="mw:PageProp/Category" href="Category:Baz"/> Bar <link rel="mw:PageProp/Category" href="Category:Baz"/> <link rel="mw:PageProp/Category" href="Category:Baz"/> <link rel="mw:PageProp/Category" href="Category:Baz"/> <link rel="mw:PageProp/Category" href="Category:Baz"/> <link rel="mw:PageProp/Category" href="Category:Baz" typeof="mw:Transclusion" data-mw='{"parts":[{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"[[Category:Baz]]"}},"i":0}}]}'/></p>
-<link rel="mw:PageProp/Category" href="Category:Baz"/>
+<p>Foo <link rel="mw:PageProp/Category" href="./Category:Baz"/> Bar</p>
+<p>Foo <link rel="mw:PageProp/Category" href="./Category:Baz"/> Bar</p>
+<p>Foo <link rel="mw:PageProp/Category" href="./Category:Baz"/> Bar</p>
+<p>Foo <link rel="mw:PageProp/Category" href="./Category:Baz"/> Bar</p>
+<p>Foo <link rel="mw:PageProp/Category" href="./Category:Baz"/> <link rel="mw:PageProp/Category" href="./Category:Baz"/> <link rel="mw:PageProp/Category" href="./Category:Baz"/> Bar <link rel="mw:PageProp/Category" href="./Category:Baz"/> <link rel="mw:PageProp/Category" href="./Category:Baz"/> <link rel="mw:PageProp/Category" href="./Category:Baz"/> <link rel="mw:PageProp/Category" href="./Category:Baz"/> <link rel="mw:PageProp/Category" href="./Category:Baz" typeof="mw:Transclusion" data-mw='{"parts":[{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"[[Category:Baz]]"}},"i":0}}]}'/></p>
+<link rel="mw:PageProp/Category" href="./Category:Baz"/>
 !! end
 
 ## We used to, but no longer wt2wt this test since the default serializer
@@ -16067,7 +16107,7 @@ div with braces in attribute value
 !! wikitext
 <div title="{}">Foo</div>
 !! html/php
-<div title="&#123;}">Foo</div>
+<div title="&#123;&#125;">Foo</div>
 
 !! html/parsoid
 <div title="{}">Foo</div>
@@ -16202,13 +16242,13 @@ HTML tag with leading space is parsed as text
 
 # This test case is fixed in Parsoid by domino 1.0.12. (bug 50604)
 # Note that html2wt is considerably more difficult if we use <b> in
-# the test case, instead of <big>
+# the test case, instead of <small>
 !! test
 Ensure that HTML adoption agency algorithm is properly implemented.
 !! wikitext
-<big>X<big>Y</big>Z</big>
+<small>X<small>Y</small>Z</small>
 !! html
-<p><big>X<big>Y</big>Z</big>
+<p><small>X<small>Y</small>Z</small>
 </p>
 !! end
 
@@ -16507,9 +16547,11 @@ Template:Div style
 Bug 2304: HTML attribute safety (safe template; regression bug 2309)
 !! wikitext
 <div title="{{test}}"></div>
-!! html
+!! html/php
 <div title="This is a test template"></div>
 
+!! html/parsoid
+<div title="This is a test template" about="#mwt2" typeof="mw:ExpandedAttrs" data-parsoid='{"stx":"html","a":{"title":"This is a test template"},"sa":{"title":"{{test}}"}}' data-mw='{"attribs":[[{"txt":"title"},{"html":"&lt;span about=\"#mwt1\" typeof=\"mw:Transclusion\" data-parsoid=&#39;{\"pi\":[[]],\"dsr\":[12,20,null,null]}&#39; data-mw=&#39;{\"parts\":[{\"template\":{\"target\":{\"wt\":\"test\",\"href\":\"./Template:Test\"},\"params\":{},\"i\":0}}]}&#39;>This is a test template&lt;/span>"}]]}'></div>
 !! end
 
 # Parsoid has enough context to handle this case
@@ -16528,29 +16570,36 @@ Bug 2304: HTML attribute safety (dangerous template; 2309)
 Bug 2304: HTML attribute safety (dangerous style template; 2309)
 !! wikitext
 <div style="{{dangerous style attribute}}"></div>
-!! html
+!! html/php
 <div style="/* insecure input */"></div>
 
+!! html/parsoid
+<div style="/* insecure input */" about="#mwt2" typeof="mw:ExpandedAttrs" data-parsoid='{"stx":"html","a":{"style":"/* insecure input */"},"sa":{"style":"{{dangerous style attribute}}"}}' data-mw='{"attribs":[[{"txt":"style"},{"html":"&lt;span about=\"#mwt1\" typeof=\"mw:Transclusion\" data-parsoid=&#39;{\"pi\":[[]],\"dsr\":[12,41,null,null]}&#39; data-mw=&#39;{\"parts\":[{\"template\":{\"target\":{\"wt\":\"dangerous style attribute\",\"href\":\"./Template:Dangerous_style_attribute\"},\"params\":{},\"i\":0}}]}&#39;>border-size: expression(alert(document.cookie))&lt;/span>"}]]}'></div>
 !! end
 
 !! test
 Bug 2304: HTML attribute safety (safe parameter; 2309)
 !! wikitext
 {{div style|width: 200px}}
-!! html
+!! html/php
 <div style="float: right; width: 200px">Magic div</div>
 
+!! html/parsoid
+<div style="float: right; width: 200px" about="#mwt1" typeof="mw:Transclusion" data-parsoid='{"stx":"html","a":{"style":"float: right; width: 200px"},"sa":{"style":"float: right; {{{1}}}"},"pi":[[{"k":"1"}]]}' data-mw='{"parts":[{"template":{"target":{"wt":"div style","href":"./Template:Div_style"},"params":{"1":{"wt":"width: 200px"}},"i":0}}]}'>Magic div</div>
 !! end
 
 !! test
 Bug 2304: HTML attribute safety (unsafe parameter; 2309)
 !! wikitext
 {{div style|width: expression(alert(document.cookie))}}
-!! html
+!! html/php
 <div style="/* insecure input */">Magic div</div>
 
+!! html/parsoid
+<div style="/* insecure input */" about="#mwt1" typeof="mw:Transclusion" data-parsoid='{"stx":"html","a":{"style":"/* insecure input */"},"sa":{"style":"float: right; {{{1}}}"},"pi":[[{"k":"1"}]]}' data-mw='{"parts":[{"template":{"target":{"wt":"div style","href":"./Template:Div_style"},"params":{"1":{"wt":"width: expression(alert(document.cookie))"}},"i":0}}]}'>Magic div</div>
 !! end
 
+## Parsoid output here differs; needs investigation.
 !! test
 Bug 2304: HTML attribute safety (unsafe breakout parameter; 2309)
 !! wikitext
@@ -16560,6 +16609,7 @@ Bug 2304: HTML attribute safety (unsafe breakout parameter; 2309)
 
 !! end
 
+## Parsoid output here differs; needs investigation.
 !! test
 Bug 2304: HTML attribute safety (unsafe breakout parameter 2; 2309)
 !! wikitext
@@ -16596,7 +16646,6 @@ Bug 2304: HTML attribute safety (bold)
 
 !! end
 
-
 !! test
 Bug 2304: HTML attribute safety (ISBN)
 !! wikitext
@@ -16646,18 +16695,22 @@ Bug 2304: HTML attribute safety (named web link)
 Bug 3244: HTML attribute safety (extension; safe)
 !! wikitext
 <div style="<nowiki>background:blue</nowiki>"></div>
-!! html
+!! html/php
 <div style="background:blue"></div>
 
+!! html/parsoid
+<div style="background:blue" data-parsoid='{"stx":"html","a":{"style":"background:blue"},"sa":{"style":"&lt;nowiki>background:blue&lt;/nowiki>"}}'></div>
 !! end
 
 !! test
 Bug 3244: HTML attribute safety (extension; unsafe)
 !! wikitext
 <div style="<nowiki>border-left:expression(alert(document.cookie))</nowiki>"></div>
-!! html
+!! html/php
 <div style="/* insecure input */"></div>
 
+!! html/parsoid
+<div style="/* insecure input */" data-parsoid='{"stx":"html","a":{"style":"/* insecure input */"},"sa":{"style":"&lt;nowiki>border-left:expression(alert(document.cookie))&lt;/nowiki>"}}'></div>
 !! end
 
 # More MSIE fun discovered by Tom Gilder
@@ -16666,45 +16719,55 @@ Bug 3244: HTML attribute safety (extension; unsafe)
 MSIE CSS safety test: spurious slash
 !! wikitext
 <div style="background-image:u\rl(javascript:alert('boo'))">evil</div>
-!! html
+!! html/php
 <div style="/* insecure input */">evil</div>
 
+!! html/parsoid
+<div style="/* insecure input */" data-parsoid='{"stx":"html","a":{"style":"/* insecure input */"},"sa":{"style":"background-image:u\\rl(javascript:alert(&#39;boo&#39;))"}}'>evil</div>
 !! end
 
 !! test
 MSIE CSS safety test: hex code
 !! wikitext
 <div style="background-image:u\72l(javascript:alert('boo'))">evil</div>
-!! html
+!! html/php
 <div style="/* insecure input */">evil</div>
 
+!! html/parsoid
+<div style="/* insecure input */" data-parsoid='{"stx":"html","a":{"style":"/* insecure input */"},"sa":{"style":"background-image:u\\72l(javascript:alert(&#39;boo&#39;))"}}'>evil</div>
 !! end
 
 !! test
 MSIE CSS safety test: comment in url
 !! wikitext
 <div style="background-image:u/**/rl(javascript:alert('boo'))">evil</div>
-!! html
+!! html/php
 <div style="background-image:u rl(javascript:alert(&#39;boo&#39;))">evil</div>
 
+!! html/parsoid
+<div style="background-image:u rl(javascript:alert('boo'))" data-parsoid='{"stx":"html","a":{"style":"background-image:u rl(javascript:alert(&#39;boo&#39;))"},"sa":{"style":"background-image:u/**/rl(javascript:alert(&#39;boo&#39;))"}}'>evil</div>
 !! end
 
 !! test
 MSIE CSS safety test: comment in expression
 !! wikitext
 <div style="background-image:expres/**/sion(alert('boo4'))">evil4</div>
-!! html
+!! html/php
 <div style="background-image:expres sion(alert(&#39;boo4&#39;))">evil4</div>
 
+!! html/parsoid
+<div style="background-image:expres sion(alert('boo4'))" data-parsoid='{"stx":"html","a":{"style":"background-image:expres sion(alert(&#39;boo4&#39;))"},"sa":{"style":"background-image:expres/**/sion(alert(&#39;boo4&#39;))"}}'>evil4</div>
 !! end
 
 !! test
 CSS safety test (all browsers): vertical tab (bug 55332 / CVE-2013-4567)
 !! wikitext
 <p style="font-size: 100px; background-image:url\b(https://www.google.com/images/srpr/logo6w.png)">A</p>
-!! html
+!! html/php
 <p style="/* invalid control char */">A</p>
 
+!! html/parsoid
+<p style="/* invalid control char */" data-parsoid='{"stx":"html","a":{"style":"/* invalid control char */"},"sa":{"style":"font-size: 100px; background-image:url\\b(https://www.google.com/images/srpr/logo6w.png)"}}'>A</p>
 !! end
 
 !! test
@@ -16712,10 +16775,13 @@ MSIE 6 CSS safety test: Fullwidth (bug 55332)
 !! wikitext
 <p style="font-size: 100px; color: expression((title='XSSed'),'red')">A</p>
 <div style="top:EXPRESSION(alert())">B</div>
-!! html
+!! html/php
 <p style="/* insecure input */">A</p>
 <div style="/* insecure input */">B</div>
 
+!! html/parsoid
+<p style="/* insecure input */" data-parsoid='{"stx":"html","a":{"style":"/* insecure input */"},"sa":{"style":"font-size: 100px; color: expression((title=&#39;XSSed&#39;),&#39;red&#39;)"}}'>A</p>
+<div style="/* insecure input */" data-parsoid='{"stx":"html","a":{"style":"/* insecure input */"},"sa":{"style":"top:EXPRESSION(alert())"}}'>B</div>
 !! end
 
 !! test
@@ -16723,10 +16789,13 @@ MSIE 6 CSS safety test: IPA extensions (bug 55332)
 !! wikitext
 <div style="background-image:uʀʟ(javascript:alert())">A</div>
 <p style="font-size: 100px; color: expʀessɪoɴ((title='XSSed'),'red')">B</p>
-!! html
+!! html/php
 <div style="/* insecure input */">A</div>
 <p style="/* insecure input */">B</p>
 
+!! html/parsoid
+<div style="/* insecure input */" data-parsoid='{"stx":"html","a":{"style":"/* insecure input */"},"sa":{"style":"background-image:uʀʟ(javascript:alert())"}}'>A</div>
+<p style="/* insecure input */" data-parsoid='{"stx":"html","a":{"style":"/* insecure input */"},"sa":{"style":"font-size: 100px; color: expʀessɪoɴ((title=&#39;XSSed&#39;),&#39;red&#39;)"}}'>B</p>
 !! end
 
 !! test
@@ -16735,23 +16804,30 @@ MSIE 6 CSS safety test: sup/sub script (bug 55332)
 <div style="background-image:url⁽javascript:alert())">A</div>
 <div style="background-image:url₍javascript:alert())">B</div>
 <p style="font-size: 100px; color: expressioⁿ((title='XSSed'),'red')">C</p>
-!! html
+!! html/php
 <div style="/* insecure input */">A</div>
 <div style="/* insecure input */">B</div>
 <p style="/* insecure input */">C</p>
 
+!! html/parsoid
+<div style="/* insecure input */" data-parsoid='{"stx":"html","a":{"style":"/* insecure input */"},"sa":{"style":"background-image:url⁽javascript:alert())"}}'>A</div>
+<div style="/* insecure input */" data-parsoid='{"stx":"html","a":{"style":"/* insecure input */"},"sa":{"style":"background-image:url₍javascript:alert())"}}'>B</div>
+<p style="/* insecure input */" data-parsoid='{"stx":"html","a":{"style":"/* insecure input */"},"sa":{"style":"font-size: 100px; color: expressioⁿ((title=&#39;XSSed&#39;),&#39;red&#39;)"}}'>C</p>
 !! end
 
-# FIXME: Parsoid fails to sanitize this! See T58846.
 !! test
 Opera -o-link CSS
+!! options
+parsoid=wt2html,html2html
 !! wikitext
 <div
 title="&#100;&#97;&#116;&#97;&#58;&#116;&#101;&#120;&#116;&#47;&#104;&#116;&#109;&#108;&#44;&#60;&#105;&#109;&#103;&#32;&#115;&#114;&#99;&#61;&#49;&#32;&#111;&#110;&#101;&#114;&#114;&#111;&#114;&#61;&#97;&#108;&#101;&#114;&#116;&#40;&#49;&#41;&#62;"
 style="-o-link:attr(title);-o-link-source:current">X</div>
-!! html
+!! html/php
 <div title="data:text/html,&lt;img src=1 onerror=alert(1)&gt;" style="/* insecure input */">X</div>
 
+!! html/parsoid
+<div title="data:text/html,&lt;img src=1 onerror=alert(1)>" style="/* insecure input */" data-parsoid='{"stx":"html","a":{"title":"data:text/html,&lt;img src=1 onerror=alert(1)>","style":"/* insecure input */"},"sa":{"title":"&amp;#100;&amp;#97;&amp;#116;&amp;#97;&amp;#58;&amp;#116;&amp;#101;&amp;#120;&amp;#116;&amp;#47;&amp;#104;&amp;#116;&amp;#109;&amp;#108;&amp;#44;&amp;#60;&amp;#105;&amp;#109;&amp;#103;&amp;#32;&amp;#115;&amp;#114;&amp;#99;&amp;#61;&amp;#49;&amp;#32;&amp;#111;&amp;#110;&amp;#101;&amp;#114;&amp;#114;&amp;#111;&amp;#114;&amp;#61;&amp;#97;&amp;#108;&amp;#101;&amp;#114;&amp;#116;&amp;#40;&amp;#49;&amp;#41;&amp;#62;","style":"-o-link:attr(title);-o-link-source:current"}}'>X</div>
 !! end
 
 !! test
@@ -16764,7 +16840,7 @@ MSIE 6 CSS safety test: Repetition markers (bug 55332)
 <p style="font-size: 100px; color: expresﹽion((title='XSSed'),'red')">E</p>
 <p style="font-size: 100px; color: expresﹼion((title='XSSed'),'red')">F</p>
 <p style="font-size: 100px; color: expresーion((title='XSSed'),'red')">G</p>
-!! html
+!! html/php
 <p style="/* insecure input */">A</p>
 <p style="/* insecure input */">B</p>
 <p style="/* insecure input */">C</p>
@@ -16773,6 +16849,14 @@ MSIE 6 CSS safety test: Repetition markers (bug 55332)
 <p style="/* insecure input */">F</p>
 <p style="/* insecure input */">G</p>
 
+!! html/parsoid
+<p style="/* insecure input */" data-parsoid='{"stx":"html","a":{"style":"/* insecure input */"},"sa":{"style":"font-size: 100px; color: expres〱ion((title=&#39;XSSed&#39;),&#39;red&#39;)"}}'>A</p>
+<p style="/* insecure input */" data-parsoid='{"stx":"html","a":{"style":"/* insecure input */"},"sa":{"style":"font-size: 100px; color: expresゝion((title=&#39;XSSed&#39;),&#39;red&#39;)"}}'>B</p>
+<p style="/* insecure input */" data-parsoid='{"stx":"html","a":{"style":"/* insecure input */"},"sa":{"style":"font-size: 100px; color: expresーion((title=&#39;XSSed&#39;),&#39;red&#39;)"}}'>C</p>
+<p style="/* insecure input */" data-parsoid='{"stx":"html","a":{"style":"/* insecure input */"},"sa":{"style":"font-size: 100px; color: expresヽion((title=&#39;XSSed&#39;),&#39;red&#39;)"}}'>D</p>
+<p style="/* insecure input */" data-parsoid='{"stx":"html","a":{"style":"/* insecure input */"},"sa":{"style":"font-size: 100px; color: expresﹽion((title=&#39;XSSed&#39;),&#39;red&#39;)"}}'>E</p>
+<p style="/* insecure input */" data-parsoid='{"stx":"html","a":{"style":"/* insecure input */"},"sa":{"style":"font-size: 100px; color: expresﹼion((title=&#39;XSSed&#39;),&#39;red&#39;)"}}'>F</p>
+<p style="/* insecure input */" data-parsoid='{"stx":"html","a":{"style":"/* insecure input */"},"sa":{"style":"font-size: 100px; color: expresーion((title=&#39;XSSed&#39;),&#39;red&#39;)"}}'>G</p>
 !! end
 
 !! test
@@ -16836,7 +16920,6 @@ Expansion of multi-line templates in attribute values (bug 6255)
 
 !! end
 
-
 !! test
 Expansion of multi-line templates in attribute values (bug 6255 sanity check)
 !! wikitext
@@ -16870,6 +16953,7 @@ Tags which are hidden from Tidy cannot pass through the Sanitizer
 ###
 ### Parser hooks (see tests/parser/parserTestsParserHook.php for the <tag> extension)
 ###
+
 !! test
 Parser hook: empty input
 !! wikitext
@@ -18840,7 +18924,6 @@ stuff
 xxx
 !! end
 
-
 !! test
 Handling of &#x0A; in URLs
 !! wikitext
@@ -18849,9 +18932,7 @@ Handling of &#x0A; in URLs
 <ul><li><ul><li> <a rel="nofollow" class="external free" href="irc://%0Aa">irc://%0Aa</a></li></ul></li></ul>
 
 !! html/parsoid
-<ul><li><ul><li> <a rel="mw:ExtLink" href="irc://
-a">irc://
-a</a></li></ul></li></ul>
+<ul><li><ul><li> <a rel="mw:ExtLink" href="irc://%0Aa" data-parsoid='{"stx":"url","a":{"href":"irc://%0Aa"},"sa":{"href":"irc://&amp;#x0A;a"}}'>irc://%0Aa</a></li></ul></li></ul>
 !! end
 
 !! test
@@ -18865,7 +18946,6 @@ Handling of %0A in URLs
 <ul><li><ul><li> <a rel="mw:ExtLink" href="irc://%0Aa">irc://%0Aa</a></li></ul></li></ul>
 !! end
 
-
 # The PHP parser strips the empty tags out for giggles; parsoid doesn't.
 !! test
 5 quotes, code coverage +1 line
@@ -19436,6 +19516,27 @@ File:Foobar.jpg|alt=galleryalt|link=http://www.example.org
 </ul>
 !! end
 
+!! test
+Gallery override link with absolute external link with LanguageConverter
+!! options
+language=zh
+!! input
+<gallery>
+File:foobar.jpg|caption|alt=galleryalt|link=http://www.example.org
+</gallery>
+!! result
+<ul class="gallery mw-gallery-traditional">
+               <li class="gallerybox" style="width: 155px"><div style="width: 155px">
+                       <div class="thumb" style="width: 150px;"><div style="margin:68px auto;"><a href="http://www.example.org"><img alt="galleryalt" src="http://example.com/images/thumb/3/3a/Foobar.jpg/120px-Foobar.jpg" width="120" height="14" srcset="http://example.com/images/thumb/3/3a/Foobar.jpg/180px-Foobar.jpg 1.5x, http://example.com/images/thumb/3/3a/Foobar.jpg/240px-Foobar.jpg 2x" /></a></div></div>
+                       <div class="gallerytext">
+<p>caption
+</p>
+                       </div>
+               </div></li>
+</ul>
+
+!! end
+
 !! test
 Gallery override link with malicious javascript (T36852)
 !! options
@@ -19458,7 +19559,7 @@ File:Foobar.jpg|alt=galleryalt|link=" onclick="alert('malicious javascript code!
 
 !! html/parsoid
 <ul class="gallery mw-gallery-traditional" typeof="mw:Extension/gallery" about="#mwt2" data-mw='{"name":"gallery","attrs":{},"body":{}}'>
-<li class="gallerybox" style="width: 155px;"><div class="thumb" style="width: 150px; height: 150px;"><span style="display: inline-block; height: 100%; vertical-align: middle;"></span><span typeof="mw:Image" style="vertical-align: middle; display: inline-block;"><a href="./&quot;_onclick=&quot;alert('malicious_javascript_code!');"><img alt="galleryalt" resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/120px-Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="14" width="120"/></a></span></div><div class="gallerytext"></div></li>
+<li class="gallerybox" style="width: 155px;"><div class="thumb" style="width: 150px; height: 150px;"><span style="display: inline-block; height: 100%; vertical-align: middle;"></span><span typeof="mw:Image" style="vertical-align: middle; display: inline-block;"><a href="./%22_onclick=%22alert('malicious_javascript_code!');"><img alt="galleryalt" resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/120px-Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="14" width="120"/></a></span></div><div class="gallerytext"></div></li>
 </ul>
 !! end
 
@@ -19488,6 +19589,24 @@ File:Foobar.jpg|link=<
 </ul>
 !! end
 
+!! test
+Serialize gallery without attrs in data-mw
+!! options
+parsoid={
+  "modes": ["html2wt"],
+  "nativeGallery": true
+}
+!! html/parsoid
+<ul class="gallery mw-gallery-traditional" typeof="mw:Extension/gallery" about="#mwt2" data-mw='{"name":"gallery","body":{}}'>
+<li class="gallerycaption">123</li>
+<li class="gallerybox" style="width: 155px;"><div class="thumb" style="width: 150px; height: 150px;"><span style="display: inline-block; height: 100%; vertical-align: middle;"></span><span style="vertical-align: middle; display: inline-block;">File:Test.png</span></div><div class="gallerytext"></div></li>
+</ul>
+!! wikitext
+<gallery caption="123">
+File:Test.png
+</gallery>
+!! end
+
 !! test
 HTML Hex character encoding (spells the word "JavaScript")
 !! options
@@ -19771,7 +19890,6 @@ dt/dd/dl test
 
 !!end
 
-
 # Images with the "|" character in external URLs in comment tags; Eats half the comment, leaves unmatched "</a>" tag.
 !! test
 Images with the "|" character in the comment
@@ -19781,7 +19899,7 @@ Images with the "|" character in the comment
 <div class="thumb tright"><div class="thumbinner" style="width:182px;"><a href="/wiki/File:Foobar.jpg" class="image"><img alt="" src="http://example.com/images/thumb/3/3a/Foobar.jpg/180px-Foobar.jpg" width="180" height="20" class="thumbimage" srcset="http://example.com/images/thumb/3/3a/Foobar.jpg/270px-Foobar.jpg 1.5x, http://example.com/images/thumb/3/3a/Foobar.jpg/360px-Foobar.jpg 2x" /></a>  <div class="thumbcaption"><div class="magnify"><a href="/wiki/File:Foobar.jpg" class="internal" title="Enlarge"></a></div>An <a rel="nofollow" class="external text" href="http://test/?param1=%7Cleft%7C&amp;param2=%7Cx">external</a> URL</div></div></div>
 
 !! html/parsoid
-<figure class="mw-default-size" typeof="mw:Image/Thumb"><a href="./File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/220px-Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="25" width="220"/></a><figcaption>An <a rel="mw:ExtLink" href="http://test/?param1=|left|&amp;param2=|x">external</a> URL</figcaption></figure>
+<figure class="mw-default-size" typeof="mw:Image/Thumb"><a href="./File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/220px-Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="25" width="220"/></a><figcaption>An <a rel="mw:ExtLink" href="http://test/?param1=%7Cleft%7C&amp;param2=%7Cx" data-parsoid='{"a":{"href":"http://test/?param1=%7Cleft%7C&amp;param2=%7Cx"},"sa":{"href":"http://test/?param1=|left|&amp;param2=|x"}}'>external</a> URL</figcaption></figure>
 !! end
 
 !! test
@@ -20333,8 +20451,8 @@ parsoid=wt2html
 !! html/php
 cat=分类 sort=
 !! html/parsoid
-<p><a rel="mw:WikiLink" href="A" title="A">A</a></p>
-<link rel="mw:PageProp/Category" href="Category:分类"/>
+<p><a rel="mw:WikiLink" href="./A" title="A">A</a></p>
+<link rel="mw:PageProp/Category" href="./Category:分类"/>
 !! end
 
 !! test
@@ -20609,6 +20727,28 @@ Nested: -{zh-hans:Hi -{zh-cn:China;zh-sg:Singapore;}-;zh-hant:Hello -{zh-tw:Taiw
 # Since Parsoid is starting to emit canonical wikitext for links,
 # [http://example.com http://example.com] will not RT back to that
 # form anymore.
+!! test
+HTML markups with conversion syntax in attribs, nested in other conversion blocks
+!! options
+language=zh variant=zh-cn
+!! wikitext
+-{zh;zh-hans;zh-hant|<span title="-{X}-">A</span>}-
+!! html
+<p><span title="X">A</span>
+</p>
+!! end
+
+!! test
+HTML markups with conversion syntax in attribs, nested in other conversion blocks (not working yet)
+!! options
+language=zh variant=zh-cn disabled
+!! wikitext
+-{<span title="-{X}-">A</span>}-
+!! html
+<p><span title="X">A</span>
+</p>
+!! end
+
 !! test
 Proper conversion of text in external links
 !! options
@@ -22368,82 +22508,6 @@ File:foobar.jpg|caption|alt=galleryalt|link=InterWikiLink
 
 !! end
 
-!!test
-Gallery override link with absolute external link (bug 34852)
-!! wikitext
-<gallery>
-File:foobar.jpg|caption|alt=galleryalt|link=http://www.example.org
-</gallery>
-!! html
-<ul class="gallery mw-gallery-traditional">
-               <li class="gallerybox" style="width: 155px"><div style="width: 155px">
-                       <div class="thumb" style="width: 150px;"><div style="margin:68px auto;"><a href="http://www.example.org"><img alt="galleryalt" src="http://example.com/images/thumb/3/3a/Foobar.jpg/120px-Foobar.jpg" width="120" height="14" srcset="http://example.com/images/thumb/3/3a/Foobar.jpg/180px-Foobar.jpg 1.5x, http://example.com/images/thumb/3/3a/Foobar.jpg/240px-Foobar.jpg 2x" /></a></div></div>
-                       <div class="gallerytext">
-<p>caption
-</p>
-                       </div>
-               </div></li>
-</ul>
-
-!! end
-
-!! test
-Gallery override link with absolute external link with LanguageConverter
-!! options
-language=zh
-!! input
-<gallery>
-File:foobar.jpg|caption|alt=galleryalt|link=http://www.example.org
-</gallery>
-!! result
-<ul class="gallery mw-gallery-traditional">
-               <li class="gallerybox" style="width: 155px"><div style="width: 155px">
-                       <div class="thumb" style="width: 150px;"><div style="margin:68px auto;"><a href="http://www.example.org"><img alt="galleryalt" src="http://example.com/images/thumb/3/3a/Foobar.jpg/120px-Foobar.jpg" width="120" height="14" srcset="http://example.com/images/thumb/3/3a/Foobar.jpg/180px-Foobar.jpg 1.5x, http://example.com/images/thumb/3/3a/Foobar.jpg/240px-Foobar.jpg 2x" /></a></div></div>
-                       <div class="gallerytext">
-<p>caption
-</p>
-                       </div>
-               </div></li>
-</ul>
-
-!! end
-
-!!test
-Gallery override link with malicious javascript (bug 34852)
-!! wikitext
-<gallery>
-File:foobar.jpg|caption|alt=galleryalt|link=" onclick="alert('malicious javascript code!');
-</gallery>
-!! html
-<ul class="gallery mw-gallery-traditional">
-               <li class="gallerybox" style="width: 155px"><div style="width: 155px">
-                       <div class="thumb" style="width: 150px;"><div style="margin:68px auto;"><a href="/wiki/%22_onclick%3D%22alert(%27malicious_javascript_code!%27);"><img alt="galleryalt" src="http://example.com/images/thumb/3/3a/Foobar.jpg/120px-Foobar.jpg" width="120" height="14" srcset="http://example.com/images/thumb/3/3a/Foobar.jpg/180px-Foobar.jpg 1.5x, http://example.com/images/thumb/3/3a/Foobar.jpg/240px-Foobar.jpg 2x" /></a></div></div>
-                       <div class="gallerytext">
-<p>caption
-</p>
-                       </div>
-               </div></li>
-</ul>
-
-!! end
-
-!!test
-Gallery with invalid title as link (bug 43964)
-!! wikitext
-<gallery>
-File:foobar.jpg|link=<
-</gallery>
-!! html
-<ul class="gallery mw-gallery-traditional">
-               <li class="gallerybox" style="width: 155px"><div style="width: 155px">
-                       <div class="thumb" style="width: 150px;"><div style="margin:68px auto;"><a href="/wiki/File:Foobar.jpg" class="image"><img alt="Foobar.jpg" src="http://example.com/images/thumb/3/3a/Foobar.jpg/120px-Foobar.jpg" width="120" height="14" srcset="http://example.com/images/thumb/3/3a/Foobar.jpg/180px-Foobar.jpg 1.5x, http://example.com/images/thumb/3/3a/Foobar.jpg/240px-Foobar.jpg 2x" /></a></div></div>
-                       <div class="gallerytext">
-                       </div>
-               </div></li>
-</ul>
-
-!! end
-
 !!test
 Language parser function
 !! wikitext
@@ -22705,7 +22769,7 @@ A <ref>
 <p>A <span about="#mwt2" class="mw-ref" id="cite_ref-1" rel="dc:references" typeof="mw:Extension/ref" data-mw='{"name":"ref","body":{"id":"mw-reference-text-cite_note-1"},"attrs":{}}'><a href="./Main_Page#cite_note-1"><span class="mw-reflink-text">[1]</span></a></span></p>
 
 <ol class="mw-references" typeof="mw:Extension/references" about="#mwt5" data-mw='{"name":"references","attrs":{}}'>
-<li about="#cite_note-1" id="cite_note-1"><a href="./Main_Page#cite_ref-1" rel="mw:referencedBy"><span class="mw-linkback-text">↑ </span></a> <span id="mw-reference-text-cite_note-1" class="mw-reference-text">This is a <b><a rel="mw:WikiLink" href="Bolded_link" title="Bolded link">bolded link</a></b> and this is a <span about="#mwt3" typeof="mw:Transclusion" data-mw='{"parts":[{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"transclusion"}},"i":0}}]}'>transclusion</span>
+<li about="#cite_note-1" id="cite_note-1"><a href="./Main_Page#cite_ref-1" rel="mw:referencedBy"><span class="mw-linkback-text">↑ </span></a> <span id="mw-reference-text-cite_note-1" class="mw-reference-text">This is a <b><a rel="mw:WikiLink" href="./Bolded_link" title="Bolded link">bolded link</a></b> and this is a <span about="#mwt3" typeof="mw:Transclusion" data-mw='{"parts":[{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"transclusion"}},"i":0}}]}'>transclusion</span>
 </span></li>
 </ol>
 !!end
index 17c1fb8..19469d9 100644 (file)
@@ -34,19 +34,24 @@ return [
         * project. directory_list won't find .inc files so
         * we augment it here.
         */
-       'file_list' => [
-               'maintenance/7zip.inc',
-               'maintenance/backupPrefetch.inc',
-               'maintenance/commandLine.inc',
-               'maintenance/sqlite.inc',
-               'maintenance/userOptions.inc',
-               'maintenance/backup.inc',
-               'maintenance/cleanupTable.inc',
-               'maintenance/importImages.inc',
-               'maintenance/userDupes.inc',
-               'maintenance/language/checkLanguage.inc',
-               'maintenance/language/languages.inc',
-       ],
+       'file_list' => array_merge(
+               function_exists( 'register_postsend_function' ) ? [] : [ 'tests/phan/stubs/hhvm.php' ],
+               function_exists( 'wikidiff2_do_diff' ) ? [] : [ 'tests/phan/stubs/wikidiff.php' ],
+               class_exists( PEAR::class ) ? [] : [ 'tests/phan/stubs/mail.php' ],
+               [
+                       'maintenance/7zip.inc',
+                       'maintenance/backupPrefetch.inc',
+                       'maintenance/commandLine.inc',
+                       'maintenance/sqlite.inc',
+                       'maintenance/userOptions.inc',
+                       'maintenance/backup.inc',
+                       'maintenance/cleanupTable.inc',
+                       'maintenance/importImages.inc',
+                       'maintenance/userDupes.inc',
+                       'maintenance/language/checkLanguage.inc',
+                       'maintenance/language/languages.inc',
+               ]
+       ),
 
        /**
         * A list of directories that should be parsed for class and
@@ -65,7 +70,6 @@ return [
                'resources/',
                'skins/',
                'vendor/',
-               'tests/phan/stubs/',
        ],
 
        /**
@@ -96,7 +100,7 @@ return [
                // External class
                'includes/libs/jsminplus.php',
                // separate repositories
-               'skins/'
+               'skins/',
        ],
 
        /**
@@ -129,7 +133,7 @@ return [
         * ```php
         * <?php
         * function test($arg):int {
-        *      return $arg;
+        *    return $arg;
         * }
         * test("abc");
         * ```
index e906cdb..7cd9016 100644 (file)
@@ -1,11 +1,11 @@
 <?php
 
-// @codingStandardsIgnoreFile
-
 /**
  * Minimal set of classes necessary for UserMailer to be happy. Types
  * taken from documentation at pear.php.net.
+ * @codingStandardsIgnoreFile
  */
+
 class PEAR {
        /**
         * @param mixed $data
index 0e83006..d2494da 100644 (file)
@@ -12,6 +12,48 @@ class OutputPageTest extends MediaWikiTestCase {
        const SCREEN_MEDIA_QUERY = 'screen and (min-width: 982px)';
        const SCREEN_ONLY_MEDIA_QUERY = 'only screen and (min-width: 982px)';
 
+       /**
+        * @covers OutputPage::addMeta
+        * @covers OutputPage::getMetaTags
+        * @covers OutputPage::getHeadLinksArray
+        */
+       public function testMetaTags() {
+               $outputPage = $this->newInstance();
+               $outputPage->addMeta( 'http:expires', '0' );
+               $outputPage->addMeta( 'keywords', 'first' );
+               $outputPage->addMeta( 'keywords', 'second' );
+               $outputPage->addMeta( 'og:title', 'Ta-duh' );
+
+               $expected = [
+                       [ 'http:expires', '0' ],
+                       [ 'keywords', 'first' ],
+                       [ 'keywords', 'second' ],
+                       [ 'og:title', 'Ta-duh' ],
+               ];
+               $this->assertSame( $expected, $outputPage->getMetaTags() );
+
+               $links = $outputPage->getHeadLinksArray();
+               $this->assertContains( '<meta http-equiv="expires" content="0"/>', $links );
+               $this->assertContains( '<meta name="keywords" content="first"/>', $links );
+               $this->assertContains( '<meta name="keywords" content="second"/>', $links );
+               $this->assertContains( '<meta property="og:title" content="Ta-duh"/>', $links );
+               $this->assertArrayNotHasKey( 'meta-robots', $links );
+       }
+
+       /**
+        * @covers OutputPage::setIndexPolicy
+        * @covers OutputPage::setFollowPolicy
+        * @covers OutputPage::getHeadLinksArray
+        */
+       public function testRobotsPolicies() {
+               $outputPage = $this->newInstance();
+               $outputPage->setIndexPolicy( 'noindex' );
+               $outputPage->setFollowPolicy( 'nofollow' );
+
+               $links = $outputPage->getHeadLinksArray();
+               $this->assertContains( '<meta name="robots" content="noindex,nofollow"/>', $links );
+       }
+
        /**
         * Tests a particular case of transformCssMedia, using the given input, globals,
         * expected return, and message
@@ -374,6 +416,29 @@ class OutputPageTest extends MediaWikiTestCase {
                $this->assertEquals( [ 0 => 'Test2' ], $outputPage->getCategories( 'normal' ) );
                $this->assertEquals( [ 0 => 'Test' ], $outputPage->getCategories( 'hidden' ) );
        }
+
+       /**
+        * @return OutputPage
+        */
+       private function newInstance() {
+               $context = new RequestContext();
+
+               $context->setConfig( new HashConfig( [
+                       'AppleTouchIcon' => false,
+                       'DisableLangConversion' => true,
+                       'EnableAPI' => false,
+                       'EnableCanonicalServerLink' => false,
+                       'Favicon' => false,
+                       'Feed' => false,
+                       'LanguageCode' => false,
+                       'ReferrerPolicy' => false,
+                       'RightsPage' => false,
+                       'RightsUrl' => false,
+                       'UniversalEditButton' => false,
+               ] ) );
+
+               return new OutputPage( $context );
+       }
 }
 
 /**
index a40db24..eaa4d17 100644 (file)
@@ -439,8 +439,8 @@ class ApiErrorFormatterTest extends MediaWikiLangTestCase {
                $formatter->addMessagesFromStatus( 'status', $status );
                $this->assertSame( [
                        'error' => [
-                               'code' => 'parentheses',
-                               'info' => $parensPlain,
+                               'code' => 'mainpage',
+                               'info' => $mainpagePlain,
                        ],
                        'warnings' => [
                                'status' => [
@@ -502,6 +502,17 @@ class ApiErrorFormatterTest extends MediaWikiLangTestCase {
                        $formatter->arrayFromStatus( $status, 'warning' ),
                        'arrayFromStatus test for warning'
                );
+
+               $result->reset();
+               $result->addValue( null, 'error', [ 'bogus' ] );
+               $formatter->addError( 'err', 'mainpage' );
+               $this->assertSame( [
+                       'error' => [
+                               'code' => 'mainpage',
+                               'info' => $mainpagePlain,
+                       ],
+                       ApiResult::META_TYPE => 'assoc',
+               ], $result->getResultData(), 'Overwrites bogus "error" value with real error' );
        }
 
        /**
index 71dafce..eff41e3 100644 (file)
@@ -546,7 +546,9 @@ class ApiMainTest extends ApiTestCase {
                                                [ 'code' => 'existing-error', 'text' => 'existing error', 'module' => 'main' ],
                                                [ 'code' => 'ue', 'text' => "Usage exception!", 'data' => [ 'foo' => 'bar' ] ]
                                        ],
-                                       'docref' => "See $doclink for API usage.",
+                                       'docref' => "See $doclink for API usage. Subscribe to the mediawiki-api-announce mailing " .
+                                               "list at &lt;https://lists.wikimedia.org/mailman/listinfo/mediawiki-api-announce&gt; " .
+                                               "for notice of API deprecations and breaking changes.",
                                        'servedby' => wfHostname(),
                                ]
                        ],
@@ -564,7 +566,9 @@ class ApiMainTest extends ApiTestCase {
                                                [ 'code' => 'sv-error1', 'text' => 'An error', 'module' => 'foo+bar' ],
                                                [ 'code' => 'sv-error2', 'text' => 'Another error', 'module' => 'foo+bar' ],
                                        ],
-                                       'docref' => "See $doclink for API usage.",
+                                       'docref' => "See $doclink for API usage. Subscribe to the mediawiki-api-announce mailing " .
+                                               "list at &lt;https://lists.wikimedia.org/mailman/listinfo/mediawiki-api-announce&gt; " .
+                                               "for notice of API deprecations and breaking changes.",
                                        'servedby' => wfHostname(),
                                ]
                        ],
index bd744c0..a12c8b2 100644 (file)
@@ -99,6 +99,37 @@ class MessageCacheTest extends MediaWikiLangTestCase {
                ];
        }
 
+       public function testReplaceMsg() {
+               global $wgContLang;
+
+               $messageCache = MessageCache::singleton();
+               $message = 'go';
+               $uckey = $wgContLang->ucfirst( $message );
+               $oldText = $messageCache->get( $message ); // "Ausführen"
+
+               $dbw = wfGetDB( DB_MASTER );
+               $dbw->startAtomic( __METHOD__ ); // simulate request and block deferred updates
+               $messageCache->replace( $uckey, 'Allez!' );
+               $this->assertEquals( 'Allez!',
+                       $messageCache->getMsgFromNamespace( $uckey, 'de' ),
+                       'Updates are reflected in-process immediately' );
+               $this->assertEquals( 'Allez!',
+                       $messageCache->get( $message ),
+                       'Updates are reflected in-process immediately' );
+               $this->makePage( 'Go', 'de', 'Race!' );
+               $dbw->endAtomic( __METHOD__ );
+
+               $this->assertEquals( 0,
+                       DeferredUpdates::pendingUpdatesCount(),
+                       'Post-commit deferred update triggers a run of all updates' );
+
+               $this->assertEquals( 'Race!', $messageCache->get( $message ), 'Correct final contents' );
+
+               $this->makePage( 'Go', 'de', $oldText );
+               $messageCache->replace( $uckey, $oldText ); // deferred update runs immediately
+               $this->assertEquals( $oldText, $messageCache->get( $message ), 'Content restored' );
+       }
+
        /**
         * There's a fallback case where the message key is given as fully qualified -- this
         * should ignore the passed $lang and use the language from the key
index ccabab6..4ff1eb8 100644 (file)
@@ -69,19 +69,12 @@ class RCCacheEntryFactoryTest extends MediaWikiLangTestCase {
 
                $diff = [ 'curid' => 5, 'diff' => 191, 'oldid' => 190 ];
                $cur = [ 'curid' => 5, 'diff' => 0, 'oldid' => 191 ];
-               $this->assertQueryLink( 'cur', $cur, $cacheEntry->curlink, 'cur link' );
-               $this->assertQueryLink( 'prev', $diff, $cacheEntry->lastlink, 'prev link' );
-               $this->assertQueryLink( 'diff', $diff, $cacheEntry->difflink, 'diff link' );
+               $this->assertQueryLink( 'cur', $cur, $cacheEntry->curlink );
+               $this->assertQueryLink( 'prev', $diff, $cacheEntry->lastlink );
+               $this->assertQueryLink( 'diff', $diff, $cacheEntry->difflink );
        }
 
        public function testNewForDeleteChange() {
-               $expected = [
-                       'title' => 'Abc',
-                       'user' => 'TestRecentChangesUser',
-                       'timestamp' => '21:21',
-                       'numberofWatchingusers' => 0,
-                       'unpatrolled' => false
-               ];
                $user = $this->getMutableTestUser()->getUser();
                $recentChange = $this->testRecentChangesHelper->makeLogRecentChange(
                        'delete',
index 91d2297..efd60e5 100644 (file)
@@ -409,6 +409,7 @@ class ContentHandlerTest extends MediaWikiTestCase {
                $this->assertArrayHasKey( 'external_link', $fields );
                $this->assertArrayHasKey( 'outgoing_link', $fields );
                $this->assertArrayHasKey( 'template', $fields );
+               $this->assertArrayHasKey( 'content_model', $fields );
        }
 
        private function newSearchEngine() {
@@ -445,6 +446,7 @@ class ContentHandlerTest extends MediaWikiTestCase {
                $this->assertArrayHasKey( 'language', $data );
                $this->assertArrayHasKey( 'testDataField', $data );
                $this->assertEquals( 'test content', $data['testDataField'] );
+               $this->assertEquals( 'wikitext', $data['content_model'] );
        }
 
        /**
index aa46c96..d7ed4bd 100644 (file)
@@ -872,6 +872,62 @@ class WANObjectCacheTest extends PHPUnit_Framework_TestCase  {
                $this->assertGreaterThan( -5.1, $curTTL, "Correct CTL" );
        }
 
+       /**
+        * @covers WANObjectCache::reap()
+        * @covers WANObjectCache::reapCheckKey()
+        */
+       public function testReap() {
+               $vKey1 = wfRandomString();
+               $vKey2 = wfRandomString();
+               $tKey1 = wfRandomString();
+               $tKey2 = wfRandomString();
+               $value = 'moo';
+
+               $knownPurge = time() - 60;
+               $goodTime = microtime( true ) - 5;
+               $badTime = microtime( true ) - 300;
+
+               $this->internalCache->set(
+                       WANObjectCache::VALUE_KEY_PREFIX . $vKey1,
+                       [
+                               WANObjectCache::FLD_VERSION => WANObjectCache::VERSION,
+                               WANObjectCache::FLD_VALUE => $value,
+                               WANObjectCache::FLD_TTL => 3600,
+                               WANObjectCache::FLD_TIME => $goodTime
+                       ]
+               );
+               $this->internalCache->set(
+                       WANObjectCache::VALUE_KEY_PREFIX . $vKey2,
+                       [
+                               WANObjectCache::FLD_VERSION => WANObjectCache::VERSION,
+                               WANObjectCache::FLD_VALUE => $value,
+                               WANObjectCache::FLD_TTL => 3600,
+                               WANObjectCache::FLD_TIME => $badTime
+                       ]
+               );
+               $this->internalCache->set(
+                       WANObjectCache::TIME_KEY_PREFIX . $tKey1,
+                       WANObjectCache::PURGE_VAL_PREFIX . $goodTime
+               );
+               $this->internalCache->set(
+                       WANObjectCache::TIME_KEY_PREFIX . $tKey2,
+                       WANObjectCache::PURGE_VAL_PREFIX . $badTime
+               );
+
+               $this->assertEquals( $value, $this->cache->get( $vKey1 ) );
+               $this->assertEquals( $value, $this->cache->get( $vKey2 ) );
+               $this->cache->reap( $vKey1, $knownPurge, $bad1 );
+               $this->cache->reap( $vKey2, $knownPurge, $bad2 );
+
+               $this->assertFalse( $bad1 );
+               $this->assertTrue( $bad2 );
+
+               $this->cache->reapCheckKey( $tKey1, $knownPurge, $tBad1 );
+               $this->cache->reapCheckKey( $tKey2, $knownPurge, $tBad2 );
+               $this->assertFalse( $tBad1 );
+               $this->assertTrue( $tBad2 );
+       }
+
        /**
         * @covers WANObjectCache::set()
         */
@@ -926,6 +982,8 @@ class WANObjectCacheTest extends PHPUnit_Framework_TestCase  {
                $wanCache->getMulti( [ 'x', 'y' ], $ctls, [ 'check2' ] );
                $wanCache->getWithSetCallback( 'p', 30, $valFunc );
                $wanCache->getCheckKeyTime( 'zzz' );
+               $wanCache->reap( 'x', time() - 300 );
+               $wanCache->reap( 'zzz', time() - 300 );
        }
 
        /**
index a81e7ec..f48507d 100644 (file)
@@ -10,6 +10,41 @@ class RightsLogFormatterTest extends LogFormatterTestCase {
        public static function provideRightsLogDatabaseRows() {
                return [
                        // Current format
+                       [
+                               [
+                                       'type' => 'rights',
+                                       'action' => 'rights',
+                                       'comment' => 'rights comment',
+                                       'user' => 0,
+                                       'user_text' => 'Sysop',
+                                       'namespace' => NS_USER,
+                                       'title' => 'User',
+                                       'params' => [
+                                               '4::oldgroups' => [],
+                                               '5::newgroups' => [ 'sysop', 'bureaucrat' ],
+                                               'oldmetadata' => [],
+                                               'newmetadata' => [
+                                                       [ 'expiry' => null ],
+                                                       [ 'expiry' => '20160101123456' ]
+                                               ],
+                                       ],
+                               ],
+                               [
+                                       'text' => 'Sysop changed group membership for User from (none) to '
+                                               . 'bureaucrat (temporary, until 12:34, 1 January 2016) and administrator',
+                                       'api' => [
+                                               'oldgroups' => [],
+                                               'newgroups' => [ 'sysop', 'bureaucrat' ],
+                                               'oldmetadata' => [],
+                                               'newmetadata' => [
+                                                       [ 'group' => 'sysop', 'expiry' => 'infinity' ],
+                                                       [ 'group' => 'bureaucrat', 'expiry' => '2016-01-01T12:34:56Z' ],
+                                               ],
+                                       ],
+                               ],
+                       ],
+
+                       // Previous format (oldgroups and newgroups as arrays, no metadata)
                        [
                                [
                                        'type' => 'rights',
@@ -30,11 +65,16 @@ class RightsLogFormatterTest extends LogFormatterTestCase {
                                        'api' => [
                                                'oldgroups' => [],
                                                'newgroups' => [ 'sysop', 'bureaucrat' ],
+                                               'oldmetadata' => [],
+                                               'newmetadata' => [
+                                                       [ 'group' => 'sysop', 'expiry' => 'infinity' ],
+                                                       [ 'group' => 'bureaucrat', 'expiry' => 'infinity' ],
+                                               ],
                                        ],
                                ],
                        ],
 
-                       // Legacy format
+                       // Legacy format (oldgroups and newgroups as numeric-keyed strings)
                        [
                                [
                                        'type' => 'rights',
@@ -56,6 +96,11 @@ class RightsLogFormatterTest extends LogFormatterTestCase {
                                        'api' => [
                                                'oldgroups' => [],
                                                'newgroups' => [ 'sysop', 'bureaucrat' ],
+                                               'oldmetadata' => [],
+                                               'newmetadata' => [
+                                                       [ 'group' => 'sysop', 'expiry' => 'infinity' ],
+                                                       [ 'group' => 'bureaucrat', 'expiry' => 'infinity' ],
+                                               ],
                                        ],
                                ],
                        ],
@@ -116,6 +161,13 @@ class RightsLogFormatterTest extends LogFormatterTestCase {
                                        'api' => [
                                                'oldgroups' => [ 'sysop' ],
                                                'newgroups' => [ 'sysop', 'bureaucrat' ],
+                                               'oldmetadata' => [
+                                                       [ 'group' => 'sysop', 'expiry' => 'infinity' ],
+                                               ],
+                                               'newmetadata' => [
+                                                       [ 'group' => 'sysop', 'expiry' => 'infinity' ],
+                                                       [ 'group' => 'bureaucrat', 'expiry' => 'infinity' ],
+                                               ],
                                        ],
                                ],
                        ],
@@ -142,6 +194,13 @@ class RightsLogFormatterTest extends LogFormatterTestCase {
                                        'api' => [
                                                'oldgroups' => [ 'sysop' ],
                                                'newgroups' => [ 'sysop', 'bureaucrat' ],
+                                               'oldmetadata' => [
+                                                       [ 'group' => 'sysop', 'expiry' => 'infinity' ],
+                                               ],
+                                               'newmetadata' => [
+                                                       [ 'group' => 'sysop', 'expiry' => 'infinity' ],
+                                                       [ 'group' => 'bureaucrat', 'expiry' => 'infinity' ],
+                                               ],
                                        ],
                                ],
                        ],
index e778270..d32915b 100644 (file)
@@ -796,6 +796,7 @@ more stuff
                $this->assertEquals( 'Admin', $rev1->getUserText() );
 
                # now, try the actual rollback
+               $admin->addToDatabase();
                $admin->addGroup( "sysop" ); # XXX: make the test user a sysop...
                $token = $admin->getEditToken(
                        [ $page->getTitle()->getPrefixedText(), $user2->getName() ],
@@ -828,6 +829,7 @@ more stuff
        public function testDoRollback() {
                $admin = new User();
                $admin->setName( "Admin" );
+               $admin->addToDatabase();
 
                $text = "one";
                $page = $this->newPage( "WikiPageTest_testDoRollback" );
@@ -854,10 +856,7 @@ more stuff
 
                # now, try the rollback
                $admin->addGroup( "sysop" ); # XXX: make the test user a sysop...
-               $token = $admin->getEditToken(
-                       [ $page->getTitle()->getPrefixedText(), $user1->getName() ],
-                       null
-               );
+               $token = $admin->getEditToken( 'rollback' );
                $errors = $page->doRollback(
                        $user1->getName(),
                        "testing revert",
@@ -884,6 +883,7 @@ more stuff
        public function testDoRollbackFailureSameContent() {
                $admin = new User();
                $admin->setName( "Admin" );
+               $admin->addToDatabase();
                $admin->addGroup( "sysop" ); # XXX: make the test user a sysop...
 
                $text = "one";
@@ -899,6 +899,7 @@ more stuff
 
                $user1 = new User();
                $user1->setName( "127.0.1.11" );
+               $user1->addToDatabase();
                $user1->addGroup( "sysop" ); # XXX: make the test user a sysop...
                $text .= "\n\ntwo";
                $page = new WikiPage( $page->getTitle() );
@@ -912,10 +913,7 @@ more stuff
 
                # now, do a the rollback from the same user was doing the edit before
                $resultDetails = [];
-               $token = $user1->getEditToken(
-                       [ $page->getTitle()->getPrefixedText(), $user1->getName() ],
-                       null
-               );
+               $token = $user1->getEditToken( 'rollback' );
                $errors = $page->doRollback(
                        $user1->getName(),
                        "testing revert same user",
@@ -929,10 +927,7 @@ more stuff
 
                # now, try the rollback
                $resultDetails = [];
-               $token = $admin->getEditToken(
-                       [ $page->getTitle()->getPrefixedText(), $user1->getName() ],
-                       null
-               );
+               $token = $admin->getEditToken( 'rollback' );
                $errors = $page->doRollback(
                        $user1->getName(),
                        "testing revert",
index d16200b..5ea7b1d 100644 (file)
@@ -61,6 +61,7 @@ class UserPasswordPolicyTest extends MediaWikiTestCase {
                $upp = $this->getUserPasswordPolicy();
 
                $user = User::newFromName( 'TestUserPolicy' );
+               $user->addToDatabase();
                $user->addGroup( 'sysop' );
 
                $this->assertArrayEquals(
@@ -106,6 +107,7 @@ class UserPasswordPolicyTest extends MediaWikiTestCase {
                $upp = $this->getUserPasswordPolicy();
 
                $user = User::newFromName( $username );
+               $user->addToDatabase();
                foreach ( $groups as $group ) {
                        $user->addGroup( $group );
                }
diff --git a/tests/phpunit/includes/rcfeed/RCFeedIntegrationTest.php b/tests/phpunit/includes/rcfeed/RCFeedIntegrationTest.php
new file mode 100644 (file)
index 0000000..97ea23c
--- /dev/null
@@ -0,0 +1,96 @@
+<?php
+
+class RCFeedIntegrationTest extends MediaWikiTestCase {
+       protected function setUp() {
+               parent::setUp();
+               $this->setMwGlobals( [
+                       'wgCanonicalServer' => 'https://example.org',
+                       'wgServerName' => 'example.org',
+                       'wgScriptPath' => '/w',
+                       'wgDBname' => 'example',
+                       'wgDBprefix' => '',
+                       'wgRCFeeds' => [],
+                       'wgRCEngines' => [],
+               ] );
+       }
+
+       /**
+        * @covers RecentChange::notifyRCFeeds
+        * @covers RecentChange::getEngine
+        * @covers RCFeedEngine
+        * @covers JSONRCFeedFormatter::formatArray
+        * @covers MachineReadableRCFeedFormatter::getLine
+        */
+       public function testNotify() {
+               $feed = $this->getMockBuilder( 'RCFeedEngine' )
+                       ->setConstructorArgs( [ [ 'formatter' => 'JSONRCFeedFormatter' ] ] )
+                       ->setMethods( [ 'send' ] )
+                       ->getMock();
+
+               $feed->method( 'send' )
+                       ->willReturn( true );
+
+               $feed->expects( $this->once() )
+                       ->method( 'send' )
+                       ->with( $this->anything(), $this->callback( function ( $line ) {
+                               $this->assertJsonStringEqualsJsonString(
+                                       json_encode( [
+                                               'id' => null,
+                                               'type' => 'log',
+                                               'namespace' => 0,
+                                               'title' => 'Example',
+                                               'comment' => '',
+                                               'timestamp' => 1301644800,
+                                               'user' => 'UTSysop',
+                                               'bot' => false,
+                                               'log_id' => 0,
+                                               'log_type' => 'move',
+                                               'log_action' => 'move',
+                                               'log_params' => [
+                                                       'color' => 'green',
+                                                       'nr' => 42,
+                                                       'pet' => 'cat',
+                                               ],
+                                               'log_action_comment' => '',
+                                               'server_url' => 'https://example.org',
+                                               'server_name' => 'example.org',
+                                               'server_script_path' => '/w',
+                                               'wiki' => 'example',
+                                       ] ),
+                                       $line
+                               );
+                               return true;
+                       } ) );
+
+               $this->setMwGlobals( [
+                       'wgRCFeeds' => [
+                               'myfeed' => [
+                                       'uri' => 'test://localhost:1234',
+                                       'formatter' => 'JSONRCFeedFormatter',
+                               ],
+                       ],
+                       'wgRCEngines' => [
+                               'test' => $feed,
+                       ],
+               ] );
+               $logpage = SpecialPage::getTitleFor( 'Log', 'move' );
+               $user = $this->getTestSysop()->getUser();
+               $rc = RecentChange::newLogEntry(
+                       '20110401080000',
+                       $logpage, // &$title
+                       $user, // &$user
+                       '', // $actionComment
+                       '127.0.0.1', // $ip
+                       'move', // $type
+                       'move', // $action
+                       Title::makeTitle( 0, 'Example' ), // $target
+                       '', // $logComment
+                       LogEntryBase::makeParamBlob( [
+                               '4::color' => 'green',
+                               '5:number:nr' => 42,
+                               'pet' => 'cat',
+                       ] )
+               );
+               $rc->notifyRCFeeds();
+       }
+}
index ff544cd..b843d17 100644 (file)
@@ -39,4 +39,62 @@ class SkinTemplateTest extends MediaWikiTestCase {
                        ]
                ];
        }
+
+       /**
+        * @return PHPUnit_Framework_MockObject_MockObject|OutputPage
+        */
+       private function getMockOutputPage( $isSyndicated, $html ) {
+               $mock = $this->getMock( OutputPage::class );
+               $mock->expects( $this->once() )
+                       ->method( 'isSyndicated' )
+                       ->will( $this->returnValue( $isSyndicated ) );
+               $mock->expects( $this->once() )
+                       ->method( 'getHTML' )
+                       ->will( $this->returnValue( $html ) );
+               return $mock;
+       }
+
+       public function provideSetupSkinUserCss() {
+               $defaultStyles = [
+                       'mediawiki.legacy.shared',
+                       'mediawiki.legacy.commonPrint',
+                       'mediawiki.sectionAnchor',
+               ];
+               $buttonStyle = 'mediawiki.ui.button';
+               $feedStyle = 'mediawiki.feedlink';
+               return [
+                       [
+                               $this->getMockOutputPage( false, '' ),
+                               $defaultStyles
+                       ],
+                       [
+                               $this->getMockOutputPage( true, '' ),
+                               array_merge( $defaultStyles, [ $feedStyle ] )
+                       ],
+                       [
+                               $this->getMockOutputPage( false, 'FOO mw-ui-button BAR' ),
+                               array_merge( $defaultStyles, [ $buttonStyle ] )
+                       ],
+                       [
+                               $this->getMockOutputPage( true, 'FOO mw-ui-button BAR' ),
+                               array_merge( $defaultStyles, [ $feedStyle, $buttonStyle ] )
+                       ],
+               ];
+       }
+
+       /**
+        * @param PHPUnit_Framework_MockObject_MockObject|OutputPage $outputPageMock
+        * @param string[] $expectedModuleStyles
+        *
+        * @covers SkinTemplate::setupSkinUserCss
+        * @dataProvider provideSetupSkinUserCss
+        */
+       public function testSetupSkinUserCss( $outputPageMock, $expectedModuleStyles ) {
+               $outputPageMock->expects( $this->once() )
+                       ->method( 'addModuleStyles' )
+                       ->with( $expectedModuleStyles );
+
+               $skinTemplate = new SkinTemplate();
+               $skinTemplate->setupSkinUserCss( $outputPageMock );
+       }
 }
index f69ecaf..d93181c 100644 (file)
@@ -1,7 +1,6 @@
 <?php
 
 class BalancerTest extends MediaWikiTestCase {
-       private $balancer;
 
        /**
         * Anything that needs to happen before your tests should go here.
@@ -11,20 +10,20 @@ class BalancerTest extends MediaWikiTestCase {
                // This makes sure that all the various cleanup and restorations
                // happen as they should (including the restoration for setMwGlobals).
                parent::setUp();
-               $this->balancer = new MediaWiki\Tidy\Balancer( [
-                       'strict' => false, /* not strict */
-                       'allowedHtmlElements' => null, /* no sanitization */
-                       'tidyCompat' => false, /* standard parser */
-                       'allowComments' => true, /* comment parsing */
-               ] );
        }
 
        /**
         * @covers MediaWiki\Tidy\Balancer::balance
         * @dataProvider provideBalancerTests
         */
-       public function testBalancer( $description, $input, $expected ) {
-               $output = $this->balancer->balance( $input );
+       public function testBalancer( $description, $input, $expected, $useTidy ) {
+               $balancer = new MediaWiki\Tidy\Balancer( [
+                       'strict' => false, /* not strict */
+                       'allowedHtmlElements' => null, /* no sanitization */
+                       'tidyCompat' => $useTidy, /* standard parser */
+                       'allowComments' => true, /* comment parsing */
+               ] );
+               $output = $balancer->balance( $input );
 
                // Ignore self-closing tags
                $output = preg_replace( '/\s*\/>/', '>', $output );
@@ -86,7 +85,7 @@ class BalancerTest extends MediaWikiTestCase {
                                        // Skip tests involving unusual doctypes.
                                        continue;
                                }
-                               $literalre = "~ <rdar: | <isindex | < /? (
+                               $literalre = "~ <rdar: | < /? (
                                        html | head | body | frame | frameset | plaintext
                                ) > ~xi";
                                if ( preg_match( $literalre, $case['data'] ) ) {
@@ -146,10 +145,20 @@ class BalancerTest extends MediaWikiTestCase {
                                $tests[] = [
                                        $filename, # use better description?
                                        $data,
-                                       $html
+                                       $html,
+                                       false # strict HTML5 compat mode, no tidy
                                ];
                        }
                }
+
+               # Some additional tests for mediawiki-specific features
+               $tests[] = [
+                       'Round-trip serialization for <pre>/<listing>/<textarea>',
+                       "<pre>\n\na</pre><listing>\n\nb</listing><textarea>\n\nc</textarea>",
+                       "<pre>\n\na</pre><listing>\n\nb</listing><textarea>\n\nc</textarea>",
+                       true # use the tidy-compatible mode
+               ];
+
                return $tests;
        }
 }
index beb3659..2b1c3e8 100644 (file)
         "html": "<html><head></head><body><p><b><b><b><b></b></b></b></b></p><p><b><b><b>x</b></b></b></p></body></html>",
         "noQuirksBodyHtml": "<p><b><b><b><b></b></b></b></b></p><p><b><b><b>x</b></b></b></p>"
       }
+    },
+    {
+      "data": "<b><em><foo><foob><fooc><aside></b></em>",
+      "errors": [
+        "(1,35): adoption-agency-1.3",
+        "(1,40): adoption-agency-1.3",
+        "(1,40): expected-closing-tag-but-got-eof"
+      ],
+      "fragment": {
+        "name": "div"
+      },
+      "document": {
+        "props": {
+          "tags": {
+            "b": true,
+            "em": true,
+            "foo": true,
+            "foob": true,
+            "fooc": true,
+            "aside": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "b",
+            "children": [
+              {
+                "tag": "em",
+                "children": [
+                  {
+                    "tag": "foo",
+                    "children": [
+                      {
+                        "tag": "foob",
+                        "children": [
+                          {
+                            "tag": "fooc"
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          },
+          {
+            "tag": "aside",
+            "children": [
+              {
+                "tag": "b"
+              }
+            ]
+          }
+        ],
+        "html": "<b><em><foo><foob><fooc></fooc></foob></foo></em></b><aside><b></b></aside>",
+        "noQuirksBodyHtml": "<b><em><foo><foob><fooc></fooc></foob></foo></em></b><aside><b></b></aside>"
+      }
     }
   ],
   "adoption02.dat": [
       "data": "FOO&#11111111111ZOO",
       "errors": [
         "(1,3): expected-doctype-but-got-chars",
-        "(1,13): illegal-codepoint-for-numeric-entity"
+        "(1,16): numeric-entity-without-semicolon",
+        "(1,16): illegal-codepoint-for-numeric-entity"
       ],
       "document": {
         "props": {
       "data": "FOO&#1111111111ZOO",
       "errors": [
         "(1,3): expected-doctype-but-got-chars",
-        "(1,13): illegal-codepoint-for-numeric-entity"
+        "(1,15): numeric-entity-without-semicolon",
+        "(1,15): illegal-codepoint-for-numeric-entity"
       ],
       "document": {
         "props": {
       "data": "FOO&#111111111111ZOO",
       "errors": [
         "(1,3): expected-doctype-but-got-chars",
-        "(1,13): illegal-codepoint-for-numeric-entity"
+        "(1,17): numeric-entity-without-semicolon",
+        "(1,17): illegal-codepoint-for-numeric-entity"
       ],
       "document": {
         "props": {
     {
       "data": "<plaintext><foo>",
       "errors": [
-        "16: End of file seen and there were open elements.",
-        "11: Unclosed element “plaintext”."
+        "(1,16): expected-closing-tag-but-got-eof"
       ],
       "fragment": {
         "name": "desc",
       "data": "<isindex>",
       "errors": [
         "(1,9): expected-doctype-but-got-start-tag",
-        "(1,9): deprecated-tag"
+        "(1,9): expected-closing-tag-but-got-eof"
       ],
       "document": {
         "props": {
             "html": true,
             "head": true,
             "body": true,
-            "form": true,
-            "hr": true,
-            "label": true,
-            "input": true
+            "isindex": true
           }
         },
         "tree": [
                 "tag": "body",
                 "children": [
                   {
-                    "tag": "form",
-                    "children": [
-                      {
-                        "tag": "hr"
-                      },
-                      {
-                        "tag": "label",
-                        "children": [
-                          {
-                            "text": "This is a searchable index. Enter search keywords: "
-                          },
-                          {
-                            "tag": "input",
-                            "attrs": [
-                              {
-                                "name": "name",
-                                "value": "isindex"
-                              }
-                            ]
-                          }
-                        ]
-                      },
-                      {
-                        "tag": "hr"
-                      }
-                    ]
+                    "tag": "isindex"
                   }
                 ]
               }
             ]
           }
         ],
-        "html": "<html><head></head><body><form><hr><label>This is a searchable index. Enter search keywords: <input name=\"isindex\"></label><hr></form></body></html>",
-        "noQuirksBodyHtml": "<form><hr><label>This is a searchable index. Enter search keywords: <input name=\"isindex\"></label><hr></form>"
+        "html": "<html><head></head><body><isindex></isindex></body></html>",
+        "noQuirksBodyHtml": "<isindex></isindex>"
       }
     },
     {
       "data": "<isindex name=\"A\" action=\"B\" prompt=\"C\" foo=\"D\">",
       "errors": [
         "(1,48): expected-doctype-but-got-start-tag",
-        "(1,48): deprecated-tag"
+        "(1,48): expected-closing-tag-but-got-eof"
       ],
       "document": {
         "props": {
             "html": true,
             "head": true,
             "body": true,
-            "form": true,
-            "hr": true,
-            "label": true,
-            "input": true
+            "isindex": true
           }
         },
         "tree": [
                 "tag": "body",
                 "children": [
                   {
-                    "tag": "form",
+                    "tag": "isindex",
                     "attrs": [
                       {
                         "name": "action",
                         "value": "B"
-                      }
-                    ],
-                    "children": [
+                      },
                       {
-                        "tag": "hr"
+                        "name": "foo",
+                        "value": "D"
                       },
                       {
-                        "tag": "label",
-                        "children": [
-                          {
-                            "text": "C"
-                          },
-                          {
-                            "tag": "input",
-                            "attrs": [
-                              {
-                                "name": "foo",
-                                "value": "D"
-                              },
-                              {
-                                "name": "name",
-                                "value": "isindex"
-                              }
-                            ]
-                          }
-                        ]
+                        "name": "name",
+                        "value": "A"
                       },
                       {
-                        "tag": "hr"
+                        "name": "prompt",
+                        "value": "C"
                       }
                     ]
                   }
             ]
           }
         ],
-        "html": "<html><head></head><body><form action=\"B\"><hr><label>C<input name=\"isindex\" foo=\"D\"></label><hr></form></body></html>",
-        "noQuirksBodyHtml": "<form action=\"B\"><hr><label>C<input name=\"isindex\" foo=\"D\"></label><hr></form>"
+        "html": "<html><head></head><body><isindex name=\"A\" action=\"B\" prompt=\"C\" foo=\"D\"></isindex></body></html>",
+        "noQuirksBodyHtml": "<isindex name=\"A\" action=\"B\" prompt=\"C\" foo=\"D\"></isindex>"
       }
     },
     {
       "data": "<form><isindex>",
       "errors": [
         "(1,6): expected-doctype-but-got-start-tag",
-        "(1,15): deprecated-tag",
         "(1,15): expected-closing-tag-but-got-eof"
       ],
       "document": {
             "html": true,
             "head": true,
             "body": true,
-            "form": true
+            "form": true,
+            "isindex": true
           }
         },
         "tree": [
                 "tag": "body",
                 "children": [
                   {
-                    "tag": "form"
+                    "tag": "form",
+                    "children": [
+                      {
+                        "tag": "isindex"
+                      }
+                    ]
                   }
                 ]
               }
             ]
           }
         ],
-        "html": "<html><head></head><body><form></form></body></html>",
-        "noQuirksBodyHtml": "<form></form>"
+        "html": "<html><head></head><body><form><isindex></isindex></form></body></html>",
+        "noQuirksBodyHtml": "<form><isindex></isindex></form>"
+      }
+    },
+    {
+      "data": "<!doctype html><isindex>x</isindex>x",
+      "errors": [],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "isindex": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "isindex",
+                    "children": [
+                      {
+                        "text": "x"
+                      }
+                    ]
+                  },
+                  {
+                    "text": "x"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><isindex>x</isindex>x</body></html>",
+        "noQuirksBodyHtml": "<isindex>x</isindex>x"
       }
     }
   ],
       }
     },
     {
-      "data": "<!doctype html><main><p>foo</main>bar",
-      "errors": [],
+      "data": "<!doctype html><main><p>foo</main>bar",
+      "errors": [],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "main": true,
+            "p": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "main",
+                    "children": [
+                      {
+                        "tag": "p",
+                        "children": [
+                          {
+                            "text": "foo"
+                          }
+                        ]
+                      }
+                    ]
+                  },
+                  {
+                    "text": "bar"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><main><p>foo</p></main>bar</body></html>",
+        "noQuirksBodyHtml": "<main><p>foo</p></main>bar"
+      }
+    },
+    {
+      "data": "<!DOCTYPE html>xxx<svg><x><g><a><main><b>",
+      "errors": [
+        " * (1,42) unexpected HTML-like start tag token in foreign content",
+        " * (1,42) unexpected end of file"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "svg svg": true,
+            "svg x": true,
+            "svg g": true,
+            "svg a": true,
+            "svg main": true,
+            "b": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "text": "xxx"
+                  },
+                  {
+                    "tag": "svg",
+                    "ns": "http://www.w3.org/2000/svg",
+                    "children": [
+                      {
+                        "tag": "x",
+                        "ns": "http://www.w3.org/2000/svg",
+                        "children": [
+                          {
+                            "tag": "g",
+                            "ns": "http://www.w3.org/2000/svg",
+                            "children": [
+                              {
+                                "tag": "a",
+                                "ns": "http://www.w3.org/2000/svg",
+                                "children": [
+                                  {
+                                    "tag": "main",
+                                    "ns": "http://www.w3.org/2000/svg"
+                                  }
+                                ]
+                              }
+                            ]
+                          }
+                        ]
+                      }
+                    ]
+                  },
+                  {
+                    "tag": "b"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body>xxx<svg><x><g><a><main></main></a></g></x></svg><b></b></body></html>",
+        "noQuirksBodyHtml": "xxx<svg><x><g><a><main><b></b></main></a></g></x></svg>"
+      }
+    }
+  ],
+  "math.dat": [
+    {
+      "data": "<math><tr><td><mo><tr>",
+      "errors": [],
+      "fragment": {
+        "name": "td"
+      },
+      "document": {
+        "props": {
+          "tags": {
+            "math math": true,
+            "math tr": true,
+            "math td": true,
+            "math mo": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "math",
+            "ns": "http://www.w3.org/1998/Math/MathML",
+            "children": [
+              {
+                "tag": "tr",
+                "ns": "http://www.w3.org/1998/Math/MathML",
+                "children": [
+                  {
+                    "tag": "td",
+                    "ns": "http://www.w3.org/1998/Math/MathML",
+                    "children": [
+                      {
+                        "tag": "mo",
+                        "ns": "http://www.w3.org/1998/Math/MathML"
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<math><tr><td><mo></mo></td></tr></math>",
+        "noQuirksBodyHtml": "<math><tr><td><mo></mo></td></tr></math>"
+      }
+    },
+    {
+      "data": "<math><tr><td><mo><tr>",
+      "errors": [],
+      "fragment": {
+        "name": "tr"
+      },
+      "document": {
+        "props": {
+          "tags": {
+            "math math": true,
+            "math tr": true,
+            "math td": true,
+            "math mo": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "math",
+            "ns": "http://www.w3.org/1998/Math/MathML",
+            "children": [
+              {
+                "tag": "tr",
+                "ns": "http://www.w3.org/1998/Math/MathML",
+                "children": [
+                  {
+                    "tag": "td",
+                    "ns": "http://www.w3.org/1998/Math/MathML",
+                    "children": [
+                      {
+                        "tag": "mo",
+                        "ns": "http://www.w3.org/1998/Math/MathML"
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<math><tr><td><mo></mo></td></tr></math>",
+        "noQuirksBodyHtml": "<math><tr><td><mo></mo></td></tr></math>"
+      }
+    },
+    {
+      "data": "<math><thead><mo><tbody>",
+      "errors": [],
+      "fragment": {
+        "name": "thead"
+      },
+      "document": {
+        "props": {
+          "tags": {
+            "math math": true,
+            "math thead": true,
+            "math mo": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "math",
+            "ns": "http://www.w3.org/1998/Math/MathML",
+            "children": [
+              {
+                "tag": "thead",
+                "ns": "http://www.w3.org/1998/Math/MathML",
+                "children": [
+                  {
+                    "tag": "mo",
+                    "ns": "http://www.w3.org/1998/Math/MathML"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<math><thead><mo></mo></thead></math>",
+        "noQuirksBodyHtml": "<math><thead><mo></mo></thead></math>"
+      }
+    },
+    {
+      "data": "<math><tfoot><mo><tbody>",
+      "errors": [],
+      "fragment": {
+        "name": "tfoot"
+      },
+      "document": {
+        "props": {
+          "tags": {
+            "math math": true,
+            "math tfoot": true,
+            "math mo": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "math",
+            "ns": "http://www.w3.org/1998/Math/MathML",
+            "children": [
+              {
+                "tag": "tfoot",
+                "ns": "http://www.w3.org/1998/Math/MathML",
+                "children": [
+                  {
+                    "tag": "mo",
+                    "ns": "http://www.w3.org/1998/Math/MathML"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<math><tfoot><mo></mo></tfoot></math>",
+        "noQuirksBodyHtml": "<math><tfoot><mo></mo></tfoot></math>"
+      }
+    },
+    {
+      "data": "<math><tbody><mo><tfoot>",
+      "errors": [],
+      "fragment": {
+        "name": "tbody"
+      },
+      "document": {
+        "props": {
+          "tags": {
+            "math math": true,
+            "math tbody": true,
+            "math mo": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "math",
+            "ns": "http://www.w3.org/1998/Math/MathML",
+            "children": [
+              {
+                "tag": "tbody",
+                "ns": "http://www.w3.org/1998/Math/MathML",
+                "children": [
+                  {
+                    "tag": "mo",
+                    "ns": "http://www.w3.org/1998/Math/MathML"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<math><tbody><mo></mo></tbody></math>",
+        "noQuirksBodyHtml": "<math><tbody><mo></mo></tbody></math>"
+      }
+    },
+    {
+      "data": "<math><tbody><mo></table>",
+      "errors": [],
+      "fragment": {
+        "name": "tbody"
+      },
+      "document": {
+        "props": {
+          "tags": {
+            "math math": true,
+            "math tbody": true,
+            "math mo": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "math",
+            "ns": "http://www.w3.org/1998/Math/MathML",
+            "children": [
+              {
+                "tag": "tbody",
+                "ns": "http://www.w3.org/1998/Math/MathML",
+                "children": [
+                  {
+                    "tag": "mo",
+                    "ns": "http://www.w3.org/1998/Math/MathML"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<math><tbody><mo></mo></tbody></math>",
+        "noQuirksBodyHtml": "<math><tbody><mo></mo></tbody></math>"
+      }
+    },
+    {
+      "data": "<math><thead><mo></table>",
+      "errors": [],
+      "fragment": {
+        "name": "tbody"
+      },
+      "document": {
+        "props": {
+          "tags": {
+            "math math": true,
+            "math thead": true,
+            "math mo": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "math",
+            "ns": "http://www.w3.org/1998/Math/MathML",
+            "children": [
+              {
+                "tag": "thead",
+                "ns": "http://www.w3.org/1998/Math/MathML",
+                "children": [
+                  {
+                    "tag": "mo",
+                    "ns": "http://www.w3.org/1998/Math/MathML"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<math><thead><mo></mo></thead></math>",
+        "noQuirksBodyHtml": "<math><thead><mo></mo></thead></math>"
+      }
+    },
+    {
+      "data": "<math><tfoot><mo></table>",
+      "errors": [],
+      "fragment": {
+        "name": "tbody"
+      },
+      "document": {
+        "props": {
+          "tags": {
+            "math math": true,
+            "math tfoot": true,
+            "math mo": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "math",
+            "ns": "http://www.w3.org/1998/Math/MathML",
+            "children": [
+              {
+                "tag": "tfoot",
+                "ns": "http://www.w3.org/1998/Math/MathML",
+                "children": [
+                  {
+                    "tag": "mo",
+                    "ns": "http://www.w3.org/1998/Math/MathML"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<math><tfoot><mo></mo></tfoot></math>",
+        "noQuirksBodyHtml": "<math><tfoot><mo></mo></tfoot></math>"
+      }
+    }
+  ],
+  "menuitem-element.dat": [
+    {
+      "data": "<menuitem>",
+      "errors": [
+        "10: Start tag seen without seeing a doctype first. Expected “<!DOCTYPE html>”."
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "menuitem": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "menuitem"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><menuitem></menuitem></body></html>",
+        "noQuirksBodyHtml": "<menuitem></menuitem>"
+      }
+    },
+    {
+      "data": "</menuitem>",
+      "errors": [
+        "11: End tag seen without seeing a doctype first. Expected “<!DOCTYPE html>”.",
+        "11: Stray end tag “menuitem”."
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body></body></html>",
+        "noQuirksBodyHtml": ""
+      }
+    },
+    {
+      "data": "<!DOCTYPE html><body><menuitem>A",
+      "errors": [],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "menuitem": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "menuitem",
+                    "children": [
+                      {
+                        "text": "A"
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><menuitem>A</menuitem></body></html>",
+        "noQuirksBodyHtml": "<menuitem>A</menuitem>"
+      }
+    },
+    {
+      "data": "<!DOCTYPE html><body><menuitem>A<menuitem>B",
+      "errors": [],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "menuitem": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "menuitem",
+                    "children": [
+                      {
+                        "text": "A"
+                      }
+                    ]
+                  },
+                  {
+                    "tag": "menuitem",
+                    "children": [
+                      {
+                        "text": "B"
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><menuitem>A</menuitem><menuitem>B</menuitem></body></html>",
+        "noQuirksBodyHtml": "<menuitem>A</menuitem><menuitem>B</menuitem>"
+      }
+    },
+    {
+      "data": "<!DOCTYPE html><body><menuitem>A<menu>B</menu>",
+      "errors": [],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "menuitem": true,
+            "menu": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "menuitem",
+                    "children": [
+                      {
+                        "text": "A"
+                      }
+                    ]
+                  },
+                  {
+                    "tag": "menu",
+                    "children": [
+                      {
+                        "text": "B"
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><menuitem>A</menuitem><menu>B</menu></body></html>",
+        "noQuirksBodyHtml": "<menuitem>A</menuitem><menu>B</menu>"
+      }
+    },
+    {
+      "data": "<!DOCTYPE html><body><menuitem>A<hr>B",
+      "errors": [],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "menuitem": true,
+            "hr": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "menuitem",
+                    "children": [
+                      {
+                        "text": "A"
+                      }
+                    ]
+                  },
+                  {
+                    "tag": "hr"
+                  },
+                  {
+                    "text": "B"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><menuitem>A</menuitem><hr>B</body></html>",
+        "noQuirksBodyHtml": "<menuitem>A</menuitem><hr>B"
+      }
+    },
+    {
+      "data": "<!DOCTYPE html><li><menuitem><li>",
+      "errors": [],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "li": true,
+            "menuitem": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "li",
+                    "children": [
+                      {
+                        "tag": "menuitem"
+                      }
+                    ]
+                  },
+                  {
+                    "tag": "li"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><li><menuitem></menuitem></li><li></li></body></html>",
+        "noQuirksBodyHtml": "<li><menuitem></menuitem></li><li></li>"
+      }
+    },
+    {
+      "data": "<!DOCTYPE html><menuitem><p></menuitem>x",
+      "errors": [
+        "39: Stray end tag “menuitem”."
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "menuitem": true,
+            "p": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "menuitem",
+                    "children": [
+                      {
+                        "tag": "p",
+                        "children": [
+                          {
+                            "text": "x"
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><menuitem><p>x</p></menuitem></body></html>",
+        "noQuirksBodyHtml": "<menuitem><p>x</p></menuitem>"
+      }
+    },
+    {
+      "data": "<!DOCTYPE html><p><b></p><menuitem>",
+      "errors": [
+        "25: End tag “p” seen, but there were open elements.",
+        "21: Unclosed element “b”.",
+        "35: End of file seen and there were open elements."
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "p": true,
+            "b": true,
+            "menuitem": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "p",
+                    "children": [
+                      {
+                        "tag": "b"
+                      }
+                    ]
+                  },
+                  {
+                    "tag": "b",
+                    "children": [
+                      {
+                        "tag": "menuitem"
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><p><b></b></p><b><menuitem></menuitem></b></body></html>",
+        "noQuirksBodyHtml": "<p><b></b></p><b><menuitem></menuitem></b>"
+      }
+    },
+    {
+      "data": "<!DOCTYPE html><menuitem><asdf></menuitem>x",
+      "errors": [
+        "40: End tag “menuitem” seen, but there were open elements.",
+        "31: Unclosed element “asdf”."
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "menuitem": true,
+            "asdf": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "menuitem",
+                    "children": [
+                      {
+                        "tag": "asdf"
+                      }
+                    ]
+                  },
+                  {
+                    "text": "x"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><menuitem><asdf></asdf></menuitem>x</body></html>",
+        "noQuirksBodyHtml": "<menuitem><asdf></asdf></menuitem>x"
+      }
+    },
+    {
+      "data": "<!DOCTYPE html></menuitem>",
+      "errors": [
+        "26: Stray end tag “menuitem”."
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body></body></html>",
+        "noQuirksBodyHtml": ""
+      }
+    },
+    {
+      "data": "<!DOCTYPE html><html></menuitem>",
+      "errors": [
+        "26: Stray end tag “menuitem”."
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body></body></html>",
+        "noQuirksBodyHtml": ""
+      }
+    },
+    {
+      "data": "<!DOCTYPE html><head></menuitem>",
+      "errors": [
+        "26: Stray end tag “menuitem”."
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body></body></html>",
+        "noQuirksBodyHtml": ""
+      }
+    },
+    {
+      "data": "<!DOCTYPE html><select><menuitem></select>",
+      "errors": [
+        "33: Stray start tag “menuitem”."
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "select": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "select"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><select></select></body></html>",
+        "noQuirksBodyHtml": "<select></select>"
+      }
+    },
+    {
+      "data": "<!DOCTYPE html><option><menuitem>",
+      "errors": [],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "option": true,
+            "menuitem": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "option",
+                    "children": [
+                      {
+                        "tag": "menuitem"
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><option><menuitem></menuitem></option></body></html>",
+        "noQuirksBodyHtml": "<option><menuitem></menuitem></option>"
+      }
+    },
+    {
+      "data": "<!DOCTYPE html><menuitem><option>",
+      "errors": [],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "menuitem": true,
+            "option": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "menuitem",
+                    "children": [
+                      {
+                        "tag": "option"
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><menuitem><option></option></menuitem></body></html>",
+        "noQuirksBodyHtml": "<menuitem><option></option></menuitem>"
+      }
+    },
+    {
+      "data": "<!DOCTYPE html><menuitem></body>",
+      "errors": [],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "menuitem": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "menuitem"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><menuitem></menuitem></body></html>",
+        "noQuirksBodyHtml": "<menuitem></menuitem>"
+      }
+    },
+    {
+      "data": "<!DOCTYPE html><menuitem></html>",
+      "errors": [],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "menuitem": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "menuitem"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><menuitem></menuitem></body></html>",
+        "noQuirksBodyHtml": "<menuitem></menuitem>"
+      }
+    },
+    {
+      "data": "<!DOCTYPE html><menuitem><p>",
+      "errors": [],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "menuitem": true,
+            "p": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "menuitem",
+                    "children": [
+                      {
+                        "tag": "p"
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><menuitem><p></p></menuitem></body></html>",
+        "noQuirksBodyHtml": "<menuitem><p></p></menuitem>"
+      }
+    },
+    {
+      "data": "<!DOCTYPE html><menuitem><li>",
+      "errors": [],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "menuitem": true,
+            "li": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "menuitem",
+                    "children": [
+                      {
+                        "tag": "li"
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><menuitem><li></li></menuitem></body></html>",
+        "noQuirksBodyHtml": "<menuitem><li></li></menuitem>"
+      }
+    }
+  ],
+  "namespace-sensitivity.dat": [
+    {
+      "data": "<body><table><tr><td><svg><td><foreignObject><span></td>Foo",
+      "errors": [],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "table": true,
+            "tbody": true,
+            "tr": true,
+            "td": true,
+            "svg svg": true,
+            "svg td": true,
+            "svg foreignObject": true,
+            "span": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "text": "Foo"
+                  },
+                  {
+                    "tag": "table",
+                    "children": [
+                      {
+                        "tag": "tbody",
+                        "children": [
+                          {
+                            "tag": "tr",
+                            "children": [
+                              {
+                                "tag": "td",
+                                "children": [
+                                  {
+                                    "tag": "svg",
+                                    "ns": "http://www.w3.org/2000/svg",
+                                    "children": [
+                                      {
+                                        "tag": "td",
+                                        "ns": "http://www.w3.org/2000/svg",
+                                        "children": [
+                                          {
+                                            "tag": "foreignObject",
+                                            "ns": "http://www.w3.org/2000/svg",
+                                            "children": [
+                                              {
+                                                "tag": "span"
+                                              }
+                                            ]
+                                          }
+                                        ]
+                                      }
+                                    ]
+                                  }
+                                ]
+                              }
+                            ]
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body>Foo<table><tbody><tr><td><svg><td><foreignObject><span></span></foreignObject></td></svg></td></tr></tbody></table></body></html>",
+        "noQuirksBodyHtml": "Foo<table><tbody><tr><td><svg><td><foreignObject><span></span></foreignObject></td></svg></td></tr></tbody></table>"
+      }
+    }
+  ],
+  "noscript01.dat": [
+    {
+      "data": "<head><noscript><!doctype html><!--foo--></noscript>",
+      "errors": [
+        "Line: 1 Col: 6 Unexpected start tag (head). Expected DOCTYPE.",
+        "Line: 1 Col: 31 Unexpected DOCTYPE. Ignored."
+      ],
+      "script": "off",
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "noscript": true,
+            "body": true
+          },
+          "comment": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head",
+                "children": [
+                  {
+                    "tag": "noscript",
+                    "children": [
+                      {
+                        "comment": "foo"
+                      }
+                    ]
+                  }
+                ]
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          }
+        ],
+        "html": "<html><head><noscript><!--foo--></noscript></head><body></body></html>",
+        "noQuirksBodyHtml": "<noscript><!--foo--></noscript>"
+      }
+    },
+    {
+      "data": "<head><noscript><html class=\"foo\"><!--foo--></noscript>",
+      "errors": [
+        "Line: 1 Col: 6 Unexpected start tag (head). Expected DOCTYPE.",
+        "Line: 1 Col: 34 html needs to be the first start tag."
+      ],
+      "script": "off",
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "noscript": true,
+            "body": true
+          },
+          "comment": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "attrs": [
+              {
+                "name": "class",
+                "value": "foo"
+              }
+            ],
+            "children": [
+              {
+                "tag": "head",
+                "children": [
+                  {
+                    "tag": "noscript",
+                    "children": [
+                      {
+                        "comment": "foo"
+                      }
+                    ]
+                  }
+                ]
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          }
+        ],
+        "html": "<html class=\"foo\"><head><noscript><!--foo--></noscript></head><body></body></html>",
+        "noQuirksBodyHtml": "<noscript><!--foo--></noscript>"
+      }
+    },
+    {
+      "data": "<head><noscript></noscript>",
+      "errors": [
+        "(1,6): expected-doctype-but-got-tag"
+      ],
+      "script": "off",
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "noscript": true,
+            "body": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head",
+                "children": [
+                  {
+                    "tag": "noscript"
+                  }
+                ]
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          }
+        ],
+        "html": "<html><head><noscript></noscript></head><body></body></html>",
+        "noQuirksBodyHtml": "<noscript></noscript>"
+      }
+    },
+    {
+      "data": "<head><noscript>   </noscript>",
+      "errors": [
+        "Line: 1 Col: 6 Unexpected start tag (head). Expected DOCTYPE."
+      ],
+      "script": "off",
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "noscript": true,
+            "body": true
+          },
+          "no_escape": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head",
+                "children": [
+                  {
+                    "tag": "noscript",
+                    "children": [
+                      {
+                        "text": "   ",
+                        "no_escape": true
+                      }
+                    ]
+                  }
+                ]
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          }
+        ],
+        "html": "<html><head><noscript>   </noscript></head><body></body></html>",
+        "noQuirksBodyHtml": "<noscript>   </noscript>"
+      }
+    },
+    {
+      "data": "<head><noscript><!--foo--></noscript>",
+      "errors": [
+        "(1,6): expected-doctype-but-got-tag"
+      ],
+      "script": "off",
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "noscript": true,
+            "body": true
+          },
+          "comment": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head",
+                "children": [
+                  {
+                    "tag": "noscript",
+                    "children": [
+                      {
+                        "comment": "foo"
+                      }
+                    ]
+                  }
+                ]
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          }
+        ],
+        "html": "<html><head><noscript><!--foo--></noscript></head><body></body></html>",
+        "noQuirksBodyHtml": "<noscript><!--foo--></noscript>"
+      }
+    },
+    {
+      "data": "<head><noscript><basefont><!--foo--></noscript>",
+      "errors": [
+        "Line: 1 Col: 6 Unexpected start tag (head). Expected DOCTYPE."
+      ],
+      "script": "off",
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "noscript": true,
+            "basefont": true,
+            "body": true
+          },
+          "comment": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head",
+                "children": [
+                  {
+                    "tag": "noscript",
+                    "children": [
+                      {
+                        "tag": "basefont"
+                      },
+                      {
+                        "comment": "foo"
+                      }
+                    ]
+                  }
+                ]
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          }
+        ],
+        "html": "<html><head><noscript><basefont><!--foo--></noscript></head><body></body></html>",
+        "noQuirksBodyHtml": "<noscript><basefont><!--foo--></noscript>"
+      }
+    },
+    {
+      "data": "<head><noscript><bgsound><!--foo--></noscript>",
+      "errors": [
+        "Line: 1 Col: 6 Unexpected start tag (head). Expected DOCTYPE."
+      ],
+      "script": "off",
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "noscript": true,
+            "bgsound": true,
+            "body": true
+          },
+          "comment": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head",
+                "children": [
+                  {
+                    "tag": "noscript",
+                    "children": [
+                      {
+                        "tag": "bgsound"
+                      },
+                      {
+                        "comment": "foo"
+                      }
+                    ]
+                  }
+                ]
+              },
+              {
+                "tag": "body"
+              }
+            ]
+          }
+        ],
+        "html": "<html><head><noscript><bgsound><!--foo--></noscript></head><body></body></html>",
+        "noQuirksBodyHtml": "<noscript><bgsound><!--foo--></noscript>"
+      }
+    },
+    {
+      "data": "<head><noscript><link><!--foo--></noscript>",
+      "errors": [
+        "Line: 1 Col: 6 Unexpected start tag (head). Expected DOCTYPE."
+      ],
+      "script": "off",
       "document": {
         "props": {
           "tags": {
             "html": true,
             "head": true,
-            "body": true,
-            "main": true,
-            "p": true
+            "noscript": true,
+            "link": true,
+            "body": true
           },
-          "doctype": true
+          "comment": true
         },
         "tree": [
-          {
-            "doctype": "html"
-          },
           {
             "tag": "html",
             "children": [
               {
-                "tag": "head"
-              },
-              {
-                "tag": "body",
+                "tag": "head",
                 "children": [
                   {
-                    "tag": "main",
+                    "tag": "noscript",
                     "children": [
                       {
-                        "tag": "p",
-                        "children": [
-                          {
-                            "text": "foo"
-                          }
-                        ]
+                        "tag": "link"
+                      },
+                      {
+                        "comment": "foo"
                       }
                     ]
-                  },
-                  {
-                    "text": "bar"
                   }
                 ]
+              },
+              {
+                "tag": "body"
               }
             ]
           }
         ],
-        "html": "<!DOCTYPE html><html><head></head><body><main><p>foo</p></main>bar</body></html>",
-        "noQuirksBodyHtml": "<main><p>foo</p></main>bar"
+        "html": "<html><head><noscript><link><!--foo--></noscript></head><body></body></html>",
+        "noQuirksBodyHtml": "<noscript><link><!--foo--></noscript>"
       }
     },
     {
-      "data": "<!DOCTYPE html>xxx<svg><x><g><a><main><b>",
+      "data": "<head><noscript><meta><!--foo--></noscript>",
       "errors": [
-        " * (1,42) unexpected HTML-like start tag token in foreign content",
-        " * (1,42) unexpected end of file"
+        "Line: 1 Col: 6 Unexpected start tag (head). Expected DOCTYPE."
       ],
+      "script": "off",
       "document": {
         "props": {
           "tags": {
             "html": true,
             "head": true,
-            "body": true,
-            "svg svg": true,
-            "svg x": true,
-            "svg g": true,
-            "svg a": true,
-            "svg main": true,
-            "b": true
+            "noscript": true,
+            "meta": true,
+            "body": true
           },
-          "doctype": true
+          "comment": true
         },
         "tree": [
-          {
-            "doctype": "html"
-          },
           {
             "tag": "html",
             "children": [
               {
-                "tag": "head"
-              },
-              {
-                "tag": "body",
+                "tag": "head",
                 "children": [
                   {
-                    "text": "xxx"
-                  },
-                  {
-                    "tag": "svg",
-                    "ns": "http://www.w3.org/2000/svg",
+                    "tag": "noscript",
                     "children": [
                       {
-                        "tag": "x",
-                        "ns": "http://www.w3.org/2000/svg",
-                        "children": [
-                          {
-                            "tag": "g",
-                            "ns": "http://www.w3.org/2000/svg",
-                            "children": [
-                              {
-                                "tag": "a",
-                                "ns": "http://www.w3.org/2000/svg",
-                                "children": [
-                                  {
-                                    "tag": "main",
-                                    "ns": "http://www.w3.org/2000/svg"
-                                  }
-                                ]
-                              }
-                            ]
-                          }
-                        ]
+                        "tag": "meta"
+                      },
+                      {
+                        "comment": "foo"
                       }
                     ]
-                  },
-                  {
-                    "tag": "b"
                   }
                 ]
+              },
+              {
+                "tag": "body"
               }
             ]
           }
         ],
-        "html": "<!DOCTYPE html><html><head></head><body>xxx<svg><x><g><a><main></main></a></g></x></svg><b></b></body></html>",
-        "noQuirksBodyHtml": "xxx<svg><x><g><a><main><b></b></main></a></g></x></svg>"
+        "html": "<html><head><noscript><meta><!--foo--></noscript></head><body></body></html>",
+        "noQuirksBodyHtml": "<noscript><meta><!--foo--></noscript>"
       }
-    }
-  ],
-  "math.dat": [
+    },
     {
-      "data": "<math><tr><td><mo><tr>",
-      "errors": [],
-      "fragment": {
-        "name": "td"
-      },
+      "data": "<head><noscript><noframes>XXX</noscript></noframes></noscript>",
+      "errors": [
+        "Line: 1 Col: 6 Unexpected start tag (head). Expected DOCTYPE."
+      ],
+      "script": "off",
       "document": {
         "props": {
           "tags": {
-            "math math": true,
-            "math tr": true,
-            "math td": true,
-            "math mo": true
-          }
+            "html": true,
+            "head": true,
+            "noscript": true,
+            "noframes": true,
+            "body": true
+          },
+          "no_escape": true
         },
         "tree": [
           {
-            "tag": "math",
-            "ns": "http://www.w3.org/1998/Math/MathML",
+            "tag": "html",
             "children": [
               {
-                "tag": "tr",
-                "ns": "http://www.w3.org/1998/Math/MathML",
+                "tag": "head",
                 "children": [
                   {
-                    "tag": "td",
-                    "ns": "http://www.w3.org/1998/Math/MathML",
+                    "tag": "noscript",
                     "children": [
                       {
-                        "tag": "mo",
-                        "ns": "http://www.w3.org/1998/Math/MathML"
+                        "tag": "noframes",
+                        "children": [
+                          {
+                            "text": "XXX</noscript>",
+                            "no_escape": true
+                          }
+                        ]
                       }
                     ]
                   }
                 ]
+              },
+              {
+                "tag": "body"
               }
             ]
           }
         ],
-        "html": "<math><tr><td><mo></mo></td></tr></math>",
-        "noQuirksBodyHtml": "<math><tr><td><mo></mo></td></tr></math>"
+        "html": "<html><head><noscript><noframes>XXX</noscript></noframes></noscript></head><body></body></html>",
+        "noQuirksBodyHtml": "<noscript><noframes>XXX</noscript></noframes></noscript>"
       }
     },
     {
-      "data": "<math><tr><td><mo><tr>",
-      "errors": [],
-      "fragment": {
-        "name": "tr"
-      },
+      "data": "<head><noscript><style>XXX</style></noscript>",
+      "errors": [
+        "Line: 1 Col: 6 Unexpected start tag (head). Expected DOCTYPE."
+      ],
+      "script": "off",
       "document": {
         "props": {
           "tags": {
-            "math math": true,
-            "math tr": true,
-            "math td": true,
-            "math mo": true
-          }
+            "html": true,
+            "head": true,
+            "noscript": true,
+            "style": true,
+            "body": true
+          },
+          "no_escape": true
         },
         "tree": [
           {
-            "tag": "math",
-            "ns": "http://www.w3.org/1998/Math/MathML",
+            "tag": "html",
             "children": [
               {
-                "tag": "tr",
-                "ns": "http://www.w3.org/1998/Math/MathML",
+                "tag": "head",
                 "children": [
                   {
-                    "tag": "td",
-                    "ns": "http://www.w3.org/1998/Math/MathML",
+                    "tag": "noscript",
                     "children": [
                       {
-                        "tag": "mo",
-                        "ns": "http://www.w3.org/1998/Math/MathML"
+                        "tag": "style",
+                        "children": [
+                          {
+                            "text": "XXX",
+                            "no_escape": true
+                          }
+                        ]
                       }
                     ]
                   }
                 ]
+              },
+              {
+                "tag": "body"
               }
             ]
           }
         ],
-        "html": "<math><tr><td><mo></mo></td></tr></math>",
-        "noQuirksBodyHtml": "<math><tr><td><mo></mo></td></tr></math>"
+        "html": "<html><head><noscript><style>XXX</style></noscript></head><body></body></html>",
+        "noQuirksBodyHtml": "<noscript><style>XXX</style></noscript>"
       }
     },
     {
-      "data": "<math><thead><mo><tbody>",
-      "errors": [],
-      "fragment": {
-        "name": "thead"
-      },
+      "data": "<head><noscript></br><!--foo--></noscript>",
+      "errors": [
+        "Line: 1 Col: 6 Unexpected start tag (head). Expected DOCTYPE.",
+        "Line: 1 Col: 21 Element br not allowed in a inhead-noscript context",
+        "Line: 1 Col: 21 Unexpected end tag (br). Treated as br element.",
+        "Line: 1 Col: 42 Unexpected end tag (noscript). Ignored."
+      ],
+      "script": "off",
       "document": {
         "props": {
           "tags": {
-            "math math": true,
-            "math thead": true,
-            "math mo": true
-          }
+            "html": true,
+            "head": true,
+            "noscript": true,
+            "body": true,
+            "br": true
+          },
+          "comment": true
         },
         "tree": [
           {
-            "tag": "math",
-            "ns": "http://www.w3.org/1998/Math/MathML",
+            "tag": "html",
             "children": [
               {
-                "tag": "thead",
-                "ns": "http://www.w3.org/1998/Math/MathML",
+                "tag": "head",
                 "children": [
                   {
-                    "tag": "mo",
-                    "ns": "http://www.w3.org/1998/Math/MathML"
+                    "tag": "noscript"
+                  }
+                ]
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "br"
+                  },
+                  {
+                    "comment": "foo"
                   }
                 ]
               }
             ]
           }
         ],
-        "html": "<math><thead><mo></mo></thead></math>",
-        "noQuirksBodyHtml": "<math><thead><mo></mo></thead></math>"
+        "html": "<html><head><noscript></noscript></head><body><br><!--foo--></body></html>",
+        "noQuirksBodyHtml": "<noscript><br><!--foo--></noscript>"
       }
     },
     {
-      "data": "<math><tfoot><mo><tbody>",
-      "errors": [],
-      "fragment": {
-        "name": "tfoot"
-      },
+      "data": "<head><noscript><head class=\"foo\"><!--foo--></noscript>",
+      "errors": [
+        "Line: 1 Col: 6 Unexpected start tag (head). Expected DOCTYPE.",
+        "Line: 1 Col: 34 Unexpected start tag (head)."
+      ],
+      "script": "off",
       "document": {
         "props": {
           "tags": {
-            "math math": true,
-            "math tfoot": true,
-            "math mo": true
-          }
+            "html": true,
+            "head": true,
+            "noscript": true,
+            "body": true
+          },
+          "comment": true
         },
         "tree": [
           {
-            "tag": "math",
-            "ns": "http://www.w3.org/1998/Math/MathML",
+            "tag": "html",
             "children": [
               {
-                "tag": "tfoot",
-                "ns": "http://www.w3.org/1998/Math/MathML",
+                "tag": "head",
                 "children": [
                   {
-                    "tag": "mo",
-                    "ns": "http://www.w3.org/1998/Math/MathML"
+                    "tag": "noscript",
+                    "children": [
+                      {
+                        "comment": "foo"
+                      }
+                    ]
                   }
                 ]
+              },
+              {
+                "tag": "body"
               }
             ]
           }
         ],
-        "html": "<math><tfoot><mo></mo></tfoot></math>",
-        "noQuirksBodyHtml": "<math><tfoot><mo></mo></tfoot></math>"
+        "html": "<html><head><noscript><!--foo--></noscript></head><body></body></html>",
+        "noQuirksBodyHtml": "<noscript><!--foo--></noscript>"
       }
     },
     {
-      "data": "<math><tbody><mo><tfoot>",
-      "errors": [],
-      "fragment": {
-        "name": "tbody"
-      },
+      "data": "<head><noscript><noscript class=\"foo\"><!--foo--></noscript>",
+      "errors": [
+        "Line: 1 Col: 6 Unexpected start tag (head). Expected DOCTYPE.",
+        "Line: 1 Col: 34 Unexpected start tag (noscript)."
+      ],
+      "script": "off",
       "document": {
         "props": {
           "tags": {
-            "math math": true,
-            "math tbody": true,
-            "math mo": true
-          }
+            "html": true,
+            "head": true,
+            "noscript": true,
+            "body": true
+          },
+          "comment": true
         },
         "tree": [
           {
-            "tag": "math",
-            "ns": "http://www.w3.org/1998/Math/MathML",
+            "tag": "html",
             "children": [
               {
-                "tag": "tbody",
-                "ns": "http://www.w3.org/1998/Math/MathML",
+                "tag": "head",
                 "children": [
                   {
-                    "tag": "mo",
-                    "ns": "http://www.w3.org/1998/Math/MathML"
+                    "tag": "noscript",
+                    "children": [
+                      {
+                        "comment": "foo"
+                      }
+                    ]
                   }
                 ]
+              },
+              {
+                "tag": "body"
               }
             ]
           }
         ],
-        "html": "<math><tbody><mo></mo></tbody></math>",
-        "noQuirksBodyHtml": "<math><tbody><mo></mo></tbody></math>"
+        "html": "<html><head><noscript><!--foo--></noscript></head><body></body></html>",
+        "noQuirksBodyHtml": "<noscript><noscript class=\"foo\"><!--foo--></noscript></noscript>"
       }
     },
     {
-      "data": "<math><tbody><mo></table>",
-      "errors": [],
-      "fragment": {
-        "name": "tbody"
-      },
+      "data": "<head><noscript></p><!--foo--></noscript>",
+      "errors": [
+        "Line: 1 Col: 6 Unexpected start tag (head). Expected DOCTYPE.",
+        "Line: 1 Col: 20 Unexpected end tag (p). Ignored."
+      ],
+      "script": "off",
       "document": {
         "props": {
           "tags": {
-            "math math": true,
-            "math tbody": true,
-            "math mo": true
-          }
+            "html": true,
+            "head": true,
+            "noscript": true,
+            "body": true
+          },
+          "comment": true
         },
         "tree": [
           {
-            "tag": "math",
-            "ns": "http://www.w3.org/1998/Math/MathML",
+            "tag": "html",
             "children": [
               {
-                "tag": "tbody",
-                "ns": "http://www.w3.org/1998/Math/MathML",
+                "tag": "head",
                 "children": [
                   {
-                    "tag": "mo",
-                    "ns": "http://www.w3.org/1998/Math/MathML"
+                    "tag": "noscript",
+                    "children": [
+                      {
+                        "comment": "foo"
+                      }
+                    ]
                   }
                 ]
+              },
+              {
+                "tag": "body"
               }
             ]
           }
         ],
-        "html": "<math><tbody><mo></mo></tbody></math>",
-        "noQuirksBodyHtml": "<math><tbody><mo></mo></tbody></math>"
+        "html": "<html><head><noscript><!--foo--></noscript></head><body></body></html>",
+        "noQuirksBodyHtml": "<noscript><p></p><!--foo--></noscript>"
       }
     },
     {
-      "data": "<math><thead><mo></table>",
-      "errors": [],
-      "fragment": {
-        "name": "tbody"
-      },
+      "data": "<head><noscript><p><!--foo--></noscript>",
+      "errors": [
+        "Line: 1 Col: 6 Unexpected start tag (head). Expected DOCTYPE.",
+        "Line: 1 Col: 19 Element p not allowed in a inhead-noscript context",
+        "Line: 1 Col: 40 Unexpected end tag (noscript). Ignored."
+      ],
+      "script": "off",
       "document": {
         "props": {
           "tags": {
-            "math math": true,
-            "math thead": true,
-            "math mo": true
-          }
+            "html": true,
+            "head": true,
+            "noscript": true,
+            "body": true,
+            "p": true
+          },
+          "comment": true
         },
         "tree": [
           {
-            "tag": "math",
-            "ns": "http://www.w3.org/1998/Math/MathML",
+            "tag": "html",
             "children": [
               {
-                "tag": "thead",
-                "ns": "http://www.w3.org/1998/Math/MathML",
+                "tag": "head",
                 "children": [
                   {
-                    "tag": "mo",
-                    "ns": "http://www.w3.org/1998/Math/MathML"
+                    "tag": "noscript"
+                  }
+                ]
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "p",
+                    "children": [
+                      {
+                        "comment": "foo"
+                      }
+                    ]
                   }
                 ]
               }
             ]
           }
         ],
-        "html": "<math><thead><mo></mo></thead></math>",
-        "noQuirksBodyHtml": "<math><thead><mo></mo></thead></math>"
+        "html": "<html><head><noscript></noscript></head><body><p><!--foo--></p></body></html>",
+        "noQuirksBodyHtml": "<noscript><p><!--foo--></p></noscript>"
       }
     },
     {
-      "data": "<math><tfoot><mo></table>",
-      "errors": [],
-      "fragment": {
-        "name": "tbody"
-      },
+      "data": "<head><noscript>XXX<!--foo--></noscript></head>",
+      "errors": [
+        "Line: 1 Col: 6 Unexpected start tag (head). Expected DOCTYPE.",
+        "Line: 1 Col: 19 Unexpected non-space character. Expected inhead-noscript content",
+        "Line: 1 Col: 30 Unexpected end tag (noscript). Ignored.",
+        "Line: 1 Col: 37 Unexpected end tag (head). Ignored."
+      ],
+      "script": "off",
       "document": {
         "props": {
           "tags": {
-            "math math": true,
-            "math tfoot": true,
-            "math mo": true
-          }
+            "html": true,
+            "head": true,
+            "noscript": true,
+            "body": true
+          },
+          "comment": true
         },
         "tree": [
           {
-            "tag": "math",
-            "ns": "http://www.w3.org/1998/Math/MathML",
+            "tag": "html",
             "children": [
               {
-                "tag": "tfoot",
-                "ns": "http://www.w3.org/1998/Math/MathML",
+                "tag": "head",
                 "children": [
                   {
-                    "tag": "mo",
-                    "ns": "http://www.w3.org/1998/Math/MathML"
+                    "tag": "noscript"
+                  }
+                ]
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "text": "XXX"
+                  },
+                  {
+                    "comment": "foo"
                   }
                 ]
               }
             ]
           }
         ],
-        "html": "<math><tfoot><mo></mo></tfoot></math>",
-        "noQuirksBodyHtml": "<math><tfoot><mo></mo></tfoot></math>"
+        "html": "<html><head><noscript></noscript></head><body>XXX<!--foo--></body></html>",
+        "noQuirksBodyHtml": "<noscript>XXX<!--foo--></noscript>"
       }
-    }
-  ],
-  "namespace-sensitivity.dat": [
+    },
     {
-      "data": "<body><table><tr><td><svg><td><foreignObject><span></td>Foo",
-      "errors": [],
+      "data": "<head><noscript>",
+      "errors": [
+        "(1,6): expected-doctype-but-got-tag",
+        "(1,6): eof-in-head-noscript"
+      ],
+      "script": "off",
       "document": {
         "props": {
           "tags": {
             "html": true,
             "head": true,
-            "body": true,
-            "table": true,
-            "tbody": true,
-            "tr": true,
-            "td": true,
-            "svg svg": true,
-            "svg td": true,
-            "svg foreignObject": true,
-            "span": true
+            "noscript": true,
+            "body": true
           }
         },
         "tree": [
             "tag": "html",
             "children": [
               {
-                "tag": "head"
-              },
-              {
-                "tag": "body",
+                "tag": "head",
                 "children": [
                   {
-                    "text": "Foo"
-                  },
-                  {
-                    "tag": "table",
-                    "children": [
-                      {
-                        "tag": "tbody",
-                        "children": [
-                          {
-                            "tag": "tr",
-                            "children": [
-                              {
-                                "tag": "td",
-                                "children": [
-                                  {
-                                    "tag": "svg",
-                                    "ns": "http://www.w3.org/2000/svg",
-                                    "children": [
-                                      {
-                                        "tag": "td",
-                                        "ns": "http://www.w3.org/2000/svg",
-                                        "children": [
-                                          {
-                                            "tag": "foreignObject",
-                                            "ns": "http://www.w3.org/2000/svg",
-                                            "children": [
-                                              {
-                                                "tag": "span"
-                                              }
-                                            ]
-                                          }
-                                        ]
-                                      }
-                                    ]
-                                  }
-                                ]
-                              }
-                            ]
-                          }
-                        ]
-                      }
-                    ]
+                    "tag": "noscript"
                   }
                 ]
+              },
+              {
+                "tag": "body"
               }
             ]
           }
         ],
-        "html": "<html><head></head><body>Foo<table><tbody><tr><td><svg><td><foreignObject><span></span></foreignObject></td></svg></td></tr></tbody></table></body></html>",
-        "noQuirksBodyHtml": "Foo<table><tbody><tr><td><svg><td><foreignObject><span></span></foreignObject></td></svg></td></tr></tbody></table>"
+        "html": "<html><head><noscript></noscript></head><body></body></html>",
+        "noQuirksBodyHtml": "<noscript></noscript>"
       }
     }
   ],
             "body": true,
             "pre": true
           },
-          "doctype": true,
-          "extraNL": true
+          "doctype": true
         },
         "tree": [
           {
                     "tag": "pre",
                     "children": [
                       {
-                        "text": "\nA",
-                        "extraNL": true
+                        "text": "\nA"
                       }
                     ]
                   }
             ]
           }
         ],
-        "html": "<!DOCTYPE html><html><head></head><body><pre>\n\nA</pre></body></html>",
-        "noQuirksBodyHtml": "<pre>\n\nA</pre>"
+        "html": "<!DOCTYPE html><html><head></head><body><pre>\nA</pre></body></html>",
+        "noQuirksBodyHtml": "<pre>\nA</pre>"
       }
     },
     {
             "body": true,
             "pre": true
           },
-          "doctype": true,
-          "extraNL": true
+          "doctype": true
         },
         "tree": [
           {
                     "tag": "pre",
                     "children": [
                       {
-                        "text": "\nA",
-                        "extraNL": true
+                        "text": "\nA"
                       }
                     ]
                   }
             ]
           }
         ],
-        "html": "<!DOCTYPE html><html><head></head><body><pre>\n\nA</pre></body></html>",
-        "noQuirksBodyHtml": "<pre>\n\nA</pre>"
+        "html": "<!DOCTYPE html><html><head></head><body><pre>\nA</pre></body></html>",
+        "noQuirksBodyHtml": "<pre>\nA</pre>"
       }
     },
     {
     {
       "data": "<html><ruby>a<rb>b<span></ruby></html>",
       "errors": [
-        "(1,6): expected-doctype-but-got-start-tag"
+        "(1,6): expected-doctype-but-got-start-tag",
+        "(1,31): unexpected-end-tag"
       ],
       "document": {
         "props": {
     {
       "data": "<html><ruby>a<rt>b<span></ruby></html>",
       "errors": [
-        "(1,6): expected-doctype-but-got-start-tag"
+        "(1,6): expected-doctype-but-got-start-tag",
+        "(1,31): unexpected-end-tag"
       ],
       "document": {
         "props": {
     {
       "data": "<html><ruby>a<rp>b<span></ruby></html>",
       "errors": [
-        "(1,6): expected-doctype-but-got-start-tag"
+        "(1,6): expected-doctype-but-got-start-tag",
+        "(1,31): unexpected-end-tag"
       ],
       "document": {
         "props": {
         "(1,11): unexpected-start-tag-in-select",
         "(1,27): unexpected-select-in-select",
         "(1,39): unexpected-end-tag",
-        "(1,48): unexpected-end-tag",
-        "(1,49): expected-closing-tag-but-got-eof"
+        "(1,48): unexpected-end-tag"
       ],
       "document": {
         "props": {
         "(1,11): unexpected-start-tag-in-select",
         "(1,27): unexpected-select-in-select",
         "(1,39): unexpected-end-tag",
-        "(1,48): unexpected-end-tag",
-        "(1,48): expected-closing-tag-but-got-eof"
+        "(1,48): unexpected-end-tag"
       ],
       "document": {
         "props": {
         "noQuirksBodyHtml": "<math attributename=\"\" attributetype=\"\" basefrequency=\"\" baseprofile=\"\" calcmode=\"\" clippathunits=\"\" diffuseconstant=\"\" edgemode=\"\" filterunits=\"\" glyphref=\"\" gradienttransform=\"\" gradientunits=\"\" kernelmatrix=\"\" kernelunitlength=\"\" keypoints=\"\" keysplines=\"\" keytimes=\"\" lengthadjust=\"\" limitingconeangle=\"\" markerheight=\"\" markerunits=\"\" markerwidth=\"\" maskcontentunits=\"\" maskunits=\"\" numoctaves=\"\" pathlength=\"\" patterncontentunits=\"\" patterntransform=\"\" patternunits=\"\" pointsatx=\"\" pointsaty=\"\" pointsatz=\"\" preservealpha=\"\" preserveaspectratio=\"\" primitiveunits=\"\" refx=\"\" refy=\"\" repeatcount=\"\" repeatdur=\"\" requiredextensions=\"\" requiredfeatures=\"\" specularconstant=\"\" specularexponent=\"\" spreadmethod=\"\" startoffset=\"\" stddeviation=\"\" stitchtiles=\"\" surfacescale=\"\" systemlanguage=\"\" tablevalues=\"\" targetx=\"\" targety=\"\" textlength=\"\" viewbox=\"\" viewtarget=\"\" xchannelselector=\"\" ychannelselector=\"\" zoomandpan=\"\"></math>"
       }
     },
+    {
+      "data": "<!DOCTYPE html><body><svg contentScriptType='' contentStyleType='' externalResourcesRequired='' filterRes=''></svg>",
+      "errors": [],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "svg svg": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "svg",
+                    "ns": "http://www.w3.org/2000/svg",
+                    "attrs": [
+                      {
+                        "name": "contentscripttype",
+                        "value": ""
+                      },
+                      {
+                        "name": "contentstyletype",
+                        "value": ""
+                      },
+                      {
+                        "name": "externalresourcesrequired",
+                        "value": ""
+                      },
+                      {
+                        "name": "filterres",
+                        "value": ""
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><svg contentscripttype=\"\" contentstyletype=\"\" externalresourcesrequired=\"\" filterres=\"\"></svg></body></html>",
+        "noQuirksBodyHtml": "<svg contentScriptType=\"\" contentStyleType=\"\" externalResourcesRequired=\"\" filterres=\"\"></svg>"
+      }
+    },
+    {
+      "data": "<!DOCTYPE html><body><svg CONTENTSCRIPTTYPE='' CONTENTSTYLETYPE='' EXTERNALRESOURCESREQUIRED='' FILTERRES=''></svg>",
+      "errors": [],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "svg svg": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "svg",
+                    "ns": "http://www.w3.org/2000/svg",
+                    "attrs": [
+                      {
+                        "name": "contentscripttype",
+                        "value": ""
+                      },
+                      {
+                        "name": "contentstyletype",
+                        "value": ""
+                      },
+                      {
+                        "name": "externalresourcesrequired",
+                        "value": ""
+                      },
+                      {
+                        "name": "filterres",
+                        "value": ""
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><svg contentscripttype=\"\" contentstyletype=\"\" externalresourcesrequired=\"\" filterres=\"\"></svg></body></html>",
+        "noQuirksBodyHtml": "<svg contentScriptType=\"\" contentStyleType=\"\" externalResourcesRequired=\"\" filterres=\"\"></svg>"
+      }
+    },
+    {
+      "data": "<!DOCTYPE html><body><svg contentscripttype='' contentstyletype='' externalresourcesrequired='' filterres=''></svg>",
+      "errors": [],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "svg svg": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "svg",
+                    "ns": "http://www.w3.org/2000/svg",
+                    "attrs": [
+                      {
+                        "name": "contentscripttype",
+                        "value": ""
+                      },
+                      {
+                        "name": "contentstyletype",
+                        "value": ""
+                      },
+                      {
+                        "name": "externalresourcesrequired",
+                        "value": ""
+                      },
+                      {
+                        "name": "filterres",
+                        "value": ""
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><svg contentscripttype=\"\" contentstyletype=\"\" externalresourcesrequired=\"\" filterres=\"\"></svg></body></html>",
+        "noQuirksBodyHtml": "<svg contentScriptType=\"\" contentStyleType=\"\" externalResourcesRequired=\"\" filterres=\"\"></svg>"
+      }
+    },
+    {
+      "data": "<!DOCTYPE html><body><math contentScriptType='' contentStyleType='' externalResourcesRequired='' filterRes=''></math>",
+      "errors": [],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "math math": true
+          },
+          "doctype": true
+        },
+        "tree": [
+          {
+            "doctype": "html"
+          },
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "math",
+                    "ns": "http://www.w3.org/1998/Math/MathML",
+                    "attrs": [
+                      {
+                        "name": "contentscripttype",
+                        "value": ""
+                      },
+                      {
+                        "name": "contentstyletype",
+                        "value": ""
+                      },
+                      {
+                        "name": "externalresourcesrequired",
+                        "value": ""
+                      },
+                      {
+                        "name": "filterres",
+                        "value": ""
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<!DOCTYPE html><html><head></head><body><math contentscripttype=\"\" contentstyletype=\"\" externalresourcesrequired=\"\" filterres=\"\"></math></body></html>",
+        "noQuirksBodyHtml": "<math contentscripttype=\"\" contentstyletype=\"\" externalresourcesrequired=\"\" filterres=\"\"></math>"
+      }
+    },
     {
       "data": "<!DOCTYPE html><body><svg><altGlyph /><altGlyphDef /><altGlyphItem /><animateColor /><animateMotion /><animateTransform /><clipPath /><feBlend /><feColorMatrix /><feComponentTransfer /><feComposite /><feConvolveMatrix /><feDiffuseLighting /><feDisplacementMap /><feDistantLight /><feFlood /><feFuncA /><feFuncB /><feFuncG /><feFuncR /><feGaussianBlur /><feImage /><feMerge /><feMergeNode /><feMorphology /><feOffset /><fePointLight /><feSpecularLighting /><feSpotLight /><feTile /><feTurbulence /><foreignObject /><glyphRef /><linearGradient /><radialGradient /><textPath /></svg>",
       "errors": [],
     {
       "data": "<!doctype html><script><!",
       "errors": [
+        "(1,25): expected-script-data-but-got-eof",
         "(1,25): expected-named-closing-tag-but-got-eof"
       ],
       "document": {
           }
         ],
         "html": "<!DOCTYPE html><html><head><noscript><!--<noscript></noscript></head><body>--&gt;</body></html>",
-        "noQuirksBodyHtml": "<noscript>&lt;!--&lt;noscript&gt;</noscript>--&gt;"
+        "noQuirksBodyHtml": "<noscript><!--<noscript></noscript>--></noscript>"
       }
     },
     {
           }
         ],
         "html": "<!DOCTYPE html><html><head><noscript><!--<noscript></noscript>--></noscript></head><body></body></html>",
-        "noQuirksBodyHtml": "<noscript>&lt;!--&lt;noscript&gt;</noscript>--&gt;"
+        "noQuirksBodyHtml": "<noscript><!--<noscript></noscript>--></noscript>"
       }
     },
     {
           }
         ],
         "html": "<!DOCTYPE html><html><head><noscript><!--</noscript></head><body>X<noscript>--></noscript></body></html>",
-        "noQuirksBodyHtml": "<noscript>&lt;!--</noscript>X<noscript>--&gt;</noscript>"
+        "noQuirksBodyHtml": "<noscript><!--</noscript>X<noscript>--></noscript>"
       }
     },
     {
           }
         ],
         "html": "<!DOCTYPE html><html><head><noscript><!--</noscript>X<noscript>--></noscript></head><body></body></html>",
-        "noQuirksBodyHtml": "<noscript>&lt;!--</noscript>X<noscript>--&gt;</noscript>"
+        "noQuirksBodyHtml": "<noscript><!--</noscript>X<noscript>--></noscript>"
       }
     },
     {
           }
         ],
         "html": "<!DOCTYPE html><html><head><noscript><iframe></noscript></head><body>X</body></html>",
-        "noQuirksBodyHtml": "<noscript>&lt;iframe&gt;</noscript>X"
+        "noQuirksBodyHtml": "<noscript><iframe></noscript>X</iframe></noscript>"
       }
     },
     {
           }
         ],
         "html": "<!DOCTYPE html><html><head><noscript></noscript></head><body><iframe></noscript>X</iframe></body></html>",
-        "noQuirksBodyHtml": "<noscript>&lt;iframe&gt;</noscript>X"
+        "noQuirksBodyHtml": "<noscript><iframe></noscript>X</iframe></noscript>"
       }
     },
     {
       "data": "<script><!",
       "errors": [
         "(1,8): expected-doctype-but-got-start-tag",
+        "(1,10): expected-script-data-but-got-eof",
         "(1,10): expected-named-closing-tag-but-got-eof"
       ],
       "document": {
           }
         ],
         "html": "<html><head><noscript><!--<noscript></noscript></head><body>--&gt;</body></html>",
-        "noQuirksBodyHtml": "<noscript>&lt;!--&lt;noscript&gt;</noscript>--&gt;"
+        "noQuirksBodyHtml": "<noscript><!--<noscript></noscript>--></noscript>"
       }
     },
     {
           }
         ],
         "html": "<html><head><noscript><!--<noscript></noscript>--></noscript></head><body></body></html>",
-        "noQuirksBodyHtml": "<noscript>&lt;!--&lt;noscript&gt;</noscript>--&gt;"
+        "noQuirksBodyHtml": "<noscript><!--<noscript></noscript>--></noscript>"
       }
     },
     {
           }
         ],
         "html": "<html><head><noscript><!--</noscript></head><body>X<noscript>--></noscript></body></html>",
-        "noQuirksBodyHtml": "<noscript>&lt;!--</noscript>X<noscript>--&gt;</noscript>"
+        "noQuirksBodyHtml": "<noscript><!--</noscript>X<noscript>--></noscript>"
       }
     },
     {
           }
         ],
         "html": "<html><head><noscript><!--</noscript>X<noscript>--></noscript></head><body></body></html>",
-        "noQuirksBodyHtml": "<noscript>&lt;!--</noscript>X<noscript>--&gt;</noscript>"
+        "noQuirksBodyHtml": "<noscript><!--</noscript>X<noscript>--></noscript>"
       }
     },
     {
           }
         ],
         "html": "<html><head><noscript><iframe></noscript></head><body>X</body></html>",
-        "noQuirksBodyHtml": "<noscript>&lt;iframe&gt;</noscript>X"
+        "noQuirksBodyHtml": "<noscript><iframe></noscript>X</iframe></noscript>"
       }
     },
     {
           }
         ],
         "html": "<html><head><noscript></noscript></head><body><iframe></noscript>X</iframe></body></html>",
-        "noQuirksBodyHtml": "<noscript>&lt;iframe&gt;</noscript>X"
+        "noQuirksBodyHtml": "<noscript><iframe></noscript>X</iframe></noscript>"
       }
     },
     {
         "noQuirksBodyHtml": "<p></p><h1></h1>"
       }
     },
-    {
-      "data": "<!doctype html><form><isindex>",
-      "errors": [
-        "(1,30): deprecated-tag",
-        "(1,30): expected-closing-tag-but-got-eof"
-      ],
-      "document": {
-        "props": {
-          "tags": {
-            "html": true,
-            "head": true,
-            "body": true,
-            "form": true
-          },
-          "doctype": true
-        },
-        "tree": [
-          {
-            "doctype": "html"
-          },
-          {
-            "tag": "html",
-            "children": [
-              {
-                "tag": "head"
-              },
-              {
-                "tag": "body",
-                "children": [
-                  {
-                    "tag": "form"
-                  }
-                ]
-              }
-            ]
-          }
-        ],
-        "html": "<!DOCTYPE html><html><head></head><body><form></form></body></html>",
-        "noQuirksBodyHtml": "<form></form>"
-      }
-    },
-    {
-      "data": "<!doctype html><isindex action=\"POST\">",
-      "errors": [
-        "(1,38): deprecated-tag"
-      ],
-      "document": {
-        "props": {
-          "tags": {
-            "html": true,
-            "head": true,
-            "body": true,
-            "form": true,
-            "hr": true,
-            "label": true,
-            "input": true
-          },
-          "doctype": true
-        },
-        "tree": [
-          {
-            "doctype": "html"
-          },
-          {
-            "tag": "html",
-            "children": [
-              {
-                "tag": "head"
-              },
-              {
-                "tag": "body",
-                "children": [
-                  {
-                    "tag": "form",
-                    "attrs": [
-                      {
-                        "name": "action",
-                        "value": "POST"
-                      }
-                    ],
-                    "children": [
-                      {
-                        "tag": "hr"
-                      },
-                      {
-                        "tag": "label",
-                        "children": [
-                          {
-                            "text": "This is a searchable index. Enter search keywords: "
-                          },
-                          {
-                            "tag": "input",
-                            "attrs": [
-                              {
-                                "name": "name",
-                                "value": "isindex"
-                              }
-                            ]
-                          }
-                        ]
-                      },
-                      {
-                        "tag": "hr"
-                      }
-                    ]
-                  }
-                ]
-              }
-            ]
-          }
-        ],
-        "html": "<!DOCTYPE html><html><head></head><body><form action=\"POST\"><hr><label>This is a searchable index. Enter search keywords: <input name=\"isindex\"></label><hr></form></body></html>",
-        "noQuirksBodyHtml": "<form action=\"POST\"><hr><label>This is a searchable index. Enter search keywords: <input name=\"isindex\"></label><hr></form>"
-      }
-    },
-    {
-      "data": "<!doctype html><isindex prompt=\"this is isindex\">",
-      "errors": [
-        "(1,49): deprecated-tag"
-      ],
-      "document": {
-        "props": {
-          "tags": {
-            "html": true,
-            "head": true,
-            "body": true,
-            "form": true,
-            "hr": true,
-            "label": true,
-            "input": true
-          },
-          "doctype": true
-        },
-        "tree": [
-          {
-            "doctype": "html"
-          },
-          {
-            "tag": "html",
-            "children": [
-              {
-                "tag": "head"
-              },
-              {
-                "tag": "body",
-                "children": [
-                  {
-                    "tag": "form",
-                    "children": [
-                      {
-                        "tag": "hr"
-                      },
-                      {
-                        "tag": "label",
-                        "children": [
-                          {
-                            "text": "this is isindex"
-                          },
-                          {
-                            "tag": "input",
-                            "attrs": [
-                              {
-                                "name": "name",
-                                "value": "isindex"
-                              }
-                            ]
-                          }
-                        ]
-                      },
-                      {
-                        "tag": "hr"
-                      }
-                    ]
-                  }
-                ]
-              }
-            ]
-          }
-        ],
-        "html": "<!DOCTYPE html><html><head></head><body><form><hr><label>this is isindex<input name=\"isindex\"></label><hr></form></body></html>",
-        "noQuirksBodyHtml": "<form><hr><label>this is isindex<input name=\"isindex\"></label><hr></form>"
-      }
-    },
     {
       "data": "<!doctype html><isindex type=\"hidden\">",
       "errors": [
-        "(1,38): deprecated-tag"
-      ],
-      "document": {
-        "props": {
-          "tags": {
-            "html": true,
-            "head": true,
-            "body": true,
-            "form": true,
-            "hr": true,
-            "label": true,
-            "input": true
-          },
-          "doctype": true
-        },
-        "tree": [
-          {
-            "doctype": "html"
-          },
-          {
-            "tag": "html",
-            "children": [
-              {
-                "tag": "head"
-              },
-              {
-                "tag": "body",
-                "children": [
-                  {
-                    "tag": "form",
-                    "children": [
-                      {
-                        "tag": "hr"
-                      },
-                      {
-                        "tag": "label",
-                        "children": [
-                          {
-                            "text": "This is a searchable index. Enter search keywords: "
-                          },
-                          {
-                            "tag": "input",
-                            "attrs": [
-                              {
-                                "name": "name",
-                                "value": "isindex"
-                              },
-                              {
-                                "name": "type",
-                                "value": "hidden"
-                              }
-                            ]
-                          }
-                        ]
-                      },
-                      {
-                        "tag": "hr"
-                      }
-                    ]
-                  }
-                ]
-              }
-            ]
-          }
-        ],
-        "html": "<!DOCTYPE html><html><head></head><body><form><hr><label>This is a searchable index. Enter search keywords: <input name=\"isindex\" type=\"hidden\"></label><hr></form></body></html>",
-        "noQuirksBodyHtml": "<form><hr><label>This is a searchable index. Enter search keywords: <input name=\"isindex\" type=\"hidden\"></label><hr></form>"
-      }
-    },
-    {
-      "data": "<!doctype html><isindex name=\"foo\">",
-      "errors": [
-        "(1,35): deprecated-tag"
+        "(1,38): expected-closing-tag-but-got-eof"
       ],
       "document": {
         "props": {
             "html": true,
             "head": true,
             "body": true,
-            "form": true,
-            "hr": true,
-            "label": true,
-            "input": true
+            "isindex": true
           },
           "doctype": true
         },
                 "tag": "body",
                 "children": [
                   {
-                    "tag": "form",
-                    "children": [
-                      {
-                        "tag": "hr"
-                      },
-                      {
-                        "tag": "label",
-                        "children": [
-                          {
-                            "text": "This is a searchable index. Enter search keywords: "
-                          },
-                          {
-                            "tag": "input",
-                            "attrs": [
-                              {
-                                "name": "name",
-                                "value": "isindex"
-                              }
-                            ]
-                          }
-                        ]
-                      },
+                    "tag": "isindex",
+                    "attrs": [
                       {
-                        "tag": "hr"
+                        "name": "type",
+                        "value": "hidden"
                       }
                     ]
                   }
             ]
           }
         ],
-        "html": "<!DOCTYPE html><html><head></head><body><form><hr><label>This is a searchable index. Enter search keywords: <input name=\"isindex\"></label><hr></form></body></html>",
-        "noQuirksBodyHtml": "<form><hr><label>This is a searchable index. Enter search keywords: <input name=\"isindex\"></label><hr></form>"
+        "html": "<!DOCTYPE html><html><head></head><body><isindex type=\"hidden\"></isindex></body></html>",
+        "noQuirksBodyHtml": "<isindex type=\"hidden\"></isindex>"
       }
     },
     {
     {
       "data": "<!DOCTYPE html><select><optgroup><option></optgroup><option><select><option>",
       "errors": [
-        "(1,68): unexpected-select-in-select",
-        "(1,76): expected-closing-tag-but-got-eof"
+        "(1,68): unexpected-select-in-select"
       ],
       "document": {
         "props": {
         "noQuirksBodyHtml": "<!-- XXX - XXX - XXX -->"
       }
     },
-    {
-      "data": "<isindex test=x name=x>",
-      "errors": [
-        "(1,23): expected-doctype-but-got-start-tag",
-        "(1,23): deprecated-tag"
-      ],
-      "document": {
-        "props": {
-          "tags": {
-            "html": true,
-            "head": true,
-            "body": true,
-            "form": true,
-            "hr": true,
-            "label": true,
-            "input": true
-          }
-        },
-        "tree": [
-          {
-            "tag": "html",
-            "children": [
-              {
-                "tag": "head"
-              },
-              {
-                "tag": "body",
-                "children": [
-                  {
-                    "tag": "form",
-                    "children": [
-                      {
-                        "tag": "hr"
-                      },
-                      {
-                        "tag": "label",
-                        "children": [
-                          {
-                            "text": "This is a searchable index. Enter search keywords: "
-                          },
-                          {
-                            "tag": "input",
-                            "attrs": [
-                              {
-                                "name": "name",
-                                "value": "isindex"
-                              },
-                              {
-                                "name": "test",
-                                "value": "x"
-                              }
-                            ]
-                          }
-                        ]
-                      },
-                      {
-                        "tag": "hr"
-                      }
-                    ]
-                  }
-                ]
-              }
-            ]
-          }
-        ],
-        "html": "<html><head></head><body><form><hr><label>This is a searchable index. Enter search keywords: <input name=\"isindex\" test=\"x\"></label><hr></form></body></html>",
-        "noQuirksBodyHtml": "<form><hr><label>This is a searchable index. Enter search keywords: <input name=\"isindex\" test=\"x\"></label><hr></form>"
-      }
-    },
     {
       "data": "test\ntest",
       "errors": [
     {
       "data": "<option><option>",
       "errors": [
-        "(1,8): expected-doctype-but-got-start-tag",
-        "(1,16): expected-closing-tag-but-got-eof"
+        "(1,8): expected-doctype-but-got-start-tag"
       ],
       "document": {
         "props": {
                     "children": [
                       {
                         "tag": "annotation-xml",
-                        "ns": "http://www.w3.org/1998/Math/MathML"
+                        "ns": "http://www.w3.org/1998/Math/MathML"
+                      }
+                    ]
+                  },
+                  {
+                    "tag": "div"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><math><annotation-xml></annotation-xml></math><div></div></body></html>",
+        "noQuirksBodyHtml": "<math><annotation-xml><div></div></annotation-xml></math>"
+      }
+    },
+    {
+      "data": "<math><annotation-xml encoding=\"application/svg+xml\"><div>",
+      "errors": [
+        "(1,6): expected-doctype-but-got-start-tag",
+        "(1,58): unexpected-html-element-in-foreign-content",
+        "(1,58): expected-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "math math": true,
+            "math annotation-xml": true,
+            "div": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "math",
+                    "ns": "http://www.w3.org/1998/Math/MathML",
+                    "children": [
+                      {
+                        "tag": "annotation-xml",
+                        "ns": "http://www.w3.org/1998/Math/MathML",
+                        "attrs": [
+                          {
+                            "name": "encoding",
+                            "value": "application/svg+xml"
+                          }
+                        ]
+                      }
+                    ]
+                  },
+                  {
+                    "tag": "div"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><math><annotation-xml encoding=\"application/svg+xml\"></annotation-xml></math><div></div></body></html>",
+        "noQuirksBodyHtml": "<math><annotation-xml encoding=\"application/svg+xml\"><div></div></annotation-xml></math>"
+      }
+    },
+    {
+      "data": "<math><annotation-xml encoding=\"application/xhtml+xml\"><div>",
+      "errors": [
+        "(1,6): expected-doctype-but-got-start-tag",
+        "(1,60): expected-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "math math": true,
+            "math annotation-xml": true,
+            "div": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "math",
+                    "ns": "http://www.w3.org/1998/Math/MathML",
+                    "children": [
+                      {
+                        "tag": "annotation-xml",
+                        "ns": "http://www.w3.org/1998/Math/MathML",
+                        "attrs": [
+                          {
+                            "name": "encoding",
+                            "value": "application/xhtml+xml"
+                          }
+                        ],
+                        "children": [
+                          {
+                            "tag": "div"
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><math><annotation-xml encoding=\"application/xhtml+xml\"><div></div></annotation-xml></math></body></html>",
+        "noQuirksBodyHtml": "<math><annotation-xml encoding=\"application/xhtml+xml\"><div></div></annotation-xml></math>"
+      }
+    },
+    {
+      "data": "<math><annotation-xml encoding=\"aPPlication/xhtmL+xMl\"><div>",
+      "errors": [
+        "(1,6): expected-doctype-but-got-start-tag",
+        "(1,60): expected-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "math math": true,
+            "math annotation-xml": true,
+            "div": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "math",
+                    "ns": "http://www.w3.org/1998/Math/MathML",
+                    "children": [
+                      {
+                        "tag": "annotation-xml",
+                        "ns": "http://www.w3.org/1998/Math/MathML",
+                        "attrs": [
+                          {
+                            "name": "encoding",
+                            "value": "aPPlication/xhtmL+xMl"
+                          }
+                        ],
+                        "children": [
+                          {
+                            "tag": "div"
+                          }
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><math><annotation-xml encoding=\"aPPlication/xhtmL+xMl\"><div></div></annotation-xml></math></body></html>",
+        "noQuirksBodyHtml": "<math><annotation-xml encoding=\"aPPlication/xhtmL+xMl\"><div></div></annotation-xml></math>"
+      }
+    },
+    {
+      "data": "<math><annotation-xml encoding=\"text/html\"><div>",
+      "errors": [
+        "(1,6): expected-doctype-but-got-start-tag",
+        "(1,48): expected-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "math math": true,
+            "math annotation-xml": true,
+            "div": true
+          }
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "math",
+                    "ns": "http://www.w3.org/1998/Math/MathML",
+                    "children": [
+                      {
+                        "tag": "annotation-xml",
+                        "ns": "http://www.w3.org/1998/Math/MathML",
+                        "attrs": [
+                          {
+                            "name": "encoding",
+                            "value": "text/html"
+                          }
+                        ],
+                        "children": [
+                          {
+                            "tag": "div"
+                          }
+                        ]
                       }
                     ]
-                  },
-                  {
-                    "tag": "div"
                   }
                 ]
               }
             ]
           }
         ],
-        "html": "<html><head></head><body><math><annotation-xml></annotation-xml></math><div></div></body></html>",
-        "noQuirksBodyHtml": "<math><annotation-xml><div></div></annotation-xml></math>"
+        "html": "<html><head></head><body><math><annotation-xml encoding=\"text/html\"><div></div></annotation-xml></math></body></html>",
+        "noQuirksBodyHtml": "<math><annotation-xml encoding=\"text/html\"><div></div></annotation-xml></math>"
       }
     },
     {
-      "data": "<math><annotation-xml encoding=\"application/svg+xml\"><div>",
+      "data": "<math><annotation-xml encoding=\"Text/htmL\"><div>",
       "errors": [
         "(1,6): expected-doctype-but-got-start-tag",
-        "(1,58): unexpected-html-element-in-foreign-content",
-        "(1,58): expected-closing-tag-but-got-eof"
+        "(1,48): expected-closing-tag-but-got-eof"
       ],
       "document": {
         "props": {
                         "attrs": [
                           {
                             "name": "encoding",
-                            "value": "application/svg+xml"
+                            "value": "Text/htmL"
+                          }
+                        ],
+                        "children": [
+                          {
+                            "tag": "div"
                           }
                         ]
                       }
                     ]
-                  },
-                  {
-                    "tag": "div"
                   }
                 ]
               }
             ]
           }
         ],
-        "html": "<html><head></head><body><math><annotation-xml encoding=\"application/svg+xml\"></annotation-xml></math><div></div></body></html>",
-        "noQuirksBodyHtml": "<math><annotation-xml encoding=\"application/svg+xml\"><div></div></annotation-xml></math>"
+        "html": "<html><head></head><body><math><annotation-xml encoding=\"Text/htmL\"><div></div></annotation-xml></math></body></html>",
+        "noQuirksBodyHtml": "<math><annotation-xml encoding=\"Text/htmL\"><div></div></annotation-xml></math>"
       }
     },
     {
-      "data": "<math><annotation-xml encoding=\"application/xhtml+xml\"><div>",
+      "data": "<math><annotation-xml encoding=\" text/html \"><div>",
       "errors": [
         "(1,6): expected-doctype-but-got-start-tag",
-        "(1,60): expected-closing-tag-but-got-eof"
+        "(1,50): unexpected-html-element-in-foreign-content",
+        "(1,50): expected-closing-tag-but-got-eof"
       ],
       "document": {
         "props": {
                         "attrs": [
                           {
                             "name": "encoding",
-                            "value": "application/xhtml+xml"
-                          }
-                        ],
-                        "children": [
-                          {
-                            "tag": "div"
+                            "value": " text/html "
                           }
                         ]
                       }
                     ]
+                  },
+                  {
+                    "tag": "div"
                   }
                 ]
               }
             ]
           }
         ],
-        "html": "<html><head></head><body><math><annotation-xml encoding=\"application/xhtml+xml\"><div></div></annotation-xml></math></body></html>",
-        "noQuirksBodyHtml": "<math><annotation-xml encoding=\"application/xhtml+xml\"><div></div></annotation-xml></math>"
+        "html": "<html><head></head><body><math><annotation-xml encoding=\" text/html \"></annotation-xml></math><div></div></body></html>",
+        "noQuirksBodyHtml": "<math><annotation-xml encoding=\" text/html \"><div></div></annotation-xml></math>"
       }
     },
     {
-      "data": "<math><annotation-xml encoding=\"aPPlication/xhtmL+xMl\"><div>",
+      "data": "<math><annotation-xml> </annotation-xml>",
       "errors": [
         "(1,6): expected-doctype-but-got-start-tag",
-        "(1,60): expected-closing-tag-but-got-eof"
+        "(1,40): expected-closing-tag-but-got-eof"
       ],
       "document": {
         "props": {
             "head": true,
             "body": true,
             "math math": true,
-            "math annotation-xml": true,
-            "div": true
+            "math annotation-xml": true
           }
         },
         "tree": [
                       {
                         "tag": "annotation-xml",
                         "ns": "http://www.w3.org/1998/Math/MathML",
-                        "attrs": [
-                          {
-                            "name": "encoding",
-                            "value": "aPPlication/xhtmL+xMl"
-                          }
-                        ],
                         "children": [
                           {
-                            "tag": "div"
+                            "text": " "
                           }
                         ]
                       }
             ]
           }
         ],
-        "html": "<html><head></head><body><math><annotation-xml encoding=\"aPPlication/xhtmL+xMl\"><div></div></annotation-xml></math></body></html>",
-        "noQuirksBodyHtml": "<math><annotation-xml encoding=\"aPPlication/xhtmL+xMl\"><div></div></annotation-xml></math>"
+        "html": "<html><head></head><body><math><annotation-xml</annotation-xml></math></body></html>",
+        "noQuirksBodyHtml": "<math><annotation-xml</annotation-xml></math>"
       }
     },
     {
-      "data": "<math><annotation-xml encoding=\"text/html\"><div>",
+      "data": "<math><annotation-xml>c</annotation-xml>",
       "errors": [
         "(1,6): expected-doctype-but-got-start-tag",
-        "(1,48): expected-closing-tag-but-got-eof"
+        "(1,40): expected-closing-tag-but-got-eof"
       ],
       "document": {
         "props": {
             "head": true,
             "body": true,
             "math math": true,
-            "math annotation-xml": true,
-            "div": true
+            "math annotation-xml": true
           }
         },
         "tree": [
                       {
                         "tag": "annotation-xml",
                         "ns": "http://www.w3.org/1998/Math/MathML",
-                        "attrs": [
+                        "children": [
                           {
-                            "name": "encoding",
-                            "value": "text/html"
+                            "text": "c"
                           }
-                        ],
+                        ]
+                      }
+                    ]
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "html": "<html><head></head><body><math><annotation-xml>c</annotation-xml></math></body></html>",
+        "noQuirksBodyHtml": "<math><annotation-xml>c</annotation-xml></math>"
+      }
+    },
+    {
+      "data": "<math><annotation-xml><!--foo-->",
+      "errors": [
+        "(1,6): expected-doctype-but-got-start-tag",
+        "(1,32): expected-closing-tag-but-got-eof"
+      ],
+      "document": {
+        "props": {
+          "tags": {
+            "html": true,
+            "head": true,
+            "body": true,
+            "math math": true,
+            "math annotation-xml": true
+          },
+          "comment": true
+        },
+        "tree": [
+          {
+            "tag": "html",
+            "children": [
+              {
+                "tag": "head"
+              },
+              {
+                "tag": "body",
+                "children": [
+                  {
+                    "tag": "math",
+                    "ns": "http://www.w3.org/1998/Math/MathML",
+                    "children": [
+                      {
+                        "tag": "annotation-xml",
+                        "ns": "http://www.w3.org/1998/Math/MathML",
                         "children": [
                           {
-                            "tag": "div"
+                            "comment": "foo"
                           }
                         ]
                       }
             ]
           }
         ],
-        "html": "<html><head></head><body><math><annotation-xml encoding=\"text/html\"><div></div></annotation-xml></math></body></html>",
-        "noQuirksBodyHtml": "<math><annotation-xml encoding=\"text/html\"><div></div></annotation-xml></math>"
+        "html": "<html><head></head><body><math><annotation-xml><!--foo--></annotation-xml></math></body></html>",
+        "noQuirksBodyHtml": "<math><annotation-xml><!--foo--></annotation-xml></math>"
       }
     },
     {
-      "data": "<math><annotation-xml encoding=\"Text/htmL\"><div>",
+      "data": "<math><annotation-xml></svg>x",
       "errors": [
         "(1,6): expected-doctype-but-got-start-tag",
-        "(1,48): expected-closing-tag-but-got-eof"
+        "(1,28): unexpected-end-tag",
+        "(1,29): expected-closing-tag-but-got-eof"
       ],
       "document": {
         "props": {
             "head": true,
             "body": true,
             "math math": true,
-            "math annotation-xml": true,
-            "div": true
+            "math annotation-xml": true
           }
         },
         "tree": [
                       {
                         "tag": "annotation-xml",
                         "ns": "http://www.w3.org/1998/Math/MathML",
-                        "attrs": [
-                          {
-                            "name": "encoding",
-                            "value": "Text/htmL"
-                          }
-                        ],
                         "children": [
                           {
-                            "tag": "div"
+                            "text": "x"
                           }
                         ]
                       }
             ]
           }
         ],
-        "html": "<html><head></head><body><math><annotation-xml encoding=\"Text/htmL\"><div></div></annotation-xml></math></body></html>",
-        "noQuirksBodyHtml": "<math><annotation-xml encoding=\"Text/htmL\"><div></div></annotation-xml></math>"
+        "html": "<html><head></head><body><math><annotation-xml>x</annotation-xml></math></body></html>",
+        "noQuirksBodyHtml": "<math><annotation-xml>x</annotation-xml></math>"
       }
     },
     {
-      "data": "<math><annotation-xml encoding=\" text/html \"><div>",
+      "data": "<math><annotation-xml><svg>x",
       "errors": [
         "(1,6): expected-doctype-but-got-start-tag",
-        "(1,50): unexpected-html-element-in-foreign-content",
-        "(1,50): expected-closing-tag-but-got-eof"
+        "(1,28): expected-closing-tag-but-got-eof"
       ],
       "document": {
         "props": {
             "body": true,
             "math math": true,
             "math annotation-xml": true,
-            "div": true
+            "svg svg": true
           }
         },
         "tree": [
                       {
                         "tag": "annotation-xml",
                         "ns": "http://www.w3.org/1998/Math/MathML",
-                        "attrs": [
+                        "children": [
                           {
-                            "name": "encoding",
-                            "value": " text/html "
+                            "tag": "svg",
+                            "ns": "http://www.w3.org/2000/svg",
+                            "children": [
+                              {
+                                "text": "x"
+                              }
+                            ]
                           }
                         ]
                       }
                     ]
-                  },
-                  {
-                    "tag": "div"
                   }
                 ]
               }
             ]
           }
         ],
-        "html": "<html><head></head><body><math><annotation-xml encoding=\" text/html \"></annotation-xml></math><div></div></body></html>",
-        "noQuirksBodyHtml": "<math><annotation-xml encoding=\" text/html \"><div></div></annotation-xml></math>"
+        "html": "<html><head></head><body><math><annotation-xml><svg>x</svg></annotation-xml></math></body></html>",
+        "noQuirksBodyHtml": "<math><annotation-xml><svg>x</svg></annotation-xml></math>"
       }
     }
   ],
         "noQuirksBodyHtml": "<command>A</command>"
       }
     },
-    {
-      "data": "<!DOCTYPE html><body><menuitem>A",
-      "errors": [],
-      "document": {
-        "props": {
-          "tags": {
-            "html": true,
-            "head": true,
-            "body": true,
-            "menuitem": true
-          },
-          "doctype": true
-        },
-        "tree": [
-          {
-            "doctype": "html"
-          },
-          {
-            "tag": "html",
-            "children": [
-              {
-                "tag": "head"
-              },
-              {
-                "tag": "body",
-                "children": [
-                  {
-                    "tag": "menuitem"
-                  },
-                  {
-                    "text": "A"
-                  }
-                ]
-              }
-            ]
-          }
-        ],
-        "html": "<!DOCTYPE html><html><head></head><body><menuitem>A</body></html>",
-        "noQuirksBodyHtml": "<menuitem>A"
-      }
-    },
     {
       "data": "<!DOCTYPE html><body><embed>A",
       "errors": [],
             "body": true,
             "pre": true
           },
-          "doctype": true,
-          "extraNL": true
+          "doctype": true
         },
         "tree": [
           {
                     "tag": "pre",
                     "children": [
                       {
-                        "text": "\nfoo",
-                        "extraNL": true
+                        "text": "\nfoo"
                       }
                     ]
                   }
             ]
           }
         ],
-        "html": "<!DOCTYPE html><html><head></head><body><pre>\n\nfoo</pre></body></html>",
-        "noQuirksBodyHtml": "<pre>\n\nfoo</pre>"
+        "html": "<!DOCTYPE html><html><head></head><body><pre>\nfoo</pre></body></html>",
+        "noQuirksBodyHtml": "<pre>\nfoo</pre>"
       }
     },
     {
             "body": true,
             "pre": true
           },
-          "doctype": true,
-          "extraNL": true
+          "doctype": true
         },
         "tree": [
           {
                     "tag": "pre",
                     "children": [
                       {
-                        "text": "\nA",
-                        "extraNL": true
+                        "text": "\nA"
                       }
                     ]
                   }
             ]
           }
         ],
-        "html": "<!DOCTYPE html><html><head></head><body><pre>\n\nA</pre></body></html>",
-        "noQuirksBodyHtml": "<pre>\n\nA</pre>"
+        "html": "<!DOCTYPE html><html><head></head><body><pre>\nA</pre></body></html>",
+        "noQuirksBodyHtml": "<pre>\nA</pre>"
       }
     },
     {
             "body": true,
             "textarea": true
           },
-          "doctype": true,
-          "extraNL": true
+          "doctype": true
         },
         "tree": [
           {
                     "tag": "textarea",
                     "children": [
                       {
-                        "text": "\nfoo",
-                        "extraNL": true
+                        "text": "\nfoo"
                       }
                     ]
                   }
             ]
           }
         ],
-        "html": "<!DOCTYPE html><html><head></head><body><textarea>\n\nfoo</textarea></body></html>",
-        "noQuirksBodyHtml": "<textarea>\n\nfoo</textarea>"
+        "html": "<!DOCTYPE html><html><head></head><body><textarea>\nfoo</textarea></body></html>",
+        "noQuirksBodyHtml": "<textarea>\nfoo</textarea>"
       }
     },
     {
           }
         ],
         "html": "<html><head><noscript><!--</noscript></head><body>--&gt;</body></html>",
-        "noQuirksBodyHtml": "<noscript>&lt;!--</noscript>--&gt;"
+        "noQuirksBodyHtml": "<noscript><!--</noscript>--></noscript>"
       }
     },
     {
           }
         ],
         "html": "<html><head><noscript><!--</noscript>--></noscript></head><body></body></html>",
-        "noQuirksBodyHtml": "<noscript>&lt;!--</noscript>--&gt;"
+        "noQuirksBodyHtml": "<noscript><!--</noscript>--></noscript>"
       }
     }
   ],
         "(1,14): foster-parenting-character",
         "(1,20): foster-parenting-character",
         "(1,25): unexpected-end-tag",
+        "(1,25): unexpected-end-tag-in-special-element",
         "(1,26): foster-parenting-character"
       ],
       "document": {
     {
       "data": "</select><option>",
       "errors": [
-        "(1,9): XXX-undefined-error",
-        "(1,17): eof-in-select"
+        "(1,9): XXX-undefined-error"
       ],
       "fragment": {
         "name": "select"
     {
       "data": "<input><option>",
       "errors": [
-        "(1,7): unexpected-input-in-select",
-        "(1,15): eof-in-select"
+        "(1,7): unexpected-input-in-select"
       ],
       "fragment": {
         "name": "select"
     {
       "data": "<keygen><option>",
       "errors": [
-        "(1,8): unexpected-input-in-select",
-        "(1,16): eof-in-select"
+        "(1,8): unexpected-input-in-select"
       ],
       "fragment": {
         "name": "select"
     {
       "data": "<textarea><option>",
       "errors": [
-        "(1,10): unexpected-input-in-select",
-        "(1,18): eof-in-select"
+        "(1,10): unexpected-input-in-select"
       ],
       "fragment": {
         "name": "select"
         "(1,25): unexpected-select-in-select",
         "(1,59): unexpected-select-in-select",
         "(1,93): unexpected-select-in-select",
-        "(1,127): unexpected-select-in-select",
-        "(1,127): expected-closing-tag-but-got-eof"
+        "(1,127): unexpected-select-in-select"
       ],
       "document": {
         "props": {
           }
         ],
         "html": "<html><head></head><body><p id=\"status\"><noscript><strong>A</strong></noscript><span>B</span></p></body></html>",
-        "noQuirksBodyHtml": "<p id=\"status\"><noscript>&lt;strong&gt;A&lt;/strong&gt;</noscript><span>B</span></p>"
+        "noQuirksBodyHtml": "<p id=\"status\"><noscript><strong>A</strong></noscript><span>B</span></p>"
       }
     },
     {
           }
         ],
         "html": "<html><head></head><body><p id=\"status\"><noscript><strong>A</strong></noscript><span>B</span></p></body></html>",
-        "noQuirksBodyHtml": "<p id=\"status\"><noscript>&lt;strong&gt;A&lt;/strong&gt;</noscript><span>B</span></p>"
+        "noQuirksBodyHtml": "<p id=\"status\"><noscript><strong>A</strong></noscript><span>B</span></p>"
       }
     },
     {
         "noQuirksBodyHtml": "<b><em><foo><foob><foob><foob><foob><fooc><fooc><fooc><fooc><food></food></fooc></fooc></fooc></fooc></foob></foob></foob></foob></foo></em></b><aside><b></b></aside>"
       }
     },
-    {
-      "data": "<isindex action=\"x\">",
-      "errors": [],
-      "fragment": {
-        "name": "table"
-      },
-      "document": {
-        "props": {
-          "tags": {
-            "form": true,
-            "hr": true,
-            "label": true,
-            "input": true
-          }
-        },
-        "tree": [
-          {
-            "tag": "form",
-            "attrs": [
-              {
-                "name": "action",
-                "value": "x"
-              }
-            ],
-            "children": [
-              {
-                "tag": "hr"
-              },
-              {
-                "tag": "label",
-                "children": [
-                  {
-                    "text": "This is a searchable index. Enter search keywords: "
-                  },
-                  {
-                    "tag": "input",
-                    "attrs": [
-                      {
-                        "name": "name",
-                        "value": "isindex"
-                      }
-                    ]
-                  }
-                ]
-              },
-              {
-                "tag": "hr"
-              }
-            ]
-          }
-        ],
-        "html": "<form action=\"x\"><hr><label>This is a searchable index. Enter search keywords: <input name=\"isindex\"></label><hr></form>",
-        "noQuirksBodyHtml": "<form action=\"x\"><hr><label>This is a searchable index. Enter search keywords: <input name=\"isindex\"></label><hr></form>"
-      }
-    },
     {
       "data": "<option><XH<optgroup></optgroup>",
       "errors": [],
       }
     }
   ]
-}
+}
\ No newline at end of file
diff --git a/tests/phpunit/includes/user/UserGroupMembershipTest.php b/tests/phpunit/includes/user/UserGroupMembershipTest.php
new file mode 100644 (file)
index 0000000..a297f29
--- /dev/null
@@ -0,0 +1,151 @@
+<?php
+
+/**
+ * @group Database
+ */
+class UserGroupMembershipTest extends MediaWikiTestCase {
+       /**
+        * @var User Belongs to no groups
+        */
+       protected $userNoGroups;
+       /**
+        * @var User Belongs to the 'unittesters' group indefinitely, and the
+        * 'testwriters' group with expiry
+        */
+       protected $userTester;
+       /**
+        * @var string The timestamp, in TS_MW format, of the expiry of $userTester's
+        * membership in the 'testwriters' group
+        */
+       protected $expiryTime;
+
+       protected function setUp() {
+               parent::setUp();
+
+               $this->setMwGlobals( [
+                       'wgGroupPermissions' => [
+                               'unittesters' => [
+                                       'runtest' => true,
+                               ],
+                               'testwriters' => [
+                                       'writetest' => true,
+                               ]
+                       ]
+               ] );
+
+               $this->userNoGroups = new User;
+               $this->userNoGroups->setName( 'NoGroups' );
+               $this->userNoGroups->addToDatabase();
+
+               $this->userTester = new User;
+               $this->userTester->setName( 'Tester' );
+               $this->userTester->addToDatabase();
+               $this->userTester->addGroup( 'unittesters' );
+               $this->expiryTime = wfTimestamp( TS_MW, time() + 100500 );
+               $this->userTester->addGroup( 'testwriters', $this->expiryTime );
+       }
+
+       /**
+        * @covers UserGroupMembership::insert
+        * @covers UserGroupMembership::delete
+        */
+       public function testAddAndRemoveGroups() {
+               $user = new User;
+               $user->addToDatabase();
+
+               // basic tests
+               $ugm = new UserGroupMembership( $user->getId(), 'unittesters' );
+               $this->assertTrue( $ugm->insert() );
+               $user->clearInstanceCache();
+               $this->assertContains( 'unittesters', $user->getGroups() );
+               $this->assertArrayHasKey( 'unittesters', $user->getGroupMemberships() );
+               $this->assertTrue( $user->isAllowed( 'runtest' ) );
+
+               // try updating without allowUpdate. Should fail
+               $ugm = new UserGroupMembership( $user->getId(), 'unittesters', $this->expiryTime );
+               $this->assertFalse( $ugm->insert() );
+
+               // now try updating with allowUpdate
+               $this->assertTrue( $ugm->insert( 2 ) );
+               $user->clearInstanceCache();
+               $this->assertContains( 'unittesters', $user->getGroups() );
+               $this->assertArrayHasKey( 'unittesters', $user->getGroupMemberships() );
+               $this->assertTrue( $user->isAllowed( 'runtest' ) );
+
+               // try removing the group
+               $ugm->delete();
+               $user->clearInstanceCache();
+               $this->assertThat( $user->getGroups(),
+                       $this->logicalNot( $this->contains( 'unittesters' ) ) );
+               $this->assertThat( $user->getGroupMemberships(),
+                       $this->logicalNot( $this->arrayHasKey( 'unittesters' ) ) );
+               $this->assertFalse( $user->isAllowed( 'runtest' ) );
+
+               // check that the user group is now in user_former_groups
+               $this->assertContains( 'unittesters', $user->getFormerGroups() );
+       }
+
+       private function addUserTesterToExpiredGroup() {
+               // put $userTester in a group with expiry in the past
+               $ugm = new UserGroupMembership( $this->userTester->getId(), 'sysop', '20010102030405' );
+               $ugm->insert();
+       }
+
+       /**
+        * @covers UserGroupMembership::getMembershipsForUser
+        */
+       public function testGetMembershipsForUser() {
+               $this->addUserTesterToExpiredGroup();
+
+               // check that the user in no groups has no group memberships
+               $ugms = UserGroupMembership::getMembershipsForUser( $this->userNoGroups->getId() );
+               $this->assertEmpty( $ugms );
+
+               // check that the user in 2 groups has 2 group memberships
+               $testerUserId = $this->userTester->getId();
+               $ugms = UserGroupMembership::getMembershipsForUser( $testerUserId );
+               $this->assertCount( 2, $ugms );
+
+               // check that the required group memberships are present on $userTester,
+               // with the correct user IDs and expiries
+               $expectedGroups = [ 'unittesters', 'testwriters' ];
+
+               foreach ( $expectedGroups as $group ) {
+                       $this->assertArrayHasKey( $group, $ugms );
+                       $this->assertEquals( $ugms[$group]->getUserId(), $testerUserId );
+                       $this->assertEquals( $ugms[$group]->getGroup(), $group );
+
+                       if ( $group === 'unittesters' ) {
+                               $this->assertNull( $ugms[$group]->getExpiry() );
+                       } elseif ( $group === 'testwriters' ) {
+                               $this->assertEquals( $ugms[$group]->getExpiry(), $this->expiryTime );
+                       }
+               }
+       }
+
+       /**
+        * @covers UserGroupMembership::getMembership
+        */
+       public function testGetMembership() {
+               $this->addUserTesterToExpiredGroup();
+
+               // groups that the user doesn't belong to shouldn't be returned
+               $ugm = UserGroupMembership::getMembership( $this->userNoGroups->getId(), 'sysop' );
+               $this->assertFalse( $ugm );
+
+               // implicit groups shouldn't be returned
+               $ugm = UserGroupMembership::getMembership( $this->userNoGroups->getId(), 'user' );
+               $this->assertFalse( $ugm );
+
+               // expired groups shouldn't be returned
+               $ugm = UserGroupMembership::getMembership( $this->userTester->getId(), 'sysop' );
+               $this->assertFalse( $ugm );
+
+               // groups that the user does belong to should be returned with correct properties
+               $ugm = UserGroupMembership::getMembership( $this->userTester->getId(), 'unittesters' );
+               $this->assertInstanceOf( UserGroupMembership::class, $ugm );
+               $this->assertEquals( $ugm->getUserId(), $this->userTester->getId() );
+               $this->assertEquals( $ugm->getGroup(), 'unittesters' );
+               $this->assertNull( $ugm->getExpiry() );
+       }
+}
index fe56d27..26e5d89 100644 (file)
@@ -25,6 +25,7 @@ class UserTest extends MediaWikiTestCase {
                $this->setUpPermissionGlobals();
 
                $this->user = new User;
+               $this->user->addToDatabase();
                $this->user->addGroup( 'unittesters' );
        }
 
@@ -99,6 +100,7 @@ class UserTest extends MediaWikiTestCase {
         */
        public function testUserGetRightsHooks() {
                $user = new User;
+               $user->addToDatabase();
                $user->addGroup( 'unittesters' );
                $user->addGroup( 'testwriters' );
                $userWrapper = TestingAccessWrapper::newFromObject( $user );
index e2e6492..88bab90 100644 (file)
@@ -1585,7 +1585,7 @@ class LanguageTest extends LanguageClassesTestCase {
         * @covers Language::translateBlockExpiry()
         * @dataProvider provideTranslateBlockExpiry
         */
-       public function testTranslateBlockExpiry( $expectedData, $str, $desc ) {
+       public function testTranslateBlockExpiry( $expectedData, $str, $now, $desc ) {
                $lang = $this->getLang();
                if ( is_array( $expectedData ) ) {
                        list( $func, $arg ) = $expectedData;
@@ -1593,27 +1593,40 @@ class LanguageTest extends LanguageClassesTestCase {
                } else {
                        $expected = $expectedData;
                }
-               $this->assertEquals( $expected, $lang->translateBlockExpiry( $str ), $desc );
+               $this->assertEquals( $expected, $lang->translateBlockExpiry( $str, null, $now ), $desc );
        }
 
        public static function provideTranslateBlockExpiry() {
                return [
-                       [ '2 hours', '2 hours', 'simple data from ipboptions' ],
-                       [ 'indefinite', 'infinite', 'infinite from ipboptions' ],
-                       [ 'indefinite', 'infinity', 'alternative infinite from ipboptions' ],
-                       [ 'indefinite', 'indefinite', 'another alternative infinite from ipboptions' ],
-                       [ [ 'formatDuration', 1023 * 60 * 60 ], '1023 hours', 'relative' ],
-                       [ [ 'formatDuration', -1023 ], '-1023 seconds', 'negative relative' ],
-                       [ [ 'formatDuration', 0 ], 'now', 'now' ],
+                       [ '2 hours', '2 hours', 0, 'simple data from ipboptions' ],
+                       [ 'indefinite', 'infinite', 0, 'infinite from ipboptions' ],
+                       [ 'indefinite', 'infinity', 0, 'alternative infinite from ipboptions' ],
+                       [ 'indefinite', 'indefinite', 0, 'another alternative infinite from ipboptions' ],
+                       [ [ 'formatDuration', 1023 * 60 * 60 ], '1023 hours', 0, 'relative' ],
+                       [ [ 'formatDuration', -1023 ], '-1023 seconds', 0, 'negative relative' ],
+                       [
+                               [ 'formatDuration', 1023 * 60 * 60 ],
+                               '1023 hours',
+                               wfTimestamp( TS_UNIX, '19910203040506' ),
+                               'relative with initial timestamp'
+                       ],
+                       [ [ 'formatDuration', 0 ], 'now', 0, 'now' ],
                        [
                                [ 'timeanddate', '20120102070000' ],
                                '2012-1-1 7:00 +1 day',
+                               0,
                                'mixed, handled as absolute'
                        ],
-                       [ [ 'timeanddate', '19910203040506' ], '1991-2-3 4:05:06', 'absolute' ],
-                       [ [ 'timeanddate', '19700101000000' ], '1970-1-1 0:00:00', 'absolute at epoch' ],
-                       [ [ 'timeanddate', '19691231235959' ], '1969-12-31 23:59:59', 'time before epoch' ],
-                       [ 'dummy', 'dummy', 'return garbage as is' ],
+                       [ [ 'timeanddate', '19910203040506' ], '1991-2-3 4:05:06', 0, 'absolute' ],
+                       [ [ 'timeanddate', '19700101000000' ], '1970-1-1 0:00:00', 0, 'absolute at epoch' ],
+                       [ [ 'timeanddate', '19691231235959' ], '1969-12-31 23:59:59', 0, 'time before epoch' ],
+                       [
+                               [ 'timeanddate', '19910910000000' ],
+                               '10 september',
+                               wfTimestamp( TS_UNIX, '19910203040506' ),
+                               'partial'
+                       ],
+                       [ 'dummy', 'dummy', 0, 'return garbage as is' ],
                ];
        }
 
index b2857d9..62d247a 100644 (file)
@@ -67,7 +67,7 @@
                );
 
                assert.deepEqual(
-                       model.getState(),
+                       model.getSelectedState(),
                        {
                                group1filter1: false,
                                group1filter2: false,
@@ -85,7 +85,7 @@
                        group3filter1: true
                } );
                assert.deepEqual(
-                       model.getState(),
+                       model.getSelectedState(),
                        {
                                group1filter1: true,
                                group1filter2: false,
                                                {
                                                        name: 'hidefilter1',
                                                        label: 'Show filter 1',
-                                                       description: 'Description of Filter 1 in Group 1'
+                                                       description: 'Description of Filter 1 in Group 1',
+                                                       default: true
                                                },
                                                {
                                                        name: 'hidefilter2',
                                                {
                                                        name: 'hidefilter3',
                                                        label: 'Show filter 3',
-                                                       description: 'Description of Filter 3 in Group 1'
+                                                       description: 'Description of Filter 3 in Group 1',
+                                                       default: true
                                                }
                                        ]
                                },
                                                {
                                                        name: 'hidefilter5',
                                                        label: 'Show filter 5',
-                                                       description: 'Description of Filter 2 in Group 2'
+                                                       description: 'Description of Filter 2 in Group 2',
+                                                       default: true
                                                },
                                                {
                                                        name: 'hidefilter6',
                                                {
                                                        name: 'filter8',
                                                        label: 'Group 3: Filter 2',
-                                                       description: 'Description of Filter 2 in Group 3'
+                                                       description: 'Description of Filter 2 in Group 3',
+                                                       default: true
                                                },
                                                {
                                                        name: 'filter9',
                                        ]
                                }
                        },
+                       defaultFilterRepresentation = {
+                               // Group 1 and 2, "send_unselected_if_any", the values of the filters are "flipped" from the values of the parameters
+                               hidefilter1: false,
+                               hidefilter2: true,
+                               hidefilter3: false,
+                               hidefilter4: true,
+                               hidefilter5: false,
+                               hidefilter6: true,
+                               // Group 3, "string_options", default values correspond to parameters and filters
+                               filter7: false,
+                               filter8: true,
+                               filter9: false
+                       },
                        model = new mw.rcfilters.dm.FiltersViewModel();
 
                model.initializeFilters( definition );
 
-               // Empty query = empty filter definition
+               // Empty query = only default values
                assert.deepEqual(
                        model.getFiltersFromParameters( {} ),
-                       {
-                               hidefilter1: false, // The text is "show filter 1"
-                               hidefilter2: false, // The text is "show filter 2"
-                               hidefilter3: false, // The text is "show filter 3"
-                               hidefilter4: false, // The text is "show filter 4"
-                               hidefilter5: false, // The text is "show filter 5"
-                               hidefilter6: false, // The text is "show filter 6"
-                               filter7: false,
-                               filter8: false,
-                               filter9: false
-                       },
-                       'Empty parameter query results in filters in initial state'
+                       defaultFilterRepresentation,
+                       'Empty parameter query results in filters in initial default state'
                );
 
                assert.deepEqual(
                        model.getFiltersFromParameters( {
-                               hidefilter1: '1'
-                       } ),
-                       {
-                               hidefilter1: false, // The text is "show filter 1"
-                               hidefilter2: true, // The text is "show filter 2"
-                               hidefilter3: true, // The text is "show filter 3"
-                               hidefilter4: false, // The text is "show filter 4"
-                               hidefilter5: false, // The text is "show filter 5"
-                               hidefilter6: false, // The text is "show filter 6"
-                               filter7: false,
-                               filter8: false,
-                               filter9: false
-                       },
-                       'One falsey parameter in a group makes the rest of the filters in the group truthy (checked) in the interface'
-               );
-
-               assert.deepEqual(
-                       model.getFiltersFromParameters( {
-                               hidefilter1: '1',
                                hidefilter2: '1'
                        } ),
-                       {
+                       $.extend( {}, defaultFilterRepresentation, {
                                hidefilter1: false, // The text is "show filter 1"
                                hidefilter2: false, // The text is "show filter 2"
-                               hidefilter3: true, // The text is "show filter 3"
-                               hidefilter4: false, // The text is "show filter 4"
-                               hidefilter5: false, // The text is "show filter 5"
-                               hidefilter6: false, // The text is "show filter 6"
-                               filter7: false,
-                               filter8: false,
-                               filter9: false
-                       },
-                       'Two falsey parameters in a \'send_unselected_if_any\' group makes the rest of the filters in the group truthy (checked) in the interface'
+                               hidefilter3: false // The text is "show filter 3"
+                       } ),
+                       'One truthy parameter in a group whose other parameters are true by default makes the rest of the filters in the group false (unchecked)'
                );
 
                assert.deepEqual(
                                hidefilter2: '1',
                                hidefilter3: '1'
                        } ),
-                       {
-                               // TODO: This will have to be represented as a different state, though.
+                       $.extend( {}, defaultFilterRepresentation, {
                                hidefilter1: false, // The text is "show filter 1"
                                hidefilter2: false, // The text is "show filter 2"
-                               hidefilter3: false, // The text is "show filter 3"
-                               hidefilter4: false, // The text is "show filter 4"
-                               hidefilter5: false, // The text is "show filter 5"
-                               hidefilter6: false, // The text is "show filter 6"
-                               filter7: false,
-                               filter8: false,
-                               filter9: false
-                       },
+                               hidefilter3: false // The text is "show filter 3"
+                       } ),
                        'All paremeters in the same \'send_unselected_if_any\' group false is equivalent to none are truthy (checked) in the interface'
                );
 
                // The ones above don't update the model, so we have a clean state.
-
+               // getFiltersFromParameters is stateless; any change is unaffected by the current state
+               // This test is demonstrating wrong usage of the method;
+               // We should be aware that getFiltersFromParameters is stateless,
+               // so each call gives us a filter state that only reflects the query given.
+               // This means that the two calls to updateFilters() below collide.
+               // The result of the first is overridden by the result of the second,
+               // since both get a full state object from getFiltersFromParameters that **only** relates
+               // to the input it receives.
                model.updateFilters(
                        model.getFiltersFromParameters( {
                                hidefilter1: '1'
 
                model.updateFilters(
                        model.getFiltersFromParameters( {
-                               hidefilter3: '1'
+                               hidefilter6: '1'
                        } )
                );
 
-               // 1 and 3 are separately unchecked via hide parameters, 2 should still be
-               // checked.
-               // This can simulate separate filters in the same group being hidden different
-               // ways (e.g. preferences and URL).
+               // The result here is ignoring the first updateFilters call
+               // We should receive default values + hidefilter6 as false
                assert.deepEqual(
-                       model.getState(),
-                       {
-                               hidefilter1: false, // The text is "show filter 1"
-                               hidefilter2: true, // The text is "show filter 2"
-                               hidefilter3: false, // The text is "show filter 3"
-                               hidefilter4: false, // The text is "show filter 4"
-                               hidefilter5: false, // The text is "show filter 5"
-                               hidefilter6: false, // The text is "show filter 6"
-                               filter7: false,
-                               filter8: false,
-                               filter9: false
-                       },
-                       'After unchecking 2 of 3 \'send_unselected_if_any\' filters via separate updateFilters calls, only the remaining one is still checked.'
+                       model.getSelectedState(),
+                       $.extend( {}, defaultFilterRepresentation, {
+                               hidefilter5: false,
+                               hidefilter6: false
+                       } ),
+                       'getFiltersFromParameters does not care about previous or existing state.'
                );
 
                // Reset
 
                model.updateFilters(
                        model.getFiltersFromParameters( {
-                               hidefilter1: '1'
+                               hidefilter1: '0'
                        } )
                );
                model.updateFilters(
                        model.getFiltersFromParameters( {
-                               hidefilter1: '0'
+                               hidefilter1: '1'
                        } )
                );
 
                // Simulates minor edits being hidden in preferences, then unhidden via URL
                // override.
                assert.deepEqual(
-                       model.getState(),
-                       {
-                               hidefilter1: false, // The text is "show filter 1"
-                               hidefilter2: false, // The text is "show filter 2"
-                               hidefilter3: false, // The text is "show filter 3"
-                               hidefilter4: false, // The text is "show filter 4"
-                               hidefilter5: false, // The text is "show filter 5"
-                               hidefilter6: false, // The text is "show filter 6"
-                               filter7: false,
-                               filter8: false,
-                               filter9: false
-                       },
-                       'After unchecking then checking a \'send_unselected_if_any\' filter (without touching other filters in that group), all are checked'
+                       model.getSelectedState(),
+                       defaultFilterRepresentation,
+                       'After checking and then unchecking a \'send_unselected_if_any\' filter (without touching other filters in that group), results are default'
                );
 
                model.updateFilters(
                        } )
                );
                assert.deepEqual(
-                       model.getState(),
-                       {
-                               hidefilter1: false, // The text is "show filter 1"
-                               hidefilter2: false, // The text is "show filter 2"
-                               hidefilter3: false, // The text is "show filter 3"
-                               hidefilter4: false, // The text is "show filter 4"
-                               hidefilter5: false, // The text is "show filter 5"
-                               hidefilter6: false, // The text is "show filter 6"
+                       model.getSelectedState(),
+                       $.extend( {}, defaultFilterRepresentation, {
                                filter7: true,
                                filter8: false,
                                filter9: false
-                       },
+                       } ),
                        'A \'string_options\' parameter containing 1 value, results in the corresponding filter as checked'
                );
 
                        } )
                );
                assert.deepEqual(
-                       model.getState(),
-                       {
-                               hidefilter1: false, // The text is "show filter 1"
-                               hidefilter2: false, // The text is "show filter 2"
-                               hidefilter3: false, // The text is "show filter 3"
-                               hidefilter4: false, // The text is "show filter 4"
-                               hidefilter5: false, // The text is "show filter 5"
-                               hidefilter6: false, // The text is "show filter 6"
+                       model.getSelectedState(),
+                       $.extend( {}, defaultFilterRepresentation, {
                                filter7: true,
                                filter8: true,
                                filter9: false
-                       },
+                       } ),
                        'A \'string_options\' parameter containing 2 values, results in both corresponding filters as checked'
                );
 
                        } )
                );
                assert.deepEqual(
-                       model.getState(),
-                       {
-                               hidefilter1: false, // The text is "show filter 1"
-                               hidefilter2: false, // The text is "show filter 2"
-                               hidefilter3: false, // The text is "show filter 3"
-                               hidefilter4: false, // The text is "show filter 4"
-                               hidefilter5: false, // The text is "show filter 5"
-                               hidefilter6: false, // The text is "show filter 6"
+                       model.getSelectedState(),
+                       $.extend( {}, defaultFilterRepresentation, {
                                filter7: false,
                                filter8: false,
                                filter9: false
-                       },
+                       } ),
                        'A \'string_options\' parameter containing all values, results in all filters of the group as unchecked.'
                );
 
                model.updateFilters(
                        model.getFiltersFromParameters( {
-                               group3: 'filter7,filter8,filter9'
+                               group3: 'filter7,all,filter9'
                        } )
                );
                assert.deepEqual(
-                       model.getState(),
-                       {
-                               hidefilter1: false, // The text is "show filter 1"
-                               hidefilter2: false, // The text is "show filter 2"
-                               hidefilter3: false, // The text is "show filter 3"
-                               hidefilter4: false, // The text is "show filter 4"
-                               hidefilter5: false, // The text is "show filter 5"
-                               hidefilter6: false, // The text is "show filter 6"
+                       model.getSelectedState(),
+                       $.extend( {}, defaultFilterRepresentation, {
                                filter7: false,
                                filter8: false,
                                filter9: false
-                       },
+                       } ),
                        'A \'string_options\' parameter containing the value \'all\', results in all filters of the group as unchecked.'
                );
 
                        } )
                );
                assert.deepEqual(
-                       model.getState(),
-                       {
-                               hidefilter1: false, // The text is "show filter 1"
-                               hidefilter2: false, // The text is "show filter 2"
-                               hidefilter3: false, // The text is "show filter 3"
-                               hidefilter4: false, // The text is "show filter 4"
-                               hidefilter5: false, // The text is "show filter 5"
-                               hidefilter6: false, // The text is "show filter 6"
+                       model.getSelectedState(),
+                       $.extend( {}, defaultFilterRepresentation, {
                                filter7: true,
                                filter8: false,
                                filter9: true
-                       },
+                       } ),
                        'A \'string_options\' parameter containing an invalid value, results in the invalid value ignored and the valid corresponding filters checked.'
                );
        } );
                        'If any value is "all", the only value is "all".'
                );
        } );
+
+       QUnit.test( 'setFiltersToDefaults', function ( assert ) {
+               var definition = {
+                               group1: {
+                                       title: 'Group 1',
+                                       type: 'send_unselected_if_any',
+                                       exclusionType: 'default',
+                                       filters: [
+                                               {
+                                                       name: 'hidefilter1',
+                                                       label: 'Show filter 1',
+                                                       description: 'Description of Filter 1 in Group 1',
+                                                       default: true
+                                               },
+                                               {
+                                                       name: 'hidefilter2',
+                                                       label: 'Show filter 2',
+                                                       description: 'Description of Filter 2 in Group 1'
+                                               },
+                                               {
+                                                       name: 'hidefilter3',
+                                                       label: 'Show filter 3',
+                                                       description: 'Description of Filter 3 in Group 1',
+                                                       default: true
+                                               }
+                                       ]
+                               },
+                               group2: {
+                                       title: 'Group 2',
+                                       type: 'send_unselected_if_any',
+                                       filters: [
+                                               {
+                                                       name: 'hidefilter4',
+                                                       label: 'Show filter 4',
+                                                       description: 'Description of Filter 1 in Group 2'
+                                               },
+                                               {
+                                                       name: 'hidefilter5',
+                                                       label: 'Show filter 5',
+                                                       description: 'Description of Filter 2 in Group 2',
+                                                       default: true
+                                               },
+                                               {
+                                                       name: 'hidefilter6',
+                                                       label: 'Show filter 6',
+                                                       description: 'Description of Filter 3 in Group 2'
+                                               }
+                                       ]
+                               }
+                       },
+                       model = new mw.rcfilters.dm.FiltersViewModel();
+
+               model.initializeFilters( definition );
+
+               assert.deepEqual(
+                       model.getFullState(),
+                       {
+                               // Group 1
+                               hidefilter1: { selected: true, active: true },
+                               hidefilter2: { selected: false, active: true },
+                               hidefilter3: { selected: true, active: true },
+                               // Group 2
+                               hidefilter4: { selected: false, active: true },
+                               hidefilter5: { selected: true, active: true },
+                               hidefilter6: { selected: false, active: true },
+                       },
+                       'Initial state: all filters are active, and select states are default.'
+               );
+
+               // Default behavior for 'exclusion' type with only 1 item selected, means that:
+               // - The items in the same group that are *not* selected are *not* active
+               // - Items in other groups are unaffected (all active)
+               model.updateFilters( {
+                       hidefilter1: false,
+                       hidefilter2: false,
+                       hidefilter3: false,
+                       hidefilter4: false,
+                       hidefilter5: false,
+                       hidefilter6: true
+               } );
+               assert.deepEqual(
+                       model.getFullState(),
+                       {
+                               // Group 1: not affected
+                               hidefilter1: { selected: false, active: true },
+                               hidefilter2: { selected: false, active: true },
+                               hidefilter3: { selected: false, active: true },
+                               // Group 2: affected
+                               hidefilter4: { selected: false, active: false },
+                               hidefilter5: { selected: false, active: false },
+                               hidefilter6: { selected: true, active: true },
+                       },
+                       'Default exclusion behavior with 1 item selected in the group.'
+               );
+
+               // Default behavior for 'exclusion' type with multiple items selected, but not all, means that:
+               // - The items in the same group that are *not* selected are *not* active
+               // - Items in other groups are unaffected (all active)
+               model.updateFilters( {
+                       // Literally updating filters to create a clean state
+                       hidefilter1: false,
+                       hidefilter2: false,
+                       hidefilter3: false,
+                       hidefilter4: false,
+                       hidefilter5: true,
+                       hidefilter6: true
+               } );
+               assert.deepEqual(
+                       model.getFullState(),
+                       {
+                               // Group 1: not affected
+                               hidefilter1: { selected: false, active: true },
+                               hidefilter2: { selected: false, active: true },
+                               hidefilter3: { selected: false, active: true },
+                               // Group 2: affected
+                               hidefilter4: { selected: false, active: false },
+                               hidefilter5: { selected: true, active: true },
+                               hidefilter6: { selected: true, active: true },
+                       },
+                       'Default exclusion behavior with multiple items (but not all) selected in the group.'
+               );
+
+               // Default behavior for 'exclusion' type with all items in the group selected, means that:
+               // - All items in the group are NOT active
+               // - Items in other groups are unaffected (all active)
+               model.updateFilters( {
+                       // Literally updating filters to create a clean state
+                       hidefilter1: false,
+                       hidefilter2: false,
+                       hidefilter3: false,
+                       hidefilter4: true,
+                       hidefilter5: true,
+                       hidefilter6: true
+               } );
+               assert.deepEqual(
+                       model.getFullState(),
+                       {
+                               // Group 1: not affected
+                               hidefilter1: { selected: false, active: true },
+                               hidefilter2: { selected: false, active: true },
+                               hidefilter3: { selected: false, active: true },
+                               // Group 2: affected
+                               hidefilter4: { selected: true, active: false },
+                               hidefilter5: { selected: true, active: false },
+                               hidefilter6: { selected: true, active: false },
+                       },
+                       'Default exclusion behavior with all items in the group.'
+               );
+       } );
+
+       QUnit.test( 'reapplyActiveFilters - "explicit" exclusion rules', function ( assert ) {
+               var definition = {
+                               group1: {
+                                       title: 'Group 1',
+                                       type: 'send_unselected_if_any',
+                                       exclusionType: 'explicit',
+                                       filters: [
+                                               {
+                                                       name: 'filter1',
+                                                       excludes: [ 'filter2', 'filter3' ],
+                                                       label: 'Show filter 1',
+                                                       description: 'Description of Filter 1 in Group 1'
+                                               },
+                                               {
+                                                       name: 'filter2',
+                                                       excludes: [ 'filter3' ],
+                                                       label: 'Show filter 2',
+                                                       description: 'Description of Filter 2 in Group 1'
+                                               },
+                                               {
+                                                       name: 'filter3',
+                                                       label: 'Show filter 3',
+                                                       excludes: [ 'filter1' ],
+                                                       description: 'Description of Filter 3 in Group 1'
+                                               },
+                                               {
+                                                       name: 'filter4',
+                                                       label: 'Show filter 4',
+                                                       description: 'Description of Filter 4 in Group 1'
+                                               }
+                                       ]
+                               }
+                       },
+                       defaultFilterRepresentation = {
+                               // Group 1 and 2, "send_unselected_if_any", the values of the filters are "flipped" from the values of the parameters
+                               hidefilter1: false,
+                               hidefilter2: true,
+                               hidefilter3: false,
+                               hidefilter4: true,
+                               hidefilter5: false,
+                               hidefilter6: true,
+                               // Group 3, "string_options", default values correspond to parameters and filters
+                               filter7: false,
+                               filter8: true,
+                               filter9: false
+                       },
+                       model = new mw.rcfilters.dm.FiltersViewModel();
+
+               model.initializeFilters( definition );
+
+               assert.deepEqual(
+                       model.getFullState(),
+                       {
+                               filter1: { selected: false, active: true },
+                               filter2: { selected: false, active: true },
+                               filter3: { selected: false, active: true },
+                               filter4: { selected: false, active: true }
+                       },
+                       'Initial state: all filters are active.'
+               );
+
+               // "Explicit" behavior for 'exclusion' with one item checked:
+               // - Items in the 'excluded' list of the selected filter are inactive
+               model.updateFilters( {
+                       // Literally updating filters to create a clean state
+                       filter1: true, // Excludes 'hidefilter2', 'hidefilter3'
+                       filter2: false, // Excludes 'hidefilter3'
+                       filter3: false, // Excludes 'hidefilter1'
+                       filter4: false // No exclusion list
+               } );
+               assert.deepEqual(
+                       model.getFullState(),
+                       {
+                               filter1: { selected: true, active: true },
+                               filter2: { selected: false, active: false },
+                               filter3: { selected: false, active: false },
+                               filter4: { selected: false, active: true }
+                       },
+                       '"Explicit" exclusion behavior with one item selected that has an exclusion list.'
+               );
+
+               // "Explicit" behavior for 'exclusion' with two item checked:
+               // - Items in the 'excluded' list of each of the selected filter are inactive
+               model.updateFilters( {
+                       // Literally updating filters to create a clean state
+                       filter1: true, // Excludes 'hidefilter2', 'hidefilter3'
+                       filter2: false, // Excludes 'hidefilter3'
+                       filter3: true, // Excludes 'hidefilter1'
+                       filter4: false // No exclusion list
+               } );
+               assert.deepEqual(
+                       model.getFullState(),
+                       {
+                               filter1: { selected: true, active: false },
+                               filter2: { selected: false, active: false },
+                               filter3: { selected: true, active: false },
+                               filter4: { selected: false, active: true }
+                       },
+                       '"Explicit" exclusion behavior with two selected items that both have an exclusion list.'
+               );
+
+               // "Explicit behavior" with two filters that exclude the same item
+
+               // Two filters selected, both exclude 'hidefilter3'
+               model.updateFilters( {
+                       // Literally updating filters to create a clean state
+                       filter1: true, // Excludes 'hidefilter2', 'hidefilter3'
+                       filter2: true, // Excludes 'hidefilter3'
+                       filter3: false, // Excludes 'hidefilter1'
+                       filter4: false // No exclusion list
+               } );
+               assert.deepEqual(
+                       model.getFullState(),
+                       {
+                               filter1: { selected: true, active: true },
+                               filter2: { selected: true, active: false }, // Excluded by filter1
+                               filter3: { selected: false, active: false }, // Excluded by both filter1 and filter2
+                               filter4: { selected: false, active: true }
+                       },
+                       '"Explicit" exclusion behavior with two selected items that both exclude another item.'
+               );
+
+               // Unselect filter2: filter3 should still be excluded, because filter1 excludes it and is selected
+               model.updateFilters( {
+                       filter2: false, // Excludes 'hidefilter3'
+               } );
+               assert.deepEqual(
+                       model.getFullState(),
+                       {
+                               filter1: { selected: true, active: true },
+                               filter2: { selected: false, active: false }, // Excluded by filter1
+                               filter3: { selected: false, active: false }, // Still excluded by filter1
+                               filter4: { selected: false, active: true }
+                       },
+                       '"Explicit" exclusion behavior unselecting one item that excludes another item, that is being excluded by a third active item.'
+               );
+
+               // Unselect filter1: filter3 should now be active, since both filters that exclude it are unselected
+               model.updateFilters( {
+                       filter1: false, // Excludes 'hidefilter3' and 'hidefilter2'
+               } );
+               assert.deepEqual(
+                       model.getFullState(),
+                       {
+                               filter1: { selected: false, active: true },
+                               filter2: { selected: false, active: true }, // No longer excluded by filter1
+                               filter3: { selected: false, active: true }, // No longer excluded by either filter1 nor filter2
+                               filter4: { selected: false, active: true }
+                       },
+                       '"Explicit" exclusion behavior unselecting both items that excluded the same third item.'
+               );
+
+       } );
 }( mediaWiki, jQuery ) );