Merge "Pull rendering of single result out of SpecialSearch"
authorjenkins-bot <jenkins-bot@gerrit.wikimedia.org>
Sat, 7 Jan 2017 07:26:05 +0000 (07:26 +0000)
committerGerrit Code Review <gerrit@wikimedia.org>
Sat, 7 Jan 2017 07:26:05 +0000 (07:26 +0000)
291 files changed:
Gemfile
Gemfile.lock
RELEASE-NOTES-1.29
autoload.php
composer.json
includes/DefaultSettings.php
includes/EditPage.php
includes/Hooks.php
includes/MagicWord.php
includes/OutputPage.php
includes/Preferences.php
includes/Sanitizer.php
includes/WatchedItemQueryService.php
includes/api/ApiBase.php
includes/api/ApiClearHasMsg.php
includes/api/ApiHelp.php
includes/api/ApiImageRotate.php
includes/api/ApiMain.php
includes/api/ApiParamInfo.php
includes/api/ApiQueryAllLinks.php
includes/api/ApiQueryBacklinks.php
includes/api/ApiQueryBacklinksprop.php
includes/api/ApiQueryLinks.php
includes/api/ApiQueryLogEvents.php
includes/api/ApiQueryRecentChanges.php
includes/api/ApiQueryUserContributions.php
includes/api/ApiRevisionDelete.php
includes/api/ApiSetPageLanguage.php [new file with mode: 0755]
includes/api/ApiTag.php
includes/api/ApiUpload.php
includes/api/i18n/br.json
includes/api/i18n/de.json
includes/api/i18n/diq.json
includes/api/i18n/en.json
includes/api/i18n/es.json
includes/api/i18n/fr.json
includes/api/i18n/gl.json
includes/api/i18n/he.json
includes/api/i18n/it.json
includes/api/i18n/ko.json
includes/api/i18n/mk.json
includes/api/i18n/nb.json
includes/api/i18n/nl.json
includes/api/i18n/qqq.json
includes/api/i18n/ru.json
includes/api/i18n/sv.json
includes/api/i18n/zh-hans.json
includes/collation/CollationFa.php
includes/diff/DiffEngine.php
includes/installer/i18n/diq.json
includes/json/FormatJson.php
includes/libs/rdbms/database/DatabaseMysqlBase.php
includes/libs/rdbms/loadbalancer/LoadBalancer.php
includes/parser/Parser.php
includes/parser/ParserOutput.php
includes/parser/Preprocessor_DOM.php
includes/parser/Preprocessor_Hash.php
includes/revisiondelete/RevDelList.php
includes/search/SearchHighlighter.php
includes/specialpage/LoginSignupSpecialPage.php
includes/specials/SpecialPageLanguage.php
includes/specials/SpecialRecentchanges.php
includes/user/User.php
languages/Language.php
languages/i18n/ar.json
languages/i18n/arz.json
languages/i18n/ast.json
languages/i18n/be-tarask.json
languages/i18n/bn.json
languages/i18n/bqi.json
languages/i18n/br.json
languages/i18n/ca.json
languages/i18n/ce.json
languages/i18n/cs.json
languages/i18n/de.json
languages/i18n/diq.json
languages/i18n/el.json
languages/i18n/en.json
languages/i18n/eo.json
languages/i18n/es.json
languages/i18n/eu.json
languages/i18n/fr.json
languages/i18n/gl.json
languages/i18n/he.json
languages/i18n/hi.json
languages/i18n/hr.json
languages/i18n/hy.json
languages/i18n/ia.json
languages/i18n/io.json
languages/i18n/it.json
languages/i18n/ko.json
languages/i18n/ku-latn.json
languages/i18n/lb.json
languages/i18n/lo.json
languages/i18n/mk.json
languages/i18n/mr.json
languages/i18n/my.json
languages/i18n/nb.json
languages/i18n/nl.json
languages/i18n/or.json
languages/i18n/pl.json
languages/i18n/ps.json
languages/i18n/pt-br.json
languages/i18n/pt.json
languages/i18n/qqq.json
languages/i18n/ru.json
languages/i18n/sah.json
languages/i18n/sgs.json
languages/i18n/sl.json
languages/i18n/sq.json
languages/i18n/yue.json
languages/i18n/zh-hans.json
languages/messages/MessagesEn.php
languages/messages/MessagesRup.php [new file with mode: 0644]
maintenance/populateInterwiki.php
resources/Resources.php
resources/lib/oojs-ui/i18n/be.json
resources/lib/oojs-ui/i18n/hif-latn.json [new file with mode: 0644]
resources/lib/oojs-ui/i18n/tr.json
resources/lib/oojs-ui/i18n/tt-cyrl.json
resources/lib/oojs-ui/oojs-ui-apex.js
resources/lib/oojs-ui/oojs-ui-core-apex.css
resources/lib/oojs-ui/oojs-ui-core-mediawiki.css
resources/lib/oojs-ui/oojs-ui-core.js
resources/lib/oojs-ui/oojs-ui-mediawiki.js
resources/lib/oojs-ui/oojs-ui-toolbars-apex.css
resources/lib/oojs-ui/oojs-ui-toolbars-mediawiki.css
resources/lib/oojs-ui/oojs-ui-toolbars.js
resources/lib/oojs-ui/oojs-ui-widgets-apex.css
resources/lib/oojs-ui/oojs-ui-widgets-mediawiki.css
resources/lib/oojs-ui/oojs-ui-widgets.js
resources/lib/oojs-ui/oojs-ui-windows-apex.css
resources/lib/oojs-ui/oojs-ui-windows-mediawiki.css
resources/lib/oojs-ui/oojs-ui-windows.js
resources/lib/oojs-ui/themes/apex/icons-interactions.json
resources/lib/oojs-ui/themes/apex/icons-moderation.json
resources/lib/oojs-ui/themes/apex/images/icons/betaLaunch-invert.png [deleted file]
resources/lib/oojs-ui/themes/apex/images/icons/betaLaunch-invert.svg [deleted file]
resources/lib/oojs-ui/themes/apex/images/icons/betaLaunch.png [deleted file]
resources/lib/oojs-ui/themes/apex/images/icons/betaLaunch.svg [deleted file]
resources/lib/oojs-ui/themes/apex/images/icons/blockUndo-ltr.png [deleted file]
resources/lib/oojs-ui/themes/apex/images/icons/blockUndo-ltr.svg [deleted file]
resources/lib/oojs-ui/themes/apex/images/icons/blockUndo-rtl.png [deleted file]
resources/lib/oojs-ui/themes/apex/images/icons/blockUndo-rtl.svg [deleted file]
resources/lib/oojs-ui/themes/apex/images/icons/flagUndo-ltr.png [deleted file]
resources/lib/oojs-ui/themes/apex/images/icons/flagUndo-ltr.svg [deleted file]
resources/lib/oojs-ui/themes/apex/images/icons/flagUndo-rtl.png [deleted file]
resources/lib/oojs-ui/themes/apex/images/icons/flagUndo-rtl.svg [deleted file]
resources/lib/oojs-ui/themes/apex/images/icons/logo-wikimediaDiscovery-invert.png [new file with mode: 0644]
resources/lib/oojs-ui/themes/apex/images/icons/logo-wikimediaDiscovery-invert.svg [new file with mode: 0644]
resources/lib/oojs-ui/themes/apex/images/icons/logo-wikimediaDiscovery.png [new file with mode: 0644]
resources/lib/oojs-ui/themes/apex/images/icons/logo-wikimediaDiscovery.svg [new file with mode: 0644]
resources/lib/oojs-ui/themes/apex/images/icons/ongoingConversation-ltr.png [new file with mode: 0644]
resources/lib/oojs-ui/themes/apex/images/icons/ongoingConversation-ltr.svg [new file with mode: 0644]
resources/lib/oojs-ui/themes/apex/images/icons/ongoingConversation-rtl.png [new file with mode: 0644]
resources/lib/oojs-ui/themes/apex/images/icons/ongoingConversation-rtl.svg [new file with mode: 0644]
resources/lib/oojs-ui/themes/apex/images/icons/trashUndo-ltr.png [deleted file]
resources/lib/oojs-ui/themes/apex/images/icons/trashUndo-ltr.svg [deleted file]
resources/lib/oojs-ui/themes/apex/images/icons/trashUndo-rtl.png [deleted file]
resources/lib/oojs-ui/themes/apex/images/icons/trashUndo-rtl.svg [deleted file]
resources/lib/oojs-ui/themes/apex/images/icons/unBlock-ltr.png [new file with mode: 0644]
resources/lib/oojs-ui/themes/apex/images/icons/unBlock-ltr.svg [new file with mode: 0644]
resources/lib/oojs-ui/themes/apex/images/icons/unBlock-rtl.png [new file with mode: 0644]
resources/lib/oojs-ui/themes/apex/images/icons/unBlock-rtl.svg [new file with mode: 0644]
resources/lib/oojs-ui/themes/apex/images/icons/unFlag-ltr.png [new file with mode: 0644]
resources/lib/oojs-ui/themes/apex/images/icons/unFlag-ltr.svg [new file with mode: 0644]
resources/lib/oojs-ui/themes/apex/images/icons/unFlag-rtl.png [new file with mode: 0644]
resources/lib/oojs-ui/themes/apex/images/icons/unFlag-rtl.svg [new file with mode: 0644]
resources/lib/oojs-ui/themes/apex/images/icons/unTrash-ltr.png [new file with mode: 0644]
resources/lib/oojs-ui/themes/apex/images/icons/unTrash-ltr.svg [new file with mode: 0644]
resources/lib/oojs-ui/themes/apex/images/icons/unTrash-rtl.png [new file with mode: 0644]
resources/lib/oojs-ui/themes/apex/images/icons/unTrash-rtl.svg [new file with mode: 0644]
resources/lib/oojs-ui/themes/mediawiki/icons-interactions.json
resources/lib/oojs-ui/themes/mediawiki/icons-moderation.json
resources/lib/oojs-ui/themes/mediawiki/icons-wikimedia.json
resources/lib/oojs-ui/themes/mediawiki/images/icons/betaLaunch-invert.png [deleted file]
resources/lib/oojs-ui/themes/mediawiki/images/icons/betaLaunch-invert.svg [deleted file]
resources/lib/oojs-ui/themes/mediawiki/images/icons/betaLaunch-progressive.png [deleted file]
resources/lib/oojs-ui/themes/mediawiki/images/icons/betaLaunch-progressive.svg [deleted file]
resources/lib/oojs-ui/themes/mediawiki/images/icons/betaLaunch.png [deleted file]
resources/lib/oojs-ui/themes/mediawiki/images/icons/betaLaunch.svg [deleted file]
resources/lib/oojs-ui/themes/mediawiki/images/icons/blockUndo-ltr-invert.png [deleted file]
resources/lib/oojs-ui/themes/mediawiki/images/icons/blockUndo-ltr-invert.svg [deleted file]
resources/lib/oojs-ui/themes/mediawiki/images/icons/blockUndo-ltr-progressive.png [deleted file]
resources/lib/oojs-ui/themes/mediawiki/images/icons/blockUndo-ltr-progressive.svg [deleted file]
resources/lib/oojs-ui/themes/mediawiki/images/icons/blockUndo-ltr.png [deleted file]
resources/lib/oojs-ui/themes/mediawiki/images/icons/blockUndo-ltr.svg [deleted file]
resources/lib/oojs-ui/themes/mediawiki/images/icons/blockUndo-rtl-invert.png [deleted file]
resources/lib/oojs-ui/themes/mediawiki/images/icons/blockUndo-rtl-invert.svg [deleted file]
resources/lib/oojs-ui/themes/mediawiki/images/icons/blockUndo-rtl-progressive.png [deleted file]
resources/lib/oojs-ui/themes/mediawiki/images/icons/blockUndo-rtl-progressive.svg [deleted file]
resources/lib/oojs-ui/themes/mediawiki/images/icons/blockUndo-rtl.png [deleted file]
resources/lib/oojs-ui/themes/mediawiki/images/icons/blockUndo-rtl.svg [deleted file]
resources/lib/oojs-ui/themes/mediawiki/images/icons/flagUndo-ltr-invert.png [deleted file]
resources/lib/oojs-ui/themes/mediawiki/images/icons/flagUndo-ltr-invert.svg [deleted file]
resources/lib/oojs-ui/themes/mediawiki/images/icons/flagUndo-ltr-progressive.png [deleted file]
resources/lib/oojs-ui/themes/mediawiki/images/icons/flagUndo-ltr-progressive.svg [deleted file]
resources/lib/oojs-ui/themes/mediawiki/images/icons/flagUndo-ltr.png [deleted file]
resources/lib/oojs-ui/themes/mediawiki/images/icons/flagUndo-ltr.svg [deleted file]
resources/lib/oojs-ui/themes/mediawiki/images/icons/flagUndo-rtl-invert.png [deleted file]
resources/lib/oojs-ui/themes/mediawiki/images/icons/flagUndo-rtl-invert.svg [deleted file]
resources/lib/oojs-ui/themes/mediawiki/images/icons/flagUndo-rtl-progressive.png [deleted file]
resources/lib/oojs-ui/themes/mediawiki/images/icons/flagUndo-rtl-progressive.svg [deleted file]
resources/lib/oojs-ui/themes/mediawiki/images/icons/flagUndo-rtl.png [deleted file]
resources/lib/oojs-ui/themes/mediawiki/images/icons/flagUndo-rtl.svg [deleted file]
resources/lib/oojs-ui/themes/mediawiki/images/icons/logo-wikimediaDiscovery-invert.png [new file with mode: 0644]
resources/lib/oojs-ui/themes/mediawiki/images/icons/logo-wikimediaDiscovery-invert.svg [new file with mode: 0644]
resources/lib/oojs-ui/themes/mediawiki/images/icons/logo-wikimediaDiscovery-progressive.png [new file with mode: 0644]
resources/lib/oojs-ui/themes/mediawiki/images/icons/logo-wikimediaDiscovery-progressive.svg [new file with mode: 0644]
resources/lib/oojs-ui/themes/mediawiki/images/icons/logo-wikimediaDiscovery.png [new file with mode: 0644]
resources/lib/oojs-ui/themes/mediawiki/images/icons/logo-wikimediaDiscovery.svg [new file with mode: 0644]
resources/lib/oojs-ui/themes/mediawiki/images/icons/trashUndo-ltr-invert.png [deleted file]
resources/lib/oojs-ui/themes/mediawiki/images/icons/trashUndo-ltr-invert.svg [deleted file]
resources/lib/oojs-ui/themes/mediawiki/images/icons/trashUndo-ltr-progressive.png [deleted file]
resources/lib/oojs-ui/themes/mediawiki/images/icons/trashUndo-ltr-progressive.svg [deleted file]
resources/lib/oojs-ui/themes/mediawiki/images/icons/trashUndo-ltr.png [deleted file]
resources/lib/oojs-ui/themes/mediawiki/images/icons/trashUndo-ltr.svg [deleted file]
resources/lib/oojs-ui/themes/mediawiki/images/icons/trashUndo-rtl-invert.png [deleted file]
resources/lib/oojs-ui/themes/mediawiki/images/icons/trashUndo-rtl-invert.svg [deleted file]
resources/lib/oojs-ui/themes/mediawiki/images/icons/trashUndo-rtl-progressive.png [deleted file]
resources/lib/oojs-ui/themes/mediawiki/images/icons/trashUndo-rtl-progressive.svg [deleted file]
resources/lib/oojs-ui/themes/mediawiki/images/icons/trashUndo-rtl.png [deleted file]
resources/lib/oojs-ui/themes/mediawiki/images/icons/trashUndo-rtl.svg [deleted file]
resources/lib/oojs-ui/themes/mediawiki/images/icons/unBlock-ltr-invert.png [new file with mode: 0644]
resources/lib/oojs-ui/themes/mediawiki/images/icons/unBlock-ltr-invert.svg [new file with mode: 0644]
resources/lib/oojs-ui/themes/mediawiki/images/icons/unBlock-ltr-progressive.png [new file with mode: 0644]
resources/lib/oojs-ui/themes/mediawiki/images/icons/unBlock-ltr-progressive.svg [new file with mode: 0644]
resources/lib/oojs-ui/themes/mediawiki/images/icons/unBlock-ltr.png [new file with mode: 0644]
resources/lib/oojs-ui/themes/mediawiki/images/icons/unBlock-ltr.svg [new file with mode: 0644]
resources/lib/oojs-ui/themes/mediawiki/images/icons/unBlock-rtl-invert.png [new file with mode: 0644]
resources/lib/oojs-ui/themes/mediawiki/images/icons/unBlock-rtl-invert.svg [new file with mode: 0644]
resources/lib/oojs-ui/themes/mediawiki/images/icons/unBlock-rtl-progressive.png [new file with mode: 0644]
resources/lib/oojs-ui/themes/mediawiki/images/icons/unBlock-rtl-progressive.svg [new file with mode: 0644]
resources/lib/oojs-ui/themes/mediawiki/images/icons/unBlock-rtl.png [new file with mode: 0644]
resources/lib/oojs-ui/themes/mediawiki/images/icons/unBlock-rtl.svg [new file with mode: 0644]
resources/lib/oojs-ui/themes/mediawiki/images/icons/unFlag-ltr-invert.png [new file with mode: 0644]
resources/lib/oojs-ui/themes/mediawiki/images/icons/unFlag-ltr-invert.svg [new file with mode: 0644]
resources/lib/oojs-ui/themes/mediawiki/images/icons/unFlag-ltr-progressive.png [new file with mode: 0644]
resources/lib/oojs-ui/themes/mediawiki/images/icons/unFlag-ltr-progressive.svg [new file with mode: 0644]
resources/lib/oojs-ui/themes/mediawiki/images/icons/unFlag-ltr.png [new file with mode: 0644]
resources/lib/oojs-ui/themes/mediawiki/images/icons/unFlag-ltr.svg [new file with mode: 0644]
resources/lib/oojs-ui/themes/mediawiki/images/icons/unFlag-rtl-invert.png [new file with mode: 0644]
resources/lib/oojs-ui/themes/mediawiki/images/icons/unFlag-rtl-invert.svg [new file with mode: 0644]
resources/lib/oojs-ui/themes/mediawiki/images/icons/unFlag-rtl-progressive.png [new file with mode: 0644]
resources/lib/oojs-ui/themes/mediawiki/images/icons/unFlag-rtl-progressive.svg [new file with mode: 0644]
resources/lib/oojs-ui/themes/mediawiki/images/icons/unFlag-rtl.png [new file with mode: 0644]
resources/lib/oojs-ui/themes/mediawiki/images/icons/unFlag-rtl.svg [new file with mode: 0644]
resources/lib/oojs-ui/themes/mediawiki/images/icons/unTrash-ltr-invert.png [new file with mode: 0644]
resources/lib/oojs-ui/themes/mediawiki/images/icons/unTrash-ltr-invert.svg [new file with mode: 0644]
resources/lib/oojs-ui/themes/mediawiki/images/icons/unTrash-ltr-progressive.png [new file with mode: 0644]
resources/lib/oojs-ui/themes/mediawiki/images/icons/unTrash-ltr-progressive.svg [new file with mode: 0644]
resources/lib/oojs-ui/themes/mediawiki/images/icons/unTrash-ltr.png [new file with mode: 0644]
resources/lib/oojs-ui/themes/mediawiki/images/icons/unTrash-ltr.svg [new file with mode: 0644]
resources/lib/oojs-ui/themes/mediawiki/images/icons/unTrash-rtl-invert.png [new file with mode: 0644]
resources/lib/oojs-ui/themes/mediawiki/images/icons/unTrash-rtl-invert.svg [new file with mode: 0644]
resources/lib/oojs-ui/themes/mediawiki/images/icons/unTrash-rtl-progressive.png [new file with mode: 0644]
resources/lib/oojs-ui/themes/mediawiki/images/icons/unTrash-rtl-progressive.svg [new file with mode: 0644]
resources/lib/oojs-ui/themes/mediawiki/images/icons/unTrash-rtl.png [new file with mode: 0644]
resources/lib/oojs-ui/themes/mediawiki/images/icons/unTrash-rtl.svg [new file with mode: 0644]
resources/src/mediawiki.legacy/shared.css
resources/src/mediawiki.rcfilters/dm/mw.rcfilters.dm.FilterItem.js [new file with mode: 0644]
resources/src/mediawiki.rcfilters/dm/mw.rcfilters.dm.FiltersViewModel.js [new file with mode: 0644]
resources/src/mediawiki.rcfilters/mw.rcfilters.Controller.js [new file with mode: 0644]
resources/src/mediawiki.rcfilters/mw.rcfilters.init.js [new file with mode: 0644]
resources/src/mediawiki.rcfilters/mw.rcfilters.js [new file with mode: 0644]
resources/src/mediawiki.rcfilters/styles/mw.rcfilters.less [new file with mode: 0644]
resources/src/mediawiki.rcfilters/styles/mw.rcfilters.ui.FilterCapsuleMultiselectWidget.less [new file with mode: 0644]
resources/src/mediawiki.rcfilters/styles/mw.rcfilters.ui.FilterGroupWidget.less [new file with mode: 0644]
resources/src/mediawiki.rcfilters/styles/mw.rcfilters.ui.FilterItemWidget.less [new file with mode: 0644]
resources/src/mediawiki.rcfilters/styles/mw.rcfilters.ui.FilterWrapperWidget.less [new file with mode: 0644]
resources/src/mediawiki.rcfilters/styles/mw.rcfilters.ui.FiltersListWidget.less [new file with mode: 0644]
resources/src/mediawiki.rcfilters/ui/mw.rcfilters.ui.FilterCapsuleMultiselectWidget.js [new file with mode: 0644]
resources/src/mediawiki.rcfilters/ui/mw.rcfilters.ui.FilterGroupWidget.js [new file with mode: 0644]
resources/src/mediawiki.rcfilters/ui/mw.rcfilters.ui.FilterItemWidget.js [new file with mode: 0644]
resources/src/mediawiki.rcfilters/ui/mw.rcfilters.ui.FilterWrapperWidget.js [new file with mode: 0644]
resources/src/mediawiki.rcfilters/ui/mw.rcfilters.ui.FiltersListWidget.js [new file with mode: 0644]
resources/src/mediawiki.skinning/elements.css
resources/src/mediawiki.special/mediawiki.special.apisandbox.css
resources/src/mediawiki.special/mediawiki.special.apisandbox.js
resources/src/mediawiki.widgets.datetime/DateTimeFormatter.js
resources/src/mediawiki.widgets.datetime/DateTimeInputWidget.js
resources/src/mediawiki.widgets.datetime/DiscordianDateTimeFormatter.js
resources/src/mediawiki.widgets.datetime/ProlepticGregorianDateTimeFormatter.js
resources/src/mediawiki/page/watch.js
tests/parser/parserTests.txt
tests/phan/config.php
tests/phpunit/includes/filerepo/FileBackendDBRepoWrapperTest.php
tests/phpunit/includes/specials/QueryAllSpecialPagesTest.php
tests/phpunit/includes/user/UserTest.php
tests/qunit/QUnitTestResources.php
tests/qunit/suites/resources/mediawiki.rcfilters/dm.FiltersViewModel.test.js [new file with mode: 0644]

diff --git a/Gemfile b/Gemfile
index 8a349bf..8bbd00f 100644 (file)
--- a/Gemfile
+++ b/Gemfile
@@ -1,5 +1,5 @@
 source 'https://rubygems.org'
 
-gem 'mediawiki_selenium', '~> 1.7', '>= 1.7.2'
+gem 'mediawiki_selenium', '~> 1.7', '>= 1.7.4'
 gem 'rake', '~> 11.1', '>= 11.1.1'
 gem 'rubocop', '~> 0.32.1', require: false
index 982619a..8243874 100644 (file)
@@ -13,55 +13,58 @@ GEM
       gherkin (~> 2.12)
       multi_json (>= 1.7.5, < 2.0)
       multi_test (>= 0.1.2)
-    data_magic (0.22)
+    data_magic (1.0)
       faker (>= 1.1.2)
       yml_reader (>= 0.6)
     diff-lcs (1.2.5)
-    domain_name (0.5.20160615)
+    domain_name (0.5.20161129)
       unf (>= 0.0.5, < 1.0.0)
-    faker (1.6.6)
+    faker (1.7.1)
       i18n (~> 0.5)
-    faraday (0.9.2)
+    faraday (0.10.0)
       multipart-post (>= 1.2, < 3)
     faraday-cookie_jar (0.0.6)
       faraday (>= 0.7.4)
       http-cookie (~> 1.0.0)
-    faraday_middleware (0.10.0)
-      faraday (>= 0.7.4, < 0.10)
+    faraday_middleware (0.10.1)
+      faraday (>= 0.7.4, < 1.0)
     ffi (1.9.14)
     gherkin (2.12.2)
       multi_json (~> 1.3)
-    headless (2.2.3)
-    http-cookie (1.0.2)
+    headless (2.3.1)
+    http-cookie (1.0.3)
       domain_name (~> 0.5)
     i18n (0.7.0)
-    json (1.8.3)
+    json (2.0.2)
     mediawiki_api (0.7.0)
       faraday (~> 0.9, >= 0.9.0)
       faraday-cookie_jar (~> 0.0, >= 0.0.6)
       faraday_middleware (~> 0.10, >= 0.10.0)
-    mediawiki_selenium (1.7.2)
+    mediawiki_selenium (1.7.4)
       cucumber (~> 1.3, >= 1.3.20)
       headless (~> 2.0, >= 2.1.0)
-      json (~> 1.8, >= 1.8.1)
+      json (~> 2.0, >= 2.0.2)
       mediawiki_api (~> 0.7, >= 0.7.0)
       page-object (~> 1.0)
       rest-client (~> 1.6, >= 1.6.7)
       rspec-core (~> 2.14, >= 2.14.4)
       rspec-expectations (~> 2.14, >= 2.14.4)
+      selenium-webdriver (< 3)
       syntax (~> 1.2, >= 1.2.0)
       thor (~> 0.19, >= 0.19.1)
-    mime-types (2.99.2)
+    mime-types (2.99.3)
     multi_json (1.12.1)
     multi_test (0.1.2)
     multipart-post (2.0.0)
+    net-http-persistent (2.9.4)
     netrc (0.11.0)
-    page-object (1.2.0)
+    page-object (1.2.2)
+      net-http-persistent (~> 2.9.4)
       page_navigation (>= 0.9)
-      selenium-webdriver (>= 2.44.0)
-      watir-webdriver (>= 0.6.11)
-    page_navigation (0.9)
-      data_magic (>= 0.14)
+      selenium-webdriver (>= 2.53.0)
+      watir-webdriver (>= 0.6.11, < 0.9.9)
+    page_navigation (0.10)
+      data_magic (>= 0.22)
     parser (2.2.2.6)
       ast (>= 1.1, < 3.0)
     powerpack (0.1.1)
@@ -87,7 +90,7 @@ GEM
       rubyzip (~> 1.0)
       websocket (~> 1.0)
     syntax (1.2.1)
-    thor (0.19.1)
+    thor (0.19.4)
     unf (0.1.4)
       unf_ext
     unf_ext (0.0.7.2)
@@ -100,6 +103,9 @@ PLATFORMS
   ruby
 
 DEPENDENCIES
-  mediawiki_selenium (~> 1.7, >= 1.7.2)
+  mediawiki_selenium (~> 1.7, >= 1.7.4)
   rake (~> 11.1, >= 11.1.1)
   rubocop (~> 0.32.1)
+
+BUNDLED WITH
+   1.13.7
index c26a8be..3630abc 100644 (file)
@@ -37,6 +37,12 @@ production.
   dnsbls, are now indicated as such and use a new i18n message when displayed.
 * Added new $wgHTTPImportTimeout setting. Sets timeout for
   downloading the XML dump during a transwiki import in seconds.
+* Parser limit report is now available in machine-readable format to JavaScript
+  via mw.config.get('wgPageParseReport').
+* Added $wgSoftBlockRanges, to allow for automatically blocking anonymous edits
+  from certain IP ranges (e.g. private IPs).
+* (T59603) Added new magic word {{PAGELANGUAGE}} which returns the language code
+  of the page being parsed.
 
 === External library changes in 1.29 ===
 
@@ -156,6 +162,7 @@ changes to languages because of Phabricator reports.
 * Title::moveNoAuth() (deprecated in 1.25) was removed. Use MovePage class instead.
 * Hook UnknownAction (deprecated in 1.19) was actually deprecated (it will now emit warnings).
   Create a subclass of Action, and add it to $wgActions instead.
+* WikiRevision:getText() (deprecated since 1.21) is no longer marked deprecated.
 
 == Compatibility ==
 
index 7e94623..c8033cf 100644 (file)
@@ -139,6 +139,7 @@ $wgAutoloadLocalClasses = [
        'ApiRsd' => __DIR__ . '/includes/api/ApiRsd.php',
        'ApiSerializable' => __DIR__ . '/includes/api/ApiSerializable.php',
        'ApiSetNotificationTimestamp' => __DIR__ . '/includes/api/ApiSetNotificationTimestamp.php',
+       'ApiSetPageLanguage' => __DIR__ . '/includes/api/ApiSetPageLanguage.php',
        'ApiStashEdit' => __DIR__ . '/includes/api/ApiStashEdit.php',
        'ApiTag' => __DIR__ . '/includes/api/ApiTag.php',
        'ApiTokens' => __DIR__ . '/includes/api/ApiTokens.php',
index 8e98710..e103d9c 100644 (file)
@@ -25,7 +25,7 @@
                "ext-xml": "*",
                "liuggio/statsd-php-client": "1.0.18",
                "mediawiki/at-ease": "1.1.0",
-               "oojs/oojs-ui": "0.18.2",
+               "oojs/oojs-ui": "0.18.3",
                "oyejorge/less.php": "1.7.0.10",
                "php": ">=5.5.9",
                "psr/log": "1.0.0",
index 449e1c2..a56c8df 100644 (file)
@@ -4817,6 +4817,7 @@ $wgDefaultUserOptions = [
        'previewonfirst' => 0,
        'previewontop' => 1,
        'rcdays' => 7,
+       'rcenhancedfilters' => 0,
        'rclimit' => 50,
        'rows' => 25,
        'showhiddencats' => 0,
@@ -4851,7 +4852,9 @@ $wgDefaultUserOptions = [
 /**
  * An array of preferences to not show for the user
  */
-$wgHiddenPrefs = [];
+$wgHiddenPrefs = [
+       'rcenhancedfilters',
+];
 
 /**
  * Characters to prevent during new account creations.
@@ -5512,6 +5515,15 @@ $wgDnsBlacklistUrls = [ 'http.dnsbl.sorbs.net.' ];
  */
 $wgProxyWhitelist = [];
 
+/**
+ * IP ranges that should be considered soft-blocked (anon-only, account
+ * creation allowed). The intent is to use this to prevent anonymous edits from
+ * shared resources such as Wikimedia Labs.
+ * @since 1.29
+ * @var string[]
+ */
+$wgSoftBlockRanges = [];
+
 /**
  * Whether to look at the X-Forwarded-For header's list of (potentially spoofed)
  * IPs and apply IP blocks to them. This allows for IP blocks to work with correctly-configured
index c11df5d..acbd130 100644 (file)
@@ -2843,7 +2843,7 @@ class EditPage {
         * @param Title[] $templates
         * @return string HTML
         */
-       protected function makeTemplatesOnThisPageList( array $templates ) {
+       public function makeTemplatesOnThisPageList( array $templates ) {
                $templateListFormatter = new TemplatesOnThisPageFormatter(
                        $this->context, MediaWikiServices::getInstance()->getLinkRenderer()
                );
index 511781d..f4f86be 100644 (file)
@@ -176,22 +176,13 @@ class Hooks {
                                throw new MWException( 'Invalid callback ' . $func . ' in hooks for ' . $event . "\n" );
                        }
 
-                       /*
-                        * Call the hook. The documentation of call_user_func_array says
-                        * false is returned on failure. However, if the function signature
-                        * does not match the call signature, PHP will issue an warning and
-                        * return null instead. The following code catches that warning and
-                        * provides better error message.
-                        */
-                       $retval = null;
-                       $badhookmsg = null;
-                       $hook_args = array_merge( $hook, $args );
-
                        // mark hook as deprecated, if deprecation version is specified
                        if ( $deprecatedVersion !== null ) {
                                wfDeprecated( "$event hook (used in $func)", $deprecatedVersion );
                        }
 
+                       // Call the hook.
+                       $hook_args = array_merge( $hook, $args );
                        $retval = call_user_func_array( $callback, $hook_args );
 
                        // Process the return value.
index 391e05a..5968e87 100644 (file)
@@ -169,6 +169,7 @@ class MagicWord {
                'localtimestamp',
                'directionmark',
                'contentlanguage',
+               'pagelanguage',
                'numberofadmins',
                'cascadingsources',
        ];
index f140f54..211f44b 100644 (file)
@@ -299,6 +299,9 @@ class OutputPage extends ContextSource {
         */
        private $copyrightUrl;
 
+       /** @var array Profiling data */
+       private $limitReportJSData = [];
+
        /**
         * Constructor for OutputPage. This should not be called directly.
         * Instead a new RequestContext should be created and it will implicitly create
@@ -1804,11 +1807,16 @@ class OutputPage extends ContextSource {
                        }
                }
 
-               // enable OOUI if requested via ParserOutput
+               // Enable OOUI if requested via ParserOutput
                if ( $parserOutput->getEnableOOUI() ) {
                        $this->enableOOUI();
                }
 
+               // Include parser limit report
+               if ( !$this->limitReportJSData ) {
+                       $this->limitReportJSData = $parserOutput->getLimitReportJSData();
+               }
+
                // Link flags are ignored for now, but may in the future be
                // used to mark individual language links.
                $linkFlags = [];
@@ -3005,6 +3013,14 @@ class OutputPage extends ContextSource {
                        }
                }
 
+               if ( $this->limitReportJSData ) {
+                       $chunks[] = ResourceLoader::makeInlineScript(
+                               ResourceLoader::makeConfigSetScript(
+                                       [ 'wgPageParseReport' => $this->limitReportJSData ]
+                               )
+                       );
+               }
+
                return self::combineWrappedStrings( $chunks );
        }
 
index cf8e7b8..263ff5b 100644 (file)
@@ -696,19 +696,23 @@ class Preferences {
                $tzOptions = self::getTimezoneOptions( $context );
 
                $tzSetting = $tzOffset;
-               if ( count( $tz ) > 1 && $tz[0] == 'Offset' ) {
-                       $minDiff = $tz[1];
-                       $tzSetting = sprintf( '%+03d:%02d', floor( $minDiff / 60 ), abs( $minDiff ) % 60 );
-               } elseif ( count( $tz ) > 1 && $tz[0] == 'ZoneInfo' &&
+               if ( count( $tz ) > 1 && $tz[0] == 'ZoneInfo' &&
                        !in_array( $tzOffset, HTMLFormField::flattenOptions( $tzOptions ) )
                ) {
-                       # Timezone offset can vary with DST
-                       $userTZ = timezone_open( $tz[2] );
-                       if ( $userTZ !== false ) {
-                               $minDiff = floor( timezone_offset_get( $userTZ, date_create( 'now' ) ) / 60 );
+                       // Timezone offset can vary with DST
+                       try {
+                               $userTZ = new DateTimeZone( $tz[2] );
+                               $minDiff = floor( $userTZ->getOffset( new DateTime( 'now' ) ) / 60 );
                                $tzSetting = "ZoneInfo|$minDiff|{$tz[2]}";
+                       } catch ( Exception $e ) {
+                               // User has an invalid time zone set. Fall back to just using the offset
+                               $tz[0] = 'Offset';
                        }
                }
+               if ( count( $tz ) > 1 && $tz[0] == 'Offset' ) {
+                       $minDiff = $tz[1];
+                       $tzSetting = sprintf( '%+03d:%02d', floor( $minDiff / 60 ), abs( $minDiff ) % 60 );
+               }
 
                $defaultPreferences['timecorrection'] = [
                        'class' => 'HTMLSelectOrOtherField',
@@ -1391,6 +1395,24 @@ class Preferences {
                $data = explode( '|', $tz, 3 );
                switch ( $data[0] ) {
                        case 'ZoneInfo':
+                               $valid = false;
+
+                               if ( count( $data ) === 3 ) {
+                                       // Make sure this timezone exists
+                                       try {
+                                               new DateTimeZone( $data[2] );
+                                               // If the constructor didn't throw, we know it's valid
+                                               $valid = true;
+                                       } catch ( Exception $e ) {
+                                               // Not a valid timezone
+                                       }
+                               }
+
+                               if ( !$valid ) {
+                                       // If the supplied timezone doesn't exist, fall back to the encoded offset
+                                       return 'Offset|' . intval( $tz[1] );
+                               }
+                               return $tz;
                        case 'System':
                                return $tz;
                        default:
@@ -1409,7 +1431,7 @@ class Preferences {
                                # Max is +14:00 and min is -12:00, see:
                                # https://en.wikipedia.org/wiki/Timezone
                                $minDiff = min( $minDiff, 840 );  # 14:00
-                               $minDiff = max( $minDiff, - 720 ); # -12:00
+                               $minDiff = max( $minDiff, -720 ); # -12:00
                                return 'Offset|' . $minDiff;
                }
        }
index 44e4e3e..6779189 100644 (file)
@@ -1262,8 +1262,9 @@ class Sanitizer {
        static function escapeHtmlAllowEntities( $html ) {
                $html = Sanitizer::decodeCharReferences( $html );
                # It seems wise to escape ' as well as ", as a matter of course.  Can't
-               # hurt.
-               $html = htmlspecialchars( $html, ENT_QUOTES );
+               # hurt. Use ENT_SUBSTITUTE so that incorrectly truncated multibyte characters
+               # don't cause the entire string to disappear.
+               $html = htmlspecialchars( $html, ENT_QUOTES | ENT_SUBSTITUTE );
                return $html;
        }
 
index cd78b49..c80e4a5 100644 (file)
@@ -471,7 +471,7 @@ class WatchedItemQueryService {
        }
 
        private function getStartEndConds( IDatabase $db, array $options ) {
-               if ( !isset( $options['start'] ) && ! isset( $options['end'] ) ) {
+               if ( !isset( $options['start'] ) && !isset( $options['end'] ) ) {
                        return [];
                }
 
index 063d661..b8dd464 100644 (file)
@@ -180,6 +180,12 @@ abstract class ApiBase extends ContextSource {
         */
        const PARAM_ALL = 17;
 
+       /**
+        * (int[]) When PARAM_TYPE is 'namespace', include these as additional possible values.
+        * @since 1.29
+        */
+       const PARAM_EXTRA_NAMESPACES = 18;
+
        /**@}*/
 
        const ALL_DEFAULT_STRING = '*';
@@ -899,6 +905,34 @@ abstract class ApiBase extends ContextSource {
                return $pageObj;
        }
 
+       /**
+        * Get a Title object from a title or pageid param, if possible.
+        * Can die, if no param is set or if the title or page id is not valid.
+        *
+        * @since 1.29
+        * @param array $params
+        * @return Title
+        */
+       public function getTitleFromTitleOrPageId( $params ) {
+               $this->requireOnlyOneParameter( $params, 'title', 'pageid' );
+
+               $titleObj = null;
+               if ( isset( $params['title'] ) ) {
+                       $titleObj = Title::newFromText( $params['title'] );
+                       if ( !$titleObj || $titleObj->isExternal() ) {
+                               $this->dieWithError( [ 'apierror-invalidtitle', wfEscapeWikiText( $params['title'] ) ] );
+                       }
+                       return $titleObj;
+               } elseif ( isset( $params['pageid'] ) ) {
+                       $titleObj = Title::newFromID( $params['pageid'] );
+                       if ( !$titleObj ) {
+                               $this->dieWithError( [ 'apierror-nosuchpageid', $params['pageid'] ] );
+                       }
+               }
+
+               return $titleObj;
+       }
+
        /**
         * Return true if we're to watch the page, false if not, null if no change.
         * @param string $watchlist Valid values: 'watch', 'unwatch', 'preferences', 'nochange'
@@ -953,44 +987,41 @@ abstract class ApiBase extends ContextSource {
                // Some classes may decide to change parameter names
                $encParamName = $this->encodeParamName( $paramName );
 
+               // Shorthand
                if ( !is_array( $paramSettings ) ) {
-                       $default = $paramSettings;
-                       $multi = false;
-                       $type = gettype( $paramSettings );
-                       $dupes = false;
-                       $deprecated = false;
-                       $required = false;
-                       $allowAll = false;
-               } else {
-                       $default = isset( $paramSettings[self::PARAM_DFLT] )
-                               ? $paramSettings[self::PARAM_DFLT]
-                               : null;
-                       $multi = isset( $paramSettings[self::PARAM_ISMULTI] )
-                               ? $paramSettings[self::PARAM_ISMULTI]
-                               : false;
-                       $type = isset( $paramSettings[self::PARAM_TYPE] )
-                               ? $paramSettings[self::PARAM_TYPE]
-                               : null;
-                       $dupes = isset( $paramSettings[self::PARAM_ALLOW_DUPLICATES] )
-                               ? $paramSettings[self::PARAM_ALLOW_DUPLICATES]
-                               : false;
-                       $deprecated = isset( $paramSettings[self::PARAM_DEPRECATED] )
-                               ? $paramSettings[self::PARAM_DEPRECATED]
-                               : false;
-                       $required = isset( $paramSettings[self::PARAM_REQUIRED] )
-                               ? $paramSettings[self::PARAM_REQUIRED]
-                               : false;
-                       $allowAll = isset( $paramSettings[self::PARAM_ALL] )
-                               ? $paramSettings[self::PARAM_ALL]
-                               : false;
-
-                       // When type is not given, and no choices, the type is the same as $default
-                       if ( !isset( $type ) ) {
-                               if ( isset( $default ) ) {
-                                       $type = gettype( $default );
-                               } else {
-                                       $type = 'NULL'; // allow everything
-                               }
+                       $paramSettings = [
+                               self::PARAM_DFLT => $paramSettings,
+                       ];
+               }
+
+               $default = isset( $paramSettings[self::PARAM_DFLT] )
+                       ? $paramSettings[self::PARAM_DFLT]
+                       : null;
+               $multi = isset( $paramSettings[self::PARAM_ISMULTI] )
+                       ? $paramSettings[self::PARAM_ISMULTI]
+                       : false;
+               $type = isset( $paramSettings[self::PARAM_TYPE] )
+                       ? $paramSettings[self::PARAM_TYPE]
+                       : null;
+               $dupes = isset( $paramSettings[self::PARAM_ALLOW_DUPLICATES] )
+                       ? $paramSettings[self::PARAM_ALLOW_DUPLICATES]
+                       : false;
+               $deprecated = isset( $paramSettings[self::PARAM_DEPRECATED] )
+                       ? $paramSettings[self::PARAM_DEPRECATED]
+                       : false;
+               $required = isset( $paramSettings[self::PARAM_REQUIRED] )
+                       ? $paramSettings[self::PARAM_REQUIRED]
+                       : false;
+               $allowAll = isset( $paramSettings[self::PARAM_ALL] )
+                       ? $paramSettings[self::PARAM_ALL]
+                       : false;
+
+               // When type is not given, and no choices, the type is the same as $default
+               if ( !isset( $type ) ) {
+                       if ( isset( $default ) ) {
+                               $type = gettype( $default );
+                       } else {
+                               $type = 'NULL'; // allow everything
                        }
                }
 
@@ -1034,6 +1065,11 @@ abstract class ApiBase extends ContextSource {
 
                        if ( isset( $value ) && $type == 'namespace' ) {
                                $type = MWNamespace::getValidNamespaces();
+                               if ( isset( $paramSettings[self::PARAM_EXTRA_NAMESPACES] ) &&
+                                       is_array( $paramSettings[self::PARAM_EXTRA_NAMESPACES] )
+                               ) {
+                                       $type = array_merge( $type, $paramSettings[self::PARAM_EXTRA_NAMESPACES] );
+                               }
                                // By default, namespace parameters allow ALL_DEFAULT_STRING to be used to specify
                                // all namespaces.
                                $allowAll = true;
index 99242a8..a5474b5 100644 (file)
 class ApiClearHasMsg extends ApiBase {
        public function execute() {
                $user = $this->getUser();
-               if ( $this->getRequest()->wasPosted() ) {
-                       $user->setNewtalk( false );
-               } else {
-                       DeferredUpdates::addCallableUpdate( function () use ( $user ) {
-                               $user->setNewtalk( false );
-                       } );
-               }
+               $user->setNewtalk( false );
                $this->getResult()->addValue( null, $this->getModuleName(), 'success' );
        }
 
index 9a0d3ff..e347a9f 100644 (file)
@@ -547,6 +547,12 @@ class ApiHelp extends ApiBase {
 
                                                                case 'namespace':
                                                                        $namespaces = MWNamespace::getValidNamespaces();
+                                                                       if ( isset( $settings[ApiBase::PARAM_EXTRA_NAMESPACES] ) &&
+                                                                               is_array( $settings[ApiBase::PARAM_EXTRA_NAMESPACES] )
+                                                                       ) {
+                                                                               $namespaces = array_merge( $namespaces, $settings[ApiBase::PARAM_EXTRA_NAMESPACES] );
+                                                                       }
+                                                                       sort( $namespaces );
                                                                        $count = count( $namespaces );
                                                                        $info[] = $context->msg( 'api-help-param-list' )
                                                                                ->params( $multi ? 2 : 1 )
index 72fb16d..71bda6d 100644 (file)
@@ -42,6 +42,14 @@ class ApiImageRotate extends ApiBase {
                        'invalidTitles', 'special', 'missingIds', 'missingRevIds', 'interwikiTitles',
                ] );
 
+               // Check if user can add tags
+               if ( count( $params['tags'] ) ) {
+                       $ableToTag = ChangeTags::canAddTagsAccompanyingChange( $params['tags'], $this->getUser() );
+                       if ( !$ableToTag->isOK() ) {
+                               $this->dieStatus( $ableToTag );
+                       }
+               }
+
                foreach ( $pageSet->getTitles() as $title ) {
                        $r = [];
                        $r['id'] = $title->getArticleID();
@@ -104,8 +112,16 @@ class ApiImageRotate extends ApiBase {
                                $comment = wfMessage(
                                        'rotate-comment'
                                )->numParams( $rotation )->inContentLanguage()->text();
-                               $status = $file->upload( $dstPath,
-                                       $comment, $comment, 0, false, false, $this->getUser() );
+                               $status = $file->upload(
+                                       $dstPath,
+                                       $comment,
+                                       $comment,
+                                       0,
+                                       false,
+                                       false,
+                                       $this->getUser(),
+                                       $params['tags'] ?: []
+                               );
                                if ( $status->isGood() ) {
                                        $r['result'] = 'Success';
                                } else {
@@ -157,6 +173,10 @@ class ApiImageRotate extends ApiBase {
                        'continue' => [
                                ApiBase::PARAM_HELP_MSG => 'api-help-param-continue',
                        ],
+                       'tags' => [
+                               ApiBase::PARAM_TYPE => 'tags',
+                               ApiBase::PARAM_ISMULTI => true,
+                       ],
                ];
                if ( $flags ) {
                        $result += $this->getPageSet()->getFinalParams( $flags );
index 4220fb8..52f1d95 100644 (file)
@@ -106,6 +106,7 @@ class ApiMain extends ApiBase {
                'managetags' => 'ApiManageTags',
                'tag' => 'ApiTag',
                'mergehistory' => 'ApiMergeHistory',
+               'setpagelanguage' => 'ApiSetPageLanguage',
        ];
 
        /**
index 46ba34b..67983e7 100644 (file)
@@ -426,6 +426,15 @@ class ApiParamInfo extends ApiBase {
                                        ( is_array( $item['type'] ) || $item['type'] === 'namespace' ) ) {
                                        $item['allspecifier'] = $allSpecifier;
                                }
+
+                               if ( $item['type'] === 'namespace' &&
+                                       isset( $settings[ApiBase::PARAM_EXTRA_NAMESPACES] ) &&
+                                       is_array( $settings[ApiBase::PARAM_EXTRA_NAMESPACES] )
+                               ) {
+                                       $item['extranamespaces'] = $settings[ApiBase::PARAM_EXTRA_NAMESPACES];
+                                       ApiResult::setArrayType( $item['extranamespaces'], 'array' );
+                                       ApiResult::setIndexedTagName( $item['extranamespaces'], 'ns' );
+                               }
                        }
                        if ( isset( $settings[ApiBase::PARAM_MAX] ) ) {
                                $item['max'] = $settings[ApiBase::PARAM_MAX];
index c3636c6..3b24e37 100644 (file)
@@ -263,7 +263,8 @@ class ApiQueryAllLinks extends ApiQueryGeneratorBase {
                        ],
                        'namespace' => [
                                ApiBase::PARAM_DFLT => $this->dfltNamespace,
-                               ApiBase::PARAM_TYPE => 'namespace'
+                               ApiBase::PARAM_TYPE => 'namespace',
+                               ApiBase::PARAM_EXTRA_NAMESPACES => [ NS_MEDIA, NS_SPECIAL ],
                        ],
                        'limit' => [
                                ApiBase::PARAM_DFLT => 10,
index 4c32320..613589e 100644 (file)
@@ -344,7 +344,7 @@ class ApiQueryBacklinks extends ApiQueryGeneratorBase {
                        $this->validateLimit( 'limit', $this->params['limit'], 1, $userMax, $botMax );
                }
 
-               $this->rootTitle = $this->getTitleOrPageId( $this->params )->getTitle();
+               $this->rootTitle = $this->getTitleFromTitleOrPageId( $this->params );
 
                // only image titles are allowed for the root in imageinfo mode
                if ( !$this->hasNS && $this->rootTitle->getNamespace() !== NS_FILE ) {
index ef7b9af..4ed7f52 100644 (file)
@@ -104,6 +104,13 @@ class ApiQueryBacklinksprop extends ApiQueryGeneratorBase {
                $titles = $pageSet->getGoodAndMissingTitles();
                $map = $pageSet->getGoodAndMissingTitlesByNamespace();
 
+               // Add in special pages, they can theoretically have backlinks too.
+               // (although currently they only do for prop=redirects)
+               foreach ( $pageSet->getSpecialTitles() as $id => $title ) {
+                       $titles[] = $title;
+                       $map[$title->getNamespace()][$title->getDBkey()] = $id;
+               }
+
                // Determine our fields to query on
                $p = $settings['prefix'];
                $hasNS = !isset( $settings['to_namespace'] );
@@ -220,8 +227,9 @@ class ApiQueryBacklinksprop extends ApiQueryGeneratorBase {
                $this->addFieldsIf( 'page_namespace', $miser_ns !== null );
 
                if ( $hasNS ) {
-                       $lb = new LinkBatch( $titles );
-                       $this->addWhere( $lb->constructSet( $p, $db ) );
+                       // Can't use LinkBatch because it throws away Special titles.
+                       // And we already have the needed data structure anyway.
+                       $this->addWhere( $db->makeWhereFrom2d( $map, $bl_namespace, $bl_title ) );
                } else {
                        $where = [];
                        foreach ( $titles as $t ) {
index e9ae132..4556e29 100644 (file)
@@ -182,7 +182,8 @@ class ApiQueryLinks extends ApiQueryGeneratorBase {
                return [
                        'namespace' => [
                                ApiBase::PARAM_TYPE => 'namespace',
-                               ApiBase::PARAM_ISMULTI => true
+                               ApiBase::PARAM_ISMULTI => true,
+                               ApiBase::PARAM_EXTRA_NAMESPACES => [ NS_MEDIA, NS_SPECIAL ],
                        ],
                        'limit' => [
                                ApiBase::PARAM_DFLT => 10,
index 2dcd0b4..4d84aad 100644 (file)
@@ -435,7 +435,8 @@ class ApiQueryLogEvents extends ApiQueryBase {
                        ],
                        'title' => null,
                        'namespace' => [
-                               ApiBase::PARAM_TYPE => 'namespace'
+                               ApiBase::PARAM_TYPE => 'namespace',
+                               ApiBase::PARAM_EXTRA_NAMESPACES => [ NS_MEDIA, NS_SPECIAL ],
                        ],
                        'prefix' => [],
                        'tag' => null,
index 8d14927..2c76e97 100644 (file)
@@ -617,7 +617,8 @@ class ApiQueryRecentChanges extends ApiQueryGeneratorBase {
                        ],
                        'namespace' => [
                                ApiBase::PARAM_ISMULTI => true,
-                               ApiBase::PARAM_TYPE => 'namespace'
+                               ApiBase::PARAM_TYPE => 'namespace',
+                               ApiBase::PARAM_EXTRA_NAMESPACES => [ NS_MEDIA, NS_SPECIAL ],
                        ],
                        'user' => [
                                ApiBase::PARAM_TYPE => 'user'
index b6d871b..31a9238 100644 (file)
@@ -65,18 +65,36 @@ class ApiQueryContributions extends ApiQueryBase {
                // TODO: if the query is going only against the revision table, should this be done?
                $this->selectNamedDB( 'contributions', DB_REPLICA, 'contributions' );
 
+               $this->requireOnlyOneParameter( $this->params, 'userprefix', 'userids', 'user' );
+
                $this->idMode = false;
                if ( isset( $this->params['userprefix'] ) ) {
                        $this->prefixMode = true;
                        $this->multiUserMode = true;
                        $this->userprefix = $this->params['userprefix'];
+               } elseif ( isset( $this->params['userids'] ) ) {
+                       $this->userids = [];
+
+                       if ( !count( $this->params['userids'] ) ) {
+                               $encParamName = $this->encodeParamName( 'userids' );
+                               $this->dieWithError( [ 'apierror-paramempty', $encParamName ], "paramempty_$encParamName" );
+                       }
+
+                       foreach ( $this->params['userids'] as $uid ) {
+                               if ( $uid <= 0 ) {
+                                       $this->dieWithError( [ 'apierror-invaliduserid', $uid ], 'invaliduserid' );
+                               }
+
+                               $this->userids[] = $uid;
+                       }
+
+                       $this->prefixMode = false;
+                       $this->multiUserMode = ( count( $this->params['userids'] ) > 1 );
+                       $this->idMode = true;
                } else {
                        $anyIPs = false;
                        $this->userids = [];
                        $this->usernames = [];
-                       if ( !is_array( $this->params['user'] ) ) {
-                               $this->params['user'] = [ $this->params['user'] ];
-                       }
                        if ( !count( $this->params['user'] ) ) {
                                $encParamName = $this->encodeParamName( 'user' );
                                $this->dieWithError(
@@ -84,7 +102,7 @@ class ApiQueryContributions extends ApiQueryBase {
                                );
                        }
                        foreach ( $this->params['user'] as $u ) {
-                               if ( is_null( $u ) || $u === '' ) {
+                               if ( $u === '' ) {
                                        $encParamName = $this->encodeParamName( 'user' );
                                        $this->dieWithError(
                                                [ 'apierror-paramempty', $encParamName ], "paramempty_$encParamName"
@@ -495,6 +513,10 @@ class ApiQueryContributions extends ApiQueryBase {
                                ApiBase::PARAM_TYPE => 'user',
                                ApiBase::PARAM_ISMULTI => true
                        ],
+                       'userids' => [
+                               ApiBase::PARAM_TYPE => 'integer',
+                               ApiBase::PARAM_ISMULTI => true
+                       ],
                        'userprefix' => null,
                        'dir' => [
                                ApiBase::PARAM_DFLT => 'older',
index 763aef5..4896e7e 100644 (file)
@@ -46,6 +46,14 @@ class ApiRevisionDelete extends ApiBase {
                        $this->dieWithError( [ 'apierror-paramempty', 'ids' ], 'paramempty_ids' );
                }
 
+               // Check if user can add tags
+               if ( count( $params['tags'] ) ) {
+                       $ableToTag = ChangeTags::canAddTagsAccompanyingChange( $params['tags'], $user );
+                       if ( !$ableToTag->isOK() ) {
+                               $this->dieStatus( $ableToTag );
+                       }
+               }
+
                $hide = $params['hide'] ?: [];
                $show = $params['show'] ?: [];
                if ( array_intersect( $hide, $show ) ) {
@@ -90,9 +98,12 @@ class ApiRevisionDelete extends ApiBase {
                $list = RevisionDeleter::createList(
                        $params['type'], $this->getContext(), $targetObj, $params['ids']
                );
-               $status = $list->setVisibility(
-                       [ 'value' => $bitfield, 'comment' => $params['reason'], 'perItemStatus' => true ]
-               );
+               $status = $list->setVisibility( [
+                       'value' => $bitfield,
+                       'comment' => $params['reason'],
+                       'perItemStatus' => true,
+                       'tags' => $params['tags']
+               ] );
 
                $result = $this->getResult();
                $data = $this->extractStatusInfo( $status );
@@ -165,6 +176,10 @@ class ApiRevisionDelete extends ApiBase {
                                ApiBase::PARAM_DFLT => 'nochange',
                        ],
                        'reason' => null,
+                       'tags' => [
+                               ApiBase::PARAM_TYPE => 'tags',
+                               ApiBase::PARAM_ISMULTI => true,
+                       ],
                ];
        }
 
diff --git a/includes/api/ApiSetPageLanguage.php b/includes/api/ApiSetPageLanguage.php
new file mode 100755 (executable)
index 0000000..3ff99f1
--- /dev/null
@@ -0,0 +1,149 @@
+<?php
+/**
+ *
+ *
+ * Created on January 1, 2017
+ *
+ * Copyright © 2017 Justin Du "<justin.d128@gmail.com>"
+ *
+ * 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
+ */
+
+/**
+ * API module that facilitates changing the language of a page.
+ * The API equivalent of SpecialPageLanguage.
+ * Requires API write mode to be enabled.
+ *
+ * @ingroup API
+ */
+class ApiSetPageLanguage extends ApiBase {
+       // Check if change language feature is enabled
+       protected function getDescriptionMessage() {
+               if ( !$this->getConfig()->get( 'PageLanguageUseDB' ) ) {
+                       return 'apihelp-setpagelanguage-description-disabled';
+               }
+               return parent::getDescriptionMessage();
+       }
+
+       /**
+        * Extracts the title and language from the request parameters and invokes
+        * the static SpecialPageLanguage::changePageLanguage() function with these as arguments.
+        * If the language change succeeds, the title, old language, and new language
+        * of the article changed, as well as the performer of the language change
+        * are added to the result object.
+        */
+       public function execute() {
+               // Check if change language feature is enabled
+               if ( !$this->getConfig()->get( 'PageLanguageUseDB' ) ) {
+                       $this->dieWithError( 'apierror-pagelang-disabled' );
+               }
+
+               // Check if the user has permissions
+               $this->checkUserRightsAny( 'pagelang' );
+
+               $this->useTransactionalTimeLimit();
+
+               $params = $this->extractRequestParams();
+
+               $pageObj = $this->getTitleOrPageId( $params, 'fromdbmaster' );
+               if ( !$pageObj->exists() ) {
+                       $this->dieWithError( 'apierror-missingtitle' );
+               }
+
+               $titleObj = $pageObj->getTitle();
+               $user = $this->getUser();
+
+               // Check that the user is allowed to edit the page
+               $this->checkTitleUserPermissions( $titleObj, 'edit' );
+
+               // If change tagging was requested, check that the user is allowed to tag,
+               // and the tags are valid
+               if ( count( $params['tags'] ) ) {
+                       $tagStatus = ChangeTags::canAddTagsAccompanyingChange( $params['tags'], $user );
+                       if ( !$tagStatus->isOK() ) {
+                               $this->dieStatus( $tagStatus );
+                       }
+               }
+
+               $status = SpecialPageLanguage::changePageLanguage(
+                       $this,
+                       $titleObj,
+                       $params['lang'],
+                       $params['reason'] === null ? '' : $params['reason'],
+                       $params['tags'] ?: []
+               );
+
+               if ( !$status->isOK() ) {
+                       $this->dieStatus( $status );
+               }
+
+               $r = [
+                       'title' => $titleObj->getPrefixedText(),
+                       'oldlanguage' => $status->value->oldLanguage,
+                       'newlanguage' => $status->value->newLanguage,
+                       'logid' => $status->value->logId
+               ];
+               $this->getResult()->addValue( null, $this->getModuleName(), $r );
+       }
+
+       public function mustBePosted() {
+               return true;
+       }
+
+       public function isWriteMode() {
+               return true;
+       }
+
+       public function getAllowedParams() {
+               return [
+                       'title' => null,
+                       'pageid' => [
+                               ApiBase::PARAM_TYPE => 'integer'
+                       ],
+                       'lang' => [
+                               ApiBase::PARAM_TYPE => array_merge(
+                                       [ 'default' ],
+                                       array_keys( Language::fetchLanguageNames( null, 'mwfile' ) )
+                               ),
+                               ApiBase::PARAM_REQUIRED => true,
+                       ],
+                       'reason' => null,
+                       'tags' => [
+                               ApiBase::PARAM_TYPE => 'tags',
+                               ApiBase::PARAM_ISMULTI => true,
+                       ],
+               ];
+       }
+
+       public function needsToken() {
+               return 'csrf';
+       }
+
+       protected function getExamplesMessages() {
+               return [
+                       'action=setpagelanguage&title=Main%20Page&lang=eu&token=123ABC'
+                               => 'apihelp-setpagelanguage-example-language',
+                       'action=setpagelanguage&pageid=123&lang=default&token=123ABC'
+                               => 'apihelp-setpagelanguage-example-default',
+               ];
+       }
+
+       public function getHelpUrls() {
+               return 'https://www.mediawiki.org/wiki/API:SetPageLanguage';
+       }
+}
index b142900..7470ff3 100644 (file)
@@ -36,6 +36,14 @@ class ApiTag extends ApiBase {
                        $this->dieBlocked( $user->getBlock() );
                }
 
+               // Check if user can add tags
+               if ( count( $params['tags'] ) ) {
+                       $ableToTag = ChangeTags::canAddTagsAccompanyingChange( $params['tags'], $user );
+                       if ( !$ableToTag->isOk() ) {
+                               $this->dieStatus( $ableToTag );
+                       }
+               }
+
                // validate and process each revid, rcid and logid
                $this->requireAtLeastOneParameter( $params, 'revid', 'rcid', 'logid' );
                $ret = [];
@@ -116,6 +124,10 @@ class ApiTag extends ApiBase {
                                ApiResult::setIndexedTagName( $idResult['added'], 't' );
                                $idResult['removed'] = $status->value->removedTags;
                                ApiResult::setIndexedTagName( $idResult['removed'], 't' );
+
+                               if ( $params['tags'] ) {
+                                       ChangeTags::addTags( $params['tags'], null, null, $status->value->logId );
+                               }
                        }
                }
                return $idResult;
@@ -154,6 +166,10 @@ class ApiTag extends ApiBase {
                        'reason' => [
                                ApiBase::PARAM_DFLT => '',
                        ],
+                       'tags' => [
+                               ApiBase::PARAM_TYPE => 'tags',
+                               ApiBase::PARAM_ISMULTI => true,
+                       ],
                ];
        }
 
index 311fa54..f821374 100644 (file)
@@ -719,7 +719,7 @@ class ApiUpload extends ApiBase {
         * @return StatusValue
         */
        protected function handleStashException( $e ) {
-               switch ( get_class( $exception ) ) {
+               switch ( get_class( $e ) ) {
                        case 'UploadStashFileNotFoundException':
                                $wrap = 'apierror-stashedfilenotfound';
                                break;
index 72933fe..a8f4dd8 100644 (file)
@@ -30,5 +30,6 @@
        "apihelp-login-example-login": "Kevreañ.",
        "apihelp-move-description": "Dilec'hiañ ur bajenn.",
        "apihelp-move-param-noredirect": "Chom hep krouiñ un adkas.",
-       "apihelp-protect-example-protect": "Gwareziñ ur bajenn."
+       "apihelp-protect-example-protect": "Gwareziñ ur bajenn.",
+       "apihelp-rollback-param-tags": "Tikedennoù da lakaat e talvoud war an distroioù."
 }
index c019d98..00a4a6f 100644 (file)
        "apihelp-help-example-query": "Hilfe für zwei Abfrage-Submodule",
        "apihelp-imagerotate-description": "Ein oder mehrere Bilder drehen.",
        "apihelp-imagerotate-param-rotation": "Anzahl der Grad, um die das Bild im Uhrzeigersinn gedreht werden soll.",
+       "apihelp-imagerotate-param-tags": "Auf den Eintrag im Datei-Logbuch anzuwendende Markierungen",
        "apihelp-imagerotate-example-simple": "<kbd>Datei:Beispiel.png</kbd> um <kbd>90</kbd> Grad drehen.",
        "apihelp-imagerotate-example-generator": "Alle Bilder in der <kbd>Kategorie:Flip</kbd> um <kbd>180</kbd> Grad drehen.",
        "apihelp-import-description": "Importiert eine Seite aus einem anderen Wiki oder von einer XML-Datei.\n\nBitte beachte, dass der HTTP-POST-Vorgang als Dateiupload ausgeführt werden muss (z.B. durch multipart/form-data), um eine Datei über den <var>xml</var>-Parameter zu senden.",
        "apihelp-revisiondelete-description": "Löscht und stellt Versionen wieder her.",
        "apihelp-revisiondelete-param-hide": "Was für jede Version versteckt werden soll.",
        "apihelp-revisiondelete-param-show": "Was für jede Version wieder eingeblendet werden soll.",
+       "apihelp-revisiondelete-param-tags": "Auf den Eintrag im Lösch-Logbuch anzuwendende Markierungen.",
        "apihelp-rsd-description": "Ein RSD-Schema (Really Simple Discovery) exportieren.",
        "apihelp-rsd-example-simple": "Das RSD-Schema exportieren",
        "apihelp-setnotificationtimestamp-param-entirewatchlist": "An allen beobachteten Seiten arbeiten.",
+       "apihelp-setpagelanguage-description": "Ändert die Sprache einer Seite.",
+       "apihelp-setpagelanguage-description-disabled": "Das Ändern der Sprache von Seiten ist auf diesem Wiki nicht erlaubt.\n\nAktiviere <var>[[mw:Manual:$wgPageLanguageUseDB|$wgPageLanguageUseDB]]</var>, um diese Aktion zu verwenden.",
+       "apihelp-setpagelanguage-param-title": "Titel der Seite, deren Sprache du ändern möchtest. Kann nicht zusammen mit <var>$1pageid</var> verwendet werden.",
+       "apihelp-setpagelanguage-param-pageid": "Kennung der Seite, deren Sprache du ändern möchtest. Kann nicht zusammen mit <var>$1title</var> verwendet werden.",
+       "apihelp-setpagelanguage-param-lang": "Code der Sprache, auf den die Seite geändert werden soll. Verwende <kbd>default</kbd>, um die Seite auf die Standardinhaltssprache des Wikis zurückzusetzen.",
+       "apihelp-setpagelanguage-param-tags": "Auf den Logbucheintrag anzuwendende Änderungsmarkierungen, die sich aus dieser Aktion ergeben.",
+       "apihelp-setpagelanguage-example-language": "Ändert die Sprache von <kbd>Hauptseite</kbd> auf Baskisch.",
+       "apihelp-setpagelanguage-example-default": "Ändert die Sprache der Seite mit der Kennung 123 auf die Standardinhaltssprache des Wikis.",
        "apihelp-stashedit-param-sectiontitle": "Der Titel für einen neuen Abschnitt.",
        "apihelp-stashedit-param-text": "Seiteninhalt.",
        "apihelp-stashedit-param-stashedtexthash": "Stattdessen zu verwendende Prüfsumme des Seiteninhalts von einem vorherigen Speicher.",
        "apihelp-stashedit-param-contentmodel": "Inhaltsmodell des neuen Inhalts.",
        "apihelp-stashedit-param-summary": "Änderungszusammenfassung.",
        "apihelp-tag-param-reason": "Grund für die Änderung.",
+       "apihelp-tag-param-tags": "Auf den Logbucheintrag anzuwendende Markierungen, die als Ergebnis dieser Aktion erstellt wurden.",
        "apihelp-tokens-param-type": "Abzufragende Tokentypen.",
        "apihelp-tokens-example-edit": "Ruft einen Bearbeitungstoken ab (Standard).",
        "apihelp-tokens-example-emailmove": "Ruft einen E-Mail- und Verschiebungstoken ab.",
        "api-help-open-in-apisandbox": "<small>[in Spielwiese öffnen]</small>",
        "api-help-authmanagerhelper-messageformat": "Zu verwendendes Format zur Rückgabe von Nachrichten.",
        "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-stashinvalidfile": "Ungültige gespeicherte Datei.",
        "apierror-systemblocked": "Du wurdest von MediaWiki automatisch gesperrt.",
        "api-credits-header": "Danksagungen",
index c817bb4..0c43bd7 100644 (file)
@@ -5,7 +5,8 @@
                        "Mirzali",
                        "Kumkumuk",
                        "Asmen",
-                       "1917 Ekim Devrimi"
+                       "1917 Ekim Devrimi",
+                       "Gambollar"
                ]
        },
        "apihelp-main-param-action": "Performansa kamci aksiyon",
@@ -35,6 +36,8 @@
        "apihelp-expandtemplates-param-text": "Wikimetıni açarnê.",
        "apihelp-expandtemplates-paramvalue-prop-wikitext": "Herabıyaye wikimetin",
        "apihelp-feedcontributions-param-feedformat": "Formata warikerdışi",
+       "apihelp-feedcontributions-param-year": "Ser ra (u rewên)",
+       "apihelp-feedcontributions-param-month": "Meng ra (u rewên)",
        "apihelp-feedcontributions-param-hideminor": "Vuryayışanê werdiyan bınımne",
        "apihelp-feedcontributions-param-showsizediff": "Goreyê ebati ferqê versiyoni bımotné.",
        "apihelp-feedrecentchanges-param-hideminor": "Vurriyayışanê werdiyan bınımne.",
@@ -58,5 +61,6 @@
        "apihelp-parse-example-text": "Wikimetini analiz ke",
        "apihelp-parse-example-summary": "Xulasay analiz ke",
        "apihelp-query+alllinks-paramvalue-prop-title": "Sernamey rê link dek",
+       "apihelp-query+allmessages-param-lang": "Mesaja açarn ena zıwan.",
        "apihelp-query+blocks-example-simple": "Listey bloqeyan"
 }
index bc9fbf6..8ac11d0 100644 (file)
 
        "apihelp-imagerotate-description": "Rotate one or more images.",
        "apihelp-imagerotate-param-rotation": "Degrees to rotate image clockwise.",
+       "apihelp-imagerotate-param-tags": "Tags to apply to the entry in the upload log.",
        "apihelp-imagerotate-example-simple": "Rotate <kbd>File:Example.png</kbd> by <kbd>90</kbd> degrees.",
        "apihelp-imagerotate-example-generator": "Rotate all images in <kbd>Category:Flip</kbd> by <kbd>180</kbd> degrees.",
 
        "apihelp-query+usercontribs-param-limit": "The maximum number of contributions to return.",
        "apihelp-query+usercontribs-param-start": "The start timestamp to return from.",
        "apihelp-query+usercontribs-param-end": "The end timestamp to return to.",
-       "apihelp-query+usercontribs-param-user": "The users to retrieve contributions for.",
-       "apihelp-query+usercontribs-param-userprefix": "Retrieve contributions for all users whose names begin with this value. Overrides $1user.",
+       "apihelp-query+usercontribs-param-user": "The users to retrieve contributions for. Cannot be used with <var>$1userids</var> or <var>$1userprefix</var>.",
+       "apihelp-query+usercontribs-param-userprefix": "Retrieve contributions for all users whose names begin with this value. Cannot be used with <var>$1user</var> or <var>$1userids</var>.",
+       "apihelp-query+usercontribs-param-userids": "The user IDs to retrieve contributions for. Cannot be used with <var>$1user</var> or <var>$1userprefix</var>.",
        "apihelp-query+usercontribs-param-namespace": "Only list contributions in these namespaces.",
        "apihelp-query+usercontribs-param-prop": "Include additional pieces of information:",
        "apihelp-query+usercontribs-paramvalue-prop-ids": "Adds the page ID and revision ID.",
        "apihelp-revisiondelete-param-show": "What to unhide for each revision.",
        "apihelp-revisiondelete-param-suppress": "Whether to suppress data from administrators as well as others.",
        "apihelp-revisiondelete-param-reason": "Reason for the deletion or undeletion.",
+       "apihelp-revisiondelete-param-tags": "Tags to apply to the entry in the deletion log.",
        "apihelp-revisiondelete-example-revision": "Hide content for revision <kbd>12345</kbd> on the page <kbd>Main Page</kbd>.",
        "apihelp-revisiondelete-example-log": "Hide all data on log entry <kbd>67890</kbd> with the reason <kbd>BLP violation</kbd>.",
 
        "apihelp-setnotificationtimestamp-example-pagetimestamp": "Set the notification timestamp for <kbd>Main page</kbd> so all edits since 1 January 2012 are unviewed.",
        "apihelp-setnotificationtimestamp-example-allpages": "Reset the notification status for pages in the <kbd>{{ns:user}}</kbd> namespace.",
 
+       "apihelp-setpagelanguage-description": "Change the language of a page.",
+       "apihelp-setpagelanguage-description-disabled": "Changing the language of a page is not allowed on this wiki.\n\nEnable <var>[[mw:Manual:$wgPageLanguageUseDB|$wgPageLanguageUseDB]]</var> to use this action.",
+       "apihelp-setpagelanguage-param-title": "Title of the page whose language you wish to change. Cannot be used together with <var>$1pageid</var>.",
+       "apihelp-setpagelanguage-param-pageid": "Page ID of the page whose language you wish to change. Cannot be used together with <var>$1title</var>.",
+       "apihelp-setpagelanguage-param-lang": "Language code of the language to change the page to. Use <kbd>default</kbd> to reset the page to the wiki's default content language.",
+       "apihelp-setpagelanguage-param-reason": "Reason for the change.",
+       "apihelp-setpagelanguage-param-tags": "Change tags to apply to the log entry resulting from this action.",
+       "apihelp-setpagelanguage-example-language": "Change the language of <kbd>Main Page</kbd> to Basque.",
+       "apihelp-setpagelanguage-example-default": "Change the language of the page with ID 123 to the wiki's default content language.",
+
        "apihelp-stashedit-description": "Prepare an edit in shared cache.\n\nThis is intended to be used via AJAX from the edit form to improve the performance of the page save.",
        "apihelp-stashedit-param-title": "Title of the page being edited.",
        "apihelp-stashedit-param-section": "Section number. <kbd>0</kbd> for the top section, <kbd>new</kbd> for a new section.",
        "apihelp-tag-param-add": "Tags to add. Only manually defined tags can be added.",
        "apihelp-tag-param-remove": "Tags to remove. Only tags that are either manually defined or completely undefined can be removed.",
        "apihelp-tag-param-reason": "Reason for the change.",
+       "apihelp-tag-param-tags": "Tags to apply to the log entry that will be created as a result of this action.",
        "apihelp-tag-example-rev": "Add the <kbd>vandalism</kbd> tag to revision ID 123 without specifying a reason",
        "apihelp-tag-example-log": "Remove the <kbd>spam</kbd> tag from log entry ID 123 with the reason <kbd>Wrongly applied</kbd>",
 
        "apierror-invalidtitle": "Bad title \"$1\".",
        "apierror-invalidurlparam": "Invalid value for <var>$1urlparam</var> (<kbd>$2=$3</kbd>).",
        "apierror-invaliduser": "Invalid username \"$1\".",
+       "apierror-invaliduserid": "User ID <var>$1</var> is not valid.",
        "apierror-maxlag-generic": "Waiting for a database server: $1 {{PLURAL:$1|second|seconds}} lagged.",
        "apierror-maxlag": "Waiting for $2: $1 {{PLURAL:$1|second|seconds}} lagged.",
        "apierror-mimesearchdisabled": "MIME search is disabled in Miser Mode.",
        "apierror-opensearch-json-warnings": "Warnings cannot be represented in OpenSearch JSON format.",
        "apierror-pagecannotexist": "Namespace doesn't allow actual pages.",
        "apierror-pagedeleted": "The page has been deleted since you fetched its timestamp.",
+       "apierror-pagelang-disabled": "Changing the language of a page is not allowed on this wiki.",
        "apierror-paramempty": "The parameter <var>$1</var> may not be empty.",
        "apierror-parsetree-notwikitext": "<kbd>prop=parsetree</kbd> is only supported for wikitext content.",
        "apierror-parsetree-notwikitext-title": "<kbd>prop=parsetree</kbd> is only supported for wikitext content. $1 uses content model $2.",
index 916f8b7..d258586 100644 (file)
        "apihelp-query+mystashedfiles-paramvalue-prop-size": "Buscar el tamaño del archivo y las dimensiones de la imagen.",
        "apihelp-query+mystashedfiles-paramvalue-prop-type": "Obtener el tipo MIME y tipo multimedia del archivo.",
        "apihelp-query+mystashedfiles-param-limit": "Cuántos archivos obtener.",
+       "apihelp-query+alltransclusions-description": "Mostrar todas las transclusiones (páginas integradas mediante &#123;&#123;x&#125;&#125;), incluidas las inexistentes.",
        "apihelp-query+alltransclusions-param-from": "El título de la transclusión por la que empezar la enumeración.",
        "apihelp-query+alltransclusions-param-to": "El título de la transclusión por la que terminar la enumeración.",
        "apihelp-query+alltransclusions-param-prefix": "Buscar todos los títulos transcluidos que comiencen con este valor.",
        "apihelp-query+blocks-paramvalue-prop-reason": "Añade la razón dada para el bloqueo.",
        "apihelp-query+blocks-paramvalue-prop-range": "Añade la gama de direcciones de IP afectó por el bloque.",
        "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+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+deletedrevisions-param-tag": "Listar solo las revisiones con esta etiqueta.",
        "apihelp-query+deletedrevisions-param-user": "Listar solo las revisiones de este usuario.",
        "apihelp-query+deletedrevisions-param-excludeuser": "No listar las revisiones de este usuario.",
+       "apihelp-query+deletedrevisions-example-revids": "Mostrar la información de la revisión borrada <kbd>123456</kbd>.",
        "apihelp-query+deletedrevs-paraminfo-modes": "{{PLURAL:$1|Modo|Modos}}: $2",
        "apihelp-query+deletedrevs-param-start": "Marca de tiempo por la que empezar la enumeración.",
        "apihelp-query+deletedrevs-param-end": "Marca de tiempo por la que terminar la enumeración.",
        "apihelp-query+duplicatefiles-example-generated": "Buscar duplicados en todos los archivos.",
        "apihelp-query+embeddedin-description": "Encuentra todas las páginas que transcluyen el título dado.",
        "apihelp-query+embeddedin-param-title": "Título a buscar. No puede usarse en conjunto con $1pageid.",
+       "apihelp-query+embeddedin-param-pageid": "Identificador de página que buscar. No se puede usar junto con $1title.",
        "apihelp-query+embeddedin-param-namespace": "El espacio de nombres que enumerar.",
        "apihelp-query+embeddedin-param-dir": "La dirección en que ordenar la lista.",
        "apihelp-query+embeddedin-param-filterredir": "Cómo filtrar las redirecciones.",
        "apihelp-query+images-param-limit": "Cuántos archivos se devolverán.",
        "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+imageusage-param-title": "Título a buscar. No puede usarse en conjunto con $1pageid.",
        "apihelp-query+imageusage-param-pageid": "ID de página a buscar. No puede usarse con $1title.",
        "apihelp-query+imageusage-param-namespace": "El espacio de nombres que enumerar.",
        "apihelp-query+info-description": "Obtener información básica de la página.",
        "apihelp-query+info-param-prop": "Qué propiedades adicionales se obtendrán:",
        "apihelp-query+info-paramvalue-prop-protection": "Listar el nivel de protección de cada página.",
+       "apihelp-query+info-paramvalue-prop-talkid": "El identificador de la página de discusión correspondiente a cada página que no es de discusión.",
        "apihelp-query+info-paramvalue-prop-subjectid": "La ID de página de la página principal de cada página de discusión.",
        "apihelp-query+info-paramvalue-prop-readable": "Si el usuario puede leer esta página.",
        "apihelp-query+info-paramvalue-prop-displaytitle": "Proporciona la manera en que se muestra realmente el título de la página",
        "apihelp-query+links-param-namespace": "Mostrar solo los enlaces en estos espacios de nombres.",
        "apihelp-query+links-param-limit": "Cuántos enlaces se devolverán.",
        "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+linkshere-param-prop": "Qué propiedades se obtendrán:",
        "apihelp-query+linkshere-paramvalue-prop-pageid": "Identificador de cada página.",
        "apihelp-query+linkshere-paramvalue-prop-title": "Título de cada página.",
        "apihelp-query+logevents-paramvalue-prop-parsedcomment": "Añade el comentario analizado del evento de registro.",
        "apihelp-query+logevents-param-start": "Marca de tiempo por la que empezar la enumeración.",
        "apihelp-query+logevents-param-end": "Marca de tiempo por la que terminar la enumeración.",
+       "apihelp-query+pagepropnames-description": "Mostrar todos los nombres de propiedades de página utilizados en el wiki.",
        "apihelp-query+pageprops-description": "Obtener diferentes propiedades de página definidas en el contenido de la página.",
        "apihelp-query+pageprops-param-prop": "Sólo listar estas propiedades de página (<kbd>[[Special:ApiHelp/query+pagepropnames|action=query&list=pagepropnames]]</kbd> devuelve los nombres de las propiedades de página en uso). Útil para comprobar si las páginas usan una determinada propiedad de página.",
+       "apihelp-query+pageprops-example-simple": "Obtener las propiedades de las páginas <kbd>Main Page</kbd> y <kbd>MediaWiki</kbd>.",
        "apihelp-query+pageswithprop-param-propname": "Propiedad de página para la cual enumerar páginas (<kbd>[[Special:ApiHelp/query+pagepropnames|action=query&list=pagepropnames]]</kbd> devuelve los nombres de las propiedades de página en uso).",
        "apihelp-query+pageswithprop-param-prop": "Qué piezas de información incluir:",
        "apihelp-query+pageswithprop-paramvalue-prop-ids": "Añade el identificador de página.",
        "apihelp-query+prefixsearch-param-limit": "Número máximo de resultados que devolver.",
        "apihelp-query+prefixsearch-param-offset": "Número de resultados que omitir.",
        "apihelp-query+prefixsearch-example-simple": "Buscar títulos de páginas que empiecen con <kbd>meaning</kbd>.",
+       "apihelp-query+prefixsearch-param-profile": "Perfil de búsqueda que utilizar.",
+       "apihelp-query+protectedtitles-description": "Mostrar todos los títulos protegidos contra creación.",
        "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+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-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+random-param-filterredir": "Cómo filtrar las redirecciones.",
+       "apihelp-query+random-example-simple": "Devuelve dos páginas aleatorias del espacio de nombres principal.",
+       "apihelp-query+random-example-generator": "Devuelve la información de dos páginas aleatorias del espacio de nombres principal.",
        "apihelp-query+recentchanges-description": "Enumerar cambios recientes.",
        "apihelp-query+recentchanges-param-start": "El sello de tiempo para comenzar la enumeración.",
        "apihelp-query+recentchanges-param-end": "El sello de tiempo para finalizar la enumeración.",
+       "apihelp-query+recentchanges-param-namespace": "Filtrar cambios solamente a los espacios de nombres dados.",
        "apihelp-query+recentchanges-param-user": "Listar solo los cambios de este usuario.",
        "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-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-flags": "Añade marcas para la edición.",
        "apihelp-query+recentchanges-paramvalue-prop-sizes": "Añade la longitud antigua y la longitud nueva de la página en bytes.",
        "apihelp-query+recentchanges-paramvalue-prop-redirect": "Etiqueta la edición si la página es una redirección.",
        "apihelp-query+recentchanges-paramvalue-prop-patrolled": "Etiqueta ediciones verificables como verificadas o no verificadas.",
+       "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-limit": "Cuántos cambios en total se devolverán.",
        "apihelp-query+recentchanges-param-type": "Cuántos tipos de cambios se mostrarán.",
        "apihelp-query+revisions+base-paramvalue-prop-content": "Texto de la revisión.",
        "apihelp-query+revisions+base-paramvalue-prop-tags": "Etiquetas para la revisión.",
        "apihelp-query+revisions+base-param-limit": "Limitar la cantidad de revisiones que se devolverán.",
+       "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+search-param-info": "Qué metadatos devolver.",
        "apihelp-query+search-param-prop": "Qué propiedades se devolverán:",
        "apihelp-query+search-paramvalue-prop-size": "Añade el tamaño de la página en bytes.",
        "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-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-prop": "Incluir piezas adicionales de información:",
        "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-param-owner": "Utilizado junto con $1token para acceder a la lista de seguimiento de otro usuario.",
+       "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-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-removeauthenticationdata-description": "Elimina los datos de autentificación del usuario actual.",
        "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-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-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-summary": "Resumen de edición personalizado. Si se deja vacío se utilizará el predeterminado.",
        "apihelp-rsd-description": "Exportar un esquema RSD (Really Simple Discovery; Descubrimiento Muy Simple).",
        "apihelp-rsd-example-simple": "Exportar el esquema RSD.",
+       "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 la API.",
        "apihelp-stashedit-param-title": "Título de la página que se está editando.",
        "apihelp-stashedit-param-section": "Número de la sección. <kbd>0</kbd> para una sección superior, <kbd>new</kbd> para una sección nueva.",
        "apihelp-stashedit-param-sectiontitle": "El título de una sección nueva.",
        "apihelp-userrights-param-add": "Agregar el usuario a estos grupos.",
        "apihelp-userrights-param-remove": "Eliminar el usuario de estos grupos.",
        "apihelp-userrights-param-reason": "Motivo del cambio.",
+       "apihelp-userrights-param-tags": "Cambia las etiquetas que aplicar a la entrada del registro de derechos del usuario.",
        "apihelp-userrights-example-user": "Agregar al usuario <kbd>FooBot</kbd> al grupo <kbd>bot</kbd> y eliminarlo de los grupos <kbd>sysop</kbd> y <kbd>bureaucrat</kbd>.",
        "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-xml-param-xslt": "Si se especifica, añade la página nombrada como una hoja de estilo XSL. El valor debe ser un título en el espacio de nombres {{ns:MediaWiki}} que termine en <code>.xsl</code>.",
        "apihelp-xml-param-includexmlnamespace": "Si se especifica, añade un espacio de nombres XML.",
        "api-format-title": "Resultado de la API de MediaWiki",
+       "api-format-prettyprint-header": "Esta es la representación en HTML del formato $1. HTML es adecuado para realizar tareas de depuración, pero no para utilizarlo en aplicaciones.\n\nUtiliza el parámetro <var>format</var> para modificar el formato de salida. Para ver la representación no HTML del formato $1, emplea <kbd>format=$2</kbd>.\n\nPara obtener más información, consulta la [[mw:API|documentación completa]] o la [[Special:ApiHelp/main|ayuda de API]].",
        "api-format-prettyprint-status": "Esta respuesta se devolvería con el estado HTTP $1 $2.",
        "api-help-title": "Ayuda de la API de MediaWiki",
        "api-help-lead": "Esta es una página de documentación autogenerada de la API de MediaWiki.\n\nDocumentación y ejemplos: https://www.mediawiki.org/wiki/API",
index cb88c55..9309630 100644 (file)
        "apihelp-help-example-query": "Aide pour deux sous-modules de recherche",
        "apihelp-imagerotate-description": "Faire pivoter une ou plusieurs images.",
        "apihelp-imagerotate-param-rotation": "Degrés de rotation de l’image dans le sens des aiguilles d’une montre.",
+       "apihelp-imagerotate-param-tags": "Balises à appliquer à l’entrée dans le journal de téléchargement.",
        "apihelp-imagerotate-example-simple": "Faire pivoter <kbd>File:Example.png</kbd> de <kbd>90</kbd> degrés.",
        "apihelp-imagerotate-example-generator": "Faire pivoter toutes les images de <kbd>Category:Flip</kbd> de <kbd>180</kbd> degrés.",
        "apihelp-import-description": "Importer une page depuis un autre wiki, ou depuis un fichier XML.\n\nNoter que le POST HTTP doit être effectué comme un import de fichier (c’est-à-dire en utilisant multipart/form-data) lors de l’envoi d’un fichier pour le paramètre <var>xml</var>.",
        "apihelp-revisiondelete-param-show": "Quoi démasquer pour chaque révision",
        "apihelp-revisiondelete-param-suppress": "S’il faut supprimer les données aux administrateurs comme aux autres.",
        "apihelp-revisiondelete-param-reason": "Motif de suppression ou d’annulation de suppression.",
+       "apihelp-revisiondelete-param-tags": "Balises à appliquer à l’entrée dans le journal de suppression.",
        "apihelp-revisiondelete-example-revision": "Masquer le contenu de la révision <kbd>12345</kbd> de la page <kbd>Main Page</kbd>",
        "apihelp-revisiondelete-example-log": "Masquer toutes les données de l’entrée de journal <kbd>67890</kbd> avec le motif <kbd>Violation de Biographie de Personne Vivante</kbd>.",
        "apihelp-rollback-description": "Annuler la dernière modification de la page.\n\nSi le dernier utilisateur à avoir modifié la page a fait plusieurs modifications sur une ligne, elles seront toutes annulées.",
        "apihelp-setnotificationtimestamp-example-page": "Réinitialiser l’état de notification pour la <kbd>Page principale<kbd>.",
        "apihelp-setnotificationtimestamp-example-pagetimestamp": "Fixer l’horodatage de notification pour <kbd>Page principale</kbd> afin que toutes les modifications depuis le 1 janvier 2012 soient non vues",
        "apihelp-setnotificationtimestamp-example-allpages": "Réinitialiser l’état de notification sur les pages dans l’espace de noms <kbd>{{ns:user}}</kbd>.",
+       "apihelp-setpagelanguage-description": "Modifier la langue d’une page.",
+       "apihelp-setpagelanguage-description-disabled": "Il n’est pas possible de modifier la langue d’une page sur ce wiki.\n\nActiver <var>[[mw:Manual:$wgPageLanguageUseDB|$wgPageLanguageUseDB]]</var> pour utiliser cette action.",
+       "apihelp-setpagelanguage-param-title": "Titre de la page dont vous souhaitez modifier la langue. Ne peut pas être utilisé avec <var>$1pageid</var>.",
+       "apihelp-setpagelanguage-param-pageid": "Identifiant (ID) de la page dont vous souhaitez modifier la langue. Ne peut être utilisé avec <var>$1title</var>.",
+       "apihelp-setpagelanguage-param-lang": "Code de langue vers lequel la page doit être changée. Utiliser <kbd>defaut</kbd> pour réinitialiser la page sur la langue par défaut du contenu du wiki.",
+       "apihelp-setpagelanguage-param-tags": "Modifier les balises à appliquer à l'entrée du journal résultant de cette action.",
+       "apihelp-setpagelanguage-example-language": "Changer la langue de la <kbd>page principale</kbd> en basque.",
+       "apihelp-setpagelanguage-example-default": "Remplacer la langue de la page ayant l'ID 123 par la langue par défaut du contenu du wiki.",
        "apihelp-stashedit-description": "Préparer une modification dans le cache partagé.\n\nCeci a pour but d’être utilisé via AJAX depuis le formulaire d’édition pour améliorer la performance de la sauvegarde de la page.",
        "apihelp-stashedit-param-title": "Titre de la page en cours de modification.",
        "apihelp-stashedit-param-section": "Numéro de section. <kbd>0</kbd> pour la section du haut, <kbd>new</kbd> pour une nouvelle section.",
        "apihelp-tag-param-add": "Balises à ajouter. Seules les balises définies manuellement peuvent être ajoutées.",
        "apihelp-tag-param-remove": "Balises à supprimer. Seules les balises qui sont soit définies manuellement soit pas du tout définies peuvent être supprimées.",
        "apihelp-tag-param-reason": "Motif de la modification.",
+       "apihelp-tag-param-tags": "Balises à appliquer à l’entrée de journal qui sera créée en résultat de cette action.",
        "apihelp-tag-example-rev": "Ajoute la balise <kbd>vandalism</kbd> à partir de l’ID de révision 123 sans indiquer de motif",
        "apihelp-tag-example-log": "Supprimer la balise <kbd>spam</kbd> à partir de l’ID d’entrée de journal 123 avec le motif <kbd>Wrongly applied</kbd>",
        "apihelp-tokens-description": "Obtenir les jetons pour les actions modifiant les données.\n\nCe module est obsolète, remplacé par [[Special:ApiHelp/query+tokens|action=query&meta=tokens]].",
        "apierror-opensearch-json-warnings": "Les avertissements ne peuvent pas être représentés dans le format JSON OpenSearch.",
        "apierror-pagecannotexist": "L’espace de noms ne permet pas de pages réelles.",
        "apierror-pagedeleted": "La page a été supprimée depuis que vous avez récupéré son horodatage.",
+       "apierror-pagelang-disabled": "Il n'est pas possible de modifier la langue d'une page sur ce wiki.",
        "apierror-paramempty": "Le paramètre <var>$1</var> ne peut pas être vide.",
        "apierror-parsetree-notwikitext": "<kbd>prop=parsetree</kbd> n’est supporté que pour le contenu wikitexte.",
        "apierror-parsetree-notwikitext-title": "<kbd>prop=parsetree</kbd> n’est supporté que pour le contenu wikitexte. $1 utilise le modèle de contenu $2.",
index 9e456bb..9792033 100644 (file)
@@ -30,7 +30,8 @@
        "apihelp-main-param-uselang": "Linga a usar para a tradución de mensaxes. <kbd>[[Special:ApiHelp/query+siteinfo|action=query&meta=siteinfo]]</kbd> con <kbd>siprop=languages</kbd> devolve unha lista de códigos de lingua, ou especificando <kbd>user</kbd> coa preferencia de lingua do usuario actual, ou especificando <kbd>content</kbd> para usar a lingua do contido desta wiki.",
        "apihelp-main-param-errorformat": "Formato a usar para a saída do texto de aviso e de erroː\n; plaintext:  texto wiki sen as etiquetas HTML e coas entidades substituídas.\n; wikitext: texto wiki sen analizar.\n; html: HTML.\n; raw: Clave de mensaxe e parámetros.\n; none: Sen saída de texto, só os códigos de erro.\n; bc: Formato utilizado antes de MediaWiki 1.29. <var>errorlang</var> e <var>errorsuselocal</var> non se teñen en conta.",
        "apihelp-block-description": "Bloquear un usuario.",
-       "apihelp-block-param-user": "Nome de usuario, dirección ou rango de IPs que quere bloquear.",
+       "apihelp-block-param-user": "Nome de usuario, dirección ou rango de IPs que quere bloquear. Non pode usarse xunto con <var>$1userid</var>",
+       "apihelp-block-param-userid": "Identificador de usuario a bloquear. Non pode usarse xunto con <var>$1user</var>.",
        "apihelp-block-param-expiry": "Tempo de caducidade. Pode ser relativo (p. ex.<kbd>5 meses</kbd> ou <kbd>2 semanas</kbd>) ou absoluto (p. ex. 2014-09-18T12:34:56Z</kbd>). Se se pon kbd>infinite</kbd>, <kbd>indefinite</kbd>, ou <kbd>never</kbd>, o bloqueo nunca caducará.",
        "apihelp-block-param-reason": "Motivo para o bloqueo.",
        "apihelp-block-param-anononly": "Bloquear só usuarios anónimos (é dicir, desactivar edicións anónimas desta dirección IP).",
        "apihelp-query+imageinfo-paramvalue-prop-archivename": "Engade o nome de ficheiro da versión do ficheiro para versións anteriores ás últimas.",
        "apihelp-query+imageinfo-paramvalue-prop-bitdepth": "Engade a profundidade de bits da versión.",
        "apihelp-query+imageinfo-paramvalue-prop-uploadwarning": "Usado pola páxina Special:Upload para obter información sobre un ficheiro existente. Non previsto para usar fóra do núcleo MediaWiki.",
+       "apihelp-query+imageinfo-paramvalue-prop-badfile": "Engadido cando o ficheiro está na [[MediaWiki:Bad image list]]",
        "apihelp-query+imageinfo-param-limit": "Cantas revisións de ficheiro a devolver por ficheiro.",
        "apihelp-query+imageinfo-param-start": "Selo de tempo dende o que comezar a lista.",
        "apihelp-query+imageinfo-param-end": "Selo de tempo no que rematar a lista.",
index c2963d7..dcbeceb 100644 (file)
        "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": "הוספת המשתמש עם המזהה <kbd>123</kbd> לקבוצה <kbd>bot</kbd> והסרתו מהקבוצות <kbd>sysop</kbd> ו־<kbd>bureaucrat</kbd>.",
        "apihelp-validatepassword-description": "לבדוק תקינות ססמה אל מול מדיניות הססמאות של הוויקי.\n\nהתקינות מדווחת כ־<samp>Good</samp> אם הססמה קבילה, <samp>Change</samp> אם הססמה יכולה לשמש לכניסה, אבל צריכה להשתנות, או <samp>Invalid</samp> אם הססמה אינה שמישה.",
        "apierror-badvalue-notmultivalue": "הפרדת ערכים מרובים ב־U+001F אפשרית רק בפרמטרים מרובי־פרמטרים.",
        "apierror-bad-watchlist-token": "סופק אסימון רשימת מעקב בלתי־תקין. נא להשתמש באסימון תקין ב־[[Special:Preferences]].",
        "apierror-blockedfrommail": "נחסמת משליחת דוא״ל.",
+       "apierror-blocked": "נחסמת מעריכה.",
+       "apierror-botsnotsupported": "הממשק הזה לא נתמך עבור בוטים.",
+       "apierror-cannotreauthenticate": "הפעולה הזאת אינה זמינה, כי הזהות שלך לא יכולה להיות מאומתת.",
+       "apierror-cannotviewtitle": "אין לך הרשאה להציג את $1.",
+       "apierror-cantblock-email": "אין לך הרשאה לחסום משתמשים משליחת דואר אלקטרוני דרך הוויקי.",
+       "apierror-cantblock": "אין לך הרשאה לחסום משתמשים.",
+       "apierror-cantchangecontentmodel": "אין לך הרשאה לשנות את דגם התוכן של דף.",
+       "apierror-canthide": "אין לך הרשאה להסתיר שמות משתמשים ביומן החסימה.",
+       "apierror-cantimport-upload": "אין לך הרשאה לייבא דפים מוּעלים.",
+       "apierror-cantimport": "אין לך הרשאה לייבא דפים.",
+       "apierror-cantoverwrite-sharedfile": "קובץ היעד קיים במאגר משותף ואין לך הרשאה לעקוף אותו.",
+       "apierror-cantsend": "לא נכנסת לחשבון, אין לך חשבון דואר אלקטרוני מאושר, או שאסור לך לשלוח דואר אלקטרוני למשתמשים אחרים, אז אינך לך אפשרות לשלוח דואר אלקטרוני.",
+       "apierror-cantundelete": "לא היה אפשר לשחזר ממחיקה: אולי הגרסאות המבוקשות אינן קיימות, ואולי הן כבר נמחקו.",
+       "apierror-changeauth-norequest": "יצירת בקשת השינוי נכשלה.",
+       "apierror-chunk-too-small": "גודל הפלח המזערי הוא {{PLURAL:$1|בית אחד|$1 בתים}} בשביל פלחים לא סופיים.",
+       "apierror-cidrtoobroad": "טווחי CIDR של $1 שרחבים יותר מ־/$2 אינם קבילים.",
+       "apierror-compare-inputneeded": "כותרת, מזהה דף, או מספר גרסה נחוצים בשביל הפרמטרים <var>from</var> ו־<var>to</var>.",
+       "apierror-contentserializationexception": "הסדרת התוכן נכשלה: $1",
+       "apierror-contenttoobig": "התוכן שסיפקת חורג מגודל הערך המרבי של {{PLURAL:$1|קילובייט אחד|$1 קילובייטים}}.",
+       "apierror-copyuploadbaddomain": "העלאות לפי URL אינם מורשות מהמתחם הזה.",
+       "apierror-copyuploadbadurl": "העלאה אינה מותרת מה־URL הזה.",
+       "apierror-create-titleexists": "כותרות קיימות אינם יכולות מוגנות עם <kbd>create</kbd>.",
+       "apierror-csp-report": "בעיבוד דו\"ח CSP אירעה שגיאה: $1",
+       "apierror-databaseerror": "[$1] שגיאת שאילתת מסד נתונים.",
+       "apierror-deletedrevs-param-not-1-2": "הפרמטר <var>$1</var> אינו יכול לשמש במצבים 1 או 2.",
+       "apierror-deletedrevs-param-not-3": "הפרמטר <var>$1</var> אינו יכול במצב 3.",
+       "apierror-emptynewsection": "יצירת פסקאות חדשות ריקות בלתי־אפשרי.",
+       "apierror-emptypage": "יצירת דפים חדשים ריקים אינו מותר.",
+       "apierror-exceptioncaught": "[$1] נתפס חריג: $2",
+       "apierror-filedoesnotexist": "הקובץ אינו קיים.",
+       "apierror-fileexists-sharedrepo-perm": "קובץ היעד קיים במאגר משותף. יש להשתמש בפרמטר <var>ignorewarnings</var> כדי לעקוף אותו.",
+       "apierror-filenopath": "לא ניתן לקבל נתיב לקובץ מקומי.",
+       "apierror-filetypecannotberotated": "לא ניתן לסובב את סוג הקובץ הזה.",
+       "apierror-formatphp": "התשובה הזאת לא יכולה להיות מיוצגת עם <kbd>format=php</kbd>. ר' https://phabricator.wikimedia.org/T68776.",
+       "apierror-imageusage-badtitle": "הכותרת בשביל <kbd>$1</kbd> צריכה להיות קובץ.",
+       "apierror-import-unknownerror": "שגיאה בלתי־ידועה בייצוא: $1.",
+       "apierror-integeroutofrange-abovebotmax": "<var>$1</var> אינו יכול להיות גדול מ־$2 (עכשיו מוגדר $3) עבור בוטים או מפעילים.",
+       "apierror-integeroutofrange-abovemax": "<var>$1</var> אינו יכול להיות גדול מ־$2 (עכשיו מוגדר $3) עבור משתמשים.",
+       "apierror-integeroutofrange-belowminimum": "<var>$1</var> אינו יכול להיות גדול מ־$2 (עכשיו מוגדר $3).",
+       "apierror-invalidcategory": "שם הקטגוריה שהזנת אינו תקין.",
+       "apierror-invalid-file-key": "לא מפתח קובץ תקין.",
+       "apierror-invalidtitle": "כותרת רעה \"$1\".",
+       "apierror-invaliduser": "שם משתמש בלתי־תקין \"$1\".",
+       "apierror-maxlag": "ממתין ל־$2: שיהוי של {{PLURAL:$1|שנייה אחת|$1 שניות}}.",
        "apierror-mustbeloggedin-generic": "חובה להיכנס.",
        "apierror-mustbeloggedin-linkaccounts": "חובה להיכנס לחשבון כדי לקשר חשבונות.",
        "apierror-mustbeloggedin-removeauth": "חובה להיכנס לחשבון כדי להסיר מידע אימות.",
index 71b1763..9f5b6d6 100644 (file)
        "apihelp-revisiondelete-param-hide": "Cosa nascondere per ogni versione.",
        "apihelp-revisiondelete-param-show": "Cosa mostrare per ogni versione.",
        "apihelp-revisiondelete-param-reason": "Motivo per l'eliminazione o il ripristino.",
+       "apihelp-setpagelanguage-description": "Cambia la lingua di una pagina.",
        "apihelp-stashedit-param-title": "Titolo della pagina che si sta modificando.",
        "apihelp-stashedit-param-sectiontitle": "Il titolo per una nuova sezione.",
        "apihelp-stashedit-param-text": "Contenuto della pagina.",
index f088618..7253941 100644 (file)
        "apihelp-main-param-requestid": "주어진 요청 값은 응답에 포함됩니다. 요청을 구분하기 위해 사용될 수 있습니다.",
        "apihelp-main-param-servedby": "결과에 요청을 처리한 호스트네임을 포함합니다.",
        "apihelp-main-param-curtimestamp": "결과의 타임스탬프를 포함합니다.",
+       "apihelp-main-param-responselanginfo": "<var>uselang</var> 및 <var>errorlang</var>에 사용되는 언어를 결과에 포함합니다.",
+       "apihelp-main-param-origin": "크로스 도메인 AJAX 요청 (CORS)을 사용하여 API에 접근할 때, 이것을 발신 도메인으로 설정하십시오. 모든 pre-flight 요청에 포함되어야 하며, 이에 따라 (POST 본문이 아닌) 요청 URI의 일부여야 합니다.\n\n인증된 요청의 경우, <code>Origin</code> 헤더의 발신지들 중 하나와 정확히 일치해야 하므로 <kbd>https://en.wikipedia.org</kbd> 또는 <kbd>https://meta.wikimedia.org</kbd>와 같이 설정되어야 합니다. 이 변수가 <code>Origin</code> 헤더와 일치하지 않으면 403 응답이 반환됩니다. 이 변수가 <code>Origin</code> 헤더와 일치하고 발신지가 화이트리스트에 있을 경우 <code>Access-Control-Allow-Origin</code>과 <code>Access-Control-Allow-Credentials</code> 헤더가 설정됩니다.\n\n인증되지 않은 요청의 경우, <kbd>*</kbd> 값을 지정하십시오. 이를 통해 <code>Access-Control-Allow-Origin</code> 헤더가 설정되지만 <code>Access-Control-Allow-Credentials</code>는 <code>false</code>로 설정되어 모든 사용자 지정 데이터가 제한을 받게 됩니다.",
        "apihelp-main-param-uselang": "메시지 번역을 위한 언어입니다. <kbd>[[Special:ApiHelp/query+siteinfo|action=query&meta=siteinfo]]</kbd>에 <kbd>siprop=languages</kbd>를 함께 사용하면 언어 코드의 목록을 반환하고, <kbd>user</kbd>를 지정하면 현재 사용자의 언어 환경 설정을 사용하며, <kbd>content</kbd>를 지정하면 이 위키의 콘텐츠 언어를 사용합니다.",
+       "apihelp-main-param-errorformat": "경고 및 오류 텍스트 출력을 위해 사용할 형식입니다.\n; plaintext: HTML 태그가 제거되고 엔티티가 치환된 위키텍스트입니다.\n; wikitext: 구문 분석되지 않은 위키텍스트입니다.\n; html: HTML입니다.\n; raw: 메시지 키와 변수입니다.\n; none: 텍스트 없이 오류 코드만 출력합니다.\n; bc: 미디어위키 1.29 이전에 사용된 형식입니다. <var>errorlang</var> 및 <var>errorsuselocal</var>은 무시됩니다.",
+       "apihelp-main-param-errorlang": "경고와 오류를 위해 사용할 언어입니다. <kbd>siprop=languages</kbd>가 포함된 <kbd>[[Special:ApiHelp/query+siteinfo|action=query&meta=siteinfo]]</kbd>는 언어 코드의 목록을 반환하고, <kbd>content</kbd>를 지정하면 이 위키의 내용 상의 언어를 사용하며, <kbd>uselang</kbd>을 지정하면 <var>uselang</var> 변수와 동일한 값을 사용합니다.",
+       "apihelp-main-param-errorsuselocal": "지정하면 오류 텍스트가 {{ns:MediaWiki}} 이름공간에서 지역적으로 정의된 메시지를 사용합니다.",
        "apihelp-block-description": "사용자를 차단합니다.",
        "apihelp-block-param-user": "차단할 사용자 이름, IP 주소, 또는 IP 주소 대역입니다. <var>$1userid</var>와(과) 함께 사용할 수 없습니다.",
        "apihelp-block-param-userid": "차단할 사용자 ID입니다. <var>$1user</var>와(과) 함께 사용할 수 없습니다.",
        "apihelp-protect-param-reason": "보호 또는 보호 해제의 이유.",
        "apihelp-protect-example-protect": "문서 보호",
        "apihelp-purge-param-forcelinkupdate": "링크 테이블을 업데이트합니다.",
+       "apihelp-query-param-prop": "조회된 페이지에 대해 가져올 속성입니다.",
+       "apihelp-query-param-list": "가져올 목록입니다.",
+       "apihelp-query-param-meta": "가져올 메타데이터입니다.",
+       "apihelp-query-param-indexpageids": "반환된 모든 페이지 ID를 나열하는 부가적인 페이지 ID 섹션을 포함합니다.",
+       "apihelp-query-param-export": "기존의 페이지나 생성된 페이지들 전체의 현재 판들을 내보냅니다.",
+       "apihelp-query-param-exportnowrap": "XML 결과물로 래핑하지 않고 엑스포트 XML을 반환합니다. $1export와만 같이 사용할 수 있습니다.",
+       "apihelp-query-param-iwurl": "제목이 인터위키 링크인 경우 전체 URL을 가져올지의 여부입니다.",
+       "apihelp-query-param-rawcontinue": "계속하기 위해 순수 <samp>query-continue</samp> 데이터를 반환합니다.",
        "apihelp-query+allcategories-description": "모든 분류를 열거합니다.",
        "apihelp-query+allcategories-param-prefix": "이 값으로 시작하는 모든 분류 제목을 검색합니다.",
        "apihelp-query+allcategories-param-dir": "정렬 방향.",
        "apihelp-query+search-paramvalue-prop-timestamp": "문서가 마지막으로 편집된 시기의 타임스탬프를 추가합니다.",
        "apihelp-query+search-example-simple": "<kbd>meaning</kbd>을 검색합니다.",
        "apihelp-query+search-example-text": "<kbd>meaning</kbd>의 텍스트를 검색합니다.",
+       "apihelp-query+siteinfo-description": "사이트의 전반적인 정보를 반환합니다.",
        "apihelp-query+siteinfo-param-prop": "가져올 정보:",
-       "apihelp-query+siteinfo-paramvalue-prop-general": "전반적인 시스템 정보.",
+       "apihelp-query+siteinfo-paramvalue-prop-general": "전반적인 시스템 정보입니다.",
+       "apihelp-query+siteinfo-paramvalue-prop-namespaces": "등록된 이름공간 및 기본 이름의 목록입니다.",
+       "apihelp-query+siteinfo-paramvalue-prop-namespacealiases": "등록된 이름공간 별칭의 목록입니다.",
+       "apihelp-query+siteinfo-paramvalue-prop-specialpagealiases": "특수 문서의 별칭 목록입니다.",
+       "apihelp-query+siteinfo-paramvalue-prop-magicwords": "매직 워드와 별칭의 목록입니다.",
        "apihelp-query+siteinfo-paramvalue-prop-statistics": "사이트 통계를 반환합니다.",
        "apihelp-query+siteinfo-paramvalue-prop-interwikimap": "인터위키 맵을 반환합니다. (<var>$1inlanguagecode</var>를 사용하여 필터링 및 지역화 선택 가능)",
+       "apihelp-query+siteinfo-paramvalue-prop-dbrepllag": "반복 지연이 가장 높은 데이터베이스 서버를 반환합니다.",
        "apihelp-query+siteinfo-paramvalue-prop-usergroups": "사용자 그룹 및 관련 권한을 반환합니다.",
        "apihelp-query+siteinfo-paramvalue-prop-libraries": "위키에 설치된 라이브러리를 반환합니다.",
        "apihelp-query+siteinfo-paramvalue-prop-extensions": "위키에 설치된 확장 기능을 반환합니다.",
        "apihelp-query+siteinfo-paramvalue-prop-skins": "사용 중인 모든 스킨의 목록을 반환합니다. (<var>$1inlanguagecode</var>를 사용하여 지역화 선택이 가능하며, 이를 사용하지 않으면 본문의 언어를 사용함)",
        "apihelp-query+siteinfo-paramvalue-prop-extensiontags": "파서 확장 태그의 목록을 반환합니다.",
        "apihelp-query+siteinfo-paramvalue-prop-functionhooks": "파서 함수 훅의 목록을 반환합니다.",
+       "apihelp-query+siteinfo-paramvalue-prop-showhooks": "예약된 모든 훅(<var>[[mw:Manual:$wgHooks|$wgHooks]]</var>의 내용)의 목록을 반환합니다.",
        "apihelp-query+siteinfo-paramvalue-prop-variables": "변수 ID의 목록을 반환합니다.",
        "apihelp-query+siteinfo-paramvalue-prop-protocols": "외부 링크에 허용된 프로토콜의 목록을 반환합니다.",
        "apihelp-query+siteinfo-paramvalue-prop-defaultoptions": "사용자 환경 설정의 기본값을 반환합니다.",
        "apihelp-query+siteinfo-paramvalue-prop-uploaddialog": "업로드 대화 상자 구성을 반환합니다.",
+       "apihelp-query+siteinfo-param-filteriw": "인터위키 맵의 로컬 또는 로컬이 아닌 항목만 반환합니다.",
+       "apihelp-query+siteinfo-param-showalldb": "가장 지연이 심한 서버뿐 아니라, 모든 데이터베이스 서버를 나열합니다.",
        "apihelp-query+siteinfo-param-numberingroup": "사용자 그룹의 사용자 수를 나열합니다.",
+       "apihelp-query+siteinfo-param-inlanguagecode": "지역화된 언어 이름 (가능한 경우) 및 스킨 이름의 언어 코드입니다.",
        "apihelp-query+siteinfo-example-simple": "사이트 정보를 가져옵니다.",
        "apihelp-query+siteinfo-example-interwiki": "로컬 인터위키 접두사 목록을 가져옵니다.",
+       "apihelp-query+siteinfo-example-replag": "현재의 반복 지연을 검사합니다.",
        "apihelp-query+tags-param-limit": "나열할 태그의 최대 수.",
        "apihelp-query+tags-paramvalue-prop-name": "태그의 이름을 추가합니다.",
        "apihelp-query+tags-paramvalue-prop-description": "태그의 설명을 추가합니다.",
        "apihelp-revisiondelete-description": "판을 삭제하거나 되살립니다.",
        "apihelp-revisiondelete-param-reason": "삭제 또는 복구 이유.",
        "apihelp-rollback-param-tags": "되돌리기를 적용하기 위해 태그합니다.",
+       "apihelp-setpagelanguage-description": "문서의 언어를 변경합니다.",
+       "apihelp-setpagelanguage-description-disabled": "이 위키에서 문서의 언어 변경은 허용되지 않습니다.\n\n이 동작을 사용하려면 <var>[[mw:Manual:$wgPageLanguageUseDB|$wgPageLanguageUseDB]]</var>을 활성화하십시오.",
+       "apihelp-setpagelanguage-example-language": "<kbd>Main Page</kbd>의 언어를 바스크어로 변경합니다.",
        "apihelp-stashedit-param-sectiontitle": "새 문단을 위한 제목.",
        "apihelp-stashedit-param-text": "문서 내용.",
        "apihelp-stashedit-param-contentmodel": "새 콘텐츠의 콘텐츠 모델.",
        "apihelp-rawfm-description": "출력 데이터, 디버깅 요소를 포함, (HTML에 포함된)JSON형식.",
        "apihelp-xml-param-includexmlnamespace": "지정하면 XML 이름공간을 추가합니다.",
        "api-format-title": "미디어위키 API 결과",
+       "api-pageset-param-titles": "작업할 제목의 목록입니다.",
+       "api-pageset-param-pageids": "작업할 페이지 ID의 목록입니다.",
+       "api-pageset-param-revids": "작업할 판 ID의 목록입니다.",
+       "api-pageset-param-generator": "특정 쿼리 모듈을 실행함으로써 작업할 페이지의 목록입니다.\n\n<strong>참고:</strong> 발생기 변수명은 \"g\"로 시작해야 합니다. 예시를 참고하십시오.",
        "api-help-title": "미디어위키 API 도움말",
        "api-help-lead": "이 페이지는 자동으로 생성된 미디어위키 API 도움말 문서입니다.\n\n설명 문서 및 예시: https://www.mediawiki.org/wiki/API",
        "api-help-main-header": "메인 모듈",
        "api-help-param-integer-min": "{{PLURAL:$1|1=값|2=값들}}은 $2 이상이어야 합니다.",
        "api-help-param-integer-max": "{{PLURAL:$1|1=값|2=값들}}은 $3 이하여야 합니다.",
        "api-help-param-integer-minmax": "{{PLURAL:$1|1=값|2=값들}}은 $2와 $3 사이여야 합니다.",
+       "api-help-param-multi-separate": "<kbd>|</kbd> 또는 [[Special:ApiHelp/main#main/datatypes|대안]]으로 값을 구분합니다.",
        "api-help-param-multi-max": "값들의 최대 수는 {{PLURAL:$1|$1}}입니다. (봇의 경우 {{PLURAL:$2|$2}})",
        "api-help-param-default": "기본값: $1",
        "api-help-param-default-empty": "기본값: <span class=\"apihelp-empty\">(비어 있음)</span>",
        "apierror-nosuchuserid": "ID $1에 해당하는 사용자가 없습니다.",
        "apierror-notarget": "이 작업을 위한 유효한 대상을 지정하지 않았습니다.",
        "apierror-pagecannotexist": "이름공간은 실제 페이지를 허용하지 않습니다.",
+       "apierror-pagelang-disabled": "이 위키에서 문서의 언어 변경은 허용되지 않습니다.",
        "apierror-permissiondenied": "$1에 대한 권한이 없습니다.",
        "apierror-permissiondenied-generic": "권한이 없습니다.",
        "apierror-permissiondenied-unblock": "사용자의 차단을 해제할 권한이 없습니다.",
index da23458..3abfdeb 100644 (file)
        "api-help-param-disabled-in-miser-mode": "Исклучено поради [[mw:Manual:$wgMiserMode|скржавиот режим]].",
        "api-help-param-limited-in-miser-mode": "<strong>Напомена:</strong> Бидејќи сте во [[mw:Manual:$wgMiserMode|скржав режим]], користејќи го ова може да добиете помалку од <var>$1limit</var> резултати пред да продолжите; во крајни случаи може да не добиете ниеден резултат.",
        "api-help-param-direction": "Во која насока да се набројува:\n;понови:Прво најстарите. Напомена: $1start мора да биде пред $1end.\n;постари:Прво најновите (по основно). Напомена: $1start мора да биде подоцна од $1end.",
-       "api-help-param-continue": "УпоÑ\82Ñ\80ебеÑ\82е Ð³Ð¾ Ð¾Ð²Ð° Ð·Ð° Ð´Ð° Ð¿Ñ\80одолжиÑ\82е ÐºÐ¾Ð³Ð° Ð¸Ð¼Ð° Ð¿Ð¾Ð²ÐµÑ\9cе Ñ\80аÑ\81положиви Ñ\80езÑ\83лÑ\82аÑ\82и.",
+       "api-help-param-continue": "УпоÑ\82Ñ\80ебеÑ\82е Ð³Ð¾ Ð¾Ð²Ð° Ð·Ð° Ð´Ð° Ð¿Ñ\80одолжиÑ\82е ÐºÐ¾Ð³Ð° Ð¸Ð¼Ð° Ð¿Ð¾Ð²ÐµÑ\9cе Ñ\80аÑ\81положиви Ñ\81Ñ\82авки.",
        "api-help-param-no-description": "<span class=\"apihelp-empty\">(нема опис)</span>",
        "api-help-examples": "{{PLURAL:$1|Пример|Примери}}:",
        "api-help-permissions": "{{PLURAL:$1|Дозвола|Дозволи}}:",
index 5079ae2..6506036 100644 (file)
        "apihelp-expandtemplates-description": "Ekspanderer alle maler i wikitekst.",
        "apihelp-expandtemplates-param-title": "Sidetittel.",
        "apihelp-expandtemplates-param-text": "Wikitekst som skal konverteres.",
+       "apihelp-expandtemplates-paramvalue-prop-wikitext": "Den utvidede wikiteksten.",
+       "apihelp-expandtemplates-paramvalue-prop-categories": "Kategorier som er tilstede i innputt som ikke representeres i utputt.",
        "apihelp-feedcontributions-param-year": "Fra år (og tidligere).",
        "apihelp-feedcontributions-param-month": "Fra måned (og tidligere).",
        "apihelp-feedcontributions-param-tagfilter": "Filtrer bidrag som har disse merkene.",
        "apihelp-feedcontributions-param-deletedonly": "Vis bare slettede bidrag.",
        "apihelp-feedcontributions-param-toponly": "Vis kun redigeringer som er gjeldende revisjoner.",
        "apihelp-feedcontributions-param-newonly": "Bare vis bidrag som er sideopprettinger.",
+       "apihelp-feedcontributions-param-hideminor": "Skjul mindre endringer.",
        "apihelp-feedcontributions-param-showsizediff": "Vis størrelsesforskjellen mellom revisjoner.",
+       "apihelp-feedcontributions-example-simple": "Returner bidrag for brukeren <kbd>Example</kbd>.",
+       "apihelp-feedrecentchanges-param-feedformat": "Matingens format.",
+       "apihelp-feedrecentchanges-param-namespace": "Navnerom resultater skal begrenses til.",
+       "apihelp-feedrecentchanges-param-invert": "Alle navnerom utenom det valgte.",
+       "apihelp-feedrecentchanges-param-associated": "Inkluder tilknyttede navnerom (diskusjons- eller hovednavnerom).",
+       "apihelp-feedrecentchanges-param-days": "Dager resultatene skal begrenses til.",
+       "apihelp-feedrecentchanges-param-limit": "Maksimalt antall resultater som skal returneres",
        "apihelp-feedrecentchanges-param-from": "Vis endringer siden da.",
        "apihelp-feedrecentchanges-param-hideminor": "Skjul mindre endringer.",
        "apihelp-feedrecentchanges-param-hidebots": "Skjul botendringer.",
+       "apihelp-feedrecentchanges-param-hideanons": "Skjul endringer gjort av anonyme brukere.",
+       "apihelp-feedrecentchanges-param-hideliu": "Skjul endringer gjort av registrerte brukere.",
+       "apihelp-feedrecentchanges-param-hidepatrolled": "Skjul patruljerte endringer.",
+       "apihelp-feedrecentchanges-param-hidemyself": "Skjul endringer gjort av den aktuelle brukeren.",
+       "apihelp-feedrecentchanges-param-hidecategorization": "Skjul endringer i kategorimedlemsskap.",
+       "apihelp-feedrecentchanges-param-tagfilter": "Filtrer etter tagger.",
+       "apihelp-feedrecentchanges-param-target": "Vis bare endringer på sider som lenkes fra denne siden.",
+       "apihelp-feedrecentchanges-param-showlinkedto": "Vis endringer på sider som lenker til den valgte siden i stedet.",
+       "apihelp-feedrecentchanges-param-categories": "Vis bare endringer på sider i alle disse kategoriene.",
+       "apihelp-feedrecentchanges-param-categories_any": "Vis bare endringer på sider som er i noen av kategoriene i stedet.",
+       "apihelp-feedrecentchanges-example-simple": "Vis siste endringer.",
+       "apihelp-feedrecentchanges-example-30days": "Vis siste endringer for 30 døgn.",
+       "apihelp-feedwatchlist-description": "Returnerer en overvåkningslistemating.",
+       "apihelp-feedwatchlist-param-feedformat": "Matingens format.",
        "apihelp-help-param-toc": "Inkluder en innholdsfortegnelse i HTML-utdataen.",
        "apihelp-help-example-main": "Hjelp for hovedmodulen.",
        "apihelp-help-example-recursive": "All hjelp på en side.",
index c1a71a4..732991a 100644 (file)
@@ -35,6 +35,7 @@
        "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-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-example-ip-simple": "Het IP-adres <kbd>192.0.2.5</kbd> voor drie dagen blokkeren met <kbd>First strike</kbd> als opgegeven reden.",
@@ -49,6 +50,7 @@
        "apihelp-createaccount-param-name": "Gebruikersnaam.",
        "apihelp-createaccount-param-email": "E-mailadres van de gebruiker (optioneel).",
        "apihelp-createaccount-param-realname": "Echte naam van de gebruiker (optioneel).",
+       "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-delete-description": "Een pagina verwijderen.",
index 9d467cc..85e24e4 100644 (file)
        "apihelp-help-example-query": "{{doc-apihelp-example|help}}",
        "apihelp-imagerotate-description": "{{doc-apihelp-description|imagerotate}}",
        "apihelp-imagerotate-param-rotation": "{{doc-apihelp-param|imagerotate|rotation}}",
+       "apihelp-imagerotate-param-tags": "{{doc-apihelp-param|imagerotate|tags}}",
        "apihelp-imagerotate-example-simple": "{{doc-apihelp-example|imagerotate}}",
        "apihelp-imagerotate-example-generator": "{{doc-apihelp-example|imagerotate}}",
        "apihelp-import-description": "{{doc-apihelp-description|import}}",
        "apihelp-query+usercontribs-param-end": "{{doc-apihelp-param|query+usercontribs|end}}",
        "apihelp-query+usercontribs-param-user": "{{doc-apihelp-param|query+usercontribs|user}}",
        "apihelp-query+usercontribs-param-userprefix": "{{doc-apihelp-param|query+usercontribs|userprefix}}",
+       "apihelp-query+usercontribs-param-userids": "{{doc-apihelp-param|query+usercontribs|userids}}",
        "apihelp-query+usercontribs-param-namespace": "{{doc-apihelp-param|query+usercontribs|namespace}}",
        "apihelp-query+usercontribs-param-prop": "{{doc-apihelp-param|query+usercontribs|prop|paramvalues=1}}",
        "apihelp-query+usercontribs-paramvalue-prop-ids": "{{doc-apihelp-paramvalue|query+usercontribs|prop|ids}}",
        "apihelp-revisiondelete-param-show": "{{doc-apihelp-param|revisiondelete|show}}",
        "apihelp-revisiondelete-param-suppress": "{{doc-apihelp-param|revisiondelete|suppress}}",
        "apihelp-revisiondelete-param-reason": "{{doc-apihelp-param|revisiondelete|reason}}",
+       "apihelp-revisiondelete-param-tags": "{{doc-apihelp-param|revisiondelete|tags}}",
        "apihelp-revisiondelete-example-revision": "{{doc-apihelp-example|revisiondelete}}",
        "apihelp-revisiondelete-example-log": "{{doc-apihelp-example|revisiondelete}}",
        "apihelp-rollback-description": "{{doc-apihelp-description|rollback}}",
        "apihelp-setnotificationtimestamp-example-page": "{{doc-apihelp-example|setnotificationtimestamp}}",
        "apihelp-setnotificationtimestamp-example-pagetimestamp": "{{doc-apihelp-example|setnotificationtimestamp}}",
        "apihelp-setnotificationtimestamp-example-allpages": "{{doc-apihelp-example|setnotificationtimestamp}}",
+       "apihelp-setpagelanguage-description": "{{doc-apihelp-description|setpagelanguage}}",
+       "apihelp-setpagelanguage-description-disabled": "{{doc-apihelp-description|setpagelanguage|info=This message is used when changing the language of a page is not allowed on the wiki because <var>[[mw:Manual:$wgPageLanguageUseDB|$wgPageLanguageUseDB]]</var> is not enabled.|seealso={{msg-mw|apihelp-setpagelanguage-description}}}}",
+       "apihelp-setpagelanguage-param-title": "{{doc-apihelp-param|setpagelanguage|title}}",
+       "apihelp-setpagelanguage-param-pageid": "{{doc-apihelp-param|setpagelanguage|pageid}}",
+       "apihelp-setpagelanguage-param-lang": "{{doc-apihelp-param|setpagelanguage|lang}}",
+       "apihelp-setpagelanguage-param-reason": "{{doc-apihelp-param|setpagelanguage|reason}}",
+       "apihelp-setpagelanguage-param-tags": "{{doc-apihelp-param|setpagelanguage|tags}}",
+       "apihelp-setpagelanguage-example-language": "{{doc-apihelp-example|setpagelanguage}}",
+       "apihelp-setpagelanguage-example-default": "{{doc-apihelp-example|setpagelanguage}}",
        "apihelp-stashedit-description": "{{doc-apihelp-description|stashedit}}",
        "apihelp-stashedit-param-title": "{{doc-apihelp-param|stashedit|title}}",
        "apihelp-stashedit-param-section": "{{doc-apihelp-param|stashedit|section}}",
        "apihelp-tag-param-add": "{{doc-apihelp-param|tag|add}}",
        "apihelp-tag-param-remove": "{{doc-apihelp-param|tag|remove}}",
        "apihelp-tag-param-reason": "{{doc-apihelp-param|tag|reason}}",
+       "apihelp-tag-param-tags": "{{doc-apihelp-param|tag|tags}}",
        "apihelp-tag-example-rev": "{{doc-apihelp-example|tag}}",
        "apihelp-tag-example-log": "{{doc-apihelp-example|tag}}",
        "apihelp-tokens-description": "{{doc-apihelp-description|tokens}}",
        "apierror-invalidtitle": "{{doc-apierror}}\n\nParameters:\n* $1 - Title that is invalid",
        "apierror-invalidurlparam": "{{doc-apierror}}\n\nParameters:\n* $1 - Module parameter prefix, e.g. \"bl\".\n* $2 - Key\n* $3 - Value.",
        "apierror-invaliduser": "{{doc-apierror}}\n\nParameters:\n* $1 - User name that is invalid.",
+       "apierror-invaliduserid": "{{doc-apierror}}",
        "apierror-maxlag-generic": "{{doc-apierror}}\n\nParameters:\n* $1 - Database is lag in seconds.",
        "apierror-maxlag": "{{doc-apierror}}\n\nParameters:\n* $1 - Database lag in seconds.\n* $2 - Database server that is lagged.",
        "apierror-mimesearchdisabled": "{{doc-apierror}}",
        "apierror-opensearch-json-warnings": "{{doc-apierror}}",
        "apierror-pagecannotexist": "{{doc-apierror}}",
        "apierror-pagedeleted": "{{doc-apierror}}",
+       "apierror-pagelang-disabled": "{{doc-apierror}}",
        "apierror-paramempty": "{{doc-apierror}}\n\nParameters:\n* $1 - Parameter name.",
        "apierror-parsetree-notwikitext": "{{doc-apierror}}",
        "apierror-parsetree-notwikitext-title": "{{doc-apierror}}\n\nParameters:\n* $1 - Page title.\n* $2 - Content model.",
index c012bef..a078f1b 100644 (file)
@@ -21,7 +21,8 @@
                        "Irus",
                        "MaxBioHazard",
                        "Kareyac",
-                       "Mailman"
+                       "Mailman",
+                       "Ping08"
                ]
        },
        "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]].",
        "api-help-permissions-granted-to": "{{PLURAL:$1|Granted to}}: $2",
        "apierror-integeroutofrange-abovemax": "<var>$1</var> не может быть более $2 (на $3) для пользователей.",
        "apierror-nosuchuserid": "Нет пользователя с ID $1.",
+       "apierror-pagelang-disabled": "Меняется язык страницы не допускается в этой Вики.",
        "apierror-protect-invalidaction": "Недопустимый тип защиты \"$1\".",
        "apierror-systemblocked": "Вы были заблокированы автоматически Медиавики.",
        "apierror-unknownformat": "Неизвестный Формат \"$1\".",
        "apierror-urlparamnormal": "Не могли нормализовать параметры изображения для $1.",
+       "api-feed-error-title": "Ошибка ($1)",
        "api-credits-header": "Создатели"
 }
index ece0818..b71c88e 100644 (file)
        "api-help-param-limit2": "Inte mer än $1 ($2 för robotar) tillåts.",
        "api-help-param-multi-separate": "Separera värden med <kbd>|</kbd> eller [[Special:ApiHelp/main#main/datatypes|alternativ]].",
        "apierror-articleexists": "Artikeln du försökte skapa har redan skapats.",
+       "apierror-baddiff": "Diff kan inte hämtas. En eller båda sidversioner finns inte eller du har inte behörighet för att visa dem.",
        "apierror-nosuchuserid": "Det finns ingen användare med ID $1.",
        "apierror-protect-invalidaction": "Ogiltig skyddstyp \"$1\".",
        "apierror-systemblocked": "Du har blockerats automatiskt av MediaWiki.",
index 60299ca..97ab184 100644 (file)
        "apihelp-help-example-query": "两个查询子模块的帮助。",
        "apihelp-imagerotate-description": "旋转一幅或多幅图像。",
        "apihelp-imagerotate-param-rotation": "顺时针旋转图像的度数。",
+       "apihelp-imagerotate-param-tags": "要在上传日志中应用到实体的标签。",
        "apihelp-imagerotate-example-simple": "<kbd>90</kbd>度旋转<kbd>File:Example.png</kbd>。",
        "apihelp-imagerotate-example-generator": "将<kbd>Category:Flip</kbd>之中的所有图像旋转<kbd>180</kbd>度。",
        "apihelp-import-description": "从另一个wiki或从一个XML文件导入页面。\n\n注意当发送一个用于<var>xml</var>参数的文件时,HTTP POST必须作为一次文件上传完成(也就是使用multipart/form-data)。",
        "apihelp-revisiondelete-param-show": "每次修订要恢复显示的东西。",
        "apihelp-revisiondelete-param-suppress": "是否对管理员及其他人禁止数据。",
        "apihelp-revisiondelete-param-reason": "删除或恢复的原因。",
+       "apihelp-revisiondelete-param-tags": "要在删除日志中应用到实体的标签。",
        "apihelp-revisiondelete-example-revision": "隐藏<kbd>首页</kbd>的修订版本<kbd>12345</kbd>的内容。",
        "apihelp-revisiondelete-example-log": "隐藏日志记录<kbd>67890</kbd>上的所有数据,原因<kbd>BLP violation</kbd>。",
        "apihelp-rollback-description": "撤销对页面的最近编辑。\n\n如果最近编辑页面的用户在一行中进行多次编辑,所有编辑将被回退。",
        "apihelp-setnotificationtimestamp-example-page": "重置用于<kbd>Main page</kbd>的通知状态。",
        "apihelp-setnotificationtimestamp-example-pagetimestamp": "设置<kbd>Main page</kbd>的通知时间戳,这样所有从2012年1月1日起的编辑都会是未复核的。",
        "apihelp-setnotificationtimestamp-example-allpages": "重置在<kbd>{{ns:user}}</kbd>名字空间中的页面的通知状态。",
+       "apihelp-setpagelanguage-description": "更改页面的语言。",
+       "apihelp-setpagelanguage-description-disabled": "此wiki不允许更改页面的语言。\n\n启用<var>[[mw:Manual:$wgPageLanguageUseDB|$wgPageLanguageUseDB]]</var>以使用此操作。",
+       "apihelp-setpagelanguage-param-title": "您希望更改语言的页面标题。不能与<var>$1pageid</var>一起使用。",
+       "apihelp-setpagelanguage-param-pageid": "您希望更改语言的页面ID。不能与<var>$1title</var>一起使用。",
+       "apihelp-setpagelanguage-param-lang": "更改页面的目标语言的语言代码。使用<kbd>default</kbd>以重置页面为wiki的默认内容语言。",
+       "apihelp-setpagelanguage-param-tags": "要应用到此操作导致的日志记录的更改标签。",
+       "apihelp-setpagelanguage-example-language": "更改<kbd>Main Page</kbd>的语言为巴斯克语。",
+       "apihelp-setpagelanguage-example-default": "更改ID为123的页面的语言为wiki的默认内容语言。",
        "apihelp-stashedit-description": "在分享的缓存中准备一次编辑。\n\n这是为了从编辑表单中通过AJAX使用,以改进页面保存的性能。",
        "apihelp-stashedit-param-title": "已开始编辑的页面标题。",
        "apihelp-stashedit-param-section": "段落数。<kbd>0</kbd>用于首段,<kbd>new</kbd>用于新的段落。",
        "apihelp-tag-param-add": "要添加的标签。只有手动定义的标签可以添加。",
        "apihelp-tag-param-remove": "要移除的标签。只有手动定义或完全不明确的标签可以被移除。",
        "apihelp-tag-param-reason": "更改原因。",
+       "apihelp-tag-param-tags": "要应用到将被创建为此操作结果的日志实体的标签。",
        "apihelp-tag-example-rev": "将<kbd>vandalism</kbd>标签添加至修订ID 123,而不指定原因",
        "apihelp-tag-example-log": "从日志记录ID 123移除<kbd>spam</kbd>标签,原因为<kbd>Wrongly applied</kbd>",
        "apihelp-tokens-description": "获取可修改数据的操作的令牌。\n\n此模块被弃用以有利于[[Special:ApiHelp/query+tokens|action=query&meta=tokens]]。",
        "apierror-opensearch-json-warnings": "警告不能以OpenSearch JSON格式表示。",
        "apierror-pagecannotexist": "名字空间不允许实际页面。",
        "apierror-pagedeleted": "在您取得页面时间戳以来,页面已被删除。",
+       "apierror-pagelang-disabled": "此wiki不允许更改页面的语言。",
        "apierror-paramempty": "参数<var>$1</var>不能为空。",
        "apierror-parsetree-notwikitext": "<kbd>prop=parsetree</kbd>只支持wiki文本内容。",
        "apierror-parsetree-notwikitext-title": "<kbd>prop=parsetree</kbd>只支持wiki文本内容。$1使用内容模型$2。",
        "apierror-ratelimited": "您已超过您的速率限制。请等待一段时间再试。",
        "apierror-readapidenied": "您需要读取权限以使用此模块。",
        "apierror-readonly": "此wiki目前为只读模式。",
+       "apierror-reauthenticate": "您在该会话中尚未经过验证,请重新验证。",
        "apierror-revdel-mutuallyexclusive": "同一字段不能同时用于<var>hide</var>和<var>show</var>。",
        "apierror-revdel-needtarget": "此修订版本删除类型需要目标标题。",
        "apierror-revdel-paramneeded": "需要<var>hide</var>和/或<var>show</var>的至少一个值。",
        "apierror-sectionreplacefailed": "不能合并更新的章节。",
        "apierror-sectionsnotsupported": "内容模型$1不支持章节。",
        "apierror-sectionsnotsupported-what": "章节不被$1所支持。",
+       "apierror-show": "不正确的参数——不可提供互斥值。",
        "apierror-siteinfo-includealldenied": "除非<var>$wgShowHostNames</var>为真,否则不能查看所有服务器的信息。",
        "apierror-sizediffdisabled": "大小差异在Miser模式中被禁用。",
        "apierror-spamdetected": "您的编辑被拒绝,因为它包含破坏性碎片:<code>$1</code>。",
index b7e45cc..9cce087 100644 (file)
  */
 
 /**
- * Temporary workaround for incorrect collation of Persian language ('fa') in ICU (bug T139110).
+ * Temporary workaround for incorrect collation of Persian language ('fa') in ICU 52 (bug T139110).
  *
- * 'ا' and 'و' should not be considered the same letter for the purposes of collation in Persian.
+ * All of the following will be considered separate letters for category headings in Persian:
+ *  - Characters 'و' 'ا' (often appear at the beginning of words)
+ *  - Characters 'ٲ' 'ٳ' (may appear at the beginning of words in loanwords)
+ *  - Characters 'ء' 'ئ' (don't appear at the beginning of words, but it's easier to implement)
  *
  * @since 1.29
  */
@@ -34,11 +37,14 @@ class CollationFa extends IcuCollation {
        }
 
        public function getPrimarySortKey( $string ) {
-               $firstLetter = mb_substr( $string, 0, 1 );
-               if ( $firstLetter === 'و' || $firstLetter === 'ا' ) {
+               $primary = parent::getPrimarySortKey( $string );
+               // We have to use a tertiary sortkey for everything with the primary sortkey of 2627.
+               // Otherwise, the "Remove duplicate prefixes" logic in IcuCollation would remove them.
+               // This matches sortkeys for the following characters: ء ئ ا و ٲ ٳ
+               if ( substr( $primary, 0, 2 ) === "\x26\x27" ) {
+                       wfDebug( "Using tertiary sortkey for '$string'\n" );
                        return $this->tertiaryCollator->getSortKey( $string );
                }
-
-               return parent::getPrimarySortKey( $string );
+               return $primary;
        }
 }
index babd00b..25d50d3 100644 (file)
@@ -182,7 +182,7 @@ class DiffEngine {
                        }
 
                        while ( $i < $len && !$changed[$i] ) {
-                               assert( $j < $other_len && ! $other_changed[$j] );
+                               assert( $j < $other_len && !$other_changed[$j] );
                                $i++;
                                $j++;
                                while ( $j < $other_len && $other_changed[$j] ) {
@@ -247,7 +247,7 @@ class DiffEngine {
                                                $i++;
                                        }
 
-                                       assert( $j < $other_len && ! $other_changed[$j] );
+                                       assert( $j < $other_len && !$other_changed[$j] );
                                        $j++;
                                        if ( $j < $other_len && $other_changed[$j] ) {
                                                $corresponding = $i;
index c80d54e..68b4720 100644 (file)
@@ -4,7 +4,8 @@
                        "Erdemaslancan",
                        "Mirzali",
                        "Marmase",
-                       "Kumkumuk"
+                       "Kumkumuk",
+                       "Gambollar"
                ]
        },
        "config-desc": "Qandé MediaWiki sazi",
@@ -26,7 +27,7 @@
        "config-page-install": "Bar ke",
        "config-page-complete": "Temamyayo",
        "config-page-restart": "Barkerdışi fına ser kı",
-       "config-page-readme": "Mı bıwane",
+       "config-page-readme": "Mı bıwan",
        "config-page-releasenotes": "Notë versiyoni",
        "config-page-copying": "Kopyayeno",
        "config-page-upgradedoc": "Berzkerdış",
index 41541ef..0c77a7b 100644 (file)
@@ -216,7 +216,7 @@ class FormatJson {
                        $count = 0;
                        $value =
                                preg_replace( '/,([ \t]*[}\]][^"\r\n]*([\r\n]|$)|[ \t]*[\r\n][ \t\r\n]*[}\]])/', '$1',
-                                       $value, - 1, $count );
+                                       $value, -1, $count );
                        if ( $count > 0 ) {
                                $result = json_decode( $value, $assoc );
                                if ( JSON_ERROR_NONE === json_last_error() ) {
index 668443b..5d680e2 100644 (file)
@@ -756,14 +756,20 @@ abstract class DatabaseMysqlBase extends Database {
         * @see https://www.percona.com/doc/percona-toolkit/2.1/pt-heartbeat.html
         */
        protected function getHeartbeatData( array $conds ) {
-               $whereSQL = $this->makeList( $conds, self::LIST_AND );
-               // Use ORDER BY for channel based queries since that field might not be UNIQUE.
-               // Note: this would use "TIMESTAMPDIFF(MICROSECOND,ts,UTC_TIMESTAMP(6))" but the
-               // percision field is not supported in MySQL <= 5.5.
-               $res = $this->query(
-                       "SELECT ts FROM heartbeat.heartbeat WHERE $whereSQL ORDER BY ts DESC LIMIT 1"
-               );
-               $row = $res ? $res->fetchObject() : false;
+               // Do not bother starting implicit transactions here
+               $this->clearFlag( self::DBO_TRX, self::REMEMBER_PRIOR );
+               try {
+                       $whereSQL = $this->makeList( $conds, self::LIST_AND );
+                       // Use ORDER BY for channel based queries since that field might not be UNIQUE.
+                       // Note: this would use "TIMESTAMPDIFF(MICROSECOND,ts,UTC_TIMESTAMP(6))" but the
+                       // percision field is not supported in MySQL <= 5.5.
+                       $res = $this->query(
+                               "SELECT ts FROM heartbeat.heartbeat WHERE $whereSQL ORDER BY ts DESC LIMIT 1"
+                       );
+                       $row = $res ? $res->fetchObject() : false;
+               } finally {
+                       $this->restoreFlags();
+               }
 
                return [ $row ? $row->ts : null, microtime( true ) ];
        }
index 14d049c..95f55b6 100644 (file)
@@ -241,10 +241,14 @@ class LoadBalancer implements ILoadBalancer {
 
                                $host = $this->getServerName( $i );
                                if ( $lag === false && !is_infinite( $maxServerLag ) ) {
-                                       $this->replLogger->error( "Server $host (#$i) is not replicating?" );
+                                       $this->replLogger->error(
+                                               "Server {host} (#$i) is not replicating?", [ 'host' => $host ] );
                                        unset( $loads[$i] );
                                } elseif ( $lag > $maxServerLag ) {
-                                       $this->replLogger->warning( "Server $host (#$i) has >= $lag seconds of lag" );
+                                       $this->replLogger->warning(
+                                               "Server {host} (#$i) has {lag} seconds of lag (>= {maxlag})",
+                                               [ 'host' => $host, 'lag' => $lag, 'maxlag' => $maxServerLag ]
+                                       );
                                        unset( $loads[$i] );
                                }
                        }
@@ -503,8 +507,10 @@ class LoadBalancer implements ILoadBalancer {
 
                if ( $result == -1 || is_null( $result ) ) {
                        // Timed out waiting for replica DB, use master instead
-                       $msg = __METHOD__ . ": Timed out waiting on $server pos {$this->mWaitForPos}";
-                       $this->replLogger->warning( "$msg" );
+                       $this->replLogger->warning(
+                               __METHOD__ . ": Timed out waiting on {host} pos {$this->mWaitForPos}",
+                               [ 'host' => $server ]
+                       );
                        $ok = false;
                } else {
                        $this->replLogger->info( __METHOD__ . ": Done" );
index 1ca9dac..79fc172 100644 (file)
@@ -547,18 +547,32 @@ class Parser {
                        $limitReport = str_replace( [ '-', '&' ], [ '‐', '&amp;' ], $limitReport );
                        $text .= "\n<!-- \n$limitReport-->\n";
 
-                       // Add on template profiling data
+                       // Add on template profiling data in human/machine readable way
                        $dataByFunc = $this->mProfiler->getFunctionStats();
                        uasort( $dataByFunc, function ( $a, $b ) {
                                return $a['real'] < $b['real']; // descending order
                        } );
-                       $profileReport = "Transclusion expansion time report (%,ms,calls,template)\n";
+                       $profileReport = [];
                        foreach ( array_slice( $dataByFunc, 0, 10 ) as $item ) {
-                               $profileReport .= sprintf( "%6.2f%% %8.3f %6d - %s\n",
+                               $profileReport[] = sprintf( "%6.2f%% %8.3f %6d %s",
                                        $item['%real'], $item['real'], $item['calls'],
                                        htmlspecialchars( $item['name'] ) );
                        }
-                       $text .= "\n<!-- \n$profileReport-->\n";
+                       $text .= "<!--\nTransclusion expansion time report (%,ms,calls,template)\n";
+                       $text .= implode( "\n", $profileReport ) . "\n-->\n";
+
+                       $this->mOutput->setLimitReportData( 'limitreport-timingprofile', $profileReport );
+
+                       // Add other cache related metadata
+                       if ( $wgShowHostnames ) {
+                               $this->mOutput->setLimitReportData( 'cachereport-origin', wfHostname() );
+                       }
+                       $this->mOutput->setLimitReportData( 'cachereport-timestamp',
+                               $this->mOutput->getCacheTime() );
+                       $this->mOutput->setLimitReportData( 'cachereport-ttl',
+                               $this->mOutput->getCacheExpiry() );
+                       $this->mOutput->setLimitReportData( 'cachereport-transientcontent',
+                               $this->mOutput->hasDynamicContent() );
 
                        if ( $this->mGeneratedPPNodeCount > $this->mOptions->getMaxGeneratedPPNodeCount() / 10 ) {
                                wfDebugLog( 'generated-pp-node-count', $this->mGeneratedPPNodeCount . ' ' .
@@ -2798,6 +2812,9 @@ class Parser {
                        case 'contentlanguage':
                                global $wgLanguageCode;
                                return $wgLanguageCode;
+                       case 'pagelanguage':
+                               $value = $pageLang->getCode();
+                               break;
                        case 'cascadingsources':
                                $value = CoreParserFunctions::cascadingsources( $this );
                                break;
@@ -4990,7 +5007,7 @@ class Parser {
                        $descQuery = false;
                        Hooks::run( 'BeforeParserFetchFileAndTitle',
                                [ $this, $title, &$options, &$descQuery ] );
-                       # Don't register it now, as ImageGallery does that later.
+                       # Don't register it now, as TraditionalImageGallery does that later.
                        $file = $this->fetchFileNoRegister( $title, $options );
                        $handler = $file ? $file->getHandler() : false;
 
@@ -5258,7 +5275,7 @@ class Parser {
                                                case 'framed':
                                                case 'thumbnail':
                                                        // use first appearing option, discard others.
-                                                       $validated = ! $seenformat;
+                                                       $validated = !$seenformat;
                                                        $seenformat = true;
                                                        break;
                                                default:
index bfaa4f7..7bf848f 100644 (file)
@@ -193,6 +193,9 @@ class ParserOutput extends CacheTime {
         */
        private $mLimitReportData = [];
 
+       /** @var array Parser limit report data for JSON */
+       private $mLimitReportJSData = [];
+
        /**
         * @var array $mParseStartTime Timestamps for getTimeSinceStart().
         */
@@ -411,6 +414,10 @@ class ParserOutput extends CacheTime {
                return $this->mLimitReportData;
        }
 
+       public function getLimitReportJSData() {
+               return $this->mLimitReportJSData;
+       }
+
        public function getTOCEnabled() {
                return $this->mTOCEnabled;
        }
@@ -1010,6 +1017,26 @@ class ParserOutput extends CacheTime {
         */
        public function setLimitReportData( $key, $value ) {
                $this->mLimitReportData[$key] = $value;
+
+               if ( is_array( $value ) ) {
+                       if ( array_keys( $value ) === [ 0, 1 ]
+                               && is_numeric( $value[0] )
+                               && is_numeric( $value[1] )
+                       ) {
+                               $data = [ 'value' => $value[0], 'limit' => $value[1] ];
+                       } else {
+                               $data = $value;
+                       }
+               } else {
+                       $data = $value;
+               }
+
+               if ( strpos( $key, '-' ) ) {
+                       list( $ns, $name ) = explode( '-', $key, 2 );
+                       $this->mLimitReportJSData[$ns][$name] = $data;
+               } else {
+                       $this->mLimitReportJSData[$key] = $data;
+               }
        }
 
        /**
index 950d66d..661318b 100644 (file)
@@ -223,7 +223,8 @@ class Preprocessor_DOM extends Preprocessor {
 
                $searchBase = "[{<\n"; # }
                if ( !$wgDisableLangConversion ) {
-                       $searchBase .= '-';
+                       // FIXME: disabled due to T153761
+                       // $searchBase .= '-';
                }
 
                // For fast reverse searches
index 1317e60..2666c93 100644 (file)
@@ -155,7 +155,8 @@ class Preprocessor_Hash extends Preprocessor {
 
                $searchBase = "[{<\n";
                if ( !$wgDisableLangConversion ) {
-                       $searchBase .= '-';
+                       // FIXME: disabled due to T153761
+                       // $searchBase .= '-';
                }
 
                // For fast reverse searches
index 674846d..833e38b 100644 (file)
@@ -97,8 +97,9 @@ abstract class RevDelList extends RevisionListBase {
         *
         * @param array $params Associative array of parameters. Members are:
         *     value:         ExtractBitParams() bitfield array
-        *     comment:       The log comment.
+        *     comment:       The log comment
         *     perItemStatus: Set if you want per-item status reports
+        *     tags:          The array of change tags to apply to the log entry
         * @return Status
         * @since 1.23 Added 'perItemStatus' param
         */
@@ -269,7 +270,8 @@ abstract class RevDelList extends RevisionListBase {
                                'comment' => $comment,
                                'ids' => $idsForLog,
                                'authorIds' => $authorIds,
-                               'authorIPs' => $authorIPs
+                               'authorIPs' => $authorIPs,
+                               'tags' => isset( $params['tags'] ) ? $params['tags'] : [],
                        ]
                );
 
@@ -327,6 +329,7 @@ abstract class RevDelList extends RevisionListBase {
         *     comment:         The log comment
         *     authorsIds:      The array of the user IDs of the offenders
         *     authorsIPs:      The array of the IP/anon user offenders
+        *     tags:            The array of change tags to apply to the log entry
         * @throws MWException
         */
        private function updateLog( $logType, $params ) {
@@ -349,6 +352,8 @@ abstract class RevDelList extends RevisionListBase {
                        'target_author_id' => $params['authorIds'],
                        'target_author_ip' => $params['authorIPs'],
                ] );
+               // Apply change tags to the log entry
+               $logEntry->setTags( $params['tags'] );
                $logId = $logEntry->insert();
                $logEntry->publish( $logId );
        }
index dd41a6e..d0e3a24 100644 (file)
@@ -75,10 +75,10 @@ class SearchHighlighter {
                        if ( preg_match( $spat, $text, $matches, PREG_OFFSET_CAPTURE, $start ) ) {
                                $epat = '';
                                foreach ( $matches as $key => $val ) {
-                                       if ( $key > 0 && $val[1] != - 1 ) {
+                                       if ( $key > 0 && $val[1] != -1 ) {
                                                if ( $key == 2 ) {
                                                        // see if this is an image link
-                                                       $ns = substr( $val[0], 2, - 1 );
+                                                       $ns = substr( $val[0], 2, -1 );
                                                        if ( $wgContLang->getNsIndex( $ns ) != NS_FILE ) {
                                                                break;
                                                        }
@@ -252,10 +252,10 @@ class SearchHighlighter {
 
                // $snippets = array_map( 'htmlspecialchars', $extended );
                $snippets = $extended;
-               $last = - 1;
+               $last = -1;
                $extract = '';
                foreach ( $snippets as $index => $line ) {
-                       if ( $last == - 1 ) {
+                       if ( $last == -1 ) {
                                $extract .= $line; // first line
                        } elseif ( $last + 1 == $index
                                && $offsets[$last] + strlen( $snippets[$last] ) >= strlen( $all[$last] )
index 540ce4b..c3ee321 100644 (file)
@@ -1088,13 +1088,13 @@ abstract class LoginSignupSpecialPage extends AuthManagerSpecialPage {
                        // B/C for old extensions that haven't been converted to AuthManager (or have been
                        // but somebody is using the old version) and still use templates via the
                        // UserCreateForm/UserLoginForm hook.
-                       // 'header' used by ConfirmEdit, CondfirmAccount, Persona, WikimediaIncubator, SemanticSignup
+                       // 'header' used by ConfirmEdit, ConfirmAccount, Persona, WikimediaIncubator, SemanticSignup
                        // 'formheader' used by MobileFrontend
                        $fieldDefinitions['header'] = [
                                'type' => 'info',
                                'raw' => true,
                                'default' => $template->get( 'header' ) ?: $template->get( 'formheader' ),
-                               'weight' => - 110,
+                               'weight' => -110,
                        ];
                }
                if ( $this->mEntryError ) {
index 61b6a8c..d4cd2ac 100644 (file)
@@ -89,6 +89,12 @@ class SpecialPageLanguage extends FormSpecialPage {
                        'default' => $this->getConfig()->get( 'LanguageCode' ),
                ];
 
+               // Allow user to enter a comment explaining the change
+               $page['reason'] = [
+                       'type' => 'text',
+                       'label-message' => 'pagelang-reason'
+               ];
+
                return $page;
        }
 
@@ -111,68 +117,108 @@ class SpecialPageLanguage extends FormSpecialPage {
        /**
         *
         * @param array $data
-        * @return bool
+        * @return Status
         */
        public function onSubmit( array $data ) {
-               $title = Title::newFromText( $data['pagename'] );
+               $pageName = $data['pagename'];
+
+               // Check if user wants to use default language
+               if ( $data['selectoptions'] == 1 ) {
+                       $newLanguage = 'default';
+               } else {
+                       $newLanguage = $data['language'];
+               }
 
-               // Check if title is valid
-               if ( !$title ) {
-                       return false;
+               try {
+                       $title = Title::newFromTextThrow( $pageName );
+               } catch ( MalformedTitleException $ex ) {
+                       return Status::newFatal( $ex->getMessageObject() );
                }
 
+               // Url to redirect to after the operation
+               $this->goToUrl = $title->getFullURL();
+
+               return self::changePageLanguage(
+                       $this->getContext(),
+                       $title,
+                       $newLanguage,
+                       $data['reason'] === null ? '' : $data['reason']
+               );
+       }
+
+       /**
+        * @param IContextSource $context
+        * @param Title $title
+        * @param string $newLanguage Language code
+        * @param string $reason Reason for the change
+        * @param array $tags Change tags to apply to the log entry
+        * @return Status
+        */
+       public static function changePageLanguage( IContextSource $context, Title $title,
+               $newLanguage, $reason, array $tags = [] ) {
                // Get the default language for the wiki
-               $defLang = $this->getConfig()->get( 'LanguageCode' );
+               $defLang = $context->getConfig()->get( 'LanguageCode' );
 
                $pageId = $title->getArticleID();
 
                // Check if article exists
                if ( !$pageId ) {
-                       return false;
+                       return Status::newFatal(
+                               'pagelang-nonexistent-page',
+                               wfEscapeWikiText( $title->getPrefixedText() )
+                       );
                }
 
                // Load the page language from DB
                $dbw = wfGetDB( DB_MASTER );
-               $langOld = $dbw->selectField(
+               $oldLanguage = $dbw->selectField(
                        'page',
                        'page_lang',
                        [ 'page_id' => $pageId ],
                        __METHOD__
                );
 
-               // Url to redirect to after the operation
-               $this->goToUrl = $title->getFullURL();
-
-               // Check if user wants to use default language
-               if ( $data['selectoptions'] == 1 ) {
-                       $langNew = null;
-               } else {
-                       $langNew = $data['language'];
+               // Check if user wants to use the default language
+               if ( $newLanguage === 'default' ) {
+                       $newLanguage = null;
                }
 
                // No change in language
-               if ( $langNew === $langOld ) {
-                       return false;
+               if ( $newLanguage === $oldLanguage ) {
+                       // Check if old language does not exist
+                       if ( !$oldLanguage ) {
+                               return Status::newFatal( ApiMessage::create(
+                                       [
+                                               'pagelang-unchanged-language-default',
+                                               wfEscapeWikiText( $title->getPrefixedText() )
+                                       ],
+                                       'pagelang-unchanged-language'
+                               ) );
+                       }
+                       return Status::newFatal(
+                               'pagelang-unchanged-language',
+                               wfEscapeWikiText( $title->getPrefixedText() ),
+                               $oldLanguage
+                       );
                }
 
                // Hardcoded [def] if the language is set to null
-               $logOld = $langOld ? $langOld : $defLang . '[def]';
-               $logNew = $langNew ? $langNew : $defLang . '[def]';
+               $logOld = $oldLanguage ? $oldLanguage : $defLang . '[def]';
+               $logNew = $newLanguage ? $newLanguage : $defLang . '[def]';
 
                // Writing new page language to database
-               $dbw = wfGetDB( DB_MASTER );
                $dbw->update(
                        'page',
-                       [ 'page_lang' => $langNew ],
+                       [ 'page_lang' => $newLanguage ],
                        [
                                'page_id' => $pageId,
-                               'page_lang' => $langOld
+                               'page_lang' => $oldLanguage
                        ],
                        __METHOD__
                );
 
                if ( !$dbw->affectedRows() ) {
-                       return false;
+                       return Status::newFatal( 'pagelang-db-failed' );
                }
 
                // Logging change of language
@@ -181,9 +227,11 @@ class SpecialPageLanguage extends FormSpecialPage {
                        '5::newlanguage' => $logNew
                ];
                $entry = new ManualLogEntry( 'pagelang', 'pagelang' );
-               $entry->setPerformer( $this->getUser() );
+               $entry->setPerformer( $context->getUser() );
                $entry->setTarget( $title );
                $entry->setParameters( $logParams );
+               $entry->setComment( $reason );
+               $entry->setTags( $tags );
 
                $logid = $entry->insert();
                $entry->publish( $logid );
@@ -191,7 +239,11 @@ class SpecialPageLanguage extends FormSpecialPage {
                // Force re-render so that language-based content (parser functions etc.) gets updated
                $title->invalidateCache();
 
-               return true;
+               return Status::newGood( (object)[
+                       'oldLanguage' => $logOld,
+                       'newLanguage' => $logNew,
+                       'logId' => $logid,
+               ] );
        }
 
        public function onSuccess() {
index 1ce61e3..b2e5674 100644 (file)
@@ -526,6 +526,14 @@ class SpecialRecentChanges extends ChangesListSpecialPage {
                parent::addModules();
                $out = $this->getOutput();
                $out->addModules( 'mediawiki.special.recentchanges' );
+               if ( $this->getUser()->getOption(
+                               'rcenhancedfilters',
+                               /*default=*/ null,
+                               /*ignoreHidden=*/ true
+                       )
+               ) {
+                       $out->addModules( 'mediawiki.rcfilters.filters' );
+               }
        }
 
        /**
index 562f0d1..fed64c2 100644 (file)
@@ -301,7 +301,8 @@ class User implements IDBAccessObject {
        protected $queryFlagsUsed = self::READ_NORMAL;
 
        /** @var string Indicates type of block (used for eventlogging)
-        * Permitted values: 'cookie-block', 'proxy-block', 'openproxy-block', 'xff-block'
+        * Permitted values: 'cookie-block', 'proxy-block', 'openproxy-block', 'xff-block',
+        * 'config-block'
         */
        public $blockTrigger = false;
 
@@ -1581,7 +1582,7 @@ class User implements IDBAccessObject {
         *   Check when actually saving should be done against master.
         */
        private function getBlockedStatus( $bFromSlave = true ) {
-               global $wgProxyWhitelist, $wgUser, $wgApplyIpBlocksToXff;
+               global $wgProxyWhitelist, $wgUser, $wgApplyIpBlocksToXff, $wgSoftBlockRanges;
 
                if ( -1 != $this->mBlockedby ) {
                        return;
@@ -1680,6 +1681,21 @@ class User implements IDBAccessObject {
                        }
                }
 
+               if ( !$block instanceof Block
+                       && $ip !== null
+                       && $this->isAnon()
+                       && IP::isInRanges( $ip, $wgSoftBlockRanges )
+               ) {
+                       $block = new Block( [
+                               'address' => $ip,
+                               'byText' => 'MediaWiki default',
+                               'reason' => wfMessage( 'softblockrangesreason', $ip )->text(),
+                               'anonOnly' => true,
+                               'systemBlock' => 'wgSoftBlockRanges',
+                       ] );
+                       $this->blockTrigger = 'config-block';
+               }
+
                if ( $block instanceof Block ) {
                        wfDebug( __METHOD__ . ": Found block.\n" );
                        $this->mBlock = $block;
index ac8d4cb..5bce76b 100644 (file)
@@ -2100,17 +2100,15 @@ class Language {
                $data = explode( '|', $tz, 3 );
 
                if ( $data[0] == 'ZoneInfo' ) {
-                       MediaWiki\suppressWarnings();
-                       $userTZ = timezone_open( $data[2] );
-                       MediaWiki\restoreWarnings();
-                       if ( $userTZ !== false ) {
-                               $date = date_create( $ts, timezone_open( 'UTC' ) );
-                               date_timezone_set( $date, $userTZ );
-                               $date = date_format( $date, 'YmdHis' );
-                               return $date;
+                       try {
+                               $userTZ = new DateTimeZone( $data[2] );
+                               $date = new DateTime( $ts, new DateTimeZone( 'UTC' ) );
+                               $date->setTimezone( $userTZ );
+                               return $date->format( 'YmdHis' );
+                       } catch ( Exception $e ) {
+                               // Unrecognized timezone, default to 'Offset' with the stored offset.
+                               $data[0] = 'Offset';
                        }
-                       # Unrecognized timezone, default to 'Offset' with the stored offset.
-                       $data[0] = 'Offset';
                }
 
                if ( $data[0] == 'System' || $tz == '' ) {
index c085628..600dc2c 100644 (file)
        "recentchanges-legend-heading": "<strong>شرح:</strong>",
        "recentchanges-legend-newpage": "{{int:recentchanges-label-newpage}} (راجع أيضا [[Special:NewPages|قائمة الصفحات الجديدة]])",
        "recentchanges-submit": "أظهر",
+       "rcfilters-activefilters": "المرشحات النشطة",
+       "rcfilters-search-placeholder": "رشح أحدث التغييرات (تصفح أو ابدأ الكتابة)",
+       "rcfilters-invalid-filter": "مرشح غير صحيح",
+       "rcfilters-filterlist-title": "مرشحات",
+       "rcfilters-filterlist-noresults": "لم يتم العثور على مرشحات",
+       "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": "المستخدمون الجدد جدا: أقل من 10 تعديلات و4 أيام من النشاط.",
+       "rcfilters-filter-userExpLevel-learner-label": "المتعلمون",
+       "rcfilters-filter-userExpLevel-learner-description": "المزيد من أيام النشاط والتعديلات أكثر من 'القادمين الجدد' ولكن أقل من 'المستخدمين ذوي الخبرة.'",
+       "rcfilters-filter-userExpLevel-experienced-label": "المستخدمون ذوو الخبرة",
+       "rcfilters-filter-userExpLevel-experienced-description": "أكثر من 30 يوما من النشاط و500 تعديل.",
        "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-url-label": "مسار الطلب:",
        "apisandbox-request-time": "وقت الطلب: {{PLURAL:$1|$1 ms}}",
        "apisandbox-results-fixtoken": "رمز الصحيح وإعادة الموافقة",
        "changecontentmodel-emptymodels-title": "لا موديلات محتوى متوفرة",
        "changecontentmodel-emptymodels-text": "المحتوى على[[:$1]] لا يمكن تغييره لأي نوع.",
        "log-name-contentmodel": "سجل تغيير نموذج المحتوى",
-       "log-description-contentmodel": "الأحداث المرتبطة بنماذج المحتوى لصفحة",
+       "log-description-contentmodel": "هذه الصفحة تعرض التغييرات لموديل المحتوى للصفحات، والصفحات التي تم إنشاؤها بموديل محتوى يختلف عن الافتراضي",
        "logentry-contentmodel-new": "$1 {{GENDER:$2|أنشأ|أنشأت}} الصفحة $3 باستخدام موديل محتوى غير قياسي \"$5\"",
        "logentry-contentmodel-change": "$1 {{GENDER:$2|غير|غيرت}} موديل المحتوى للصفحة $3 من \"$4\" إلى \"$5\"",
        "logentry-contentmodel-change-revertlink": "استرجع",
        "pagelang-use-default": "استخدام اللغة الافتراضية",
        "pagelang-select-lang": "اختر اللغة",
        "pagelang-submit": "إرسال",
+       "pagelang-nonexistent-page": "الصفحة $1 غير موجودة.",
+       "pagelang-unchanged-language": "الصفحة $1 مضبوطة فعلا للغة $2.",
+       "pagelang-unchanged-language-default": "الصفحة $1 مضبوطة فعلا للغة المحتوى الافتراضية الخاصة بالويكي.",
+       "pagelang-db-failed": "قاعدة البيانات فشلت في تغيير لغة الصفحة.",
        "right-pagelang": "تغيير لغة الصفحة",
        "action-pagelang": "تغيير لغة الصفحة",
        "log-name-pagelang": "سجل تغيير اللغة",
        "log-action-filter-block-reblock": "منع التعديل",
        "log-action-filter-block-unblock": "رفع المنع",
        "log-action-filter-contentmodel-change": "تغيير موديل المحتوى",
-       "log-action-filter-contentmodel-new": "إنشاء صفحة بموديل محتوى غير قياسي",
+       "log-action-filter-contentmodel-new": "إنشاء صفحة بموديل محتوى غير افتراضي",
        "log-action-filter-delete-delete": "حذف الصفحات",
        "log-action-filter-delete-delete_redir": "إعادة الكتابة فوق التحويلة",
        "log-action-filter-delete-restore": "استرجاع الصفحات",
index e58456d..50a5601 100644 (file)
        "sp-contributions-blocked-notice": "اليوزر ده ممنوع دلوقتى.\nآخر عمليه منع في السجل موجوده تحت كمرجع:",
        "sp-contributions-search": "دور على مساهمات",
        "sp-contributions-username": "عنوان أيبى أو اسم يوزر:",
-       "sp-contributions-toponly": "اظÙ\87ر Ø§Ø®ØªÙ\8aر ØªØ¹Ø¯Ù\8aÙ\84  Ø¨Ø³",
+       "sp-contributions-toponly": "اظهر اخر تعديل  بس",
        "sp-contributions-submit": "تدوير",
        "whatlinkshere": "ايه بيوصل هنا",
        "whatlinkshere-title": "الصفحات اللى بتوصل لـ \"$1\"",
index 59ff584..3c3f9ac 100644 (file)
        "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-url-label": "URL 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",
index e823ba7..42cd160 100644 (file)
        "editpage-invalidcontentmodel-text": "Мадэль зьместу «$1» не падтрымліваецца.",
        "editpage-notsupportedcontentformat-title": "Фармат зьмесьціва не падтрымліваецца",
        "editpage-notsupportedcontentformat-text": "Фармат зьмесьціва $1 не падтрымліваецца мадэльлю зьмесьціва $2.",
-       "content-model-wikitext": "вікі-тэкст",
+       "content-model-wikitext": "вікітэкст",
        "content-model-text": "просты тэкст",
        "content-model-javascript": "JavaScript",
        "content-model-css": "CSS",
        "duplicate-args-category-desc": "Старонкі, якія ўтрымліваюць шаблёны з парамэтрамі-дублікатамі, напрыклад, <code><nowiki>{{foo|bar=1|bar=2}}</nowiki></code> або <code><nowiki>{{foo|bar|1=baz}}</nowiki></code>.",
        "expensive-parserfunction-warning": "Папярэджаньне: гэтая старонка ўтрымлівае зашмат працаёмістых зваротаў да функцыяў парсэра.\n\nПавінна быць ня болей за $2 {{PLURAL:$2|зварот|звароты|зваротаў}}, а цяпер ўтрымліваецца {{PLURAL:$1|$1 зварот|$1 звароты|$1 зваротаў}}.",
        "expensive-parserfunction-category": "Старонкі, якія ўтрымліваюць зашмат працаёмістых зваротаў да функцыяў парсэра",
-       "post-expand-template-inclusion-warning": "Папярэджаньне: Памер уключаемых шаблёнаў занадта вялікі.\nНекаторыя шаблёны ня будуць уключаныя.",
+       "post-expand-template-inclusion-warning": "<strong>Папярэджаньне</strong>: памер выкарыстаных шаблёнаў занадта вялікі.\nНекаторыя шаблёны ня будуць уключаныя.",
        "post-expand-template-inclusion-category": "Старонкі, у якіх перавышаны дапушчальны памер уключаных шаблёнаў",
        "post-expand-template-argument-warning": "Увага: Гэтая старонка ўтрымлівае прынамсі адзін парамэтар шаблёна, які мае занадта вялікі выгляд у разгорнутым выглядзе.\nГэтыя парамэтры былі прапушчаныя.",
        "post-expand-template-argument-category": "Старонкі, у якіх прапушчаныя парамэтры шаблёнаў",
        "recentchanges-legend-heading": "<strong>Легенда:</strong>",
        "recentchanges-legend-newpage": "{{int:recentchanges-label-newpage}} (глядзіце таксама [[Special:NewPages|сьпіс новых старонак]])",
        "recentchanges-submit": "Паказаць",
+       "rcfilters-activefilters": "Актыўныя фільтры",
+       "rcfilters-search-placeholder": "Фільтар апошніх зьменаў (праглядзець або пачніце друкаваць)",
+       "rcfilters-invalid-filter": "Няслушны фільтар",
+       "rcfilters-filterlist-title": "Фільтры",
        "rcnotefrom": "Ніжэй {{PLURAL:$5|знаходзіцца зьмена|знаходзяцца зьмены}} з <strong>$4 $3</strong> (да <strong>$1</strong> на старонку).",
        "rclistfrom": "Паказаць зьмены з $2 $3",
        "rcshowhideminor": "$1 дробныя праўкі",
        "authmanager-authn-not-in-progress": "Аўтэнтыфікацыя не выконваецца або страчаныя зьвесткі пра сэсію. Калі ласка, пачніце зноў з самага пачатку.",
        "authmanager-authn-no-primary": "Пададзеныя ўліковыя зьвесткі ня могуць быць правераныя на сапраўднасьць.",
        "authmanager-authn-no-local-user": "Пададзеныя ўліковыя зьвесткі не зьвязаныя зь ніводным удзельнікам гэтай вікі.",
+       "authmanager-authn-autocreate-failed": "Аўтаматычнае стварэньне лякальнага рахунку не атрымалася: $1",
+       "authmanager-change-not-supported": "Пададзеныя ўліковыя зьвесткі ня могуць быць зьмененыя, бо яны ня будуць выкарыстаныя.",
        "authmanager-realname-label": "Сапраўднае імя",
        "authmanager-provider-temporarypassword": "Часовы пароль",
        "changecredentials": "Зьмена ўліковых зьвестак",
index 051b5ec..f1ba848 100644 (file)
        "resetpass-submit-cancel": "বাতিল",
        "resetpass-wrong-oldpass": "ভুল অস্থায়ী অথবা বর্তমান পাসওয়ার্ড।\nসম্ভবতঃ আপনি ইতোমধ্যেই আপনার পাসওয়ার্ডটি পরিবর্তন করেছেন অথবা একটি নতুন অস্থায়ী পাসওয়ার্ডের জন্য অনুরোধ করেছেন।",
        "resetpass-recycled": "অনুগ্রহ করে বর্তমানে ব্যবহার করছেন এমন পাসওয়ার্ডের পরিবর্তে নতুন একটি পাসওয়ার্ড নির্ধারণ করুন।",
-       "resetpass-temp-emailed": "à¦\86পনি à¦\87মà§\87à¦\87লà¦\95à§\83ত à¦¸à¦¾à¦®à¦¯à¦¼à¦¿à¦\95 à¦\95à§\8bড à¦¦à¦¿à¦¯à¦¼à§\87 à¦ªà§\8dরবà§\87শ à¦\95রà§\87à¦\9bà§\87ন।\nপà§\8dরবà§\87শ à¦\95রার à¦\9cনà§\8dয à¦\86পনাà¦\95à§\87 à¦\85বশà§\8dযà¦\87 à¦\8fà¦\95à¦\9fি à¦¨à¦¤à§\81ন à¦ªà¦¾à¦¸à¦\93য়ারà§\8dড à¦¨à¦¿à¦°à§\8dধারন করতে হবে:",
+       "resetpass-temp-emailed": "à¦\86পনি à¦\87মà§\87à¦\87লà¦\95à§\83ত à¦¸à¦¾à¦®à¦¯à¦¼à¦¿à¦\95 à¦\95à§\8bড à¦¦à¦¿à¦¯à¦¼à§\87 à¦ªà§\8dরবà§\87শ à¦\95রà§\87à¦\9bà§\87ন।\nপà§\8dরবà§\87শ à¦\95রার à¦\9cনà§\8dয à¦\86পনাà¦\95à§\87 à¦\85বশà§\8dযà¦\87 à¦\8fà¦\95à¦\9fি à¦¨à¦¤à§\81ন à¦ªà¦¾à¦¸à¦\93য়ারà§\8dড à¦¨à¦¿à¦°à§\8dধারণ করতে হবে:",
        "resetpass-temp-password": "অস্থায়ী পাসওয়ার্ড:",
        "resetpass-abort-generic": "পাসওয়ার্ড পরিবর্তন একটি এক্সটেনশনের কারণে স্থগিত করা হয়েছে।",
        "resetpass-expired": "আপনার পাসওয়ার্ডের মেয়াদ উত্তীর্ণ হয়েছে। অনুগ্রহ করে নতুন পাসওয়ার্ড নির্ধারণ করুন।",
        "resetpass-expired-soft": "আপনার পাসওয়ার্ডের মেয়াদ উত্তীর্ণ হয়েছে এবং আপনাকে একটি নতুন পাসওয়ার্ড নির্ধারণ করতে হবে। অনুগ্রহ করে এখনই একটি নতুন পাসওয়ার্ড নির্ধারণ করুন অথবা পরে পরিবর্তন করতে চাইলে \"{{int:authprovider-resetpass-skip-label}}\" বাটনে ক্লিক করুন।",
        "resetpass-validity-soft": "আপনার পাসওয়ার্ড বৈধ নয়: $1\n\nদয়া করে একটি নতুন পাসওয়ার্ড নির্ধারণ করুন অথবা পরে করার জন্য \"{{int:authprovider-resetpass-skip-label}}\" ক্লিক করুন।",
        "passwordreset": "পাসওয়ার্ড রিসেট",
-       "passwordreset-text-one": "à¦\86পনার à¦ªà¦¾à¦¸à¦\93য়ারà§\8dড à¦ªà§\81নরায় à¦¸à§\87à¦\9f à¦\95রতà§\87 à¦\8fà¦\87 à¦«à¦°à§\8dমà¦\9fি পূরণ করুন।",
+       "passwordreset-text-one": "à¦\87মà§\87à¦\87লà§\87র à¦®à¦¾à¦§à§\8dযমà§\87 à¦\8fà¦\95à¦\9fি à¦\85সà§\8dথায়à§\80 à¦ªà¦¾à¦¸à¦\93য়ারà§\8dড à¦ªà§\87তà§\87 à¦\8fà¦\87 à¦«à¦°à¦® পূরণ করুন।",
        "passwordreset-text-many": "{{PLURAL:$1|ইমেইলের মাধ্যমে একটি অস্থায়ী পাসওয়ার্ড পেতে ঘরগুলির একটি পূরণ করুন।}}",
        "passwordreset-disabled": "এই উইকিতে পাসওয়ার্ড রিসেটের সুবিধা নিষ্ক্রিয় রয়েছে।",
        "passwordreset-emaildisabled": "এই উইকিতে ইমেইল অপশনটি বন্ধ করা হয়েছে।",
        "revdelete-modify-missing": "$1 আইডি সম্বলিত তথ্যটি সম্পাদনা করা যাচ্ছে না: এটি ডাটাবেজ থেকে হারিয়ে গিয়েছে!",
        "revdelete-no-change": "'''সতর্কতা:''' $2, $1 তারিখ সম্বলিত তথ্যটিতে পূর্বেই অনুরোধকৃত সেটিংস রয়েছে।",
        "revdelete-concurrent-change": "$2, $1 তারিখ সম্বলিত তথ্যটি সম্পাদনা করা যাচ্ছে না: আপনার সম্পাদনা শুরুর আগে কেউ এটির অবস্থা পরিবর্তন করেছেন।\nঅনুগ্রহ করে লগ দেখুন।",
-       "revdelete-only-restricted": "$2, $1 à¦¤à¦¾à¦°à¦¿à¦\96 à¦¸à¦®à§\8dবলিত à¦¤à¦¥à§\8dযà¦\9fি à¦²à§\81à¦\95ানà§\8b à¦¯à¦¾à¦\9aà§\8dà¦\9bà§\87 à¦¨à¦¾: à¦¤à¦¥à§\8dয à¦ªà§\8dরদরà§\8dশনà§\87র à¦\85নà§\8dযানà§\8dয à¦\85পশনà¦\97à§\81লà§\8b à¦¨à¦¿à¦°à§\8dধারন করা ব্যতিত আপনি এটি শুধুমাত্র প্রশাসকদের জন্য দেখার উপযোগী করতে পারবেন না।",
+       "revdelete-only-restricted": "$2, $1 à¦¤à¦¾à¦°à¦¿à¦\96 à¦¸à¦®à§\8dবলিত à¦¤à¦¥à§\8dযà¦\9fি à¦²à§\81à¦\95ানà§\8b à¦¯à¦¾à¦\9aà§\8dà¦\9bà§\87 à¦¨à¦¾: à¦¤à¦¥à§\8dয à¦ªà§\8dরদরà§\8dশনà§\87র à¦\85নà§\8dযানà§\8dয à¦¬à¦¿à¦\95লà§\8dপà¦\97à§\81লি à¦¨à¦¿à¦°à§\8dধারণ করা ব্যতিত আপনি এটি শুধুমাত্র প্রশাসকদের জন্য দেখার উপযোগী করতে পারবেন না।",
        "revdelete-reason-dropdown": "*সাধারণ অপসারণের কারণসমূহ\n** কপিরাইট লঙ্ঘন\n** অনুপযুক্ত ব্যক্তিগত তথ্য\n** অনুপযুক্ত ব্যবহারকারী নাম\n** সম্ভাব্য ক্ষতিকারক তথ্য",
        "revdelete-otherreason": "অন্য/বাড়তি কারণ:",
        "revdelete-reasonotherlist": "অন্য কারণ",
        "recentchangesdays-max": "সর্বোচ্চ $1 {{PLURAL:$1|দিন|দিন}}",
        "recentchangescount": "সাম্প্রতিক পরিবর্তনে প্রদর্শিত সম্পাদনার সংখ্যা:",
        "prefs-help-recentchangescount": "এতে সাম্প্রতিক পরিবর্তনসমূহ, পাতার ইতিহাস এবং লগ অন্তর্ভুক্ত।",
-       "prefs-help-watchlist-token2": "à¦\8fà¦\9fি à¦\86পনার à¦¨à¦\9cরতালিà¦\95ার à¦\93য়à§\87ব à¦«à¦¿à¦¡à§\87র à¦\97à§\8bপন à¦\9aাবি। à¦¯à§\87 à¦\95à§\87à¦\89 à¦¯à¦¿à¦¨à¦¿ à¦\8fà¦\9fা à¦\9cানà§\87ন à¦¤à¦¿à¦¨à¦¿ à¦\86পনার à¦¨à¦\9cরতালিà¦\95া à¦ªà¦¡à¦¼à¦¤à§\87 à¦¸à¦\95à§\8dষম à¦¹à¦¬à§\87ন, à¦¤à¦¾à¦\87 à¦\8fà¦\9fি à¦ªà§\8dরà¦\95াশ à¦\95রবà§\87ন à¦¨à¦¾à¥¤ [[Special:ResetTokens|à¦\86পনার à¦\8fà¦\9fি à¦ªà§\81নরায় à¦¸à§\87à¦\9f করার প্রয়োজন হলে এখানে ক্লিক করুন]]।",
+       "prefs-help-watchlist-token2": "à¦\8fà¦\9fি à¦\86পনার à¦¨à¦\9cরতালিà¦\95ার à¦\93য়à§\87ব à¦«à¦¿à¦¡à§\87র à¦\97à§\8bপন à¦\9aাবি। à¦¯à§\87 à¦\95à§\87à¦\89 à¦¯à¦¿à¦¨à¦¿ à¦\8fà¦\9fা à¦\9cানà§\87ন à¦¤à¦¿à¦¨à¦¿ à¦\86পনার à¦¨à¦\9cরতালিà¦\95া à¦ªà¦¡à¦¼à¦¤à§\87 à¦¸à¦\95à§\8dষম à¦¹à¦¬à§\87ন, à¦¤à¦¾à¦\87 à¦\8fà¦\9fি à¦ªà§\8dরà¦\95াশ à¦\95রবà§\87ন à¦¨à¦¾à¥¤ [[Special:ResetTokens|à¦\86পনার à¦\8fà¦\9fি à¦ªà§\81নà¦\83নিরà§\8dধারণ করার প্রয়োজন হলে এখানে ক্লিক করুন]]।",
        "savedprefs": "আপনার পছন্দগুলো সংরক্ষণ করা হয়েছে।",
        "savedrights": "{{GENDER:$1|$1}}-এর ব্যবহারকারী দল সংরক্ষিত হয়েছে।",
        "timezonelegend": "সময়স্থান:",
        "apisandbox-results": "ফলাফল",
        "apisandbox-sending-request": "API অনুরোধ পাঠানো হচ্ছে...",
        "apisandbox-loading-results": "API ফলাফল গ্রহণ করা হচ্ছে...",
+       "apisandbox-request-params-json": "JSON প্যারামিটার:",
        "apisandbox-request-url-label": "অনুরোধের URL:",
        "apisandbox-request-time": "অনুরোধের সময়: {{PLURAL:$1|$1 মি.সে.}}",
        "apisandbox-results-fixtoken": "টোকেন সংশোধন ও পুনরায় জমা",
        "cant-move-to-user-page": "আপনার কোনো পাতা ব্যবহারকারী পাতার স্থানান্তরের অনুমতি নেই (ব্যবহারকারী উপপাতা ব্যতিত)।",
        "cant-move-category-page": "আপনার বিষয়শ্রেণী পাতা স্থানান্তরের অনুমতি নেই।",
        "cant-move-to-category-page": "আপনার পাতাটিকে বিষয়শ্রেণী পাতায় স্থানান্তরের অনুমতি নেই।",
+       "cant-move-subpages": "আপনার উপপাতা স্থানান্তরের অনুমতি নেই।",
        "newtitle": "নতুন শিরোনাম:",
        "move-watch": "এই পাতাটি নজরে রাখুন",
        "movepagebtn": "পাতা স্থানান্তর করুন",
        "log-action-filter-block-block": "বাধাদান",
        "log-action-filter-block-reblock": "বাধাদান পরিবর্তন",
        "log-action-filter-block-unblock": "বাধা অপসারণ",
-       "log-action-filter-contentmodel-change": "বিষয়বসà§\8dতà§\81র à¦®à¦¡à§\87ল পরিবর্তন",
+       "log-action-filter-contentmodel-change": "বিষয়বসà§\8dতà§\81র à¦°à§\82প পরিবর্তন",
        "log-action-filter-contentmodel-new": "অ-মানক বিষয়বস্তুর রূপসহ পাতা তৈরি",
        "log-action-filter-delete-delete": "পাতা অপসারণ",
        "log-action-filter-delete-restore": "পাতা পুনঃরুদ্ধার",
index cf50e95..a0d4c05 100644 (file)
        "about": "درباره",
        "newwindow": "(پنجره تازه واز کن)",
        "cancel": "لغو",
+       "moredotdotdot": "بيشدر",
        "mypage": "بألگأ",
        "mytalk": "چأک چنأ",
        "anontalk": "چأک چنأ",
        "qbbrowse": "قأرز کردن",
        "qbedit": "اصلاح",
        "qbpageoptions": "اي بألگأ",
+       "qbmyoptions": "بألگإ آ مو",
        "faq": "اف ای کیو",
        "faqpage": "Project:اف ای کیو",
        "namespaces": "نوم ڤأرگأ آ",
        "help": "راهنما",
        "search": "پئی جوٙری",
        "searchbutton": "پئی جوٙری",
+       "go": "رۉ",
        "searcharticle": "برو",
        "history": "گزارش صفحه",
        "history_short": "گزارش تاریخی",
        "disclaimers": "تیە پوٙشنا",
        "disclaimerpage": "Project: تیە پوشنیدٙئنئ کولی",
        "edithelp": "کمک برای اصلاح",
+       "helppage-top-gethelp": "هومیاري",
        "mainpage": "سأرآسوٙنە",
        "mainpage-description": "صفحه اصلی",
        "policy-url": "Project:خط مشی",
        "toc": "محتواها",
        "showtoc": "نمایش",
        "hidetoc": "قایم",
+       "collapsible-expand": "گأپ کلۈن کردن",
        "confirmable-yes": "هرإ",
        "confirmable-no": "نأ",
        "thisisdeleted": "دیدن یا اعاده $1?",
        "wrongpassword": "رمز وارد وابیده درست نه.\nلطفا دوباره سعی کنین.",
        "wrongpasswordempty": "رمز وارد وابیده عقیم یامبهم بی.\nلطفا دوباره سعی کنین.",
        "passwordtooshort": "رمز ایسا غیر معتبر یا کوتاه هده.\nآن وا داشته بوه حداقل {{PLURAL:$1|1 کاراکتر|$1 کاراکترها}} همچنین وا زه نام کاربریتو متفاوت بوه.",
-       "mailmypassword": "اÙ\85Û\8cÙ\84 Ø±Ù\85ز ØªØ§Ø²Ù\87",
+       "mailmypassword": "ز Ù\86Û\89 Ø¯Ø§Ú\8cÙ\86 Ø±Ø§Ø²Ù\8aÙ\86Ø¥ Ú¯Ù\88أرتÙ\86",
        "passwordremindertitle": "رمز موقتی تازه سی {{SITENAME}}",
        "passwordremindertext": "یه نفر (شاید خودتو, زه نشانی آی پی$1) درخواست یه رمز تازه کرده سی {{SITENAME}} ($4). یه رمز موقتی سی کاربر\n\"$2\" درست شده وگذاشته وابیده به\"$3\". ایر مطابق میل ایسا بوه, نیازه که داخل سیستم بوین ویه رمز تازه انتخاب کنین.\n\nایر آن فرد همچنین درخواست کرده بوه  یونه, یا ایر ایسا رمزتو را به خاط داشته این ,\nوسی مدت طولانی نه خوین هونه تغییر بدین, ایسا وا نادیده بگیرین ای پیام  را وهمچنان زه رمز قدیمی خوتو استفاده کنین",
        "noemail": "وجود نداره نشانی امیل ضبط وابده زه کاریر \"$1\".",
        "pt-createaccount": "راسد کردن هساڤ کارياري",
        "pt-userlogout": "ز سامۈنإ درأڤوڌن",
        "retypenew": "تایپ دوباره رمز:",
+       "botpasswords-label-create": "راس كردن",
+       "botpasswords-label-cancel": "أنجومشيڤ کردن",
+       "botpasswords-label-delete": "پاکسا کردن",
+       "botpasswords-label-resetpassword": "ز نۉ داڌن رازينإ گوأرتن",
+       "resetpass-submit-cancel": "أنجومشيڤ کردن",
        "passwordreset": "ز نۉ داڌن رازينإ گوأرتن",
+       "passwordreset-username": "نوم کارياري",
+       "passwordreset-domain": "پوشگر",
+       "passwordreset-email": "تيرنشۈن أنجومانامأ",
+       "changeemail-none": "(هيش كوم)",
        "bold_sample": "متن گپ نما",
        "bold_tip": "متن گپ نما",
        "italic_sample": "متن شکسته",
        "sig_tip": "امضای ایسا و برچسب زمان",
        "hr_tip": "خط افقی (کم استفاده کنین)",
        "summary": "خلاصه:",
-       "subject": "موضوع/سرخط:",
+       "subject": "داسۈن",
        "minoredit": "ای یه اصلاح ریزه-رز",
        "watchthis": "پیگیری ای صفحه",
        "savearticle": "صفحه ضبط بوه",
        "template-semiprotected": "(نیمه حمایت وابیده)",
        "nocreatetext": "{{SITENAME}}قابلیت درست کردن صفحات تازه را محدود کرده‌. ترین برگردین و صفحه‌ موجود را اصلاح کنین یا اینکه  [[Special:UserLogin|به سیستم داخل بوین یا حساب کاربری درست کنین]].",
        "recreate-moveddeleted-warn": "'''هشدار: ایسا در حال درست کردن دوباره صفحه‌ای هدین که قبلاً حذف وابیده '''در نظر داشته بوین که ادامه اصلاح ای صفحه کار درستی هده یا نه. نمایه حذف مربوط به ای صفحه سی راحتی کار در ادامه اویده",
+       "content-model-wikitext": "ڤيکي تکست",
+       "content-model-javascript": "جاڤا إسکريپت",
        "viewpagelogs": "نشودادن نمایه ها سی ای صفحه",
        "currentrev": "نسخه جاری",
        "currentrev-asof": "آخرين ڤانيأري جۈر $1",
        "nextrevision": "نسخه بعدی →",
        "currentrevisionlink": "نسخه جاری",
        "cur": "فعلی",
+       "next": "نيایي",
        "last": "قبلی",
        "page_first": "اولین",
        "page_last": "آخری",
        "histlegend": "انتخاب متفاوت: علامت بنین رو رادیو جعبه ها زه آن نسخه ها سی مقایسه وامتیاز دادن ویا داخل تکمه های زیر سی مسابقه بوین  .<br />\n'شرح: (فعلی) = تفاوت با نسخه جاری\n(قبلی) = تفاوت با نسخه قبلی، جز = ویرایش جزئی',",
-       "histfirst": "کهنه ترین",
-       "histlast": "تازه ترین",
+       "histfirst": "دينداتري",
+       "histlast": "تازإترين",
+       "historyempty": "(هالي)",
        "history-feed-item-nocomment": "$1 در $2",
        "rev-delundel": "آلشد هال و بال ديإن",
+       "rev-showdeleted": "دياري کردن",
+       "revdelete-show-file-submit": "هأرإ",
        "history-title": "دڤارتإ دیئن ڤيرگار $1",
        "difference-title": "فرخ مإنجقا ڤانإیريا \"$1\"",
        "lineno": "سطر $1:",
        "recentchanges-label-minor": "یو یه ويرايشت کوچيره",
        "recentchanges-label-bot": "اي ڤيرایشد نأ یأ بوت أنجوم داڌإ",
        "recentchanges-label-unpatrolled": "ای ويرايشت هنی تيه واداشت نوابيه",
+       "recentchanges-label-plusminus": "أندازإ بألگأ ب شومار اي بایتا آلشد کردإ.",
        "recentchanges-legend-heading": "<strong>میراث:</strong>",
+       "recentchanges-legend-newpage": "{{int:recentchanges-label-newpage}} (همچنو سإیل کونين ب[[Special:بألگإیل تازأ|نومگأ بإلگإیل تازأ]])",
        "rcnotefrom": "در زیر تغییرات زه تاریخ <b>$2</b> آمده‌اند (تا <b>$1</b> مورد نشو داده ابوه).",
        "rclistfrom": "نشودادن تغییرات تازه با شروع زه $3 $2",
        "rcshowhideminor": "اصلاحات کوچیک $1",
        "undeletebtn": "بازیافت",
        "namespace": "فضای نام:",
        "invert": "انتخاب برعکس بوه",
+       "tooltip-invert": "ز ري اي جأڤأ بپۈرنين و آلشدایي نأ کإ مإنجقا نوم ڤأرگأ إنتخاڤ ڤابيڌن أنجوم داڌإ ڤابيڌنإ قام کونين.",
        "namespace_association": "نوم جایل یأکاگرهڌأ",
+       "tooltip-namespace_association": "اي جأڤإ نأ ڤارسي کونين اي جأڤأ د ڤأرگرهڌإ چأک چنإ آ داسۈن نوم ڤأرگأ شريکي و نوم ڤأرگأ گولإڤورچينإ.",
        "blanknamespace": "(اصلی)",
        "contributions": "{{GENDER:$1|کاریار}} هومیاریا",
        "mycontris": "هومياریا",
        "tooltip-upload": "شروع آپلود",
        "tooltip-rollback": "\"اعاده\" برگرداندن به وضع اولیه سی ای صفحه که بخاطر مشارکت  آخر اصلاح وابیده بایک کلیک",
        "tooltip-summary": "یأ چکسدأ کۈچير ڤارڌ کونين",
+       "simpleantispam-label": "Anti-spam check.\nپور<strong>نکنين</strong> ايچو نأ!",
        "pageinfo-toolboxlink": "دونسمندیا بلگه",
        "previousdiff": "← اصلاح قدیمی",
        "nextdiff": "تفاوت بعدی→",
index 5a7af97..fc16576 100644 (file)
@@ -35,6 +35,8 @@
        "tog-watchdefault": "Ouzhpennañ ar pajennoù kemmet ganin da'm roll evezhiañ",
        "tog-watchmoves": "Ouzhpennañ ar pajennoù dilec'hiet ganin da'm roll evezhiañ",
        "tog-watchdeletion": "Ouzhpennañ ar pajennoù diverket ganin da'm roll evezhiañ",
+       "tog-watchuploads": "Ouzhpennañ em roll-evezhiañ ar restroù nevez a enporzhian.",
+       "tog-watchrollback": "Ouzhpennañ ar pajennoù ma'z on distro war ma roll evezhiañ.",
        "tog-minordefault": "Sellet ouzh ar c'hemmoù degaset ganin<br /> evel kemmoù dister dre ziouer",
        "tog-previewontop": "Rakwelet tres ar bajenn a-us ar prenestr skridaozañ",
        "tog-previewonfirst": "Rakwelet tres ar bajenn kerkent hag an aozadenn gentañ",
        "tog-enotifminoredits": "Kas ur postel din, ha pa vije evit kemenn kemmoù dister",
        "tog-enotifrevealaddr": "Lakaat ma chomlec'h postel war wel er posteloù kemenn-diwall",
        "tog-shownumberswatching": "Diskouez an niver a lennerien",
-       "tog-oldsig": "Ar sinadur zo evit poent :",
+       "tog-oldsig": "Ho sinadur evit poent :",
        "tog-fancysig": "Ober gant ar sinadur evel pa vefe wikitestenn (hep liamm emgefre)",
-       "tog-uselivepreview": "Implijout Rakwelet prim (taol-arnod)",
+       "tog-uselivepreview": "Ober gant ar Rakwel prim",
        "tog-forceeditsummary": "Kemenn din pa ne skrivan netra er stern diverrañ",
        "tog-watchlisthideown": "Kuzhat ma c'hemmoù er rollad evezhiañ",
        "tog-watchlisthidebots": "Kuzhat kemmoù ar botoù er rollad evezhiañ",
        "tog-watchlisthideminor": "Kuzhat ar c'hemmoù dister er rollad evezhiañ",
        "tog-watchlisthideliu": "Er roll evezhiañ, kuzhat kemmoù an implijerien kevreet.",
+       "tog-watchlistreloadautomatically": "Adkargañ ar roll-evezhiañ bep tro ma vez cheñchet ur sil (rekis eo kaout JavaScript)",
        "tog-watchlisthideanons": "Er roll evezhiañ, kuzhat kemmoù an implijerien dianav",
        "tog-watchlisthidepatrolled": "Kuzhat ar c'hemmoù evezhiet diouzh ar roll evezhiañ",
+       "tog-watchlisthidecategorization": "Kuzhat rummatadur ar pajennoù",
        "tog-ccmeonemails": "Kas din un eilskrid eus ar posteloù a gasan da implijerien all",
        "tog-diffonly": "Arabat diskouez danvez ar pennadoù dindan an diforc'hioù",
        "tog-showhiddencats": "Diskouez ar rummadoù kuzhet",
-       "tog-norollbackdiff": "Na ziskouez an diff goude un distaoladenn",
+       "tog-norollbackdiff": "Na ziskouez an diforc'hioù goude un distro",
        "tog-useeditwarning": "Kas keloù din pa guitaan ur bajenn degaset kemmoù enni hep enrollañ",
        "tog-prefershttps": "Implijout bepred ur c'hevreadur suraet pa vezit kevreet",
        "underline-always": "Atav",
        "newwindow": "(digeriñ en ur prenestr nevez)",
        "cancel": "Nullañ",
        "moredotdotdot": "Ha muioc'h c'hoazh...",
-       "morenotlisted": "N'eo ket klok ar roll-mañ.",
+       "morenotlisted": "Marteze eo diglok ar roll-mañ.",
        "mypage": "Ma zammig pajenn",
        "mytalk": "Ma c'haozeadennoù",
-       "anontalk": "Kaozeal gant ar chomlec'h IP-mañ",
+       "anontalk": "Kaozeal",
        "navigation": "Merdeiñ",
        "and": "&#32;ha(g)",
        "qbfind": "Klask",
        "talk": "Kaozeadenn",
        "views": "Gweladennoù",
        "toolbox": "Ostilhoù",
+       "tool-link-userrights": "Kemmañ strolladoù an {{GENDER:$1|implijer|implijerez}}",
+       "tool-link-emailuser": "Kas ur postel d'an {{PLURAL:$1|an implijer-mañ|an implijerez-mañ}}",
        "userpage": "Pajenn implijer",
        "projectpage": "Pajenn meta",
        "imagepage": "Gwelet pajenn ar restr",
        "laggedslavemode": "Diwallit : marteze a-walc'h n'emañ ket ar c'hemmoù diwezhañ war ar bajenn-mañ",
        "readonly": "Hizivadurioù stanket war ar bank roadennoù",
        "enterlockreason": "Merkit perak eo stanket hag istimit pegeit e chomo evel-henn",
-       "readonlytext": "Evit poent n'haller ket ouzhpennañ pe gemmañ netra er bank roadennoù mui. Un tamm kempenn boutin d'ar bank moarvat. goude-se e vo plaen an traoù en-dro.\n\nSetu displegadenn ar merour bet prennet ar bank gantañ : $1",
+       "readonlytext": "Evit poent n'haller ket ouzhpennañ pe gemmañ netra en diaz roadennoù mui. Un tamm kempenn boutin d'an diaz moarvat. Goude-se e vo plaen an traoù en-dro.\n\nSetu displegadenn ar merour bet prennet an diaz gantañ : $1",
        "missing-article": "N'eo ket bet kavet gant an diaz titouroù testenn ur bajenn en dije dleet kavout hag anvet \"$1\" $2.\n\nPeurliesañ e c'hoarvez evit bezañ heuliet liamm dispredet un diforc'h pe an istor war-du ur bajenn bet diverket abaoe.\n\nMard ned eo ket se eo, hoc'h eus marteze kavet un draen er meziant.\nKasit keloù d'ur [[Special:ListUsers/sysop|merer]], en ur verkañ dezhañ chomlec'h an URL.",
        "missingarticle-rev": "(adweladenn # : $1)",
        "missingarticle-diff": "(Dif : $1, $2)",
        "createaccount-text": "Unan bennak en deus krouet ur gont gant ho chomlec'h postel war {{SITENAME}} ($4) zo e anv \"$2\" hag a ra gant ar ger-tremen \"$3\".\nMat e vefe deoc'h kevreañ ha cheñch ho ker-tremen bremañ.\n\nNa daolit ket evezh ouzh ar c'hemenn-mañ m'eo bet krouet ar gont dre fazi.",
        "login-throttled": "Betek re oc'h heus klasket kevreañ en aner.\nGortozit $1, mar plij, a-raok esaeañ en-dro.",
        "login-abort-generic": "Dibosupl ho kevreañ - Dilezet",
+       "login-migrated-generic": "Dilec'hiet eo bet ho kont ha n'eus ket eus hoc'h anv implijer war ar wiki-mañ ken.",
        "loginlanguagelabel": "Yezh : $1",
        "suspicious-userlogout": "Distaolet eo bet ho koulenn digevreañ rak kaset e oa bet gant ur merdeer direizhet pe krubuilhadenn ur proksi, evit doare.",
        "createacct-another-realname-tip": "Diret eo skrivañ hoc'h anv gwir. Ma skrivit anezhañ e vo implijet evit lakaat war wel ar pezh a vo bet degaset ganeoc'h.",
        "newpassword": "Ger-tremen nevez :",
        "retypenew": "Adskrivañ ar ger-tremen nevez :",
        "resetpass_submit": "Cheñch ar ger-tremen ha kevreañ",
-       "changepassword-success": "Cheñchet eo bet ho ker-tremen !",
+       "changepassword-success": "Cheñchet eo bet ho ker-tremen ervat !",
        "changepassword-throttled": "Betek re hoc'h heus klasket kevreañ en aner.\nGortozit $1, mar plij, a-raok esaeañ en-dro.",
+       "botpasswords": "Gerioù-tremen ar botoù",
+       "botpasswords-summary": "Aotren a ra <em>gerioù-tremen ar botoù</em> implijout kont un implijer dre an API hep ober gant titouroù-kred pennañ ar gont. Ur wech kevreet dre ger-tremen ur bot e c'hall gwirioù an implijer bezañ strishaet.\n\nMa n'ouzit ket mat perak e c'hallfec'h kaout c'hoant d'ober se, eo furoc'h chom hep en ober. Den ebet ne zlefe goulenn diganeoc'h biken genel unan hag e reiñ dezhañ.",
+       "botpasswords-disabled": "Diweredekaet eo gerioù-tremen ar botoù.",
+       "botpasswords-existing": "Gerioù-tremen botoù a zo anezho",
+       "botpasswords-createnew": "Krouiñ ur ger-tremen bot nevez",
+       "botpasswords-editexisting": "Cheñch ger-tremen ur bot a zo anezhañ c'hoazh",
        "botpasswords-label-appid": "Anv ar robot",
        "botpasswords-label-create": "Krouiñ",
        "botpasswords-label-update": "Hizivaat",
        "botpasswords-label-cancel": "Nullañ",
        "botpasswords-label-delete": "Dilemel",
        "botpasswords-label-resetpassword": "Adderaouekaat ar ger-tremen",
+       "botpasswords-label-grants": "Aotreoù a c'haller ober ganto :",
        "botpasswords-label-grants-column": "Aotreet",
        "botpasswords-bad-appid": "N'eo ket reizh anv ar robot « $1 »",
        "botpasswords-insert-failed": "C'hwitet eo ouzhpennadenn ar robot « $1 ». Hag ouzhpennet eo bet ?",
        "botpasswords-newpassword": "<strong>\"$2\"</strong> eo ar ger-tremen evit kevreañ gant <strong>$1</strong>. Enrollit anezhañ, par plij, evit ober dave dezhañ diwezhatoc'h.</em>",
        "botpasswords-no-provider": "N'eo ket hegerz BotPasswordsSessionProvider.",
        "resetpass_forbidden": "N'haller ket cheñch ar gerioù-termen",
+       "resetpass_forbidden-reason": "N'haller ket cheñch ar gerioù-termen : $1",
        "resetpass-no-info": "Ret eo deoc'h bezañ kevreet a-benn mont d'ar bajenn-se war-eeun.",
        "resetpass-submit-loggedin": "Cheñch ger-tremen",
        "resetpass-submit-cancel": "Nullañ",
-       "resetpass-wrong-oldpass": "Direizh eo ar ger-tremen a-vremañ pe da c'hortoz.",
+       "resetpass-wrong-oldpass": "Direizh eo ar ger-tremen dibad pe an hini a-vremañ. Moarvat ez eus bet cheñchet ger-tremen ganeoc'h c'hoazh pe goulennet ur ger-tremen dibad nevez.",
        "resetpass-recycled": "Ret eo d'ho ker-tremen nevez bezañ disheñvel diouzh ho ker-tremen a vremañ.",
        "resetpass-temp-emailed": "Kevreet e oac'h bet gant ur c'hod dibad kaset deoc'h dre bostel.\nEvit echuiñ kevreañ e rankit lakaat ur ger-tremen nevez amañ :",
        "resetpass-temp-password": "Ger-tremen da c'hortoz :",
        "passwordreset-emailtext-user": "Goulennet en deus an implijer $1 war  {{SITENAME}} e vefe degaset soñj dezhañ eus titouroù e gont evit {{SITENAME}} ($4). Emañ liammet {{PLURAL:$3|ar gont implijer|ar c'hontoù implijer}} da-heul gant ar chomlec'h postel-mañ :\n\n$2\n\nMont a raio da get {{PLURAL:$3|ar ger-tremen da c'hortoz|ar gerioù-tremen da c'hortoz}} a-benn {{PLURAL:$5|un devezh|$5 deiz}}.\nMat e vefe deoc'h kevreañ ha dibab ur ger-tremen nevez bremañ. Mard eo bet goulennet kement-se gant unan bennak all pe m'hoc'h eus soñj eus ho ker-tremen orin ha mar ne fell ket deoc'h e cheñch ken, na daolit ket evezh ouzh ar gemennadenn-mañ ha dalc'hit d'ober gant ho ker-tremen kozh.",
        "passwordreset-emailelement": "Anv implijer :           \n$1\n\nGer-tremen da c'hortoz : \n$2",
        "passwordreset-emailsentemail": "Kaset ez eus bet ur postel deoc'h da adderaouekaat ho ker-tremen.",
+       "passwordreset-nocaller": "Ret eo merkañ anv ur galver",
+       "passwordreset-nosuchcaller": "N'eus ket eus ar galver : $1",
        "passwordreset-invalidemail": "Chomlec'h postel direizh",
        "changeemail": "Kemmañ ar chomlec'h postel",
        "changeemail-header": "Kemmañ chomlec'h postel ar gont",
        "changeemail-password": "Ho ker-tremen war {{SITENAME}}:",
        "changeemail-submit": "Cheñch chomlec'h postel",
        "changeemail-throttled": "Betek re hoc'h heus klasket kevreañ en aner.\nGortozit $1, mar plij, a-raok esaeañ en-dro.",
+       "changeemail-nochange": "Merkit ur chomlec'h postel all.",
        "resettokens": "Adderaouekaat ar jedoueroù",
        "resettokens-no-tokens": "N'eus jedouer ebet da adderaouekaat.",
        "resettokens-tokens": "Jedoueroù :",
        "content-model-javascript": "Javascript",
        "content-model-css": "CSS",
        "content-json-empty-object": "Elfenn goullo",
+       "content-json-empty-array": "Taolenn c'houllo",
        "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.",
        "prefs-watchlist-token": "Jedouer evit ar roll evezhiañ :",
        "prefs-misc": "Penndibaboù liesseurt",
        "prefs-resetpass": "Cheñch ar ger-tremen",
-       "prefs-changeemail": "Cheñch chomlec'h postel",
+       "prefs-changeemail": "Cheñch ar chomlec'h postel pe dilemel anezhañ",
        "prefs-setemail": "Termeniñ ur chomlec'h postel",
        "prefs-email": "Dibarzhioù postel",
        "prefs-rendering": "Neuz",
        "columns": "Bannoù",
        "searchresultshead": "Klask",
        "stub-threshold": "Bevenn uhelañ evit al liammoù war-du an danvez pennadoù ($1) :",
+       "stub-threshold-sample-link": "skouer",
        "stub-threshold-disabled": "Diweredekaet",
        "recentchangesdays": "Niver a zevezhioù da ziskouez er c'hemmoù diwezhañ :",
        "recentchangesdays-max": "D'ar muiañ $1 {{PLURAL:$1|deiz|deiz}}",
        "prefs-help-prefershttps": "Efediñ a ray an dibarzh-mañ kentañ gwech ma kevreoc'h.",
        "prefs-tabs-navigation-hint": "Titourig : Gallout a rit implijout an touchennoù bir kleiz ha bir dehoù evit merdeiñ etre an ivinelloù e roll an ivinelloù.",
        "userrights": "Merañ statud an implijerien",
-       "userrights-lookup-user": "Merañ strolladoù an implijer",
+       "userrights-lookup-user": "Diuzañ un implijer",
        "userrights-user-editname": "Lakait un anv implijer :",
-       "editusergroup": "Kemmañ ar strolladoù implijerien",
-       "editinguser": "Kemmañ gwirioù an implijer '''[[User:$1|$1]]''' $2",
+       "editusergroup": "Kargañ strolladoù implijerien",
+       "editinguser": "O kemmañ gwirioù an {{GENDER:$1|implijer|implijerez}} <strong>[[User:$1|$1]]</strong> $2",
        "userrights-editusergroup": "Kemmañ strolladoù an implijer",
        "userrights-viewusergroup": "Gwelet ar strolladoù implijerien",
        "saveusergroups": "Enrollañ strolladoù an {{GENDER:$1|implijer|implijerez}}",
        "grant-blockusers": "Stankañ ha distankañ implijerien",
        "grant-createaccount": "Krouiñ kontoù",
        "grant-createeditmovepage": "Krouiñ, aozañ ha dilec'hiañ pajennoù",
-       "grant-editmywatchlist": "Aozañ ho roll evezhiañ",
-       "grant-editpage": "Aoañ pajennoù a zo anezho dija",
-       "grant-editprotected": "Aozañ pajennoù gwarezet",
+       "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-protect": "Gwareziñ ha diwareziñ pajennoù",
+       "grant-rollback": "Distreiñ war ar c'hemmoù er pajennoù",
        "grant-sendemail": "Kas ur postel d'an implijerien all",
+       "grant-uploadfile": "Enporzhiañ restroù nevez",
        "grant-basic": "Gwirioù diazez",
-       "grant-viewdeleted": "Gwelet an titouroù dilamet",
+       "grant-viewdeleted": "Gwelet ar restroù ha pajennoù dilamet",
        "grant-viewmywatchlist": "Gwelet ho roll evezhiañ",
        "newuserlogpage": "Marilh ar c'hontoù krouet",
        "newuserlogpagetext": "Marilh krouiñ ar c'hontoù implijer.",
        "rightslogtext": "Setu marilh ar c'hemmoù statud bet c'hoarvezet d'an implijerien.",
        "action-read": "lenn ar bajenn-mañ",
        "action-edit": "kemmañ ar bajenn-mañ",
-       "action-createpage": "krouiñ pajennoù",
+       "action-createpage": "krouiñ ar bajenn-mañ",
        "action-createtalk": "krouiñ pajennoù kaozeal",
        "action-createaccount": "krouiñ ar gont implijer-mañ",
        "action-history": "gwelet istor ar bajenn-mañ",
        "action-userrights-interwiki": "Kemmañ gwirioù an implijerien war wikioù all",
        "action-siteadmin": "Prennañ pe dibrennañ ar bank roadennoù",
        "action-sendemail": "Kas posteloù",
+       "action-editmyoptions": "Kemmañ ho penndibaboù",
        "action-editmywatchlist": "kemmañ ho roll evezhiañ",
        "action-viewmywatchlist": "gwelet ho roll evezhiañ",
        "action-viewmyprivateinfo": "Gwelet ho titouroù prevez",
        "action-editmyprivateinfo": "aozañ ho titouroù prevez",
        "action-deletechangetags": "Diverkañ tikedennoù a-ziwar an diaz-roadennoù",
+       "action-purge": "spurjañ ar bajenn-mañ",
        "nchanges": "$1 {{PLURAL:$1|kemm|kemm}}",
        "enhancedrc-since-last-visit": "$1 {{PLURAL:$1|abaoe ho kweladenn diwezhañ}}",
        "enhancedrc-history": "istor",
        "recentchanges-legend-heading": "<strong>Alc'hwez :</strong>",
        "recentchanges-legend-newpage": "{{int:recentchanges-label-newpage}} (gwelet ivez [[Special:NewPages|roll ar pajennoù nevez]])",
        "recentchanges-submit": "Diskouez",
-       "rcnotefrom": "Setu aze roll ar c'hemmoù c'hoarvezet abaoe an <strong>$2</strong> (<strong>$1</strong> d'ar muiañ).",
+       "rcfilters-activefilters": "Siloù oberiant",
+       "rcfilters-invalid-filter": "Sil direizh",
+       "rcfilters-filterlist-title": "Siloù",
+       "rcfilters-filterlist-noresults": "N'eus bet kavet sil ebet",
+       "rcfilters-filter-editsbyself-label": "Kemmet ganeoc'h",
+       "rcfilters-filter-editsbyself-description": "Kemmet ganeoc'h",
+       "rcfilters-filter-editsbyother-label": "Kemmet gant tud all",
+       "rcfilters-filter-editsbyother-description": "Kemmoù graet gant implijerien all (ket ganeoc'h).",
+       "rcfilters-filtergroup-userExpLevel": "Live skiant-prenañ an implijer",
+       "rcfilters-filter-userExpLevel-newcomer-label": "Tud nevez-deuet",
+       "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.",
+       "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",
        "rcshowhideminor-show": "Diskouez",
        "recentchangeslinked-summary": "Rollet eo war ar bajenn dibar-mañ ar c'hemmoù diwezhañ bet degaset war ar pajennoù liammet ouzh ur bajenn lakaet (pe ouzh izili ur rummad lakaet).\nE '''tev''' emañ ar pajennoù zo war ho [[Special:Watchlist|roll evezhiañ]].",
        "recentchangeslinked-page": "Anv ar bajenn :",
        "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",
        "upload": "Kargañ war ar servijer",
        "uploadbtn": "Kargañ ur restr",
        "upload-form-label-infoform-description": "Deskrivadur",
        "upload-form-label-usage-title": "Implij",
        "upload-form-label-usage-filename": "Anv ar restr",
+       "upload-form-label-own-work": "Setu aze ma zammig labour din-me",
        "upload-form-label-infoform-categories": "Rummadoù",
        "upload-form-label-infoform-date": "Deiziad",
        "backend-fail-stream": "Dibosupl eo lenn ar restr $1.",
        "protectedpages-performer": "Gwareziñ an implijer",
        "protectedpages-params": "Arventennoù gwareziñ",
        "protectedpages-reason": "Abeg",
+       "protectedpages-submit": "Diskwel ar pajennoù",
        "protectedpages-unknown-timestamp": "Dianav",
        "protectedpages-unknown-performer": "Implijer dianav",
        "protectedtitles": "Titloù gwarezet",
        "protectedtitlesempty": "N'eus bet gwarezet titl ebet dezhañ an arventennoù-se evit poent.",
+       "protectedtitles-submit": "Diskwel an titloù",
        "listusers": "Roll an implijerien",
        "listusers-editsonly": "Na ziskouez nemet an implijerien o deus degaset un dra bennak",
        "listusers-creationsort": "Renket dre urzh krouiñ",
        "nopagetext": "N'eus ket eus ar bajenn dal merket ganeoc'h.",
        "pager-newer-n": "{{PLURAL:$1|1 nevesoc'h|$1 nevesoc'h}}",
        "pager-older-n": "{{PLURAL:$1|1 koshoc'h|$1 koshoc'h}}",
-       "suppress": "Dindan evezh",
+       "suppress": "Dilemel",
        "querypage-disabled": "Diweredekaet eo bet ar bajenn dibar-mañ evit aesaat d'ar reizhiad un tammig.",
        "apihelp": "Skoazell an API",
        "apihelp-no-such-module": "N'eo ket bet kavet ar vodulenn \"$1\".",
        "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-values": "$1 (An holl dalvoudoù)",
        "booksources": "Oberennoù dave",
        "booksources-search-legend": "Klask en oberennoù dave",
        "booksources-isbn": "ISBN :",
        "booksources-search": "Klask",
        "booksources-text": "Ur roll liammoù a gas da lec'hiennoù all ma werzher levrioù kozh ha nevez a gavot a-is; marteze e kavot eno titouroù pelloc'h war al levrioù a glaskit :",
        "booksources-invalid-isbn": "Evit doare n'eo ket reizh an ISBN merket; gwiriit ha n'oc'h ket faziet en ur eilañ adal ar vammenn orin.",
+       "magiclink-tracking-isbn": "Pajennoù a ra gant liammoù burzhudus ISBN",
        "specialloguserlabel": "Implijer :",
        "speciallogtitlelabel": "Bukadenn (titl pe implijer) :",
        "log": "Marilhoù",
        "trackingcategories": "Rummadoù evezhiañ",
        "trackingcategories-msg": "Rummad evezhiañ",
        "trackingcategories-name": "Anv ar gemennadenn",
+       "trackingcategories-desc": "Dezverkoù evit degemer rummadoù",
        "broken-file-category-desc": "Er bajenn-mañ ez eus ul liamm restr torr (ul liamm da enframmañ ur restr pa n'eus ket eus ar restr-se).",
        "trackingcategories-nodesc": "N'eus deskrivadur ebet.",
        "trackingcategories-disabled": "Diweredekaet eo ar rummad",
        "lockdbsuccesstext": "Prennet eo bank roadennnoù {{SITENAME}}.\n\n<br />Na zisoñjit ket e zibrennañ pa vo bet kaset da benn vat hoc'h oberiadenn drezalc'h.",
        "unlockdbsuccesstext": "Dibrennet eo bank roadennoù {{SITENAME}}.",
        "lockfilenotwritable": "N'haller ket skrivañ war restr prennañ ar bank roadennoù. A-benn prennañ-dibrennañ ar bank e rankit bezañ aotreet da skrivañ war ar servijer Kenrouedad.",
+       "databaselocked": "Prennet eo an diaz roadennoù c'hoazh.",
        "databasenotlocked": "N'eo ket prennet an diaz roadennoù.",
        "lockedbyandtime": "(gant $1 d'an $2 da $3)",
        "move-page": "Dilec'hiañ $1",
        "export-download": "Aotren enrollañ evel ur restr",
        "export-templates": "Lakaat ar patromoù e-barzh ivez",
        "export-pagelinks": "Lakaat ar pajennoù liammet e-barzh betek un donder a :",
+       "export-manual": "Ouzhpennañ pajennoù gant an dorn :",
        "allmessages": "Roll kemennoù ar reizhiad",
        "allmessagesname": "Anv",
        "allmessagesdefault": "Kemennadenn dre ziouer",
        "confirm-unwatch-button": "Mat eo",
        "confirm-unwatch-top": "Lemel ar bajenn-mañ a-ziwar ho roll evezhiañ",
        "confirm-rollback-button": "Mat eo",
+       "confirm-rollback-top": "Disteurel ar c'hemmoù graet er bajenn-mañ ?",
        "quotation-marks": "« $1 »",
        "imgmultipageprev": "&larr; pajenn gent",
        "imgmultipagenext": "pajenn war-lerc'h &rarr;",
        "watchlistedit-raw-done": "Nevesaet eo bet ho roll evezhiañ.",
        "watchlistedit-raw-added": "Ouzhpennet ez eus bet {{PLURAL:$1|1 pajenn|$1 pajenn}} :",
        "watchlistedit-raw-removed": "Tennet ez eus bet {{PLURAL:$1|1 pajenn|$1 pajenn}} :",
-       "watchlistedit-clear-title": "Roll evezhiañ goulloet",
+       "watchlistedit-clear-title": "Diverkañ ar roll-evezhiañ",
        "watchlistedit-clear-legend": "Diverkañ ar roll-evezhiañ",
        "watchlistedit-clear-explain": "Lamet e vo an holl ditloù eus ho roll evezhiañ",
        "watchlistedit-clear-titles": "Titloù :",
        "version-entrypoints": "URLoù ar poent mont e-barzh",
        "version-entrypoints-header-entrypoint": "Poent mont e-barzh",
        "version-entrypoints-header-url": "URL",
+       "version-libraries": "Levraouegoù staliet",
        "version-libraries-library": "Levraoueg",
        "version-libraries-version": "Stumm",
        "version-libraries-license": "Aotre-implijout",
        "htmlform-cloner-create": "Ouzhpennañ muioc'h",
        "htmlform-cloner-delete": "Dilemel",
        "htmlform-cloner-required": "Un dalvoudenn a zo ret da vihanañ.",
+       "htmlform-date-placeholder": "BBBB-MM-DD",
+       "htmlform-time-placeholder": "HH:MM:SS",
+       "htmlform-datetime-placeholder": "BBBB-MM-DD HH:MM:SS",
+       "htmlform-title-not-exists": "N'eus ket eus $1.",
+       "htmlform-user-not-exists": "N'eus ket eus <strong>$1</strong>.",
+       "htmlform-user-not-valid": "Un anv implijer direizh eo <strong>$1</strong>.",
        "logentry-delete-delete": "Diverket eo bet ar bajenn $3 gant $1",
        "logentry-delete-restore": "Assavet eo bet ar bajenn $3 gant $1",
        "logentry-delete-event": "Kemmet eo bet gwelusted {{PLURAL:$5|un darvoud eus ar marilh|$5 darvoud eus ar marilh}} d'an $3 gant $1 : $4",
        "json-error-state-mismatch": "JSON direizh pe stummet fall",
        "json-error-syntax": "Fazi ereadur",
        "json-error-utf8": "Arouezennoù UTF-8 stummet fall, enkodet en un doare direizh marteze",
+       "headline-anchor-title": "Liamm war-zu ar rannbennad-mañ",
        "special-characters-group-latin": "Latin",
        "special-characters-group-latinextended": "Latin astennet",
        "special-characters-group-ipa": "LFE (IPA)",
        "mw-widgets-titleinput-description-redirect": "adkas war-zu $1",
        "mw-widgets-categoryselector-add-category-placeholder": "Ouzhpennañ ur rummad...",
        "randomrootpage": "Pajenn wrizienn dargouezhek",
+       "log-action-filter-block": "Seurt bloc'had :",
        "log-action-filter-all": "An holl",
        "log-action-filter-block-block": "Stankañ",
        "log-action-filter-block-unblock": "Distankañ",
+       "log-action-filter-protect-protect": "Gwarez",
+       "log-action-filter-protect-unprotect": "Diwarez",
+       "log-action-filter-rights-autopromote": "Kemm emgefre",
+       "authmanager-authn-no-primary": "N'eus ket bet gallet gwiriañ an titouroù kred lakaet.",
+       "authmanager-authn-no-local-user-link": "Reizh eo an titouroù kred lakaet met n'int ket liammet ouzh implijer ebet eus ar wiki-mañ. Ma kevreit en ur mod all pe ma krouit ur gont implijer nevez e c'hallot liammañ ho titouroù kred kent ouzh ar gont-mañ.",
+       "authmanager-change-not-supported": "N'haller ket cheñch an titouroù kred rak netra na rafe ganto.",
+       "authmanager-create-no-primary": "N'eus ket bet gallet implijout an titouroù kred lakaet evit krouiñ ur gont.",
+       "authmanager-authplugin-setpass-failed-title": "C'hwitet eo bet ar cheñchamant ger-tremen",
        "authmanager-authplugin-setpass-bad-domain": "Domani direizh.",
+       "authmanager-userdoesnotexist": "N'eo ket enrollet ar gont implijer \"$1\".",
+       "authmanager-retype-help": "Adkadarnaat ar ger-tremen.",
        "authmanager-email-label": "Postel",
        "authmanager-email-help": "Chomlec'h postel",
        "authmanager-realname-label": "Anv gwir",
        "authmanager-realname-help": "Anv gwir an implijer",
        "authmanager-provider-password": "Gwiriekadur diazezet war ur ger-termen",
        "authmanager-provider-temporarypassword": "Ger-tremen da c'hortoz",
+       "authprovider-confirmlink-success-line": "$1: bet liammet ervat.",
        "authprovider-resetpass-skip-label": "Lammat",
        "authprovider-resetpass-skip-help": "Lammat adderaouekaat ar ger-tremen.",
+       "authform-newtoken": "Jedouer a vank. $1",
+       "authform-notoken": "Jedouer a vank",
+       "authform-wrongtoken": "Jedouer fall",
        "specialpage-securitylevel-not-allowed-title": "Berzet",
+       "authpage-cannot-login": "N'haller ket kregiñ da gevreañ",
+       "authpage-cannot-create": "N'haller ket kregiñ da grouiñ ar gont.",
        "cannotauth-not-allowed-title": "Aotre nac'het",
        "cannotauth-not-allowed": "N'oc'h ket aotreet d'ober gant ar bajenn-mañ",
+       "changecredentials": "Kemmañ an titouroù kred",
+       "changecredentials-submit": "Kemmañ an titouroù kred",
+       "changecredentials-invalidsubpage": "N'eo ket $1 ur seurt titour kred reizh.",
+       "removecredentials": "Lemel an titouroù kred",
+       "removecredentials-submit": "Lemel an aotreoù",
+       "removecredentials-invalidsubpage": "N'eo ket $1 ur seurt titour kred reizh.",
+       "credentialsform-provider": "Seurt titouroù kred :",
        "credentialsform-account": "Anv ar gont :",
        "cannotlink-no-provider-title": "N'eus kont ebet da liammañ",
+       "cannotlink-no-provider": "N'eus kont ebet da liammañ.",
        "linkaccounts": "Kontoù liammet",
        "linkaccounts-success-text": "Liammet eo bet ar gont.",
        "linkaccounts-submit": "Liammañ ar c'hontoù",
        "unlinkaccounts": "Diliammañ ar c'hontoù",
-       "unlinkaccounts-success": "Diliammet eo bet ar gont."
+       "unlinkaccounts-success": "Diliammet eo bet ar gont.",
+       "revid": "Adweladenn $1",
+       "pageid": "ID ar bajenn $1"
 }
index abe68a5..e42972d 100644 (file)
        "action-deleterevision": "suprimeix les revisions",
        "action-deletelogentry": "suprimeix les entrades de registre",
        "action-deletedhistory": "mostra l'historial esborrat d'una pàgina",
+       "action-deletedtext": "mostra el text de la revisió eliminada",
        "action-browsearchive": "cercar pàgines esborrades",
        "action-undelete": "restaura les pàgines",
        "action-suppressrevision": "revisa i restaura les revisions ocultes",
        "recentchanges-legend-newpage": "{{int:recentchanges-label-newpage}} (vegeu també la [[Special:NewPages|llista de pàgines noves]])",
        "recentchanges-legend-plusminus": "(''±123'')",
        "recentchanges-submit": "Mostra",
+       "rcfilters-activefilters": "Filtres actius",
+       "rcfilters-search-placeholder": "Canvis recents dels filtres (navegueu o comenceu a escriure)",
+       "rcfilters-invalid-filter": "Filtre no vàlid",
+       "rcfilters-filterlist-title": "Filtres",
+       "rcfilters-filterlist-noresults": "No s'ha trobat cap filtre",
+       "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)",
        "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-dynamic-error-exists": "Ja existeix un paràmetre anomenat \"$1\".",
        "apisandbox-deprecated-parameters": "Paràmetres obsolets",
        "apisandbox-submit-invalid-fields-title": "Alguns camps no són vàlids",
+       "apisandbox-submit-invalid-fields-message": "Corregiu els camps marcats i torneu-ho a provar.",
        "apisandbox-results": "Resultats",
        "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-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».",
        "apisandbox-alert-page": "Els camps en aquesta pàgina no són vàlids.",
        "apisandbox-alert-field": "El valor d'aquest camp no és vàlid.",
        "apisandbox-continue": "Continua",
        "activeusers-intro": "Aquí hi ha una llista d'usuaris que han tingut algun tipus d'activitat en {{PLURAL:$1|el darrer dia|els darrers $1 dies}}.",
        "activeusers-count": "$1 {{PLURAL:$1|acció|accions}} en {{PLURAL:$3|el darrer dia|els $3 darrers dies}}",
        "activeusers-from": "Mostra els usuaris començant per:",
+       "activeusers-groups": "Mostra els usuaris que pertanyen als grups:",
        "activeusers-excludegroups": "Exclou els usuaris que pertanyen als grups:",
        "activeusers-noresult": "No s'han trobat usuaris.",
        "activeusers-submit": "Mostra els usuaris actius",
        "rollbacklinkcount": "reverteix $1 {{PLURAL:$1|edició|edicions}}",
        "rollbacklinkcount-morethan": "reverteix més de $1 {{PLURAL:$1|edició|edicions}}",
        "rollbackfailed": "No s'ha pogut revocar",
+       "rollback-missingparam": "Paràmetres necessaris que falten en la sol·licitud.",
        "rollback-missingrevision": "No es poden carregar les dades de revisió.",
        "cantrollback": "No s'han pogut revertir les edicions; el darrer col·laborador és l'únic autor de la pàgina.",
        "alreadyrolled": "No es pot revertir la darrera modificació de [[:$1]]\nde l'usuari [[User:$2|$2]] ([[User talk:$2|Discussió]]{{int:pipe-separator}}[[Special:Contributions/$2|{{int:contribslink}}]]). Algú altre ja ha modificat o revertit la pàgina.\n\nLa darrera modificació l'ha fet l'usuari [[User:$3|$3]] ([[User talk:$3|Discussió]]{{int:pipe-separator}}[[Special:Contributions/$3|{{int:contribslink}}]]).",
        "revertpage": "Revertides les edicions de [[Special:Contributions/$2|$2]] ([[User talk:$2|discussió]]) a l'última versió de [[User:$1|$1]]",
        "revertpage-nouser": "Edicions revertides per un usuari ocult a l'última revisió de {{GENDER:$1|[[User:$1|$1]]}}",
        "rollback-success": "Edicions revertides de $1; s'ha canviat a la darrera versió de $2.",
+       "rollback-success-notify": "Modificacions revertides per $1;\ns'ha revertit a la darrera versió de $2. [$3 Mostra els canvis]",
        "sessionfailure-title": "Error de sessió",
        "sessionfailure": "S'ha produït un error amb la vostra sessió. S'ha anul·lat aquesta acció en prevenció de pirateig de sessió. Premeu «Torna», recarregueu la pàgina des d'on veniu i torneu-ho a intentar.",
        "changecontentmodel": "Canvia el model de contingut d'una pàgina",
        "changecontentmodel-emptymodels-title": "No hi ha models de contingut",
        "changecontentmodel-emptymodels-text": "El contingut a [[:$1]] no pot convertir-se a cap tipus.",
        "log-name-contentmodel": "Registre de canvis del model de contingut",
-       "log-description-contentmodel": "Esdeveniments relacionats amb els models de contingut d'una pàgina",
+       "log-description-contentmodel": "Aquesta pàgina llista els canvis al model de contingut de les pàgines, i les pàgines que van ser creades amb un model de contingut diferent del que és per defecte.",
+       "logentry-contentmodel-new": "$1 {{GENDER:$2|va crear}} la pàgina $3 utilitzant un model de contingut no per defecte («$5»)",
        "logentry-contentmodel-change": "$1 {{GENDER:$2|ha canviat}} el model de contingut de la pàgina $3 de «$4» a «$5»",
        "logentry-contentmodel-change-revertlink": "reverteix",
        "logentry-contentmodel-change-revert": "reverteix",
        "modifiedarticleprotection": "ha canviat el nivell de protecció de «[[$1]]»",
        "unprotectedarticle": "ha desprotegit \"[[$1]]\"",
        "movedarticleprotection": "ha traslladat els ajustaments de protecció des de «[[$2]]» a «[[$1]]»",
+       "protectedarticle-comment": "{{GENDER:$2|Ha protegit}} «[[$1]]»",
+       "modifiedarticleprotection-comment": "{{GENDER:$2|Ha canviat el nivell de protecció}} de «[[$1]]»",
+       "unprotectedarticle-comment": "{{GENDER:$2|Ha suprimit la protecció}} de «[[$1]]»",
        "protect-title": "Canviant la protecció de «$1»",
        "protect-title-notallowed": "Mostra el nivell de protecció de \" $1 \"",
        "prot_1movedto2": "[[$1]] mogut a [[$2]]",
        "cant-move-to-user-page": "No teniu permís per a moure una pàgina a una pàgina d'usuari (independentment de poder fer-ho cap a una subpàgina d'usuari).",
        "cant-move-category-page": "No teniu permisos per a moure pàgines de categoria.",
        "cant-move-to-category-page": "No teniu permisos per a moure una pàgina a una pàgina de categoria.",
+       "namespace-nosubpages": "L'espai de noms «$1» no permet subpàgines.",
        "newtitle": "Títol nou:",
        "move-watch": "Vigila aquesta pàgina",
        "movepagebtn": "Reanomena la pàgina",
        "pageinfo-length": "Mida de la pàgina (en bytes)",
        "pageinfo-article-id": "ID de la pàgina",
        "pageinfo-language": "Llengua del contingut de la pàgina",
+       "pageinfo-language-change": "canvia",
        "pageinfo-content-model": "Plantilla de contingut de pàgina",
        "pageinfo-content-model-change": "canvia",
        "pageinfo-robot-policy": "Indexació per robots",
        "log-show-hide-patrol": "$1 el registre de patrulla",
        "log-show-hide-tag": "$1 el registre d’etiquetes",
        "confirm-markpatrolled-button": "D'acord",
+       "confirm-markpatrolled-top": "Voleu marcar la revisió $3 de $2 com a patrullada?",
        "deletedrevision": "S'ha eliminat la revisió antiga $1.",
        "filedeleteerror-short": "Error en suprimir el fitxer: $1",
        "filedeleteerror-long": "S'han produït errors en suprimir el fitxer:\n\n$1",
        "pagelang-use-default": "Utilitza l'idioma per defecte",
        "pagelang-select-lang": "Selecciona un idioma",
        "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.",
+       "pagelang-unchanged-language-default": "La pàgina $1 ja està configurada en la llengua de contingut per defecte del wiki.",
+       "pagelang-db-failed": "La base de dades no ha pogut canviar la llengua de la pàgina.",
        "right-pagelang": "Canvia l'idioma de la pàgina",
        "action-pagelang": "canvia l'idioma de la pàgina",
        "log-name-pagelang": "Registre de canvi de llengua",
        "log-action-filter-delete-restore": "Restauració de pàgines",
        "log-action-filter-delete-event": "Registre de supressió",
        "log-action-filter-delete-revision": "Supressió de revisions",
+       "log-action-filter-import-upload": "Importació mitjançant càrrega d'XML",
        "log-action-filter-managetags-create": "Creació de l'etiqueta",
        "log-action-filter-managetags-delete": "Supressió de l'etiqueta",
        "log-action-filter-managetags-activate": "Activació de l'etiqueta",
        "authmanager-authplugin-setpass-failed-title": "El canvi de contrasenya ha fallat",
        "authmanager-authplugin-setpass-bad-domain": "Domini invàlid.",
        "authmanager-userdoesnotexist": "El compte d'usuari «$1» no està registrat.",
+       "authmanager-username-help": "Nom d'usuari per a l'autenticació.",
+       "authmanager-password-help": "Contrasenya per a l'autenticació.",
+       "authmanager-domain-help": "Domini per a l'autenticació externa.",
        "authmanager-retype-help": "Contrasenya de nou per confirmar",
        "authmanager-email-label": "Correu electrònic",
        "authmanager-email-help": "Adreça electrònica",
        "cannotauth-not-allowed": "No teniu permisos per utilitzar la pàgina",
        "changecredentials": "Canvi de dades credencials",
        "changecredentials-submit": "Canvia les dades credencials",
+       "changecredentials-success": "Les vostres credencials han estat canviades.",
        "removecredentials": "Suprimeix les credencials",
        "removecredentials-submit": "Suprimeix les credencials",
        "removecredentials-invalidsubpage": "$1 no és un tipus de credencial vàlid.",
index eecc893..78e430e 100644 (file)
        "undelete-show-file-submit": "ХӀаъ",
        "namespace": "ЦӀерийн меттигаш:",
        "invert": "Хаьржинарг къайлаяккха",
-       "tooltip-invert": "ХӀоттае хӀара билгало, хаьржинчу цӀерийн анан агӀонийн хийцамаш къайлабаха (кхин дихкина цӀерийн анаш, гайтина елахь)",
+       "tooltip-invert": "ХӀоттае хӀара билгало, хаьржинчу цӀерийн меттигийн агӀонийн хийцамаш къайлабаха (кхин дихкина цӀерийн анаш, гайтина елахь)",
+       "tooltip-whatlinkshere-invert": "ХӀоттае хӀара билгало, хаьржинчу цӀерийн меттигийн агӀонийн хьажоргаш къайлаяха.",
        "namespace_association": "Йихкина меттиг",
        "tooltip-namespace_association": "ХӀоттае хӀара билгало, иштта дийцарийн (я кхин) цӀерийн меттиг юкъахь хилийта",
        "blanknamespace": "(Коьрта)",
index f0a86b9..11e01b7 100644 (file)
        "api-error-unclassified": "Došlo k neznámé chybě.",
        "api-error-unknown-code": "Neznámá chyba: „$1“.",
        "api-error-unknown-error": "Vnitřní chyba: došlo k chybě při pokusu o načtení souboru.",
-       "api-error-unknown-warning": "Neznámé varování: $1",
+       "api-error-unknown-warning": "Neznámé varování: „$1“.",
        "api-error-unknownerror": "Neznámá chyba: „$1“.",
        "api-error-uploaddisabled": "Načítání souborů je na této wiki vypnuto.",
        "api-error-verification-error": "Soubor je možná poškozen nebo má špatnou příponu.",
        "pagelang-use-default": "Použít implicitní jazyk",
        "pagelang-select-lang": "Vybrat jazyk",
        "pagelang-submit": "Odeslat",
+       "pagelang-nonexistent-page": "Stránka $1 neexistuje.",
+       "pagelang-unchanged-language": "Stránka $1 již má nastavený jazyk $2.",
+       "pagelang-unchanged-language-default": "Stránka $1 již má jako jazyk nastavený výchozí jazyk obsahu wiki.",
+       "pagelang-db-failed": "Databázi se nepodařilo změnit jazyk stránky.",
        "right-pagelang": "Změnit jazyk stránky",
        "action-pagelang": "měnit jazyk stránky",
        "log-name-pagelang": "Kniha změn jazyků",
index b84a025..59fc82e 100644 (file)
        "recentchanges-legend-newpage": "{{int:recentchanges-label-newpage}} (siehe auch die [[Special:NewPages|Liste neuer Seiten]])",
        "recentchanges-legend-plusminus": "''(±123)''",
        "recentchanges-submit": "Anzeigen",
+       "rcfilters-activefilters": "Aktive Filter",
+       "rcfilters-search-placeholder": "Letzte Änderungen filtern (durchsuchen oder beginne mit der Eingabe)",
+       "rcfilters-invalid-filter": "Ungültiger Filter",
+       "rcfilters-filterlist-title": "Filter",
+       "rcfilters-filterlist-noresults": "Keine Filter gefunden",
+       "rcfilters-filtergroup-authorship": "Bearbeitungs-Autorenschaft",
+       "rcfilters-filter-editsbyself-label": "Deine eigenen Bearbeitungen",
+       "rcfilters-filter-editsbyself-description": "Bearbeitungen von dir.",
+       "rcfilters-filter-editsbyother-label": "Bearbeitungen von anderen",
+       "rcfilters-filter-editsbyother-description": "Bearbeitungen von anderen Benutzern (nicht von dir)",
+       "rcfilters-filtergroup-userExpLevel": "Niveau der Benutzererfahrung",
+       "rcfilters-filter-userExpLevel-newcomer-label": "Neulinge",
+       "rcfilters-filter-userExpLevel-newcomer-description": "Sehr neue Autoren: Weniger als 10 Bearbeitungen und eine Aktivität von weniger als 4 Tagen.",
+       "rcfilters-filter-userExpLevel-learner-label": "Anfänger",
+       "rcfilters-filter-userExpLevel-learner-description": "Eine Aktivität von mehreren Tagen und mehr Bearbeitungen als „Neulinge“, aber weniger als „Erfahrene Benutzer“.",
+       "rcfilters-filter-userExpLevel-experienced-label": "Erfahrene Benutzer",
+       "rcfilters-filter-userExpLevel-experienced-description": "Eine Aktivität von mehr als 30 Tagen und mehr als 500 Bearbeitungen.",
        "rcnotefrom": "Angezeigt {{PLURAL:$5|wird die Änderung|werden die Änderungen}} seit <strong>$3, $4</strong> (max. <strong>$1</strong> Einträge).",
        "rclistfrom": "Nur Änderungen seit $3, $2 Uhr zeigen.",
        "rcshowhideminor": "Kleine Änderungen $1",
        "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-url-label": "Anforderungs-URL:",
        "apisandbox-request-time": "Dauer der Anfrage: {{PLURAL:$1|Eine Millisekunde|$1 Millisekunden}}",
        "apisandbox-results-fixtoken": "Token korrigieren und erneut übertragen",
        "movepage-page-exists": "Die Seite „$1“ ist bereits vorhanden und kann nicht automatisch überschrieben werden.",
        "movepage-page-moved": "Die Seite „$1“ wurde nach „$2“ verschoben.",
        "movepage-page-unmoved": "Die Seite „$1“ konnte nicht nach „$2“ verschoben werden.",
-       "movepage-max-pages": "Die Maximalanzahl von $1 {{PLURAL:$1|Seite|Seiten}} wurde verschoben, Alle weiteren Seiten können nicht automatisch verschoben werden.",
+       "movepage-max-pages": "Es wurde die Maximalanzahl von {{PLURAL:$1|einer Seite|$1 Seiten}} verschoben. Alle weiteren Seiten können nicht automatisch verschoben werden.",
        "movelogpage": "Verschiebungs-Logbuch",
        "movelogpagetext": "Dies ist eine Liste aller verschobenen Seiten.",
        "movesubpage": "{{PLURAL:$1|Unterseite|Unterseiten}}",
        "pagelang-language": "Sprache",
        "pagelang-use-default": "Standardsprache verwenden",
        "pagelang-select-lang": "Sprache auswählen",
+       "pagelang-reason": "Grund",
        "pagelang-submit": "Übermitteln",
+       "pagelang-nonexistent-page": "Die Seite $1 ist nicht vorhanden.",
+       "pagelang-unchanged-language": "Die Seite $1 ist bereits auf die Sprache $2 festgelegt.",
+       "pagelang-unchanged-language-default": "Die Seite $1 ist bereits auf die Standardinhaltssprache des Wikis festgelegt.",
+       "pagelang-db-failed": "Die Datenbank konnte die Seitensprache nicht ändern.",
        "right-pagelang": "Seitensprache ändern",
        "action-pagelang": "die Seitensprache zu ändern",
        "log-name-pagelang": "Sprachenänderungs-Logbuch",
index e7a5dc5..15c3607 100644 (file)
        "badaccess-group0": "Heqa şıma çıniya, karo ke şıma waşt, bıkerê.",
        "badaccess-groups": "No fealiyeto ke şıma waşt, tenya karberanê {{PLURAL:$2|grubi|gruban ra yewi}} rê akerdeyo: $1.",
        "versionrequired": "No $1 MediaWiki lazımo",
-       "versionrequiredtext": "Gırweynayışê ena perre rê gani versiyonê $1ê MediaWiki bo. \n[[Special:Version|Versiyonê pere\nr]] bıvêne.",
+       "versionrequiredtext": "Gırweynayışê ena perre rê gani versiyonê $1ê MediaWiki bo. \n[[Special:Version|Versiyonê perre]] bıvêne.",
        "ok": "Temam",
        "pagetitle": "$1 – {{SITENAME}}",
        "pagetitle-view-mainpage": "{{SITENAME}}",
        "prefs-user-pages": "Pelê karberi",
        "prefs-personal": "Profilê karberi",
        "prefs-rc": "Vurnayışê peyêni",
-       "prefs-watchlist": "Lista seyrkerdışi",
+       "prefs-watchlist": "Liste ya seyr kerdışi",
        "prefs-editwatchlist": "Lista seyrkerdışi bıvurne",
        "prefs-editwatchlist-label": "Listey serkerdışanê cıkewtışi timar kerê",
        "prefs-editwatchlist-edit": "Listey seyr kerdışê sernameyanê xo bımotné u timar kerê",
        "usermessage-editor": "Xeberdarê sistemi",
        "usermessage-template": "MediaWiki:UserMessage",
        "watchlist": "Listey pawıteyan",
-       "mywatchlist": "Listey seyr kerdışi",
+       "mywatchlist": "Lista seyrkerdışi",
        "watchlistfor2": "Qandê $1 ($2)",
        "nowatchlist": "listeya temaşa kerdıişê şıma de yew madde zi çina.",
        "watchlistanontext": "qey vurnayişê maddeya listeya temaşakerdiş ronıştış akerê",
        "namespace_association": "Heruna namanê elaqedaran",
        "tooltip-namespace_association": "Herunda canemiya elekeyın nışan kerdışi sero qıse kerdışi yana zerre dekerdışi rê ena dora tesdiqi nışan kerê",
        "blanknamespace": "(Wesiqe)",
-       "contributions": "İştırakê {{GENDER:$1|karber}}i",
-       "contributions-title": "Dekerdenê karber de $1",
+       "contributions": "İştirakê {{GENDER:$1|karber}}i",
+       "contributions-title": "Dekerdenê karberê  $1",
        "mycontris": "İştıraki",
        "anoncontribs": "İştıraki",
        "contribsub2": "Qandê {{GENDER:$3|$1}} ($2)",
        "fileduplicatesearch-result-1": "Dosyayê ''$1î'' de hem-kopya çini yo.",
        "fileduplicatesearch-result-n": "Dosyayê ''$1î'' de {{PLURAL:$2|1 hem-kopya|$2 hem-kopyayî'}} esto.",
        "fileduplicatesearch-noresults": "Ebe namey \"$1\" ra dosya nêdiyayê.",
-       "specialpages": "Perrê xasi",
+       "specialpages": "Perrê hısusi",
        "specialpages-note-top": "Kıtabek",
        "specialpages-note": "* Pelê xasê normali.\n* <span class=\"mw-specialpagerestricted\">Pelê xasê nımıtey.</span>",
        "specialpages-group-maintenance": "Raporê pawıtışi",
index 3cfb2c2..28f3888 100644 (file)
        "accountcreated": "Ο λογαριασμός δημιουργήθηκε",
        "accountcreatedtext": "Ο λογαριασμός χρήστη για τον/την [[{{ns:User}}:$1|$1]] ([[{{ns:User talk}}:$1|συζήτηση]]) έχει δημιουργηθεί.",
        "createaccount-title": "Δημιουργία λογαριασμού για {{SITENAME}}",
-       "createaccount-text": "Î\9aάÏ\80οιοÏ\82 Î´Î·Î¼Î¹Î¿Ï\8dÏ\81γηÏ\83ε Î­Î½Î±Î½ Î»Î¿Î³Î±Ï\81ιαÏ\83μÏ\8c Î³Î¹Î± Ï\84η Î´Î¹ÎµÏ\8dθÏ\85νÏ\83η email Ï\83αÏ\82 Ï\83Ï\84ο {{SITENAME}} ($4) Î¼Îµ Ï\84ο Ï\8cνομα \"$2\", Î¼Îµ ÎºÏ\89δικÏ\8c Ï\80Ï\81Ï\8cÏ\83βαÏ\83ηÏ\82 \"$3\". Î\98α Ï\80Ï\81έÏ\80ει Î½Î± Ï\83Ï\85νδεθείÏ\84ε ÎºÎ±Î¹ Î½Î± Î±Î»Î»Î¬Î¾ÎµÏ\84ε Ï\84ον ÎºÏ\89δικÏ\8c Ï\80Ï\81Ï\8cÏ\83βαÏ\83ήÏ\82 Ï\83αÏ\82 Ï\84Ï\8eÏ\81α.\n\nÎ\9cÏ\80οÏ\81είÏ\84ε Î½Î± Î±Î³Î½Î¿Î®Ï\83εÏ\84ε Î±Ï\85Ï\84Ï\8c Ï\84ο Î¼Î®Î½Ï\85μα, Î±Î½ Î±Ï\85Ï\84Ï\8cÏ\82 Î¿ Î»Î¿Î³Î±Ï\81ιαÏ\83μÏ\8cÏ\82 Î´Î·Î¼Î¹Î¿Ï\85Ï\81γήθηκε ÎµÏ\83Ï\86αλμένα.",
+       "createaccount-text": "Î\9aάÏ\80οιοÏ\82 Î´Î·Î¼Î¹Î¿Ï\8dÏ\81γηÏ\83ε Î»Î¿Î³Î±Ï\81ιαÏ\83μÏ\8c Î³Î¹Î± Ï\84η Î´Î¹ÎµÏ\8dθÏ\85νÏ\83η Ï\83αÏ\82 Î·Î»ÎµÎºÏ\84Ï\81ονικοÏ\8d Ï\84αÏ\87Ï\85δÏ\81ομείοÏ\85 Ï\83Ï\84ο {{SITENAME}} ($4) Î¼Îµ Ï\8cνομα Â«$2» ÎºÎ±Î¹ Ï\83Ï\85νθημαÏ\84ικÏ\8c Â«$3». Î¤Ï\8eÏ\81α Î¸Î± Ï\80Ï\81έÏ\80ει Î½Î± Ï\83Ï\85νδεθείÏ\84ε ÎºÎ±Î¹ Î½Î± Î±Î»Î»Î¬Î¾ÎµÏ\84ε Ï\84ο Ï\83Ï\85νθημαÏ\84ικÏ\8c Ï\83αÏ\82.\n\nÎ\9cÏ\80οÏ\81είÏ\84ε Î½Î± Î±Î³Î½Î¿Î®Ï\83εÏ\84ε Î±Ï\85Ï\84Ï\8c Ï\84ο Î¼Î®Î½Ï\85μα, Î±Î½ Î±Ï\85Ï\84Ï\8cÏ\82 Î¿ Î»Î¿Î³Î±Ï\81ιαÏ\83μÏ\8cÏ\82 Î´Î·Î¼Î¹Î¿Ï\85Ï\81γήθηκε Î±Ï\80Ï\8c Î»Î¬Î¸Î¿Ï\82.",
        "login-throttled": "Κάνατε πάρα πολλές πρόσφατες απόπειρες σύνδεσης.\nΠαρακαλούμε περιμένετε $1 προτού ξαναδοκιμάσετε.",
        "login-abort-generic": "Η είσοδος σας απέτυχε - Ματαίωση",
        "login-migrated-generic": "Ο λογαριασμός σας έχει μεταναστεύσει, και το όνομα χρήστη σας δεν υπάρχει πλέον σε αυτό το wiki.",
index 2d7a53e..a621f1c 100644 (file)
        "recentchanges-legend-unpatrolled": "{{int:recentchanges-label-unpatrolled}}",
        "recentchanges-legend-plusminus": "(<em>±123</em>)",
        "recentchanges-submit": "Show",
+       "rcfilters-activefilters": "Active filters",
+       "rcfilters-search-placeholder": "Filter recent changes (browse or start typing)",
+       "rcfilters-invalid-filter": "Invalid filter",
+       "rcfilters-filterlist-title": "Filters",
+       "rcfilters-filterlist-noresults": "No filters found",
+       "rcfilters-filtergroup-authorship": "Edit authorship",
+       "rcfilters-filter-editsbyself-label": "Your own edits",
+       "rcfilters-filter-editsbyself-description": "Edits by you.",
+       "rcfilters-filter-editsbyother-label": "Edits by others",
+       "rcfilters-filter-editsbyother-description": "Edits created by other users (not you.)",
+       "rcfilters-filtergroup-userExpLevel": "User experience level",
+       "rcfilters-filter-userExpLevel-newcomer-label": "Newcomers",
+       "rcfilters-filter-userExpLevel-newcomer-description": "Very new editors: fewer than 10 edits and 4 days of activity.",
+       "rcfilters-filter-userExpLevel-learner-label": "Learners",
+       "rcfilters-filter-userExpLevel-learner-description": "More days of activity and edits than 'Newcomers' but fewer than 'Experienced users.'",
+       "rcfilters-filter-userExpLevel-experienced-label": "Experienced users",
+       "rcfilters-filter-userExpLevel-experienced-description": "More than 30 days of activity and 500 edits.",
        "rcnotefrom": "Below {{PLURAL:$5|is the change|are the changes}} since <strong>$3, $4</strong> (up to <strong>$1</strong> shown).",
        "rclistfrom": "Show new changes starting from $2, $3",
        "rcshowhideminor": "$1 minor edits",
        "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 URL:",
        "apisandbox-request-time": "Request time: {{PLURAL:$1|$1 ms}}",
        "apisandbox-results-fixtoken": "Correct token and resubmit",
        "sorbs": "DNSBL",
        "sorbsreason": "Your IP address is listed as an open proxy in the DNSBL used by {{SITENAME}}.",
        "sorbs_create_account_reason": "Your IP address is listed as an open proxy in the DNSBL used by {{SITENAME}}.\nYou cannot create an account.",
+       "softblockrangesreason": "Anonymous contributions are not allowed from your IP address ($1). Please log in.",
        "xffblockreason": "An IP address present in the X-Forwarded-For header, either yours or that of a proxy server you are using, has been blocked. The original block reason was: $1",
        "cant-see-hidden-user": "The user you are trying to block has already been blocked and hidden.\nSince you do not have the hideuser right, you cannot see or edit the user's block.",
        "ipbblocked": "You cannot block or unblock other users because you are yourself blocked.",
        "pagelang-language": "Language",
        "pagelang-use-default": "Use default language",
        "pagelang-select-lang": "Select language",
+       "pagelang-reason": "Reason",
        "pagelang-submit": "Submit",
+       "pagelang-nonexistent-page": "The page $1 does not exist.",
+       "pagelang-unchanged-language": "The page $1 is already set to language $2.",
+       "pagelang-unchanged-language-default": "The page $1 is already set to the wiki's default content language.",
+       "pagelang-db-failed": "The database failed to change the page language.",
        "right-pagelang": "Change page language",
        "action-pagelang": "change the page language",
        "log-name-pagelang": "Language change log",
index 2056f6d..8e07873 100644 (file)
        "recentchanges-legend-heading": "<strong>Klarigo:</strong>",
        "recentchanges-legend-newpage": "{{int:recentchanges-label-newpage}} (vidu ankaŭ [[Special:NewPages|liston de novaj paĝoj]])",
        "recentchanges-submit": "Montri",
+       "rcfilters-activefilters": "Aktivaj filtriloj",
+       "rcfilters-filterlist-title": "Filtriloj",
+       "rcfilters-filter-editsbyself-description": "Viaj redaktoj.",
+       "rcfilters-filter-editsbyother-label": "Redaktoj de aliuloj",
+       "rcfilters-filter-userExpLevel-newcomer-label": "Novuloj",
+       "rcfilters-filter-userExpLevel-learner-label": "Lernantoj",
+       "rcfilters-filter-userExpLevel-experienced-label": "Spertaj uzantoj",
        "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",
        "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",
        "api-error-unclassified": "Okazis nekonata eraro",
        "api-error-unknown-code": "Nekonata eraro: \"$1\"",
        "api-error-unknown-error": "Interna eraro: io misokazis en la alŝuto de via dosiero.",
-       "api-error-unknown-warning": "Nekonata averto: $1",
+       "api-error-unknown-warning": "Nekonata averto: \"$1\".",
        "api-error-unknownerror": "Nekonata eraro: \"$1\"",
        "api-error-uploaddisabled": "Alŝutato estas malebligata en tiu ĉi vikio.",
        "api-error-verification-error": "Tiu ĉi dosiero eble estas difektita, aŭ havas la malĝustan dosieran finaĵon.",
        "pagelang-use-default": "Uzi defaŭltan lingvon",
        "pagelang-select-lang": "Elekti la lingvon",
        "pagelang-submit": "Ek!",
+       "pagelang-nonexistent-page": "La paĝo $1 ne ekzistas.",
        "right-pagelang": "Ŝanĝi paĝan lingvon",
        "action-pagelang": "ŝanĝi la lingvon de la paĝo",
        "log-name-pagelang": "Protokolo pri lingvajn ŝanĝojn",
index 9a37b03..b84a0f1 100644 (file)
        "recentchanges-legend-heading": "<strong>Leyenda:</strong>",
        "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-invalid-filter": "Filtro no válido",
+       "rcfilters-filterlist-title": "Filtros",
+       "rcfilters-filterlist-noresults": "No se encontraron filtros",
+       "rcfilters-filter-editsbyself-label": "Tus propias ediciones",
+       "rcfilters-filter-editsbyself-description": "Ediciones tuyas",
+       "rcfilters-filter-editsbyother-label": "Ediciones de otros",
        "rcnotefrom": "Debajo aparece{{PLURAL:$5| el cambio|n los cambios}} desde <strong>$3, $4</strong> (se muestran hasta <strong>$1</strong>).",
        "rclistfrom": "Mostrar cambios nuevos desde las $2 del $3",
        "rcshowhideminor": "$1 ediciones menores",
        "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-url-label": "URL solicitante:",
        "apisandbox-request-time": "Tiempo de solicitud: {{PLURAL:$1|$1 ms}}",
        "apisandbox-results-fixtoken": "Corrige el token y vuelve a enviar",
        "pagelang-use-default": "Utilizar el idioma predeterminado",
        "pagelang-select-lang": "Seleccionar idioma",
        "pagelang-submit": "Enviar",
+       "pagelang-db-failed": "La base de datos no ha podido cambiar el idioma de la página.",
        "right-pagelang": "Cambiar el idioma de la página",
        "action-pagelang": "cambiar el idioma de la página",
        "log-name-pagelang": "Registro de cambios de idiomas",
index 9c58de8..5269c65 100644 (file)
        "virus-scanfailed": "eskaneatze txarra ($1 kodea)",
        "virus-unknownscanner": "antibirus ezezaguna:",
        "logouttext": "'''Saioa itxi egin duzu.'''\n\nJakin ezazu hainbat orrialdetan ager daitekela oraindik saioa ez duzula itxi, zure nabigatzailearen katxea garbitzen ez duzun arte.",
+       "cannotlogoutnow-title": "Ezin da saioa itxi orain",
+       "cannotlogoutnow-text": "Saioa ezin da itxi $1 erabiltzean.",
        "welcomeuser": "Ongi etorri, $1!",
        "welcomecreation-msg": "Zure kontua sortua izan da.\nEz ezazu ahaztu zure [[Special:Preferences|{{SITENAME}} hobespenak]] aldatzea.",
        "yourname": "Erabiltzaile izena",
        "createacct-yourpasswordagain-ph": "Sartu pasahitza berriro ere",
        "userlogin-remembermypassword": "Manten nazazu barruan",
        "userlogin-signwithsecure": "Erabili konexio ziurra",
+       "cannotlogin-title": "Ezin da saioa hasi",
+       "cannotlogin-text": "Saioa hastea ez da posible izan.",
+       "cannotloginnow-title": "Ezin da saioa hasi orain",
+       "cannotloginnow-text": "Saioa ezin da hasi $1 erabiltzean.",
+       "cannotcreateaccount-title": "Kontuak ezin dira sortu",
        "yourdomainname": "Zure domeinua",
        "password-change-forbidden": "Ezin duzu pasahitzarik aldatu wiki honetan.",
        "externaldberror": "Kanpoko datu-base autentifikazio errorea gertatu da edo ez duzu zure kanpo kontua eguneratzeko baimenik.",
        "login": "Hasi saioa",
+       "login-security": "Zure nortasuna egiaztatu",
        "nav-login-createaccount": "Hasi saioa / sortu kontua",
        "userlogin": "Saioa hasi / kontua sortu",
        "userloginnocreate": "Hasi saioa",
index 2b112be..95fd0e0 100644 (file)
        "search-relatedarticle": "Reliés",
        "searchrelated": "reliés",
        "searchall": "tout",
-       "showingresults": "Affichage de <b>$1</b> résultat{{PLURAL:$1||s}} à partir du n°<b>$2</b>.",
+       "showingresults": "Affichage de <strong>$1</strong> résultat{{PLURAL:$1||s}} à partir du n°<strong>$2</strong>.",
        "showingresultsinrange": "Afficher ci-dessous jusqu’à {{PLURAL:$1|<strong>1</strong> résultat|<strong>$1</strong> résultats}} dans la série #<strong>$2</strong> à #<strong>$3</strong>.",
        "search-showingresults": "{{PLURAL:$4|Résultat <strong>$1</strong> parmi <strong>$3</strong>|Résultats <strong>$1 à $2</strong> parmi <strong>$3</strong>}}",
        "search-nonefound": "Il n'y a aucun résultat correspondant à la requête.",
        "recentchanges-legend-newpage": "{{int:recentchanges-label-newpage}} (voir aussi la [[Special:NewPages|liste des nouvelles pages]]).",
        "recentchanges-legend-plusminus": "(''±123'')",
        "recentchanges-submit": "Lister",
+       "rcfilters-activefilters": "Filtres actifs",
+       "rcfilters-search-placeholder": "Modifications récentes de filtres (naviguer ou commencer à saisir)",
+       "rcfilters-invalid-filter": "Filtre non valide",
+       "rcfilters-filterlist-title": "Filtres",
+       "rcfilters-filterlist-noresults": "Aucun filtre trouvé",
+       "rcfilters-filtergroup-authorship": "Modifier la paternité",
+       "rcfilters-filter-editsbyself-label": "Vos propres modifications",
+       "rcfilters-filter-editsbyself-description": "Vos modifications.",
+       "rcfilters-filter-editsbyother-label": "Modifications par d’autres.",
+       "rcfilters-filter-editsbyother-description": "Modifications créées par d’autres utilisateurs (pas vous).",
+       "rcfilters-filtergroup-userExpLevel": "Niveau d’expérience utilisateur",
+       "rcfilters-filter-userExpLevel-newcomer-label": "Nouveaux arrivants",
+       "rcfilters-filter-userExpLevel-newcomer-description": "Tout nouveaux éditeurs : moins de 10 modifications et 4 jours d’activité.",
+       "rcfilters-filter-userExpLevel-learner-label": "Apprentis",
+       "rcfilters-filter-userExpLevel-learner-description": "Davantage de jours d’activité et de modifications que les 'Nouveaux arrivants' mais moins que les 'Utilisateurs expérimentés'.",
+       "rcfilters-filter-userExpLevel-experienced-label": "Utilisateurs expérimentés",
+       "rcfilters-filter-userExpLevel-experienced-description": "Plus de 30 jours d’activité et 500 modifications",
        "rcnotefrom": "Ci-dessous {{PLURAL:$5|la modification effectuée|les modifications effectuées}} depuis le <strong>$3, $4</strong> (affichées jusqu’à <strong>$1</strong>).",
        "rclistfrom": "Afficher les nouvelles modifications depuis le $3 à $2",
        "rcshowhideminor": "$1 les modifications mineures",
        "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-url-label": "Requête URL :",
        "apisandbox-request-time": "Durée de la demande: {{PLURAL:$1|$1 ms}}",
        "apisandbox-results-fixtoken": "Corrigez le jeton et renvoyez",
        "pagelang-use-default": "Utiliser la langue par défaut",
        "pagelang-select-lang": "Sélectionner la langue",
        "pagelang-submit": "Envoyer",
+       "pagelang-nonexistent-page": "La page $1 n’existe pas.",
+       "pagelang-unchanged-language": "La page $1 est déjà positionnée sur la langue $2.",
+       "pagelang-unchanged-language-default": "La page $1 est déjà positionnée dans la langue par défaut du contenu du wiki.",
+       "pagelang-db-failed": "La base de données n’a pas réussi à modifier la langue de la page.",
        "right-pagelang": "Changer la langue de la page",
        "action-pagelang": "changer la langue de la page",
        "log-name-pagelang": "Tracer les changements de langue",
index 4745280..f5da074 100644 (file)
        "api-error-unclassified": "Houbo un erro descoñecido.",
        "api-error-unknown-code": "Erro descoñecido: \"$1\"",
        "api-error-unknown-error": "Erro interno: Houbo un problema ao intentar cargar o ficheiro.",
-       "api-error-unknown-warning": "Advertencia descoñecida: $1",
+       "api-error-unknown-warning": "Advertencia descoñecida: \"$1\".",
        "api-error-unknownerror": "Erro descoñecido: \"$1\".",
        "api-error-uploaddisabled": "As cargas están desactivadas neste wiki.",
        "api-error-verification-error": "Este ficheiro podería estar corrupto ou ter unha extensión incorrecta.",
        "log-action-filter-block-reblock": "Modificación de bloqueo",
        "log-action-filter-block-unblock": "Desbloquear",
        "log-action-filter-contentmodel-change": "Cambio de modelo de contido",
-       "log-action-filter-contentmodel-new": "Creación de páxins cun modelo de contido non estándar",
+       "log-action-filter-contentmodel-new": "Creación de páxina cun modelo de contido diferente do contido por defecto",
        "log-action-filter-delete-delete": "Borrado de páxinas",
        "log-action-filter-delete-delete_redir": "Sobreescritura de redirección",
        "log-action-filter-delete-restore": "Restauración de páxinas",
index f60d6be..f6f555e 100644 (file)
        "recentchanges-legend-newpage": "{{int:recentchanges-label-newpage}} ({{GENDER:|ראה|ראי|ראו}} גם את [[Special:NewPages|רשימת הדפים החדשים]])",
        "recentchanges-legend-plusminus": "(<em>±123</em>)",
        "recentchanges-submit": "הצגה",
+       "rcfilters-activefilters": "מסננים פעילים",
+       "rcfilters-search-placeholder": "סינון שינויים אחרונים (עיינו או התחילו להקליד)",
+       "rcfilters-invalid-filter": "מסנן בלתי־תקין",
+       "rcfilters-filterlist-title": "מסננים",
+       "rcfilters-filterlist-noresults": "לא נמצאו מסננים",
+       "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": "עורכים חדשים מאוד: פחות מ־10 עריכות ו־4 ימים של פעילות.",
+       "rcfilters-filter-userExpLevel-learner-label": "לומדים",
+       "rcfilters-filter-userExpLevel-learner-description": "יותר ימי פעילות ועריכות מ\"חדשים\", אבל פחות מ\"משתמשים מנוסים\".",
+       "rcfilters-filter-userExpLevel-experienced-label": "משתמשים מנוסים",
+       "rcfilters-filter-userExpLevel-experienced-description": "יותר מ־30 ימים של פעילות ו־500 עריכות.",
        "rcnotefrom": "להלן {{PLURAL:$5|השינוי שבוצע|השינויים שבוצעו}} מאז <strong>$3, $4</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": "אנא תקנו את האסימון ושלחו שוב",
        "pagelang-language": "שפה",
        "pagelang-use-default": "להשתמש בשפה הרגילה",
        "pagelang-select-lang": "בחירת שפה",
+       "pagelang-reason": "סיבה",
        "pagelang-submit": "שליחה",
+       "pagelang-nonexistent-page": "הדף $1 אינו קיים.",
+       "pagelang-unchanged-language": "הדף $1 כבר מוגדר לשפה $2.",
+       "pagelang-unchanged-language-default": "הדף $1 כבר מוגדר לשפת התוכן ההתחלתית של אתר הוויקי.",
+       "pagelang-db-failed": "בסיס הנתונים לא הצליח לשנות את שפת הדף.",
        "right-pagelang": "שינוי שפות של דפים",
        "action-pagelang": "לשנות את שפת הדף",
        "log-name-pagelang": "יומן שינוי שפה",
index ef65acd..456ba8d 100644 (file)
        "editusergroup": "{{GENDER:$1|सदस्य}} समूहों का संपादन करें",
        "editinguser": "सदस्य '''[[User:$1|$1]]''' $2 के अधिकार बदलें\n{{GENDER:$1|सदस्य}} के सदस्य अधिकार बदले जा रहे हैं <strong>[[User:$1|$1]]</strong> $2",
        "userrights-editusergroup": "सदस्य समूहों का संपादन करें",
+       "userrights-viewusergroup": "सदस्य समूह देखें",
        "saveusergroups": "{{GENDER:$1|सदस्य}} समूह सहेजें",
        "userrights-groupsmember": "निम्न {{PLURAL:$1|समूह|समूहों}} का सदस्य:",
        "userrights-groupsmember-auto": "निम्न {{PLURAL:$1|समूह|समूहों}} का अंतर्निहित सदस्य:",
        "action-userrights-interwiki": "अन्य विकियों पर सदस्य अधिकार बदलने",
        "action-siteadmin": "डाटाबेस को ताला लगाने या खोलने",
        "action-sendemail": "ई-मेल भेजने",
+       "action-editmyoptions": "अपनी पसंद संपादित करें",
        "action-editmywatchlist": "ध्यानसूची सम्पादित करने",
        "action-viewmywatchlist": "अपनी ध्यानसूची देखें",
        "action-viewmyprivateinfo": "अपनी व्यक्तिगत जानकारी देखने",
        "cant-move-to-user-page": "आपको किसी पन्नो को सदस्य पृष्ठ पर ले जाने की अनुमति नहीं है (सिवाय सदस्य उप पृष्ठ के)",
        "cant-move-category-page": "आपको श्रेणी प्रष्ठों को स्थानांतरित करने की अनुमति नहीं है।",
        "cant-move-to-category-page": "आपको किसी पृष्ठ को श्रेणी पृष्ठ पर स्थानांतरित करने की अनुमति नहीं है।",
+       "namespace-nosubpages": "\"$1\" नामस्थान उपपृष्ठ की अनुमति नहीं देता है।",
        "newtitle": "नया शीर्षक:",
        "move-watch": "ध्यान रखें",
        "movepagebtn": "नाम बदलें",
        "special-characters-title-minus": "ऋण चिह्न",
        "mw-widgets-dateinput-no-date": "कुछ चयनित नहीं",
        "mw-widgets-dateinput-placeholder-day": "DD-MM-YYYY",
+       "mw-widgets-mediasearch-noresults": "कोई परिणाम नहीं मिला",
        "mw-widgets-titleinput-description-new-page": "पृष्ठ अभी मौजूद नहीं है",
        "mw-widgets-titleinput-description-redirect": "$1 को अनुप्रेषित",
        "mw-widgets-categoryselector-add-category-placeholder": "श्रेणी जोड़ें...",
index 1517b0f..1e48a43 100644 (file)
        "editusergroup": "Učitaj suradničke skupine",
        "editinguser": "Promjena suradničkih prava {{GENDER:$1|suradnika|suradnice}} <strong>[[User:$1|$1]]</strong> $2",
        "userrights-editusergroup": "Uredi suradničke skupine",
-       "userrights-viewusergroup": "Pregled suradničkih skupinâ",
+       "userrights-viewusergroup": "Pregled suradničkih skupina",
        "saveusergroups": "Spremi {{GENDER:$1|suradničke}} grupe",
        "userrights-groupsmember": "Član:",
        "userrights-groupsmember-auto": "Uključeni član:",
index 30353f9..67500f2 100644 (file)
        "recentchanges-legend-heading": "<strong>Լեգենդ՝</strong>",
        "recentchanges-legend-newpage": "{{int:recentchanges-label-newpage}} (տես նաև՝  [[Special:NewPages|նոր էջերի ցանկ]])",
        "recentchanges-submit": "Ցույց տալ",
+       "rcfilters-filterlist-title": "Զտիչներ",
+       "rcfilters-filter-editsbyself-label": "Ձեր խմբագրումներ",
        "rcnotefrom": "Ստորև բերված են փոփոխությունները սկսած՝ '''$2''' (մինչև՝ '''$1''')։",
        "rclistfrom": "Ցույց տալ նոր փոփոխությունները սկսած $3 $2",
        "rcshowhideminor": "$1 չնչին խմբագրումները",
        "duration-centuries": "$1 {{PLURAL:$1|դար}}",
        "duration-millennia": "$1 {{PLURAL:$1|հազարամյակ}}",
        "expandtemplates": "Կաղապարների ընդարձակում",
+       "pagelang-nonexistent-page": "$1 էջը գոյություն չունի",
        "special-characters-group-latin": "Լատիներեն",
        "special-characters-group-latinextended": "Լատիներեն ընդլայնված",
        "special-characters-group-ipa": "IPA",
index 7430931..4d062a4 100644 (file)
        "recentchanges-legend-newpage": "{{int:recentchanges-label-newpage}} (vide etiam le [[Special:NewPages|lista de nove paginas]])",
        "recentchanges-legend-plusminus": "(''±123'')",
        "recentchanges-submit": "Monstrar",
+       "rcfilters-activefilters": "Filtros active",
+       "rcfilters-search-placeholder": "Filtrar le modificationes recente (naviga o comencia a scriber)",
+       "rcfilters-invalid-filter": "Filtro non valide",
+       "rcfilters-filterlist-title": "Filtros",
+       "rcfilters-filterlist-noresults": "Nulle filtro trovate",
+       "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-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-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-experienced-label": "Usatores con experientia",
+       "rcfilters-filter-userExpLevel-experienced-description": "Plus de 30 dies de activitate e 500 modificationes.",
        "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-url-label": "URL de requesta:",
        "apisandbox-request-time": "Duration del requesta: {{PLURAL:$1|$1 ms}}",
        "apisandbox-results-fixtoken": "Corrige le indicio e reinvia",
        "pagelang-use-default": "Usar lingua predefinite",
        "pagelang-select-lang": "Selige lingua",
        "pagelang-submit": "Submitter",
+       "pagelang-nonexistent-page": "Le pagina $1 non existe.",
+       "pagelang-unchanged-language": "Le pagina $1 es jam fixate sur le lingua $2.",
+       "pagelang-unchanged-language-default": "Le pagina $1 es jam fixate sur le lingua predefinite de contento del wiki.",
+       "pagelang-db-failed": "Le base de datos non ha potite cambiar le lingua del pagina.",
        "right-pagelang": "Cambiar lingua del pagina",
        "action-pagelang": "cambiar le lingua del pagina",
        "log-name-pagelang": "Registro de cambios de lingua",
index 41aa59c..b1faaef 100644 (file)
@@ -13,7 +13,8 @@
                        "לערי ריינהארט",
                        "아라",
                        "Macofe",
-                       "Robin van der Vliet"
+                       "Robin van der Vliet",
+                       "Algentem"
                ]
        },
        "tog-underline": "Sub-strekizez ligili:",
        "article": "artiklo",
        "newwindow": "(aparos en nova panelo)",
        "cancel": "Anular",
-       "moredotdotdot": "Plus...",
+       "moredotdotdot": "Plua...",
        "mypage": "Mea pagino",
        "mytalk": "Diskuti",
        "anontalk": "Diskuto relatant ad ica IP",
        "yourname": "Vua uzantonomo:",
        "yourpassword": "Pasovorto:",
        "yourpasswordagain": "Riskribez la pasovorto:",
+       "cannotlogin-title": "Ne povis enirar",
+       "cannotloginnow-title": "Ne povas enirar nun",
        "yourdomainname": "Vua domano:",
        "login": "Enirar",
-       "nav-login-createaccount": "Enirar",
+       "nav-login-createaccount": "Enirar / Krear konto",
        "userlogin": "Enirar / krear konto",
        "userloginnocreate": "Enirar",
        "logout": "Ekirar",
        "badretype": "La pasovorti vu donis ne esas sama.",
        "userexists": "La uzantonomo, quan vu skribis, ja selektesis antee.\nVoluntez, elektez ula diferanta uzantonomo.",
        "loginerror": "Eroro enirante",
+       "nocookiesnew": "L'uzero-konto esis kreita, ma vu ne esas eniranta.\n{{SITENAME}} uzas ''bisquiti'' por eniras uzeri.\n''Bisquiti'' esas desacendita.\nVoluntez acendar li, lore enirez per vua nova uzero e pasovorto.",
        "nocookieslogin": "{{SITENAME}} uzas ''cookies'' por la registrago dil uzanti. Vu havas la ''cookies'' desaktivigita. Voluntez aktivigar oli e probez altrafoye.",
        "noname": "Vu ne donis valida uzantonomo.",
        "loginsuccesstitle": "Eniro sucesoza",
        "preferences": "Preferaji",
        "mypreferences": "Preferaji",
        "prefs-edits": "Nombro di redaktaji:",
+       "prefsnologintext2": "Voluntez enirar por chanjar vua ajusti.",
        "prefs-skin": "Pelo",
        "skin-preview": "Pre-videz",
        "datedefault": "Sen prefero",
        "recentchanges-label-minor": "Ica es mikra redaktajo",
        "recentchanges-label-bot": "Ta chanjo facita da bot",
        "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",
        "notargettext": "Vu ne definis en qua pagino agar ica funciono.",
        "pager-newer-n": "{{PLURAL:$1|plu nova 1|plu nova $1}}",
        "pager-older-n": "{{PLURAL:$1|plu anciena 1|plu anciena $1}}",
+       "apihelp-no-such-module": "Modulo « $1 » ne esis trovita.",
+       "apisandbox-loading": "Charjas informo pri modulo « $1 » di API...",
        "booksources": "Fonti di libri",
        "booksources-search-legend": "Serchez librala fonti",
        "specialloguserlabel": "Uzanto:",
        "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-info": "Plua informo pri ca pagino",
        "tooltip-t-upload": "Adkargez arkivi",
        "tooltip-t-specialpages": "Montrez listo di omna specala pagini",
        "tooltip-t-print": "Imprimebla versiono di ca pagino",
        "tags-hitcount": "$1 {{PLURAL:$1|chanjo|chanji}}",
        "htmlform-reset": "Desfacar chanji",
        "htmlform-selectorother-other": "Altra",
+       "htmlform-cloner-create": "Adjuntar plue",
        "rightsnone": "(nula)",
        "revdelete-summary": "redakto-rezumo",
        "searchsuggest-search": "Serchez",
        "special-characters-group-greek": "Grekiana",
        "special-characters-group-cyrillic": "Kirila",
        "special-characters-group-arabic": "Arabiana",
-       "special-characters-group-persian": "Persiana"
+       "special-characters-group-persian": "Persiana",
+       "sessionprovider-nocookies": "''Bisquiti'' forsan esas desacendita. Certigez ke vu acendar ''bisquiti'' e riprobez."
 }
index ebf8ad7..c32f4a3 100644 (file)
        "api-error-badtoken": "Errore interno: token errato.",
        "api-error-blocked": "Sei stato bloccato, non puoi fare modifiche.",
        "api-error-copyuploaddisabled": "Il caricamento tramite URL è disabilitato su questo server.",
-       "api-error-duplicate": "Sul sito {{PLURAL:$1|c'è già un altro documento|ci sono già altri documenti}} con lo stesso contenuto.",
-       "api-error-duplicate-archive": "{{PLURAL:$1|C'era un altro file|C'erano altri file}} già nel sito con lo stesso contenuto, ma {{PLURAL:$1|è stato cancellato|sono stati cancellati}}.",
+       "api-error-duplicate": "{{PLURAL:$1|Esiste già un altro file|Esistono già altri file}} sul sito con lo stesso contenuto.",
+       "api-error-duplicate-archive": "{{PLURAL:$1|Esiste già un altro file|Esistono già altri file}} sul sito con lo stesso contenuto, ma {{PLURAL:$1|è stato cancellato|sono stati cancellati}}.",
        "api-error-empty-file": "Il file selezionato era vuoto.",
        "api-error-emptypage": "La creazione di nuove pagine vuote non è consentita.",
        "api-error-fetchfileerror": "Errore interno: si è verificato un problema durante il recupero del file.",
        "api-error-missingresult": "Errore interno: impossibile determinare se la copia è riuscita.",
        "api-error-mustbeloggedin": "Devi aver effettuato l'accesso per caricare i file.",
        "api-error-mustbeposted": "Errore interno: la richiesta richiede HTTP POST.",
-       "api-error-noimageinfo": "Il caricamento è riuscito, ma il server non ci ha dato alcuna informazione sul file.",
+       "api-error-noimageinfo": "Il caricamento è riuscito, ma il server non ci ha restituito alcuna informazione sul file.",
        "api-error-nomodule": "Errore interno: non è stato impostato il modulo di caricamento.",
        "api-error-ok-but-empty": "Errore interno: nessuna risposta dal server.",
        "api-error-overwrite": "Sovrascrivere un file esistente non è consentito.",
        "api-error-unclassified": "Si è verificato un errore sconosciuto.",
        "api-error-unknown-code": "Errore sconosciuto: \"$1\"",
        "api-error-unknown-error": "Errore interno: qualcosa è andato storto provando a caricare il file.",
-       "api-error-unknown-warning": "Avviso sconosciuto: $1",
+       "api-error-unknown-warning": "Avvertimento sconosciuto: \"$1\".",
        "api-error-unknownerror": "Errore sconosciuto: \"$1\".",
        "api-error-uploaddisabled": "Il caricamento è disabilitato su questa wiki.",
        "api-error-verification-error": "Questo file potrebbe essere danneggiato, o avere l'estensione sbagliata.",
        "pagelang-use-default": "Utilizza la lingua predefinita",
        "pagelang-select-lang": "Seleziona lingua",
        "pagelang-submit": "Invia",
+       "pagelang-nonexistent-page": "La pagina $1 non esiste.",
        "right-pagelang": "Modifica la lingua della pagina",
        "action-pagelang": "modificare la lingua della pagina",
        "log-name-pagelang": "Modifiche lingua",
index ed5ffde..44f19eb 100644 (file)
        "eauthentsent": "입력한 이메일로 확인 이메일을 보냈습니다.\n다른 모든 형태의 이메일을 당신의 계정으로 보내기 전에, 계정이 정말 당신의 것인지 확인하기 위해 이메일 내용의 지시대로 계정 확인 절차를 실행해 주셔야 합니다.",
        "throttled-mailpassword": "비밀번호 재설정 이메일을 이미 최근 {{PLURAL:$1|$1시간}} 안에 보냈습니다.\n악용을 방지하기 위해 비밀번호 재설정 메일은 {{PLURAL:$1|$1시간}}마다 오직 하나씩만 보낼 수 있습니다.",
        "mailerror": "메일을 보내는 중 오류: $1",
-       "acct_creation_throttle_hit": "당신의 IP 주소를 이용한 방문자가 $2에 이미 {{PLURAL:$1|계정 $1개}}를 만들어, 계정 만들기 한도를 초과하였습니다.\n따라서 지금은 이 IP 주소로는 더 이상 계정을 만들 수 없습니다.",
+       "acct_creation_throttle_hit": "당신의 IP 주소를 이용한 이 위키의 방문자가 $2에 {{PLURAL:$1|계정 $1개}}를 만들었으며, 이 기간 안에 허용되는 계정 만들기 한도를 초과하였습니다.\n따라서 지금 이 IP 주소를 사용하는 방문자는 더 이상 계정을 만들 수 없습니다.",
        "emailauthenticated": "이메일 주소가 $2 $3에 인증되었습니다.",
        "emailnotauthenticated": "이메일 주소를 인증하지 않았습니다.\n이메일 확인 절차를 거치지 않으면 다음 이메일 기능을 사용할 수 없습니다.",
        "noemailprefs": "이 기능을 사용하려면 사용자 환경 설정에서 이메일 주소를 지정하세요.",
        "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-no-provider": "'BotPasswordsSessionProvider'는 이용할 수 없습니다.",
        "botpasswords-restriction-failed": "봇 비밀번호 제한으로 인해 로그인할 수 없습니다.",
        "botpasswords-invalid-name": "지정된 사용자 이름은 봇 비밀번호 구분자(\"$1\")를 포함하고 있지 않습니다.",
        "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이고, 차단 ID는 #$5입니다.\n문의할 때에 이 정보를 같이 알려주세요.",
        "autoblockedtext": "당신의 IP 주소는 $1님이 차단한 사용자가 사용했던 IP이기 때문에 자동으로 차단되었습니다.\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이고, 차단 ID는 #$5입니다.\n문의할 때에 이 정보를 같이 알려주세요.",
+       "systemblockedtext": "당신의 사용자 이름 또는 IP 주소가 자동으로 미디어위키에 의해 차단되었습니다.\n이유는 다음과 같습니다:\n\n:<em>$2</em>\n\n* 차단 시작: $8\n* 차단 만료: $6\n* 차단 대상: $7\n\n당신의 현재 IP 주소는 $3입니다.\n문의에 대해 상기의 상세 설명을 모두 포함해 주십시오.",
        "blockednoreason": "이유를 입력하지 않음",
        "whitelistedittext": "문서를 편집하기 전에 $1해야 합니다.",
        "confirmedittext": "문서를 고치려면 이메일 인증 절차가 필요합니다.\n[[Special:Preferences|사용자 환경 설정]]에서 이메일 주소를 입력하고 이메일 주소 인증을 해주시기 바랍니다.",
        "userrights-user-editname": "사용자 이름 입력:",
        "editusergroup": "사용자 그룹 불러오기",
        "editinguser": "<strong>[[User:$1|$1]]</strong> $2 {{GENDER:$1|사용자}}의 권한 바꾸기",
+       "viewinguserrights": "<strong>[[User:$1|$1]]</strong> $2 {{GENDER:$1|사용자}}의 권한을 보는 중",
        "userrights-editusergroup": "사용자 그룹 편집",
        "userrights-viewusergroup": "사용자 그룹 보기",
        "saveusergroups": "{{GENDER:$1|사용자}} 권한 저장",
        "action-deletedtext": "삭제된 판의 문자열 보기",
        "action-browsearchive": "삭제된 문서 검색",
        "action-undelete": "문서 되살리기",
-       "action-suppressrevision": "ì\9d´ ì\88¨ê²¨ì§\84 í\8c\90ì\9d\84 ê²\80í\86 í\95\98ê³  ë³µêµ¬í\95\98기",
+       "action-suppressrevision": "숨겨진 판을 검토하고 복구하기",
        "action-suppressionlog": "비공개 기록 보기",
        "action-block": "이 사용자가 편집하지 못하도록 차단",
        "action-protect": "이 문서의 보호 설정을 바꾸기",
        "recentchanges-legend-newpage": "{{int:recentchanges-label-newpage}} ([[Special:NewPages|새 문서 목록]]도 보세요)",
        "recentchanges-legend-plusminus": "(<em>±123</em>)",
        "recentchanges-submit": "보기",
+       "rcfilters-activefilters": "사용 중인 필터",
+       "rcfilters-search-placeholder": "필터 최근 바뀜 (찾아보거나 입력을 시작하십시오)",
+       "rcfilters-invalid-filter": "유효하지 않은 필터",
+       "rcfilters-filterlist-title": "필터",
+       "rcfilters-filterlist-noresults": "필터를 찾을 수 없습니다",
+       "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개 이상의 편집.",
        "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-url-label": "요청 URL:",
        "apisandbox-request-time": "요청 처리 시간: {{PLURAL:$1|$1 ms}}",
        "apisandbox-results-fixtoken": "토큰 수정 후 다시 제출",
        "cant-move-to-user-page": "문서를 사용자 문서로 이동할 권한이 없습니다 (하위 문서는 예외).",
        "cant-move-category-page": "분류 문서를 이동할 권한이 없습니다.",
        "cant-move-to-category-page": "문서를 분류 문서로 이동할 권한이 없습니다.",
+       "cant-move-subpages": "하위 문서를 이동할 권한이 없습니다.",
+       "namespace-nosubpages": "\"$1\" 이름공간은 하위 문서를 허용하지 않습니다.",
        "newtitle": "새 제목:",
        "move-watch": "원래 문서와 대상 문서를 주시하기",
        "movepagebtn": "문서 이동",
        "htmlform-date-placeholder": "YYYY-MM-DD",
        "htmlform-time-placeholder": "HH:MM:SS",
        "htmlform-datetime-placeholder": "YYYY-MM-DD HH:MM:SS",
+       "htmlform-date-invalid": "지정한 값은 인식할 수 있는 날짜가 아닙니다. YYYY-MM-DD 형식을 사용하세요.",
+       "htmlform-time-invalid": "지정한 값은 인식할 수 있는 시간이 아닙니다. HH:MM:SS 형식을 사용하세요.",
+       "htmlform-datetime-invalid": "지정한 값은 인식할 수 있는 날짜 및 시간이 아닙니다. YYYY-MM-DD HH:MM:SS 형식을 사용하세요.",
        "htmlform-title-badnamespace": "[[:$1]] 문서는 \"{{ns:$2}}\" 이름공간에 없습니다.",
        "htmlform-title-not-creatable": "\"$1\"은 만들 수 없는 문서 제목입니다.",
        "htmlform-title-not-exists": "$1 문서는 존재하지 않습니다.",
        "api-error-missingresult": "내부 오류: 파일의 복제가 성공했는지 판단할 수 없습니다.",
        "api-error-mustbeloggedin": "파일을 올리려면 로그인해야 합니다.",
        "api-error-mustbeposted": "내부 오류: HTTP POST에 요청이 필요합니다.",
-       "api-error-noimageinfo": "파일 올리기는 성공했지만 서버가 파일에 대해 어떠한 정보도 주지 않았습니다.",
+       "api-error-noimageinfo": "업로드는 성공했지만 서버가 파일에 대해 어떠한 정보도 제공하지 않았습니다.",
        "api-error-nomodule": "내부 오류: 올리기 모듈이 설정되지 않았습니다.",
        "api-error-ok-but-empty": "내부 오류: 서버에서 응답이 없습니다.",
        "api-error-overwrite": "이미 있는 파일을 덮어쓸 수 없습니다.",
        "api-error-stashnotloggedin": "파일을 업로드하기 위해 로그인이 필요합니다.",
        "api-error-stashwrongowner": "저장된 임시 저장소에 존재하는 파일에 접근할 권한이 없습니다.",
        "api-error-stashnosuchfilekey": "미공개 위치에 접근을 시도한 파일 키는 존재하지 않습니다.",
-       "api-error-timeout": "ì\84\9cë²\84ê°\80 ì \9c ì\8b\9cê°\84 ë\82´ì\97\90 ì\9d\91ë\8bµí\95\98ì§\80 ì\95\8aì\95\98ì\8aµë\8b\88ë\8b¤.",
+       "api-error-timeout": "ì\84\9cë²\84ê°\80 ì\98\88측ë\90\9c ì\8b\9cê°\84 ë\82´ì\97\90 ì\9d\91ë\8bµí\95\98ì§\80 ì\95\8aì\95\98ì\8aµë\8b\88ë\8b¤.",
        "api-error-unclassified": "알 수 없는 오류가 발생했습니다.",
        "api-error-unknown-code": "알 수 없는 오류: \"$1\"",
        "api-error-unknown-error": "내부 오류: 파일을 올리려 하는 도중에 무엇인가가 잘못되었습니다.",
-       "api-error-unknown-warning": "알 수 없는 경고: \"$1\"",
+       "api-error-unknown-warning": "알 수 없는 경고: \"$1\".",
        "api-error-unknownerror": "알 수 없는 오류: \"$1\"",
        "api-error-uploaddisabled": "이 위키에서 파일 올리기가 비활성화되어 있습니다.",
        "api-error-verification-error": "파일이 손상되었거나 잘못된 확장자를 사용하고 있습니다.",
        "pagelang-use-default": "기본 언어 사용",
        "pagelang-select-lang": "언어 선택",
        "pagelang-submit": "제출",
+       "pagelang-nonexistent-page": "$1 문서가 존재하지 않습니다.",
+       "pagelang-unchanged-language": "$1 문서는 이미 $2 언어로 설정되어 있습니다.",
+       "pagelang-unchanged-language-default": "$1 문서는 이미 위키의 기본 콘텐츠 언어로 설정되어 있습니다.",
+       "pagelang-db-failed": "데이터베이스가 문서 언어 변경에 실패했습니다.",
        "right-pagelang": "문서 언어 바꾸기",
        "action-pagelang": "문서 언어 바꾸기",
        "log-name-pagelang": "언어 바꾸기 기록",
        "sessionprovider-nocookies": "브라우저의 쿠키 기능이 꺼져 있는지 확인하십시오. 쿠키 기능을 켠 다음 다시 시작해야 합니다.",
        "randomrootpage": "임의 루트 페이지",
        "log-action-filter-block": "차단의 유형:",
-       "log-action-filter-contentmodel": "콘텐츠 모델 수정 분류:",
+       "log-action-filter-contentmodel": "콘텐츠 모델 변경 분류:",
        "log-action-filter-delete": "삭제 종류:",
        "log-action-filter-import": "가져오기 종류:",
        "log-action-filter-managetags": "태그 관리 동작 종류:",
        "log-action-filter-block-reblock": "차단 변경",
        "log-action-filter-block-unblock": "차단 해제",
        "log-action-filter-contentmodel-change": "콘텐츠 모델 변경",
-       "log-action-filter-contentmodel-new": "비표준 콘텐츠 모델 문서 생성",
+       "log-action-filter-contentmodel-new": "기본이 아닌 콘텐츠 모델 문서 생성",
        "log-action-filter-delete-delete": "문서 삭제",
+       "log-action-filter-delete-delete_redir": "넘겨주기 덮어쓰기",
        "log-action-filter-delete-restore": "문서 복구",
        "log-action-filter-delete-event": "로그 삭제",
        "log-action-filter-delete-revision": "판 삭제",
index dcc8529..ff6e09a 100644 (file)
        "previewnote": "'''Ji bîr neke ku ev tenê pêşdîtinek e.'''\nGuhertinên te hê nehatine tomarkirin!",
        "continue-editing": "Here qada sazandinê",
        "editing": "$1 tê guherandin",
-       "creating": "$1 tê çêkirin",
+       "creating": "\"$1\" tê çêkirin",
        "editingsection": "Tê guherandin: $1 (beş)",
        "editingcomment": "$1 (beşek nû) tê guherandin.",
        "editconflict": "Têkçûna guherandinan: $1",
        "shown-title": "Li her rûpelê $1 {{PLURAL:$1|encam|encaman}} nîşan bide",
        "viewprevnext": "($1 {{int:pipe-separator}} $2) ($3) nîşan bide",
        "searchmenu-exists": "'''Rûpeleke bi navê \"[[:$1]]\" li ser vê wîkiyê heye.'''",
-       "searchmenu-new": "<strong>Rûpela \"[[:$1]]\" çêke!</strong>{{PLURAL:$2|0=|See also the page found with your search.|Herwiha li encamên hatiye dîtin jî binêre.}}",
+       "searchmenu-new": "<strong>Rûpela \"[[:$1]]\" çêke!</strong> {{PLURAL:$2|0=|Herwiha li encama hatiye dîtin jî binêre.|Herwiha li encamên hatine dîtin jî binêre.}}",
        "searchprofile-articles": "Rûpelên naverokê",
        "searchprofile-images": "Multîmedya",
        "searchprofile-everything": "Her tişt",
index 6c8208a..5fe5262 100644 (file)
        "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.",
        "cant-move-to-user-page": "Dir hutt net d'Recht fir eng Säit op eng Benotzersäit (ausser op eng Ënnersäit vun enger Benotzersäit) ze réckelen.",
        "cant-move-category-page": "Dir hutt net déi néideg Rechter fir Kategorie-Säiten ze réckelen.",
        "cant-move-to-category-page": "Dir hutt net déi néideg Rechter fir eng Säit op eng Kategoriesäit ze réckelen.",
+       "cant-move-subpages": "Dir hutt net d'Recht fir Ënnersäiten ze réckelen.",
        "newtitle": "Neien Titel:",
        "move-watch": "Dës Säit iwwerwaachen",
        "movepagebtn": "Säit réckelen",
        "bad_image_list": "Format:\n\nNëmmen Zeilen, déi mat engem * ufänken, ginn ausgewäert. Als éischt no dem * muss ee Link op een net gewënscht Bild stoen.\nDuerno sti Linken déi Ausnamen definéieren, an deenen hirem Kontext dat Bild awer opdauchen däerf.",
        "metadata": "Metadaten",
        "metadata-help": "An dësem Fichier si weider Informatiounen, déi normalerweis vun der Digitalkamera oder dem benotzte Scanner kommen. Wann de Fichier nodréiglech geännert gouf, kann et sinn datt eenzel Detailer net mat dem aktuelle Fichier iwwereneestëmmen.",
-       "metadata-expand": "Weis detailléiert Informatiounen",
-       "metadata-collapse": "Verstopp detailléiert Informatiounen",
+       "metadata-expand": "Detailléiert Informatioune weisen",
+       "metadata-collapse": "Detailléiert Informatioune verstoppen",
        "metadata-fields": "D'Bild-Meta-Felder aus dëser Lëscht ginn op Bildbeschreiwungssäite gewise wann d'Metadatentafel zesummegeklappt ass.\nDéi aner sinn am Standard verstoppt.\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": "Breet",
        "exif-imagelength": "Längt",
index b60a85c..97a2fd2 100644 (file)
        "faq": "ຄຳຖາມທີ່ພົບເລື້ອຍໆ",
        "faqpage": "Project:ຄຳຖາມທີ່ພົບເລື້ອຍໆ",
        "actions": "ການກະທຳ",
-       "namespaces": "à»\80àº\99ມສະà»\80àº\9bດ",
+       "namespaces": "àº\8aືà»\88àº\82ອàº\9aà»\80àº\82ດ",
        "variants": "ຄວາມແຕກຕ່າງ",
        "navigation-heading": "ລາຍການການນຳທາງ",
        "errorpagetitle": "ຂໍ້ຜິດພາດ",
        "nosuchspecialpage": "ບໍ່ມີໝ້າພິເສດດັ່ງກ່າວ",
        "error": "ຂໍ້ຜິດພາດ",
        "databaseerror": "ມີຂໍ້ຜິດພາດກ່ຽວກັບຖານຂໍ້ມູນ",
+       "databaseerror-error": "ຂໍ້ຜິດພາດ: $1",
        "laggedslavemode": "<strong>ຄຳເຕືອນ:</strong> ໜ້ານີ້ອາດຈະບໍ່ລວມຂໍ້ມູນລ້າສຸດ.",
        "readonly": "ຖານຂໍ້ມູນຖືກລັອກ",
        "enterlockreason": "ກະລຸນາຂຽນເຫດຜົນໃນການລັອກ, ລວມທັງປະມານເວລາທີ່ຈະປົດລັອກ",
        "directoryreadonlyerror": "ໄດເຣກທໍຣີ \"$1\" ສາມາດອ່ານໄດ້ເທົ່ານັ້ນ.",
        "directorynotreadableerror": "ໄດເຣກທໍຣີ \"$1\" ບໍ່ສາມາດອ່ານໄດ້.",
        "filenotfound": "ບໍ່ພົບໄຟລ໌ \"$1\".",
+       "formerror": "ຂໍ້ຜິດພາດ: ບໍ່ສາມາດສົ່ງແບບຟອມໄດ້.",
        "badarticleerror": "ບໍ່ສາມາດດຳເນີນການນີ້ຢູ່ເທິງໜ້ານີ້ໄດ້.",
        "cannotdelete": "ບໍ່ສາມາດລຶບໜ້າຫຼືໄຟລ໌ \"$1\" ໄດ້.\nມັນອາດຈະຖືກລຶບໂດຍໃຜຜູ້ໜຶ່ງແລ້ວ.",
        "cannotdelete-title": "ບໍ່ສາມາດລຶບໜ້າ \"$1\" ໄດ້",
        "myprivateinfoprotected": "ທ່ານບໍ່ໄດ້ຮັບອະນຸຍາດໃຫ້ແກ້ໄຂໜ້າຂໍ້ມູນສ່ວນບຸກຄົນຂອງທ່ານ.",
        "mypreferencesprotected": "ທ່ານບໍ່ໄດ້ຮັບອະນຸຍາດໃຫ້ແກ້ໄຂການຕັ້ງຄ່າຂອງທ່ານ.",
        "ns-specialprotected": "ບໍ່ສາມາດແກ້ໄຂໜ້າພິເສດໄດ້.",
+       "invalidtitle-knownnamespace": "ຊື່ເລື່ອງທີ່ມີຂອບເຂດຊື່ \"$2\" ແລະຂໍ້ຄວາມ \"$3\" ບໍ່ຖືກຕ້ອງ",
+       "invalidtitle-unknownnamespace": "ຊື່ເລື່ອງທີ່ມີຂອບເຂດຊື່ໝາຍເລກ $1 ແລະຂໍ້ຄວາມ \"$2\"",
        "exception-nologin": "ບໍ່ໄດ້ເຂົ້າສູ່ລະບົບ",
        "exception-nologin-text": "ກະລຸນາເຂົ້າສູ່ລະບົບເພື່ອໃຫ້ສາມາດເຂົ້າເບິ່ງ ຫຼື ດຳເນີນການໃດໆກັບໜ້ານີ້ໄດ້.",
        "exception-nologin-text-manual": "ກະລຸນາ $1 ເພື່ອໃຫ້ສາມາດເຂົ້າເບິ່ງ ຫຼື ດຳເນີນການໃດໆກັບໜ້ານີ້ໄດ້.",
        "wrongpassword": "ລະຫັດຜ່ານບໍ່ຖືກ. ກະລຸນາເຮັດຄືນໃໝ່.",
        "wrongpasswordempty": "ບໍ່ມີລະຫັດຜ່ານຖືກພິມເຂົ້າ. ກະລຸນາເຮັດຄືນໃໝ່.",
        "mailmypassword": "ຕັ້ງຄ່າລະຫັດຜ່ານໃໝ່",
+       "blocked-mailpassword": "ທີ່ຢູ່ IP ຂອງທ່ານໄດ້ຖືກບລັອກບໍ່ໃຫ້ແກ້ໄຂ. ເພື່ອເປັນການປ້ອງກັນການໃຊ້ງານໃນທາງທີ່ຜິດ, ຈຶ່ງບໍ່ອະນຸຍາດໃຫ້ໃຊ້ການກູ້ຄືນລະຫັດຜ່ານໂດຍໃຊ້ທີ່ຢູ່ IP ນີ້.",
        "acct_creation_throttle_hit": "ຂໍໂທດຫຼາຍໆ, ທ່ານ ໄດ້ສ້າງ $1 ບັນຊີແລ້ວ. ທ່ານ ບໍ່ສາມາດ ສ້ງບັນຊີໄດ້ອີກ.",
        "emailauthenticated": "ອີເມລຂອງທ່ານໄດ້ຖືກຢືນຢັນແລ້ວເມື່ອວັນທີ່ $2 ເວລາ $3.",
        "emailconfirmlink": "ຢືນຢັນ ທີ່ຢູ່ ອີເມລ ຂອງ ທ່ານ",
        "accountcreated": "ບັນຊີ ໄດ້ຖືກສ້າງ ແລ້ວ",
-       "accountcreatedtext": "ບັນຊີ ຂອງ  $1 ໄດ້ ຖືກສ້າງແລ້ວ.",
+       "accountcreatedtext": "ບັນຊີຜູ້ໃຊ້ຂອງ [[{{ns:User}}:$1|$1]] ([[{{ns:User talk}}:$1|talk]]) ໄດ້ຖືກສ້າງຂຶ້ນແລ້ວ.",
        "pt-login": "ເຂົ້າສູ່ລະບົບ",
        "pt-createaccount": "ສ້າງບັນຊີ",
        "changepassword": "ປ່ຽນລະຫັດຜ່ານ",
        "newpassword": "ລະຫັດຜ່ານໃໝ່:",
        "retypenew": "ພິມລະຫັດຜ່ານໃໝ່ອີກ:",
        "resetpass_submit": "ຕັ້ງລະຫັດຜ່ານ ແລະ ເຊັນເຂົ້າ",
-       "changepassword-success": "ສຳà»\80ລັàº\94àº\81າàº\99àº\9bà»\88ຽàº\99à»\81àº\9bàº\87 àº¥àº°àº«àº±àº\94àº\9cà»\88າàº\99àº\82ອàº\87àº\97à»\88າàº\99à»\81ລà»\89ວ! àº\94ຽວàº\99ີà»\89 àº\97à»\88າàº\99 à»\80àº\8aັà»\88àº\99à»\80àº\82ົà»\89າ à»\83àº\99 ...",
+       "changepassword-success": "ລະຫັàº\94àº\9cà»\88າàº\99àº\82ອàº\87àº\97à»\88າàº\99àº\96ືàº\81àº\9bà»\88ຽàº\99à»\81ລà»\89ວ!",
        "passwordreset-invalidemail": "ທີ່ຢູ່ອີເມລບໍ່ຖືກຕ້ອງ",
        "bold_sample": "ໂຕໜັງສືເຂັ້ມ",
        "bold_tip": "ໂຕໜັງສືເຂັ້ມ",
        "preview": "ລອງເບິ່ງຜົນ",
        "showpreview": "ລອງເບິ່ງຜົນ",
        "showdiff": "ສະແດງສ່ວນຕ່າງ",
-       "anoneditwarning": "'''ເຕືອນ:''' ທ່ານ ບໍ່ໄດ້ເຊັນເຂົ້າ. ທີ່ຢູ່ IP ຂອງ ທ່ານ ຈະຖືກບັນທຶກໄວ້ ໃນ ປະຫວັດການດັດແກ້ ຂອງ ໜ້ານີ້.",
+       "anoneditwarning": "<strong>ເຕືອນ:</strong> ທ່ານບໍ່ໄດ້ເຂົ້າສູ່ລະບົບ. ທຸກໆຄົນຈະເຫັນທີ່ຢູ່ IP ຂອງທ່ານ ຖ້າທ່ານເຮັດການແກ້ໄຂໃດໆ. ຖ້າທ່ານ<strong>[$1 ເຂົ້າສູ່ລະບົບ]</strong> ຫຼື <strong>[$2 ສ້າງບັນຊີ]</strong>, ການແກ້ໄຂຂອງທ່ານຈະຖືວ່າແມ່ນຂອງຜູ້ໃຊ້ຄົນນັ້ນແທນ, ນອກຈາກນີ້ ຍັງມີປະໂຫຍດອື່ນໆອີກຫຼາຍຢ່າງນຳກັນ.",
        "blockedtitle": "ຜູ້ໃຊ້ຖືກຫ້າມ",
        "whitelistedittext": "ທ່ານ ຈະຕ້ອງ  $1 ເພື່ອ ຈະດັດແກ້.",
        "loginreqtitle": "ຈຳເປັນຕ້ອງ ເຊັນເຂົ້າ",
        "accmailtext": "ລະຫັດຜ່ານ ຂອງ \"$1\" ໄດ້ຖືກສົ່ງໄປ  $2 ແລ້ວ.",
        "newarticle": "(ໃໝ່)",
        "newarticletext": "ທ່ານ ໄດ້ມາຮອດ ໜ້າທີ່ຍັງບໍ່ໄດ້ຖືກສ້າງຂຶ້ນເທື່ອ. ທ່ານ ສາມາດເລີ່ມ ສ້າງໜ້າ ໂດຍ ພິມໃສ່ ກັບ ຂ້າງລຸ່ມ.(ເບິ່ງລາຍລະອຽດຕື່ມ ທີ່ [$1 ໜ້າຊ່ວຍເຫຼືອ]).\nຖ້າ ທ່ານ ມາຮອດນີ້ ໂດຍຄວາມຜິດພາດ, ກະລຸນາ ກົດ ປຸ່ມ '''ກັບຄືນ''', ຢູ່ ໂປຣແກຣມ ທ່ອງເວັບ ຂອງທ່ານ.",
-       "noarticletext": "àº\8dັàº\87àº\9aà»\8dà»\88ມີà»\80àº\99ືà»\89ອà»\83àº\99 àº¢àº¹à»\88 à»\9cà»\89າàº\99ີà»\89, àº\97à»\88າàº\99ສາມາàº\94 [[Special:Search/{{PAGENAME}}|àº\84ົà»\89àº\99ຫາà»\9cà»\89າຫົວàº\82à»\8dà»\89àº\99ີà»\89]] àº«àº¼àº· [{{fullurl:{{FULLPAGENAME}}|action=edit}} àº\94ັàº\94à»\81àº\81à»\89ໜ້ານີ້].",
-       "previewnote": "'''ນີ້ ແມ່ນ ການລອງເບິ່ງຜົນເທົ່ານັ້ນ; ການດັດແກ້ຍັງບໍ່ທັນຖືກບັນທຶກ!'''",
+       "noarticletext": "àº\95ອàº\99àº\99ີà»\89à»\9cà»\89າàº\99ີà»\89àº\8dັàº\87àº\9aà»\8dà»\88ມີà»\80àº\99ືà»\89ອà»\83àº\99à»\83àº\94à»\86, àº\97à»\88າàº\99ສາມາàº\94[[Special:Search/{{PAGENAME}}|àº\84ົà»\89àº\99ຫາà»\9cà»\89າຫົວàº\82à»\8dà»\89àº\99ີà»\89]]à»\83àº\99à»\9cà»\89າອືà»\88àº\99à»\86, <span class=\"plainlinks\">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} àº\84ົà»\89àº\99ຫາàº\9aັàº\99àº\97ຶàº\81ອືà»\88àº\99à»\86àº\97ີà»\88àº\81à»\88ຽວàº\82à»\89ອàº\87], àº«àº¼àº· [{{fullurl:{{FULLPAGENAME}}|action=edit}} àºªà»\89າàº\87ໜ້ານີ້].",
+       "previewnote": "<strong>ຈຳໄວ້ວ່ານີ້ແມ່ນພຽງການສະແດງໂຕຢ່າງເທົ່ານັ້ນ.</strong>\nການແກ້ໄຂຂອງທ່ານຍັງບໍ່ທັນຖືກບັນທຶກ!",
        "editing": "ພວມດັດແກ້ $1",
        "editingsection": "ພວມດັດແກ້ $1 (ພາກ)",
        "yourtext": "ເນື້ອໃນ",
        "page_first": "ທຳອິດ",
        "page_last": "ສຸດທ້າຍ",
        "histlegend": "ເລືອກສ່ວນຕ່າງ: ເລືອກກັບວົງມົນ ລະຫວ່າງສະບັບ ຢາກສົມທຽບ ແລ້ວ ກົດເອັນເຕີ ຫຼື ປຸ່ນຢູ່ທາງລຸ່ມ.<br />\nຄວາມໝາຍ: (ດຽວນີ້) = ສ່ວນຕ່າງສົມທຽບໃສ່ສະບັບດຽວນີ້,\n(ຫຼ້າສຸດ) = ສ່ວນຕ່າງສົມທຽບໃສ່ສະບັບກ່ອນໜ້ານີ້, M = ດັດແກ້ເລັກນ້ອຍ.",
-       "histfirst": "àº\97ຳອິດ",
-       "histlast": "ຫຼà»\89າສຸດ",
+       "histfirst": "à»\80àº\81ົà»\88າສຸດ",
+       "histlast": "à»\83à»\9dà»\88ສຸດ",
        "rev-delundel": "ສະແດງ/ເຊື່ອງ",
-       "history-title": "àº\9bະຫວັàº\94àº\81າàº\99àº\94ັàº\94à»\81àº\81à»\89 ຂອງ \"$1\"",
+       "history-title": "àº\9bະຫວັàº\94àº\81າàº\99à»\81àº\81à»\89à»\84àº\82ຂອງ \"$1\"",
        "lineno": "ແຖວ $1:",
        "compareselectedversions": "ສົມທຽບ ລະຫວ່າງ ສະບັບເລືອກ",
        "editundo": "ກັບຄືນ",
+       "searchresults": "ຜົນການຄົ້ນຫາ",
+       "searchresults-title": "ຜົນການຄົ້ນຫາສຳລັບ \"$1\"",
        "prevn": "{{PLURAL:$1|$1}} ກ່ອນໜ້າ",
        "nextn": "{{PLURAL:$1|$1}} ຕໍ່ໄປ",
+       "shown-title": "ສະແດງ{{PLURAL:$1|ຜົນທີ່ໄດ້ຮັບ}} $1 ລາຍການຕໍ່ໜຶ່ງໜ້າ",
        "viewprevnext": "ເບິ່ງ ($1 {{int:pipe-separator}} $2) ($3).",
        "search-result-size": "$1 ({{PLURAL:$2|1 ຄຳ|$2 ຄຳ}})",
-       "search-redirect": "(à»\82ອàº\99 $1)",
+       "search-redirect": "(àº\9bà»\88ຽàº\99à»\80ສັà»\89àº\99àº\97າàº\87ມາàº\88າàº\81 $1)",
        "search-relatedarticle": "ກ່ຽວຂ້ອງ",
        "searchrelated": "ກ່ຽວຂ້ອງ",
        "searchall": "ທັງໜົດ",
        "showingresults": "ສະແດງທາງລຸ່ມ ຮອດ {{PLURAL:$1|'''1''' ຜົນ|'''$1''' ຜົນ}} ເລີ່ມຈາກ  #'''$2'''.",
        "preferences": "ການຕັ້ງຄ່າ",
-       "mypreferences": "ຕັ້ງຄ່າ",
+       "mypreferences": "àº\81າàº\99àº\95ັà»\89àº\87àº\84à»\88າ",
        "prefs-edits": "ຈຳນວນການດັດແກ້:",
        "prefs-skin": "ລວດລາຍ",
        "skin-preview": "ລອງເບິ່ງ",
        "columns": "ຖັນ:",
        "searchresultshead": "ຊອກຫາ",
        "recentchangesdays": "ຈຳນວນມື້ສະແດງໃນການປ່ຽນແປງຫຼ້າສຸດ:",
-       "recentchangescount": "àº\88ຳàº\99ວàº\99àº\81າàº\99àº\94ັàº\94à»\81àº\81à»\89ສະà»\81àº\94àº\87à»\83àº\99àº\81າàº\99àº\9bà»\88ຽàº\99à»\81àº\9bàº\87ຫຼà»\89າສຸàº\94:",
+       "recentchangescount": "àº\88ຳàº\99ວàº\99àº\81າàº\99à»\81àº\81à»\89à»\84àº\82àº\97ີà»\88àº\95à»\89ອàº\87àº\81າàº\99ສະà»\81àº\94àº\87à»\82àº\94àº\8dàº\9bະລິàº\8dາàº\8d:",
        "savedprefs": "ການຕັ້ງຄ່າຂອງທ່ານໄດ້ຖືກບັນທຶກແລ້ວ.",
-       "timezonelegend": "ເຂດເວລາ",
-       "localtime": "ເວລາທ້ອງຖິ່ນ",
-       "servertime": "ເວລາເຊີເວີ",
+       "timezonelegend": "ເຂດເວລາ:",
+       "localtime": "ເວລາທ້ອງຖິ່ນ:",
+       "servertime": "ເວລາເຊີເວີ:",
        "guesstimezone": "ເອົາເວລາຈາກໂປຣແກຣມທ່ອງເວັບ",
        "allowemail": "ອະນຸຍາດ ໃຫ້ຜູ້ໃຊ້ອື່ນ ສົ່ງອີເມລຫາຂ້ອຍ",
        "prefs-files": "ໄຟລ໌",
        "youremail": "ອີເມລ *:",
-       "username": "ຊື່ຜູ້ໃຊ້:",
+       "username": "{{GENDER:$1|ຊື່ຜູ້ໃຊ້}}:",
        "yourrealname": "ຊື່ແທ້ *:",
        "yourlanguage": "ພາສາ:",
        "yournick": "ຊື່ຫຼິ້ນ:",
        "filehist-dimensions": "ມິຕິ",
        "filehist-filesize": "ຂະໜາດໄຟລ໌",
        "filehist-comment": "ຄຳເຫັນ",
-       "imagelinks": "ລິà»\89àº\87àº\84໌",
-       "linkstoimage": "ລິ້ງຄ໌ຕໍ່ໄປນີ້ເຊື່ອມຕໍ່ຫາໄຟລ໌:",
+       "imagelinks": "àº\81າàº\99à»\83àº\8aà»\89à»\84àº\9fລ໌",
+       "linkstoimage": "{{PLURAL:$1|ໜ້າຕໍ່ໄປນີ້ເຊື່ອມໂຍງ|$1 ໜ້າຕໍ່ໄປນີ້ເຊື່ອມໂຍງ}}ຫາໄຟລ໌ນີ້:",
        "nolinkstoimage": "ບໍ່ມີໜ້າໃດ ລິ້ງຄ໌ ຫາ ໄຟລ໌ນີ້.",
        "sharedupload": "ໄຟລ໌ນີ້ແມ່ນການອັບໂຫຼດຣ່ວມ ແລະ ອາດຖືກໃຊ້ໂດຍໂຄງການອື່ນໆ.",
        "listredirects": "ລາຍການການໂອນໜ້າ",
        "undeletepagetext": "ໜ້າຕ່ອໄປນີ້ຖຶກລຶບໄປແຕ່ຍັງຄົງຢູ່ໃນກຸທີ່ສາມາດຮຽກຄືນໄດ້ (ກຸຂໍ້ມູນອາດຖຶກລຶບເປັນລະຍະ)",
        "cannotundelete": "ບໍ່ສາມາດ ກັບຄືນ ຫາສະບັບກ່ອນການລຶບ; ບາງຄົນອາດເຮັດກ່ອນແລ້ວ.",
        "undelete-search-submit": "ຊອກຫາ",
-       "namespace": "àº\82ອàº\9aà»\80àº\82àº\94àº\8aືà»\88:",
+       "namespace": "àº\8aືà»\88àº\82ອàº\9aà»\80àº\82àº\94:",
        "blanknamespace": "(ຫຼັກ)",
        "contributions": "ການປະກອບສ່ວນ",
        "mycontris": "ປະກອບສ່ວນ",
        "ipblocklist": "ລາຍການ ທີ່ຢູ່ IP ແລະ ຊື່ຜູ້ໃຊ້ ທີ່ຖືກຫ້າມ",
        "blocklink": "ຫ້າມ",
        "contribslink": "ເລື່ອງທີ່ຂຽນ",
-       "autoblocker": "ຫà»\89າມà»\82àº\94àº\8dອັàº\94àº\95າà»\82àº\99ມັàº\94 àº\8dà»\89ອàº\99 àº\97ີà»\88ຢູà»\88 IP àº\82ອàº\87àº\97à»\88າàº\99 àº\96ືàº\81à»\83àº\8aà»\89à»\82àº\94àº\8d \"[[User:$1|$1]]\" à»\83àº\99à»\84ລàº\8dະຫຼັàº\87. à»\80ຫàº\94àº\9cົàº\99à»\83àº\99àº\81າàº\99ຫà»\89າມ  $1 à»\81ມà»\88àº\99 : \"$2\"",
+       "autoblocker": "àº\96ືàº\81àº\9aລັອàº\81à»\82àº\94àº\8dອັàº\94àº\95ະà»\82àº\99ມັàº\94àº\8dà»\89ອàº\99àº\97ີà»\88ຢູà»\88 IP àº\82ອàº\87àº\97à»\88າàº\99àº\96ືàº\81à»\83àº\8aà»\89à»\82àº\94àº\8d \"[[User:$1|$1]]\" à»\80ມືà»\88ອà»\84ວà»\86àº\99ີà»\89.\nà»\80ຫàº\94àº\9cົàº\99à»\83àº\99àº\81າàº\99àº\9aລັອàº\81 $1 à»\81ມà»\88àº\99 \"$2\"",
        "blocklogpage": "ບັນທຶກການຫ້າມ",
        "blocklogentry": "ໄດ້ຫ້າມ \"[[$1]]\" ຈົນຮອດ $2 $3",
        "move-page-legend": "ຍ້າຍໜ້າ",
        "tooltip-pt-createaccount": "ນີ້ບໍ່ແມ່ນການບັງຄັບ. ແຕ່ຢ່າງໃດກໍຕາມ, ທ່ານຄວນທີ່ຈະສ້າງບັນຊີແລະເຂົ້າສູ່ລະບົບ.",
        "tooltip-ca-talk": "ສົນທະນາກ່ຽວກັບເນື້ອໃນຂອງໜ້າ",
        "tooltip-ca-edit": "ແກ້ໄຂໜ້ານີ້",
-       "tooltip-ca-addsection": "à»\80àº\9eີà»\88ມ àº\84ຳà»\80ຫັàº\99 à»\83ສà»\88 àº\81າàº\99ສົàº\99àº\97ະàº\99າàº\99ີà»\89.",
+       "tooltip-ca-addsection": "à»\80ລີà»\88ມàº\9eາàº\81à»\83à»\9dà»\88",
        "tooltip-ca-viewsource": "ໜ້ານີ້ຖືກປົກປ້ອງ. ທ່ານສາມາດເບິ່ງຊອສ.",
        "tooltip-ca-history": "ລຸ້ນແກ້ໄຂເກົ່າຂອງໜ້ານີ້",
        "tooltip-ca-protect": "ປົກປ້ອງໜ້ານີ້",
        "tooltip-search": "ຄົ້ນຫາ {{SITENAME}}",
        "tooltip-search-go": "ໄປຫາໜ້າທີ່ມີຊື່ທີ່ແນ່ນອນນີ້ຖ້າມັນມີຢູ່",
        "tooltip-search-fulltext": "ຄົ້ນຫາຂໍ້ຄວາມນີ້ໃນໜ້າ",
-       "tooltip-p-logo": "à»\80àº\82ົà»\89າສູà»\88ໜ້າຫຼັກ",
+       "tooltip-p-logo": "ຢà»\89ຽມàº\8aົມໜ້າຫຼັກ",
        "tooltip-n-mainpage": "ໄປເບິ່ງໜ້າຫຼັກ",
-       "tooltip-n-mainpage-description": "à»\80àº\82ົà»\89າສູà»\88ໜ້າຫຼັກ",
+       "tooltip-n-mainpage-description": "à»\80àº\82ົà»\89າຢà»\89ຽມàº\8aົມໜ້າຫຼັກ",
        "tooltip-n-portal": "ກ່ຽວກັບໂຄງການ, ສິ່ງທີ່ທ່ານເຮັດໄດ້, ແລະບ່ອນທີ່ສາມາດຫາສິ່ງຕ່າງໆໄດ້",
        "tooltip-n-currentevents": "ຄົ້ນຫາມູນກ່ຽວກັບກິດຈະກຳທີ່ກຳລັງດຳເນີນ",
        "tooltip-n-recentchanges": "ລາຍການການປ່ຽນແປງລ້າສຸດໃນວິກິ",
        "tooltip-t-permalink": "ລິງຄ໌ຖາວອນມາລຸ້ນແກ້ໄຂເກົ່າຂອງໜ້ານີ້",
        "tooltip-ca-nstab-main": "ເບິ່ງໜ້າເນື້ອໃນ",
        "tooltip-ca-nstab-user": "ເບິ່ງໜ້າຜູ້ໃຊ້",
+       "tooltip-ca-nstab-special": "ໜ້ານີ້ແມ່ນໜ້າພິເສດ, ແລະບໍ່ສາມາດແກ້ໄຂໄດ້",
        "tooltip-ca-nstab-project": "ເບິ່ງໜ້າໂຄງການ",
-       "tooltip-ca-nstab-image": "ເບິງໜ້າໄຟລ໌",
+       "tooltip-ca-nstab-image": "à»\80àº\9aິà»\88àº\87à»\9cà»\89າà»\84àº\9fລà»\8c",
        "tooltip-ca-nstab-template": "ເບິ່ງແມ່ແບບ",
        "tooltip-ca-nstab-category": "ເບິ່ງ ໜ້າໝວດ",
        "tooltip-minoredit": "ໝາຍວ່າແມ່ນການດັດແກ້ເລັກນ້ອຍ",
        "thumbsize": "ຂະໜາດສະແດງ:",
        "file-info-size": "$1 × $2  ປິກເຊລ, ຂະໜາດໄຟລ໌: $3, MIME type: $4",
        "file-nohires": "ບໍ່ມີຂະໜາດລະອຽດກວ່າ",
-       "show-big-image": "à»\80àº\95ັມàº\82ະà»\9cາàº\94",
+       "show-big-image": "à»\84àº\9fລà»\8càº\95ົà»\89àº\99ສະàº\9aັàº\9a",
        "show-big-image-size": "$1 × $2 ພິກເຊວ",
        "newimages": "ໄຟລ໌ຮູບໃໝ່",
        "newimages-summary": "ໜ້າພິເສດນີ້ສະແດງໄຟລ໌ທີ່ຖຶກອັປໂຫຼດຫຼ້າສຸດ",
index 63e207a..e5f9175 100644 (file)
        "recentchanges-legend-newpage": "{{int:recentchanges-label-newpage}} (погл. и [[Special:NewPages|списокот на нови страници]])",
        "recentchanges-legend-plusminus": "(''±123'')",
        "recentchanges-submit": "Прикажи",
+       "rcfilters-activefilters": "Активни филтри",
+       "rcfilters-search-placeholder": "Филтрирај скорешни промени (прелстајте или почнете да пишувате)",
+       "rcfilters-invalid-filter": "Неважечки филтер",
+       "rcfilters-filterlist-title": "Филтри",
+       "rcfilters-filterlist-noresults": "Не пронајдов ниеден филтер",
+       "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": "Многу нови уредници: помалку од 10 уредувања и 4 дена активност.",
+       "rcfilters-filter-userExpLevel-learner-label": "Ученици",
+       "rcfilters-filter-userExpLevel-learner-description": "Повеќе денови активност од новодојденците, но помалку од искусните корисници.",
+       "rcfilters-filter-userExpLevel-experienced-label": "Искусни корисници",
+       "rcfilters-filter-userExpLevel-experienced-description": "Повеќе од 30 дена активност и 500 уредувања.",
        "rcnotefrom": "Подолу {{PLURAL:$5|е прикажана промената|се прикажани промените}} почнувајќи од <strong>$3, $4</strong>  (се прикажуваат до <b>$1</b>).",
        "rclistfrom": "Прикажи нови промени почнувајќи од $3 $2",
        "rcshowhideminor": "$1 ситни промени",
        "apisandbox-sending-request": "Испраќам барање до извршникот...",
        "apisandbox-loading-results": "Добивам исход од извршникот...",
        "apisandbox-results-error": "Се појави грешка при вчитувањето на одговорот од барањето до извршникот: $1.",
+       "apisandbox-request-params-json": "JSON-параметри:",
        "apisandbox-request-url-label": "URL на барањето:",
        "apisandbox-request-time": "Време за барањето: {{PLURAL:$1|$1 милисекунда|$1 милисекунди}}",
        "apisandbox-results-fixtoken": "Исправи ја шифрата и поднеси одново",
        "pagelang-use-default": "Користи стандарден јазик",
        "pagelang-select-lang": "Одберете јазик",
        "pagelang-submit": "Поднеси",
+       "pagelang-nonexistent-page": "Страницата $1 не постои.",
+       "pagelang-unchanged-language": "Страницата $1 е веќе наместена на јазикот $2.",
+       "pagelang-unchanged-language-default": "Страницата $1 е веќе наместена на матичниот содржински јазик на викито.",
+       "pagelang-db-failed": "Базата не успеа да го смени содржинскиот јазик.",
        "right-pagelang": "Менување јазик на страница",
        "action-pagelang": "менување јазик на страница",
        "log-name-pagelang": "Дневник на менување на јазикот",
index 1596eb6..e1d1b38 100644 (file)
        "listgrants-grant": "अनुदान",
        "listgrants-rights": "अधिकार",
        "trackingcategories": "मागोवा घेणारे वर्ग",
-       "trackingcategories-summary": "या à¤ªà¤¾à¤¨à¤¾à¤¤ à¤¤à¥\87 à¤°à¥\87à¤\96ापथनातà¥\80ल à¤µà¤°à¥\8dà¤\97(tracking categories) आहेत, जे, मिडियाविकि संचेतनाद्वारे स्वयंचलितरित्या वसविण्यात (तयार करण्यात) आले आहेत. त्यांची नावे, {{ns:8}} नामविश्वातील संबंधित प्रणाली संदेशात फेरफार करुन, बदलविता येतात.",
+       "trackingcategories-summary": "या à¤ªà¤¾à¤¨à¤¾à¤¤ à¤¤à¥\87 à¤®à¤¾à¤\97à¥\8bवा à¤\98à¥\87णारà¥\87 à¤µà¤°à¥\8dà¤\97 (tracking categories) आहेत, जे, मिडियाविकि संचेतनाद्वारे स्वयंचलितरित्या वसविण्यात (तयार करण्यात) आले आहेत. त्यांची नावे, {{ns:8}} नामविश्वातील संबंधित प्रणाली संदेशात फेरफार करुन, बदलविता येतात.",
        "trackingcategories-msg": "मागोवा घेणारा वर्ग",
        "trackingcategories-name": "संदेश नाम",
        "trackingcategories-desc": "वर्ग अंतर्भूत करण्याचे निकष",
+       "restricted-displaytitle-ignored-desc": "या पानात दुर्लक्षित <code><nowiki>{{DISPLAYTITLE}}</nowiki></code> आहे कारण ते पानाच्या मूळ शीर्षकासम नाही.",
+       "noindex-category-desc": "हे पान सांगकाम्यांद्वारे अनुक्रमित नाही कारण त्यात <code><nowiki>__NOINDEX__</nowiki></code> हा जादुई शब्द आहे व ते त्या नामविश्वात आहे, जेथे या खूणपताकेची परवानगी आहे.",
+       "index-category-desc": "या पानात <code><nowiki>__INDEX__</nowiki></code> ही खूणपताका आहे (व ते अश्या नामविश्वात आहे जेथे या खूणपताकेची परवानगी आहे), आणि म्हणून ही सांगकाम्यांद्वारे अनुक्रमित आहे, जेथे ती सामान्यपणे असावयास नको.",
+       "post-expand-template-inclusion-category-desc": "येथील सर्व साच्यांचा विस्तार केल्यावर, या पानाचा आकार <code>$wgMaxArticleSize</code> पेक्षा जास्त मोठा झाला आहे, म्हणून काही साचे विस्तारल्या गेले नाहीत.",
+       "broken-file-category-desc": "या पानात तुटलेला संचिका-दुवा आहे (तो दुवा, जो अस्तित्वात नसलेल्या संचिकेस जोडण्याचा प्रयत्न करतो).",
+       "hidden-category-category-desc": "या वर्गाच्या आशय मजकूरात <code><nowiki>__HIDDENCAT__</nowiki></code> ही खूणपताका आहे, जी त्या पानास, पानांसाठी   असलेल्या वर्गदुवेपेटीत दिसण्यापासून अविचलरित्या रोखते.",
        "trackingcategories-nodesc": "वर्णन उपलब्ध नाही.",
        "trackingcategories-disabled": "वर्ग अक्षम केल्या गेला आहे",
        "mailnologin": "पाठविण्याचा पत्ता नाही",
index 9eb9458..1d2f69a 100644 (file)
        "wantedpages": "အလိုရှိသော စာမျက်နှာများ",
        "wantedfiles": "အလိုရှိသော ဖိုင်များ",
        "wantedtemplates": "အလိုရှိသော တမ်းပလိတ်များ",
+       "mostlinked": "အများဆုံး လာရောက်ချိတ်ဆက်ထားသည့် စာမျက်နှာများ",
+       "mostlinkedcategories": "အများဆုံး လာရောက် ချိတ်ဆက်ထားသည့် ကဏ္ဍများ",
        "mostcategories": "ကဏ္ဍအများဆုံးပါသော စာမျက်နှာများ",
+       "mostimages": "အများဆုံး လာရောက်ချိတ်ဆက်ထားသည့် ဖိုင်များ",
+       "mostrevisions": "တည်းဖြတ်မှု အများဆုံး စာမျက်နှာများ",
        "prefixindex": "ရှေ့ဆုံးမှ prefix ပါသော စာမျက်နှာ အားလုံး",
        "prefixindex-submit": "ပြသရန်",
        "shortpages": "စာမျက်နှာတို",
        "longpages": "ရှည်လျားသောစာမျက်နှာများ",
-       "deadendpages": "လမ်းပိတ်နေသော (လင့်မရှိသော) စာမျက်နှာများ",
+       "deadendpages": "လမ်းဆုံးနေသော (လင့်ခ်မချိတ်ထားသော) စာမျက်နှာများ",
+       "deadendpagestext": "အောက်ပါ စာမျက်နှာများသည် {{SITENAME}} တွင် အခြား စာမျက်နှာများသို့ လင့်ခ်ချိတ်ဆက်ထားခြင်း မရှိပါ။",
        "protectedpages": "ကာကွယ်ထားသော စာမျက်နှာများ",
        "protectedpages-noredirect": "ပြန်ညွှန်းများအား ဝှက်ရန်",
        "protectedtitles": "ကာကွယ်ထားသော ခေါင်းစဉ်များ",
        "listgrouprights-removegroup-all": "အုပ်စုအားလုံးကို ဖယ်ရှားရန်",
        "listgrouprights-addgroup-self-all": "အုပ်စုအားလုံးကို မိမိ၏အကောင့်သို့ ပေါင်းထည့်ရန်",
        "listgrouprights-removegroup-self-all": "မိမိ၏အကောင့်မှ အုပ်စုအားလုံးကို ဖယ်ရှားရန်",
+       "trackingcategories": "နောက်ယောင်ခံ ကဏ္ဍများ",
        "mailnologin": "ပို့ရန်လိပ်စာ မရှိပါ",
        "emailuser": "ဤ​အ​သုံး​ပြု​သူ​အား​ အီး​မေး​ပို့​ပါ​",
        "emailuser-title-target": "{{GENDER:$1|အသုံးပြုသူ}}ကို အီးမေးပို့ရန်",
index f7acd4f..b41c93a 100644 (file)
        "recentchanges-legend-newpage": "{{int:recentchanges-label-newpage}} (se også [[Special:NewPages|liste over nye sider]])",
        "recentchanges-legend-plusminus": "«(±123)»",
        "recentchanges-submit": "Vis",
+       "rcfilters-activefilters": "Aktive filtre",
+       "rcfilters-search-placeholder": "Filtrer siste endringer (søk eller begyn å skrive)",
+       "rcfilters-invalid-filter": "Ugyldig filter",
+       "rcfilters-filterlist-title": "Filtre",
+       "rcfilters-filterlist-noresults": "Ingen filtre funnet",
+       "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-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-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.",
        "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-url-label": "Forespurt URL:",
        "apisandbox-request-time": "Forespørselstid: {{PLURAL:$1|$1 ms}}",
        "apisandbox-results-fixtoken": "Fiks nøkkelen og send på nytt",
        "pagelang-use-default": "Bruk standardspråk",
        "pagelang-select-lang": "Velg språk",
        "pagelang-submit": "Lagre",
+       "pagelang-nonexistent-page": "Siden «$1» eksisterer ikke.",
+       "pagelang-unchanged-language": "Siden «$1» er allerede satt til språket $2.",
+       "pagelang-unchanged-language-default": "Siden $1 er allerede satt til wikiens standard innholdsspråk.",
+       "pagelang-db-failed": "Databasen kunne ikke endre sidespråket.",
        "right-pagelang": "Endre sidespråk",
        "action-pagelang": "endre sidespråket",
        "log-name-pagelang": "Logg for språkendringer",
index e85c61d..c12edba 100644 (file)
        "recentchanges-legend-newpage": "{{int:recentchanges-label-newpage}} (zie ook de [[Special:NewPages|lijst met nieuwe pagina's]])",
        "recentchanges-legend-plusminus": "(''±123'')",
        "recentchanges-submit": "Weergeven",
+       "rcfilters-activefilters": "Actieve filters",
+       "rcfilters-search-placeholder": "Filter recente wijzigingen (blader of begin met intypen)",
+       "rcfilters-invalid-filter": "Ongeldig filter",
+       "rcfilters-filterlist-title": "Filters",
+       "rcfilters-filterlist-noresults": "Geen filters gevonden",
+       "rcfilters-filter-editsbyself-label": "Uw eigen bewerkingen",
+       "rcfilters-filter-editsbyself-description": "Bewerkingen door u.",
+       "rcfilters-filter-editsbyother-label": "Bewerkingen door anderen",
+       "rcfilters-filter-editsbyother-description": "Bewerkingen die gemaakt zijn door andere gebruikers (niet door uzelf.)",
+       "rcfilters-filtergroup-userExpLevel": "Gebruikerservarings niveau",
+       "rcfilters-filter-userExpLevel-newcomer-label": "Nieuwkomers",
+       "rcfilters-filter-userExpLevel-newcomer-description": "Zeer nieuwe bewerkers: minder dan 10 bewerkingen en 4 dagen van activiteit.",
+       "rcfilters-filter-userExpLevel-learner-label": "Leerlingen",
+       "rcfilters-filter-userExpLevel-experienced-label": "Ervaren gebruikers",
+       "rcfilters-filter-userExpLevel-experienced-description": "Meer dan 30 dagen van activiteit en 500 bewerkingen.",
        "rcnotefrom": "Wijzigingen sinds <strong>$3 om $4</strong> (maximaal <strong>$1</strong> {{PLURAL:$1|wijziging|wijzigingen}}).",
        "rclistfrom": "Wijzigingen bekijken vanaf $3 $2",
        "rcshowhideminor": "Kleine bewerkingen $1",
        "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-url-label": "Verzoek-URL:",
        "apisandbox-request-time": "Doorlooptijd verzoek: {{PLURAL:$1|$1 ms}}",
        "apisandbox-results-fixtoken": "Token corrigeren en opnieuw verzenden",
        "changecontentmodel-emptymodels-title": "Geen inhoudsmodellen beschikbaar",
        "changecontentmodel-emptymodels-text": "De inhoud van [[:$1]] kan niet worden omgezet in een ander type.",
        "log-name-contentmodel": "Wijzigingenlogboek van inhoudsmodel",
-       "log-description-contentmodel": "Gebeurtenissen rond het inhoudsmodel van een pagina",
+       "log-description-contentmodel": "Deze pagina bevat wijzigingen rond het inhoudsmodel van pagina's en pagina's die aangemaakt zijn met een inhoudsmodel anders dan het standaardmodel.",
        "logentry-contentmodel-new": "$1 {{GENDER:$2|maakte}} de pagina $3 aan met behulp van een niet-standaard inhoudsmodel \"$5\"",
        "logentry-contentmodel-change": "$1 {{GENDER:$2|heeft}} het inhoudsmodel gewijzigd van pagina $3 van \"$4\" in \"$5\"",
        "logentry-contentmodel-change-revertlink": "terugdraaien",
        "tag-filter": "[[Special:Tags|Labelfilter]]:",
        "tag-filter-submit": "Filteren",
        "tag-list-wrapper": "([[Special:Tags|Label{{PLURAL:$1||s}}]]: $2)",
+       "tag-mw-contentmodelchange": "inhoudsmodel wijzigen",
+       "tag-mw-contentmodelchange-description": "Bewerkingen die [https://www.mediawiki.org/wiki/Special:MyLanguage/Help:ChangeContentModel het  inhoudsmodel van een pagina wijzigen]",
        "tags-title": "Labels",
        "tags-intro": "Op deze pagina staan de labels waarmee de software iedere bewerking kan markeren, en hun betekenis.",
        "tags-tag": "Labelnaam",
        "pagelang-use-default": "Standaard taal gebruiken",
        "pagelang-select-lang": "Taal selecteren",
        "pagelang-submit": "Opslaan",
+       "pagelang-nonexistent-page": "De pagina $1 bestaat niet.",
+       "pagelang-unchanged-language": "De pagina $1 is al ingesteld op de taal $2.",
+       "pagelang-unchanged-language-default": "De pagina $1 is al ingesteld op de wiki's standaard inhoudstaal.",
+       "pagelang-db-failed": "De database kon de paginataal niet wijzigen.",
        "right-pagelang": "Paginataal wijzigen",
        "action-pagelang": "paginataal te wijzigen",
        "log-name-pagelang": "Logboek taalwijzigingen",
        "sessionprovider-nocookies": "Cookies kunnen uitgeschakeld zijn. Zorg ervoor dat u cookies hebt ingeschakeld en probeer het opnieuw.",
        "randomrootpage": "Willekeurige hoofdpagina",
        "log-action-filter-block": "Soort blokkade:",
+       "log-action-filter-contentmodel": "Soort inhoudsmodel wijziging:",
        "log-action-filter-delete": "Soort verwijdering:",
        "log-action-filter-import": "Type import:",
        "log-action-filter-managetags": "Type labelbeheerhandeling:",
        "log-action-filter-block-block": "Blokkade",
        "log-action-filter-block-reblock": "Aanpassing van blokkade",
        "log-action-filter-block-unblock": "Opheffing van blokkade",
+       "log-action-filter-contentmodel-change": "Wijziging van het inhoudsmodel",
+       "log-action-filter-contentmodel-new": "Pagina creatie met een niet-standaard inhoudsmodel",
        "log-action-filter-delete-delete": "Verwijderen van pagina",
        "log-action-filter-delete-delete_redir": "Overschrijven van doorverwijzingen",
        "log-action-filter-delete-restore": "Terugplaatsen van pagina",
index d2376a5..ef834e3 100644 (file)
        "lag-warn-high": "ଅଧିକ ଡାଟାବେସ ସର୍ଭର ପଛୁଆ ଅବସ୍ଥା ହେତୁ $1 {{PLURAL:$1|ସେକେଣ୍ଡ|ସେକେଣ୍ଡ}}ରୁ ନୂଆ ବଦଳସବୁ ଏହି ତାଲିକାରେ ଦେଖାଯିବ ନାହିଁ ।",
        "watchlistedit-normal-title": "ଦେଖଣାତାଲିକା ସମ୍ପାଦନା କରିବେ",
        "watchlistedit-normal-legend": "ଦେଖିଥିବା ପୃଷ୍ଠାଗୁଡିକରୁ ଶିରୋନାମା ହଟାଇବେ ।",
-       "watchlistedit-normal-explain": "à¬\86ପଣà¬\99à­\8dà¬\95ର à¬¦à­\87à¬\96ଣା à¬¤à¬¾à¬²à¬¿à¬\95ାର à¬¶à¬¿à¬°à­\8bନାମାà¬\97à­\81ଡିà¬\95 à¬¤à¬³à­\87 à¬¦à­\87à¬\96ା à¬¯à¬¾à¬\87à¬\9bି à¥¤\nଶିରà­\8bନାମା  ହଟାଇବାକୁ ଚାହୁଁଥିଲେ, ଏହାର ପାଖରେ ଥିବା ବାକ୍ସରେ ଟିକ ମାରନ୍ତୁ ଏବଂ \"{{int:Watchlistedit-normal-submit}}\"ରେ କ୍ଲିକ କରନ୍ତୁ ।\nଆପଣ [[Special:EditWatchlist/raw|edit the raw list]] ମଧ୍ୟ କରିପାରିବେ ।",
+       "watchlistedit-normal-explain": "à¬\86ପଣà¬\99à­\8dà¬\95ର à¬¦à­\87à¬\96ଣା à¬¤à¬¾à¬²à¬¿à¬\95ାର à¬¶à¬¿à¬°à­\8bନାମà¬\97à­\81ଡ଼ିà¬\95 à¬¤à¬³à­\87 à¬¦à­\87à¬\96ା à¬¯à¬¾à¬\87à¬\9bି à¥¤\nଶିରà­\8bନାମ ହଟାଇବାକୁ ଚାହୁଁଥିଲେ, ଏହାର ପାଖରେ ଥିବା ବାକ୍ସରେ ଟିକ ମାରନ୍ତୁ ଏବଂ \"{{int:Watchlistedit-normal-submit}}\"ରେ କ୍ଲିକ କରନ୍ତୁ ।\nଆପଣ [[Special:EditWatchlist/raw|edit the raw list]] ମଧ୍ୟ କରିପାରିବେ ।",
        "watchlistedit-normal-submit": "ଶିରୋନାମାଗୁଡିକୁ ଲିଭାଇବେ",
        "watchlistedit-normal-done": "{{PLURAL:$1|ଗୋଟିଏ ନାମ|$1 ଗୋଟି ନାମ}} ଆପଣଙ୍କ ଦେଖଣାତାଲିକାରୁ କାଢ଼ିଦିଆଗଲା:",
        "watchlistedit-raw-title": "ଫାଙ୍କା ଦେଖା ତାଲିକାଟିର ସମ୍ପାଦନା କରିବେ",
index f21aaa8..312a0c2 100644 (file)
        "recentchanges-legend-newpage": "{{int:recentchanges-label-newpage}} (zobacz też [[Special:NewPages|listę nowych stron]])",
        "recentchanges-legend-plusminus": "(''±123'')",
        "recentchanges-submit": "Pokaż",
+       "rcfilters-activefilters": "Aktywne filtry",
+       "rcfilters-filterlist-title": "Filtry",
+       "rcfilters-filterlist-noresults": "Nie znaleziono filtrów",
        "rcnotefrom": "Poniżej {{PLURAL:$5|pokazano zmianę|pokazano zmiany}} {{PLURAL:$5|wykonaną|wykonane}} po <strong>$3, $4</strong> (nie więcej niż '''$1''' pozycji).",
        "rclistfrom": "Pokaż nowe zmiany od $3 $2",
        "rcshowhideminor": "$1 drobne edycje",
        "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",
        "changecontentmodel-emptymodels-title": "Nie ma dostępnych modeli treści",
        "changecontentmodel-emptymodels-text": "Zawartość [[:$1]] nie może być przekształcona do żadnego typu.",
        "log-name-contentmodel": "Rejestr zmian modelu zawartości",
-       "log-description-contentmodel": "Wydarzenia związane z modelami zawartości stron",
+       "log-description-contentmodel": "Ta strona wymienia zmiany w modelu zawartości stron oraz tworzenie nowych stron z modelem zawartości innym niż domyślnie.",
        "logentry-contentmodel-new": "$1 {{GENDER:$2|utworzył|utworzyła}} stronę $3 o niebędącym domyślnym modelu zawartości \"$5\"",
        "logentry-contentmodel-change": "$1 {{GENDER:$2|zmienił|zmieniła|zmienił(a)}} model zawartości strony $3 z „$4” na „$5”",
        "logentry-contentmodel-change-revertlink": "Przywróć",
        "pagelang-use-default": "Użyj domyślnego języka",
        "pagelang-select-lang": "Wybierz język",
        "pagelang-submit": "Wyślij",
+       "pagelang-nonexistent-page": "Strona $1 nie istnieje.",
        "right-pagelang": "Zmiana języka strony",
        "action-pagelang": "zmiany języka strony",
        "log-name-pagelang": "Rejestr zmian języka",
        "sessionprovider-nocookies": "Być może cookies są wyłączone. Upewnij się, że masz włączone cookies i zacznij od nowa.",
        "randomrootpage": "Losowa strona (bez podstron)",
        "log-action-filter-block": "Rodzaj blokady:",
-       "log-action-filter-contentmodel": "Typ modyfikacji modelu zawartości:",
+       "log-action-filter-contentmodel": "Typ zmiany modelu zawartości:",
        "log-action-filter-delete": "Rodzaj usunięcia:",
        "log-action-filter-import": "Typ importu:",
        "log-action-filter-managetags": "Typ działania zarządzania znacznikami:",
        "log-action-filter-block-reblock": "Zmiana blokady",
        "log-action-filter-block-unblock": "Odblokowanie",
        "log-action-filter-contentmodel-change": "Zmiana modelu zawartości",
-       "log-action-filter-contentmodel-new": "Utworzenie strony z niestandardowym modelem zawartości",
+       "log-action-filter-contentmodel-new": "Utworzenie strony z niedomyślnym modelem zawartości",
        "log-action-filter-delete-delete": "Usunięcie strony",
        "log-action-filter-delete-delete_redir": "Nadpisanie przekierowania",
        "log-action-filter-delete-restore": "Odtworzenie strony",
index c23e1c5..c8a8f90 100644 (file)
        "passwordreset-emaildisabled": "په دې ويکي باندې د برېښليک ځانتياوې ناچارنې شوي دي.",
        "passwordreset-username": "کارن-نوم:",
        "passwordreset-domain": "شپول:",
-       "passwordreset-capture": "د پايلې برېښليک کتل غواړې؟",
        "passwordreset-email": "برېښليک پته:",
        "passwordreset-emailtitle": "د {{SITENAME}} د گڼون څرگندنې",
        "passwordreset-emailelement": "کارن-نوم: \n$1\n\nلنډمهاله پټنوم: \n$2",
        "right-userrights-interwiki": "په نورو ويکي گانو د نورو کارنانو  کارن-رښتې سمول",
        "right-siteadmin": "توکبنسټ کولپول او پرانيستل",
        "right-sendemail": "نورو کارنانو ته برېښليک لېږل",
-       "right-passwordreset": "د پټنوم بياپرځايولو برېښليکونه کتل",
        "grant-group-email": "برېښليک لېږل",
        "grant-group-other": "بېلابېل فعاليتونه",
        "grant-blockusers": "په کارنانو بنديز لگول او بنديز ليرې کول",
        "recentchanges-legend-newpage": "{{int:recentchanges-label-newpage}} ([[Special:NewPages|د نويو مخونو لړليک]] هم وگورئ)",
        "recentchanges-legend-plusminus": "(<em>±123</em>)",
        "recentchanges-submit": "ښکاره کول",
+       "rcfilters-filterlist-title": "چاڼگران",
+       "rcfilters-filter-userExpLevel-newcomer-label": "نوي راغلي",
+       "rcfilters-filter-userExpLevel-learner-label": "زده کوونکي",
        "rcnotefrom": "دلته لاندې د <strong>$2</strong> څخه راپدېخوا پېښ شوي بدلونونه راغلي (تر <strong>$1</strong> پورې ښکاري).",
        "rclistfrom": "نوي بدلونونه چې له $3، $2 څخه پيلېږي ښکاره کول",
        "rcshowhideminor": "وړې سمونې $1",
index 90db865..0138d59 100644 (file)
        "rev-deleted-comment": "(resumo da edição suprimido)",
        "rev-deleted-user": "(nome de usuário(a) removido)",
        "rev-deleted-event": "(registros de detalhes eliminados)",
-       "rev-deleted-user-contribs": "[nome de usuário(a) ou endereço de IP eliminado – edição ocultada das contribuições]",
+       "rev-deleted-user-contribs": "[nome de usuário(a) ou endereço de IP ocultado no histórico – edição invisível nas contribuições públicas]",
        "rev-deleted-text-permission": "Esta revisão desta página foi '''eliminada'''.\nPodem existir mais detalhes no [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} registro de eliminações].",
        "rev-suppressed-text-permission": "A revisão desta página foi '''eliminada'''.\nVocê pode visualizá-la; podem existir mais detalhes no [{{fullurl:{{#Special:Log}}/suppress|page={{FULLPAGENAMEE}}}} registro de eliminação].",
        "rev-deleted-text-unhide": "Esta revisão desta página foi '''removida'''.\nPoderá haver detalhes no [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} registro de eliminação].\nVocê ainda pode [$1 ver esta revisão] se deseja prosseguir.",
        "usercreated": "{{GENDER:$3|criado|criada|criado(a)}} em $1 às $2",
        "newpages": "Páginas novas",
        "newpages-submit": "Exibir",
-       "newpages-username": "Nome de usuário:",
+       "newpages-username": "Nome de usuário(a):",
        "ancientpages": "Páginas mais antigas",
        "move": "Mover",
        "movethispage": "Mover esta página",
        "linksearch-ns": "Espaço nominal:",
        "linksearch-ok": "Pesquisar",
        "linksearch-text": "É possível usar caracteres coringa, como \"*.wikipedia.org\".\nNecessário no mínimo um domínio de nível superior, por exemplo \"*.org\".<br />\n{{PLURAL:$2|Protocolo suportado|Protocolos suportados}}: $1 (caso nenhum seja especificado, o protocolo http:// será selecionado automaticamente).",
-       "linksearch-line": "$2 possui links para $1",
+       "linksearch-line": "$1 na página $2",
        "linksearch-error": "\"Caracteres mágicos\" (''wildcards'') só podem ser usados no início do endereço.",
        "listusersfrom": "Mostrar usuários começando em:",
        "listusers-submit": "Exibir",
        "notvisiblerev": "Edição eliminada",
        "watchlist-details": "{{PLURAL:$1|$1 página|$1 páginas}} na sua lista de páginas vigiadas, excluindo as páginas de discussão.",
        "wlheader-enotif": "A notificação por email encontra-se ativada.",
-       "wlheader-showupdated": "Páginas modificadas desde a sua última visita são mostradas em '''negrito'''",
+       "wlheader-showupdated": "As páginas modificadas desde a sua última visita são mostradas em <strong>negrito</strong>.",
        "wlnote": "A seguir {{PLURAL:$1|está a última alteração ocorrida|estão as últimas <strong>$1</strong> alterações ocorridas}} {{PLURAL:$2|na última hora|nas últimas <strong>$2</strong> horas}} até $3, $4.",
        "wlshowlast": "Ver últimas $1 horas $2 dias",
        "watchlist-hide": "Ocultar",
        "logentry-import-upload": "$1 {{GENDER:$2|importado}} $3 por envio de arquivo",
        "logentry-import-interwiki": "$1 {{GENDER:$2|importado}} $3 de outra wiki",
        "logentry-merge-merge": "$1 {{GENDER:$2|fundiu}} $3 com $4 (edições até $5)",
-       "logentry-move-move": "$1 moveu a página $3 para $4",
-       "logentry-move-move-noredirect": "$1 moveu a página $3 para $4 sem deixar um redirecionamento",
-       "logentry-move-move_redir": "$1 {{GENDER:$2|moveu}} a página $3 para seu redirecionamento $4",
-       "logentry-move-move_redir-noredirect": "$1 {{GENDER:$2|moveu}} a página $3 para seu redirecionamento $4 suprimindo o primeiro",
+       "logentry-move-move": "$1 moveu $3 para $4",
+       "logentry-move-move-noredirect": "$1 moveu $3 para $4 sem deixar um redirecionamento",
+       "logentry-move-move_redir": "$1 {{GENDER:$2|moveu}} $3 para seu redirecionamento $4",
+       "logentry-move-move_redir-noredirect": "$1 {{GENDER:$2|moveu}} $3 para seu redirecionamento $4 suprimindo o primeiro",
        "logentry-patrol-patrol": "$1 {{GENDER:$2|marcou}} a revisão $4 da página $3 como patrulhada",
        "logentry-patrol-patrol-auto": "$1 {{GENDER:$2|marcou}} automaticamente a revisão $4 da página $3 como patrulhada",
        "logentry-newusers-newusers": "A conta de usuário $1 foi {{GENDER:$2|criada}}",
        "logentry-tag-update-revision": "$1 {{GENDER:$2|atualizou}} etiquetas em revisão $4 da página $3 ({{PLURAL:$7|adicionou}} $6; {{PLURAL:$9|removeu}} $8)",
        "logentry-tag-update-logentry": "$1 {{GENDER:$2|atualizou}} etiquetas na entrada de registro $5 da página $3 ({{PLURAL:$7|adicionou}} $6; {{PLURAL:$9|removeu}} $8)",
        "rightsnone": "(nenhum)",
-       "revdelete-summary": "sumário de edição",
+       "revdelete-summary": "resumo da edição",
        "feedback-adding": "Adicionando os comentários na página...",
        "feedback-back": "Voltar",
        "feedback-bugcheck": "Perfeito! Apenas verifique se não é um dos [$1 bugs já conhecidos].",
index ba79643..d64c8ff 100644 (file)
        "rev-deleted-comment": "(resumo da edição suprimido)",
        "rev-deleted-user": "(nome de utilizador(a) removido)",
        "rev-deleted-event": "(registos de detalhes eliminados)",
-       "rev-deleted-user-contribs": "[nome de utilizador(a) ou IP removido – edição ocultada das contribuições]",
+       "rev-deleted-user-contribs": "[nome de utilizador(a) ou IP removido do histórico – edição ocultada das contribuições públicas]",
        "rev-deleted-text-permission": "Esta revisão de página foi <strong>eliminada</strong>.\nEncontrará detalhes no [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} registo de eliminações].",
        "rev-suppressed-text-permission": "Esta revisão de página foi <strong>suprimida</strong>.\nPode consultar os detalhes no [{{fullurl:{{#Special:Log}}/suppress|page={{FULLPAGENAMEE}}}} registo de supressões].",
        "rev-deleted-text-unhide": "Esta revisão de página foi <strong>eliminada</strong>.\nEncontrará detalhes no [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} registo de eliminações].\nPode mesmo assim [$1 ver esta revisão] se deseja prosseguir.",
        "changecontentmodel-emptymodels-title": "Não há modelos de conteúdo disponíveis",
        "changecontentmodel-emptymodels-text": "O conteúdo em [[:$1]] não pode ser convertido para qualquer tipo.",
        "log-name-contentmodel": "Registo de alteração de modelo de conteúdo",
-       "log-description-contentmodel": "Eventos relacionados com os modelos de conteúdo de uma página",
+       "log-description-contentmodel": "Esta página lista alterações do modelo de conteúdo das páginas e páginas criadas com um modelo de conteúdo diferente do padrão.",
        "logentry-contentmodel-new": "$1 {{GENDER:$2|criou}} a página $3 com o modelo de conteúdo desconhecido \"$5\"",
        "logentry-contentmodel-change": "$1 {{GENDER:$2|alterou}} o modelo de conteúdo da página $3 de \"$4\" para \"$5\"",
        "logentry-contentmodel-change-revertlink": "reverter",
        "recreate": "Recriar",
        "confirm_purge_button": "OK",
        "confirm-purge-top": "Limpar a memória cache desta página?",
-       "confirm-purge-bottom": "Recarregar uma página, limpa a cache e força a sua versão mais recente a aparecer.",
+       "confirm-purge-bottom": "Recarregar uma página limpa a cache e força a sua versão mais recente a aparecer.",
        "confirm-watch-button": "OK",
        "confirm-watch-top": "Adicionar esta página à lista de páginas vigiadas?",
        "confirm-unwatch-button": "OK",
        "logentry-import-interwiki": "$1 {{GENDER:$2|importou}} $3 de outra wiki",
        "logentry-import-interwiki-details": "$1 {{GENDER:$2|importou}} $3 de $5 ($4 {{PLURAL:$4|revisão|revisões}})",
        "logentry-merge-merge": "$1 {{GENDER:$2|fundiu}} $3 com $4 (edições até $5)",
-       "logentry-move-move": "$1 moveu a página $3 para $4",
-       "logentry-move-move-noredirect": "$1 moveu a página $3 para $4 sem deixar um redirecionamento",
-       "logentry-move-move_redir": "$1 {{GENDER:$2|moveu}} a página $3 para o seu redirecionamento $4",
-       "logentry-move-move_redir-noredirect": "$1 {{GENDER:$2|moveu}} a página $3 para o seu redirecionamento $4, suprimindo o primeiro",
+       "logentry-move-move": "$1 moveu $3 para $4",
+       "logentry-move-move-noredirect": "$1 moveu $3 para $4 sem deixar um redirecionamento",
+       "logentry-move-move_redir": "$1 {{GENDER:$2|moveu}} $3 para o seu redirecionamento $4",
+       "logentry-move-move_redir-noredirect": "$1 {{GENDER:$2|moveu}} $3 para o seu redirecionamento $4, suprimindo o primeiro",
        "logentry-patrol-patrol": "$1 {{GENDER:$2|marcou}} a revisão $4 da página $3 como patrulhada",
        "logentry-patrol-patrol-auto": "$1 {{GENDER:$2|marcou}} automaticamente a revisão $4 da página $3 como patrulhada",
        "logentry-newusers-newusers": "A conta de utilizador $1 foi {{GENDER:$2|criada}}",
        "sessionprovider-nocookies": "Os cookies podem estar desativados. Certifique-se de que os cookies estão ativados e inicie novamente.",
        "randomrootpage": "Página aleatória de raiz",
        "log-action-filter-block": "Tipo de bloqueio:",
-       "log-action-filter-contentmodel": "Tipo de alteração de modelo de conteúdo:",
+       "log-action-filter-contentmodel": "Tipo de alteração do modelo de conteúdo:",
        "log-action-filter-delete": "Tipo de eliminação:",
        "log-action-filter-import": "Tipo de importação:",
        "log-action-filter-managetags": "Tipo de ação de gestão de etiqueta:",
        "log-action-filter-block-block": "Bloqueio",
        "log-action-filter-block-reblock": "Alteração de bloqueio",
        "log-action-filter-block-unblock": "Desbloqueio",
-       "log-action-filter-contentmodel-change": "Alteração de modelo de conteúdo",
+       "log-action-filter-contentmodel-change": "Alteração do modelo de conteúdo",
        "log-action-filter-contentmodel-new": "Criação de página com modelo de conteúdo não padronizado",
        "log-action-filter-delete-delete": "Eliminação de página",
        "log-action-filter-delete-delete_redir": "Sobrescrição de redirecionamento",
index 33e2a8c..4df97b0 100644 (file)
        "recentchanges-legend-unpatrolled": "Used as legend on [[Special:RecentChanges]] and [[Special:Watchlist]].\n\nRefers to {{msg-mw|Recentchanges-label-unpatrolled}}.",
        "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-search-placeholder": "Placeholder for the filter search input.",
+       "rcfilters-invalid-filter": "A label for an ivalid filter.",
+       "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-authorship": "Title for the filter group for edit authorship. This filter group allows the user to choose between \"Your own edits\" and \"Edits by others\". More info: https://phabricator.wikimedia.org/T149859\n\n{{doc-important|This is another typical example of ambiguity in the English language. Only the documentation will reveal that this message means \"(filter by) authorship of these edits\", not \"edit the authorship\". That is, \"edit\" is a modifying noun, not a verb.}}",
+       "rcfilters-filter-editsbyself-label": "Label for the filter for showing edits made by the current user.",
+       "rcfilters-filter-editsbyself-description": "Description for the filter for showing edits made by the current user.",
+       "rcfilters-filter-editsbyother-label": "Label for the filter for showing edits made by anyone other than the current user.",
+       "rcfilters-filter-editsbyother-description": "Description for the filter for showing edits made by anyone other than the current user.",
+       "rcfilters-filtergroup-userExpLevel": "Title for the filter group for user experience levels.",
+       "rcfilters-filter-userExpLevel-newcomer-label": "Label for the filter for showing edits made by new editors.",
+       "rcfilters-filter-userExpLevel-newcomer-description": "Description for the filter for showing edits made by new editors.",
+       "rcfilters-filter-userExpLevel-learner-label": "Label for the filter for showing edits made by learning editors.",
+       "rcfilters-filter-userExpLevel-learner-description": "Description for the filter for showing edits made by learning editors.",
+       "rcfilters-filter-userExpLevel-experienced-label": "Label for the filter for showing edits made by experienced editors.",
+       "rcfilters-filter-userExpLevel-experienced-description": "Description for the filter for showing edits made by experienced editors.",
        "rcnotefrom": "This message is displayed at [[Special:RecentChanges]] when viewing recentchanges from some specific time.\n\nThe corresponding message is {{msg-mw|Rclistfrom}}.\n\nParameters:\n* $1 - the maximum number of changes that are displayed\n* $2 - (Optional) a date and time\n* $3 - a date\n* $4 - a time\n* $5 - Number of changes are displayed, for use with PLURAL",
        "rclistfrom": "Used on [[Special:RecentChanges]]. Parameters:\n* $1 - (Currently not use) date and time. The date and the time adds to the rclistfrom description.\n* $2 - time. The time adds to the rclistfrom link description (with split of date and time).\n* $3 - date. The date adds to the rclistfrom link description (with split of date and time).\n\nThe corresponding message is {{msg-mw|Rcnotefrom}}.",
        "rcshowhideminor": "Option text in [[Special:RecentChanges]]. Parameters:\n* $1 - the \"show/hide\" command, with the text taken from either {{msg-mw|rcshowhideminor-show}} or {{msg-mw|rcshowhideminor-hide}}\n{{Identical|Minor edit}}",
        "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-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",
        "sorbs": "{{optional}}",
        "sorbsreason": "See also:\n* {{msg-mw|Sorbsreason}}\n* {{msg-mw|Sorbs create account_reason}}",
        "sorbs_create_account_reason": "Used in [[Special:UserLogin]] when creating an account.\n\nSee also:\n* {{msg-mw|Sorbsreason}}\n* {{msg-mw|Sorbs create account_reason}}",
+       "softblockrangesreason": "This text is shown to the user as a block reason and describes that the user is being blocked because the user is not logged in and their IP is in [[mw:Special:MyLanguage/Manual:$wgSoftBlockRanges|$wgSoftBlockRanges]].\n\nParameters:\n* $1 - The IP address that is blocked.",
        "xffblockreason": "This text is shown to the user as a block reason and describes that the user is being blocked because an IP in the X-Forwarded-For header (which lists the user's IP as well as all IPs of the transparent proxy servers they went through) sent when they loaded the page has been blocked:\n* $1 is the original block reason for the IP address matched in the X-Forwarded-For header",
        "cant-see-hidden-user": "Used as (red) error message on [[Special:Block]] when you try to change (as sysop without the hideuser right) the block of a hidden user.",
        "ipbblocked": "Error message shown when a user tries to alter block settings when they are themselves blocked.",
        "pagelang-language": "Language selector label for Special:PageLanguage\n{{Identical|Language}}",
        "pagelang-use-default": "Radio label for selector on Special:PageLanguage for default language",
        "pagelang-select-lang": "Radio label for selector on Special:PageLanguage for language selection\n{{Identical|Select language}}",
+       "pagelang-reason": "Input label for reason on Special:PageLanguage\n\n{{Identical|Reason}}",
        "pagelang-submit": "Submit button label for Special:PageLanguage form\n{{Identical|Submit}}",
+       "pagelang-nonexistent-page": "Error message shown when the page the user is trying to change the language on does not exist.\n\nParameters:\n* $1 - the title of the nonexistent page",
+       "pagelang-unchanged-language": "Error message shown when the language the user is trying to change the page to and the current language the page is in are the same.\n\nParameters:\n* $1 - the title of the target page\n* $2 - the current language of the page",
+       "pagelang-unchanged-language-default": "Error message shown when the language the user is trying to set a page to fall back to the wiki's default content language, but the page is already set to do so.\n\nParameters:\n* $1 - the title of the target page",
+       "pagelang-db-failed": "Error message shown when the database fails to update the language of the page",
        "right-pagelang": "{{Doc-right|pagelang}}\nRight to change page language on Special:PageLanguage",
        "action-pagelang": "{{Doc-action|pagelang}}",
        "log-name-pagelang": "Display entry for log name for changes in page language in Special:Log.",
index 095d97e..7457515 100644 (file)
        "recentchanges-legend-newpage": "{{int:recentchanges-label-newpage}} (см. также [[Special:NewPages|список новых страниц]])",
        "recentchanges-legend-plusminus": "(''±123'')",
        "recentchanges-submit": "Показать",
+       "rcfilters-filtergroup-authorship": "Редактировать авторство",
+       "rcfilters-filter-editsbyother-description": "Изменения, созданные другими пользователями (а не вами.)",
+       "rcfilters-filtergroup-userExpLevel": "Уровня опыта пользователей",
+       "rcfilters-filter-userExpLevel-newcomer-label": "Новички",
+       "rcfilters-filter-userExpLevel-learner-label": "Учащиеся",
+       "rcfilters-filter-userExpLevel-experienced-label": "Опытные пользователи",
+       "rcfilters-filter-userExpLevel-experienced-description": "Более 30 дней активности и 500 правок.",
        "rcnotefrom": "Ниже {{PLURAL:$5|указано изменение|перечислены изменения}} с <strong>$3, $4</strong> (показано не более <strong>$1</strong>).",
        "rclistfrom": "Показать изменения с $3 $2.",
        "rcshowhideminor": "$1 малые правки",
        "logentry-move-move_redir": "$1 {{GENDER:$2|переименовал|переименовала}} страницу $3 в $4 поверх перенаправления",
        "logentry-move-move_redir-noredirect": "$1 {{GENDER:$2|переименовал|переименовала}} страницу $3 в $4 поверх перенаправления и без оставления перенаправления",
        "logentry-patrol-patrol": "$1 {{GENDER:$2|отпатрулировал|отпатрулировала}} версию $4 страницы $3",
-       "logentry-patrol-patrol-auto": "$1 автоматически {{GENDER:$2|отпатрулировал|отпатрулировала}} \"старым патрулированием\" версию $4 страницы $3",
+       "logentry-patrol-patrol-auto": "$1 автоматически {{GENDER:$2|отпатрулировал|отпатрулировала}} «старым патрулированием» версию $4 страницы $3",
        "logentry-newusers-newusers": "{{GENDER:$2|Участник создал|Участница создала}} учётную запись $1",
        "logentry-newusers-create": "{{GENDER:$2|Участник создал|Участница создала}} учётную запись $1",
        "logentry-newusers-create2": "$1 {{GENDER:$2|создал|создала}} учётную запись $3",
        "pagelang-use-default": "Использовать язык по умолчанию",
        "pagelang-select-lang": "Выберите язык",
        "pagelang-submit": "Отправить",
+       "pagelang-nonexistent-page": "Страница $1 не существует.",
        "right-pagelang": "изменение языка страницы",
        "action-pagelang": "изменять язык страницы",
        "log-name-pagelang": "Журнал изменения языка",
index 8ef53b8..b84a95b 100644 (file)
        "recentchanges-legend-heading": "<strong>Легендата:</strong>",
        "recentchanges-legend-newpage": "{{int:recentchanges-label-newpage}} (өссө көр: [[Special:NewPages|Саҥа сирэйдэр тиһиктэрэ]])",
        "recentchanges-submit": "Көрдөр",
+       "rcfilters-filterlist-title": "Сиидэ",
+       "rcfilters-filterlist-noresults": "Сиидэ көстүбэтэ",
        "rcnotefrom": "Манна {{PLURAL:$5|уларытыы көрдөрүлүннэ|уларытыылар көһүннүлэр}} баччаттан <strong>$3, $4</strong> (баччаттан элбэх көстүбэт <strong>$1</strong>).",
        "rclistfrom": "Бу кэм $3 $2 кэнниттэн оҥоһуллубуттары көрдөр",
        "rcshowhideminor": "$1 кыра уларыйыылары",
        "cant-move-to-user-page": "Эн кыттааччы аатын далыгар сирэйдэри уларытар кыаҕыҥ суох (анныкы сирэйдэриттэн ураты).",
        "cant-move-category-page": "Категория сирэйин аатын уларытар кыаҕыҥ суох эбит.",
        "cant-move-to-category-page": "Сирэй аатын уларытан категория сирэйэ гынар кыаҕыҥ суох эбит.",
+       "namespace-nosubpages": "«$1» аат далыгар сирэй оҥорор табыллыбат эбит.",
        "newtitle": "Саҥа аата:",
        "move-watch": "Кэтээн көрөргө",
        "movepagebtn": "Аатын уларыт",
        "api-error-badtoken": "Ис алҕас: Омсолоох токен.",
        "api-error-blocked": "Уларытар кыаххын быспыттар эбит.",
        "api-error-copyuploaddisabled": "URL көмөтүнэн киллэрии бу сиэрбэргэ араарыллыбыт.",
-       "api-error-duplicate": "Маннык иһинээҕилээх {{PLURAL:$1|атын билэ баар эбит}}",
+       "api-error-duplicate": "Маннык иһинээҕилээх атын {{PLURAL:$1|билэ баар|билэлэр бааллар}} эбит",
        "api-error-duplicate-archive": "Урут ситим-сиргэ маннык иһинээҕилээх {{PLURAL:$1|билэ баар|билэлэр бааллар}} этэ, ол гынан баран {{PLURAL:$1|сотуллубута|сотуллубуттара}}.",
        "api-error-empty-file": "Ыыппыт билэҥ кураанах.",
        "api-error-emptypage": "Саҥа кураанах сирэйи оҥорор табыллыбат.",
index 0da808b..dce7088 100644 (file)
@@ -49,7 +49,7 @@
        "tog-diffonly": "Neruodītė poslapė torėnė puo skėrtomās",
        "tog-showhiddencats": "Ruodītė pakavuotas kateguorėjės",
        "tog-norollbackdiff": "Nekrēptė diemesė i skėrtoma atlėkus atmetėma",
-       "tog-useeditwarning": "Monėi dout žėnuot, kāp ėšēno ėš poslapė anon naėšsauguojis",
+       "tog-useeditwarning": "Monėi doutė žėnuotė, kap ėšēno ėš poslapė anon naėšsauguojė̄s",
        "tog-prefershttps": "Vėsūmet nauduotė saugu rīši kap būno prisijongė̄s",
        "underline-always": "Vėsūmet",
        "underline-never": "Nikūmet",
index 16177ca..4868bed 100644 (file)
        "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-search-placeholder": "Zadnje spremembe filtrov (prebrskajte ali začnite vnašati)",
+       "rcfilters-invalid-filter": "Neveljaven filter",
+       "rcfilters-filterlist-title": "Filtri",
+       "rcfilters-filterlist-noresults": "Nismo našli nobenega filtra",
+       "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-filter-userExpLevel-newcomer-label": "Novinci",
+       "rcfilters-filter-userExpLevel-newcomer-description": "Zelo novi sodelavci: 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.",
        "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-url-label": "URL zahteve:",
        "apisandbox-request-time": "Trajanje zahteve: {{PLURAL:$1|$1 ms}}",
        "apisandbox-results-fixtoken": "Popravite žeton in ponovno pošljite",
        "pagelang-use-default": "Uporabi privzeti jezik",
        "pagelang-select-lang": "Izberite jezik",
        "pagelang-submit": "Potrdi",
+       "pagelang-nonexistent-page": "Stran $1 ne obstaja.",
+       "pagelang-unchanged-language": "Stran $1 že ima nastavljen jezik $2.",
+       "pagelang-unchanged-language-default": "Stran $1 že ima nastavljen wikijev privzeti jezik vsebine.",
+       "pagelang-db-failed": "Zbirka podatkov ni uspela spremeniti jezika strani.",
        "right-pagelang": "Spreminjanje jezika strani",
        "action-pagelang": "spreminjanje jezika strani",
        "log-name-pagelang": "Dnevnik sprememb jezika",
index fbb68ab..bc98608 100644 (file)
        "talk": "Diskutimet",
        "views": "Shikime",
        "toolbox": "Mjete",
+       "tool-link-emailuser": "Dërgo email {{GENDER:$1|user}}",
        "userpage": "Shfaq faqen e përdoruesit",
        "projectpage": "Shfaq faqen e projektit",
        "imagepage": "Shfaq faqen e skedës",
index 49820f5..b021371 100644 (file)
@@ -29,7 +29,8 @@
                        "Macofe",
                        "Jdforrester",
                        "Tungakl",
-                       "Suzukaze-c"
+                       "Suzukaze-c",
+                       "Asdfugil"
                ]
        },
        "tog-underline": "連結加底線:",
@@ -56,7 +57,7 @@
        "tog-enotifminoredits": "喺頁面同檔案有細修改時,用電郵通知我。",
        "tog-enotifrevealaddr": "喺電郵通知信上面話畀人聽我嘅電郵地址",
        "tog-shownumberswatching": "顯示有幾多人監視",
-       "tog-oldsig": "現有簽名:",
+       "tog-oldsig": "你而家嘅簽名:",
        "tog-fancysig": "將簽名以維基字對待(冇自動連結)",
        "tog-uselivepreview": "用即時預覽",
        "tog-forceeditsummary": "我冇入修改註解時通知我",
        "newwindow": "(響新視窗度打開)",
        "cancel": "取消",
        "moredotdotdot": "更多...",
-       "morenotlisted": "爾張清單重未完成。",
+       "morenotlisted": "爾張清單可能重未完成。",
        "mypage": "版",
        "mytalk": "傾偈",
        "anontalk": "傾偈",
        "createacct-yourpasswordagain-ph": "入多次密碼",
        "userlogin-remembermypassword": "記住我有簽到",
        "userlogin-signwithsecure": "用安全連線",
+       "cannotlogin-title": "簽到唔到",
+       "cannotlogin-text": "冇可能簽到",
+       "cannotloginnow-title": "而家簽到唔到",
        "yourdomainname": "你嘅網域:",
        "password-change-forbidden": "你唔可以改呢個維基站嘅密碼。",
        "externaldberror": "驗證資料庫出錯,或者唔允許你更新你嘅外部帳戶。",
        "nocookieslogin": "{{SITENAME}} 登入要開 cookies。熄咗佢。請你開咗再試。",
        "nocookiesfornew": "呢位用戶嘅戶開未開,我哋唔能夠確認佢嘅來源。\n請肯定你已經開咗 cookies,重新載入再試。",
        "noname": "你未指定一個有效嘅用戶名。",
-       "loginsuccesstitle": "ç\99»å\85¥成功",
+       "loginsuccesstitle": "ç°½å\88°成功",
        "loginsuccess": "'''「$1」登入咗{{SITENAME}}。'''",
-       "nosuchuser": "呢度冇叫做 \"$1\"嘅用戶。\n用戶名係有分大細楷嘅。\n請檢查你個名嘅輸入方法,或者[[Special:CreateAccount|建立一個新嘅戶口]]。",
+       "nosuchuser": "呢度冇用戶叫做 \"$1\"嘅。\n用戶名係有分大細楷嘅。\n請檢查你個名嘅輸入方法,或者[[Special:CreateAccount|建立一個新嘅戶口]]。",
        "nosuchusershort": "呢度冇叫做 \"$1\"嘅用戶。 請檢查你個名嘅輸入方法。",
        "nouserspecified": "你需要指定一個用戶名。",
        "login-userblocked": "呢位用戶封鎖咗。唔容許登入。",
        "resetpass_submit": "設定密碼同登入",
        "changepassword-success": "你嘅密碼已經成功噉改咗!",
        "changepassword-throttled": "你已經試咗太多次簽到動作。\n請等$1再試過。",
+       "botpasswords-label-create": "創造",
+       "botpasswords-label-update": "上載",
+       "botpasswords-label-cancel": "取消",
+       "botpasswords-label-delete": "刪除",
+       "botpasswords-label-resetpassword": "改過個個密碼",
        "resetpass_forbidden": "唔可以更改密碼",
        "resetpass-no-info": "你一定要登入咗去直接入來呢一版。",
        "resetpass-submit-loggedin": "改密碼",
        "searchprofile-advanced-tooltip": "響自定空間名度搵",
        "search-result-size": "$1 ($2個字)",
        "search-result-category-size": "$1位成員 ($2個細類,$3個檔案)",
-       "search-redirect": "(跳轉 $1)",
+       "search-redirect": "(由$1過嚟)",
        "search-section": "(小節 $1)",
        "search-category": "(類 $1)",
        "search-file-match": "(夾啱樓案内容)",
index 320f902..581ba75 100644 (file)
        "recentchanges-legend-newpage": "{{int:recentchanges-label-newpage}}(见[[Special:NewPages|新页面列表]])",
        "recentchanges-legend-plusminus": "(<em>±123</em>)",
        "recentchanges-submit": "显示",
+       "rcfilters-activefilters": "活跃的过滤器",
+       "rcfilters-search-placeholder": "过滤器最近更改(浏览或开始输入)",
+       "rcfilters-invalid-filter": "无效过滤器",
+       "rcfilters-filterlist-title": "过滤器",
+       "rcfilters-filterlist-noresults": "找不到过滤器",
+       "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": "非常新的编辑者:少于10次编辑和4天活跃。",
+       "rcfilters-filter-userExpLevel-learner-label": "初学者",
+       "rcfilters-filter-userExpLevel-learner-description": "比“新手”拥有更多活跃天数和编辑数,但少于“有经验的用户。”",
+       "rcfilters-filter-userExpLevel-experienced-label": "有经验的用户",
+       "rcfilters-filter-userExpLevel-experienced-description": "超过30天活跃和500次编辑。",
        "rcnotefrom": "下面{{PLURAL:$5|是}}<strong>$3 $4</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-url-label": "请求的URL:",
        "apisandbox-request-time": "请求时间:{{PLURAL:$1|$1毫秒}}",
        "apisandbox-results-fixtoken": "改正令牌并重新提交",
        "pagelang-use-default": "使用默认语言",
        "pagelang-select-lang": "选择语言",
        "pagelang-submit": "提交",
+       "pagelang-nonexistent-page": "页面$1不存在。",
+       "pagelang-unchanged-language": "页面$1已设置为语言$2。",
+       "pagelang-unchanged-language-default": "页面$1已设置为wiki的默认内容语言。",
+       "pagelang-db-failed": "数据库更改页面语言失败。",
        "right-pagelang": "更改页面语言",
        "action-pagelang": "更改页面语言",
        "log-name-pagelang": "语言更改日志",
index 67369e2..99d3f64 100644 (file)
@@ -349,6 +349,7 @@ $magicWords = [
        'directionmark'           => [ 1, 'DIRECTIONMARK', 'DIRMARK' ],
        'language'                => [ 0, '#LANGUAGE:' ],
        'contentlanguage'         => [ 1, 'CONTENTLANGUAGE', 'CONTENTLANG' ],
+       'pagelanguage'            => [ 1, 'PAGELANGUAGE' ],
        'pagesinnamespace'        => [ 1, 'PAGESINNAMESPACE:', 'PAGESINNS:' ],
        'numberofadmins'          => [ 1, 'NUMBEROFADMINS' ],
        'formatnum'               => [ 0, 'FORMATNUM' ],
diff --git a/languages/messages/MessagesRup.php b/languages/messages/MessagesRup.php
new file mode 100644 (file)
index 0000000..041dc46
--- /dev/null
@@ -0,0 +1,10 @@
+<?php
+/** Aromanian (armãneashti)
+ *
+ * To improve a translation please visit https://translatewiki.net
+ *
+ * @ingroup Language
+ * @file
+ */
+
+$fallback = 'ro';
index 5d32b99..8f7a918 100644 (file)
@@ -33,11 +33,6 @@ class PopulateInterwiki extends Maintenance {
         */
        private $source;
 
-       /**
-        * @var BagOStuff
-        */
-       private $cache;
-
        public function __construct() {
                parent::__construct();
 
@@ -64,8 +59,6 @@ TEXT
                $force = $this->getOption( 'force', false );
                $this->source = $this->getOption( 'source', 'https://en.wikipedia.org/w/api.php' );
 
-               $this->cache = wfGetMainCache();
-
                $data = $this->fetchLinks();
 
                if ( $data === false ) {
@@ -136,7 +129,7 @@ TEXT
                                __METHOD__
                        );
 
-                       if ( ! $row ) {
+                       if ( !$row ) {
                                $dbw->insert(
                                        'interwiki',
                                        [
@@ -149,7 +142,7 @@ TEXT
                                );
                        }
 
-                       $this->clearCacheEntry( $prefix );
+                       Interwiki::invalidateCache( $prefix );
                }
 
                $this->output( "Interwiki links are populated.\n" );
@@ -157,14 +150,6 @@ TEXT
                return true;
        }
 
-       /**
-        * @param string $prefix
-        */
-       private function clearCacheEntry( $prefix ) {
-               $key = wfMemcKey( 'interwiki', $prefix );
-               $this->cache->delete( $key );
-       }
-
 }
 
 $maintClass = PopulateInterwiki::class;
index ae95c78..1c16cc3 100644 (file)
@@ -1775,6 +1775,51 @@ return [
 
        /* MediaWiki Special pages */
 
+       'mediawiki.rcfilters.filters' => [
+               'scripts' => [
+                       'resources/src/mediawiki.rcfilters/mw.rcfilters.js',
+                       'resources/src/mediawiki.rcfilters/dm/mw.rcfilters.dm.FilterItem.js',
+                       'resources/src/mediawiki.rcfilters/dm/mw.rcfilters.dm.FiltersViewModel.js',
+                       'resources/src/mediawiki.rcfilters/ui/mw.rcfilters.ui.FiltersListWidget.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.FilterCapsuleMultiselectWidget.js',
+                       'resources/src/mediawiki.rcfilters/ui/mw.rcfilters.ui.FilterWrapperWidget.js',
+                       'resources/src/mediawiki.rcfilters/mw.rcfilters.Controller.js',
+                       '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',
+                       'resources/src/mediawiki.rcfilters/styles/mw.rcfilters.ui.FilterWrapperWidget.less',
+                       'resources/src/mediawiki.rcfilters/styles/mw.rcfilters.ui.FilterCapsuleMultiselectWidget.less',
+               ],
+               'messages' => [
+                       'rcfilters-activefilters',
+                       'rcfilters-search-placeholder',
+                       'rcfilters-invalid-filter',
+                       'rcfilters-filterlist-title',
+                       'rcfilters-filterlist-noresults',
+                       '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',
+                       'rcfilters-filter-userExpLevel-learner-description',
+                       'rcfilters-filter-userExpLevel-experienced-label',
+                       'rcfilters-filter-userExpLevel-experienced-description',
+               ],
+               'dependencies' => [
+                       'oojs-ui',
+                       'mediawiki.Uri',
+               ],
+       ],
        'mediawiki.special' => [
                'styles' => 'resources/src/mediawiki.special/mediawiki.special.css',
                'targets' => [ 'desktop', 'mobile' ],
@@ -1826,6 +1871,7 @@ return [
                        'apisandbox-sending-request',
                        'apisandbox-loading-results',
                        'apisandbox-results-error',
+                       'apisandbox-request-params-json',
                        'apisandbox-request-url-label',
                        'apisandbox-request-time',
                        'apisandbox-results-fixtoken',
index 7db7547..7b4e546 100644 (file)
@@ -3,7 +3,8 @@
                "authors": [
                        "Чаховіч Уладзіслаў",
                        "Artificial123",
-                       "Goshaproject"
+                       "Goshaproject",
+                       "Mechanizatar"
                ]
        },
        "ooui-outline-control-move-down": "Перамясціць элемент ўніз",
@@ -18,6 +19,7 @@
        "ooui-dialog-process-dismiss": "Прапусціць",
        "ooui-dialog-process-retry": "Паспрабаваць яшчэ раз",
        "ooui-dialog-process-continue": "Працягнуць",
+       "ooui-selectfile-button-select": "Выбраць файл",
        "ooui-selectfile-not-supported": "Выбраны файл не падтрымліваецца",
        "ooui-selectfile-placeholder": "Файл не выбраны"
 }
diff --git a/resources/lib/oojs-ui/i18n/hif-latn.json b/resources/lib/oojs-ui/i18n/hif-latn.json
new file mode 100644 (file)
index 0000000..9e903ca
--- /dev/null
@@ -0,0 +1,23 @@
+{
+       "@metadata": {
+               "authors": [
+                       "Thakurji"
+               ]
+       },
+       "ooui-outline-control-move-down": "Item ke niche karo",
+       "ooui-outline-control-move-up": "Item ke uppar karo",
+       "ooui-outline-control-remove": "Item ke hatao",
+       "ooui-toolbar-more": "Aur",
+       "ooui-toolgroup-expand": "Aur",
+       "ooui-toolgroup-collapse": "Kamtii",
+       "ooui-dialog-message-accept": "OK",
+       "ooui-dialog-message-reject": "Cancel karo",
+       "ooui-dialog-process-error": "Koi chij wrong hoe gais",
+       "ooui-dialog-process-dismiss": "Dismiss karo",
+       "ooui-dialog-process-retry": "Fir se try karo",
+       "ooui-dialog-process-continue": "Continue",
+       "ooui-selectfile-button-select": "Ek file ke select karo",
+       "ooui-selectfile-not-supported": "File selection ke support nai karaa jaawe hai",
+       "ooui-selectfile-placeholder": "Koi file ke nai select karaa gais hai",
+       "ooui-selectfile-dragdrop-placeholder": "Hian pe file ke girao"
+}
index dbe9f86..9b88695 100644 (file)
@@ -11,7 +11,8 @@
                        "Sayginer",
                        "Meelo",
                        "McAang",
-                       "Uğurkent"
+                       "Uğurkent",
+                       "1917 Ekim Devrimi"
                ]
        },
        "ooui-outline-control-move-down": "Ögeyi aşağı taşı",
@@ -28,5 +29,6 @@
        "ooui-dialog-process-continue": "Devam et",
        "ooui-selectfile-button-select": "Dosya seç",
        "ooui-selectfile-not-supported": "Dosya seçimi desteklenmiyor",
-       "ooui-selectfile-placeholder": "Herhangi bir dosya seçilmedi"
+       "ooui-selectfile-placeholder": "Herhangi bir dosya seçilmedi",
+       "ooui-selectfile-dragdrop-placeholder": "Dosyayı buraya aç"
 }
index 911b618..335e509 100644 (file)
@@ -18,5 +18,7 @@
        "ooui-dialog-process-retry": "Кабатлау",
        "ooui-dialog-process-continue": "Дәвам итү",
        "ooui-selectfile-button-select": "Файлны сайлагыз",
-       "ooui-selectfile-placeholder": "Файл сайланмаган"
+       "ooui-selectfile-not-supported": "Файл сайлау хупланмый",
+       "ooui-selectfile-placeholder": "Файл сайланмаган",
+       "ooui-selectfile-dragdrop-placeholder": "Файлны монда куегыз"
 }
index 1acedf2..556196c 100644 (file)
@@ -1,12 +1,12 @@
 /*!
- * OOjs UI v0.18.2
+ * OOjs UI v0.18.3
  * https://www.mediawiki.org/wiki/OOjs_UI
  *
- * Copyright 2011–2016 OOjs UI Team and other contributors.
+ * Copyright 2011–2017 OOjs UI Team and other contributors.
  * Released under the MIT license
  * http://oojs.mit-license.org
  *
- * Date: 2016-12-06T23:32:53Z
+ * Date: 2017-01-04T00:22:40Z
  */
 ( function ( OO ) {
 
index 72df673..c36774a 100644 (file)
@@ -1,12 +1,12 @@
 /*!
- * OOjs UI v0.18.2
+ * OOjs UI v0.18.3
  * https://www.mediawiki.org/wiki/OOjs_UI
  *
- * Copyright 2011–2016 OOjs UI Team and other contributors.
+ * Copyright 2011–2017 OOjs UI Team and other contributors.
  * Released under the MIT license
  * http://oojs.mit-license.org
  *
- * Date: 2016-12-06T23:32:57Z
+ * Date: 2017-01-04T00:22:45Z
  */
 .oo-ui-element-hidden {
   display: none !important;
      -moz-box-sizing: border-box;
           box-sizing: border-box;
 }
-.oo-ui-floatableElement-hidden {
-  display: none;
-}
 .oo-ui-iconElement .oo-ui-iconElement-icon,
 .oo-ui-iconElement.oo-ui-iconElement-icon {
   background-size: contain;
@@ -403,6 +400,9 @@ body:not( :-moz-handler-blocked ) .oo-ui-fieldsetLayout {
   white-space: normal;
   float: left;
 }
+.oo-ui-fieldsetLayout.oo-ui-labelElement > .oo-ui-labelElement-label:empty {
+  display: none;
+}
 .oo-ui-fieldsetLayout-group {
   clear: both;
 }
@@ -414,7 +414,7 @@ body:not( :-moz-handler-blocked ) .oo-ui-fieldsetLayout {
 }
 .oo-ui-fieldsetLayout > .oo-ui-fieldsetLayout-help .oo-ui-fieldsetLayout-help-content {
   padding: 0.5em 0.75em;
-  line-height: 1.5;
+  line-height: 1.4;
 }
 .oo-ui-fieldsetLayout + .oo-ui-fieldsetLayout,
 .oo-ui-fieldsetLayout + .oo-ui-formLayout {
@@ -449,6 +449,8 @@ body:not( :-moz-handler-blocked ) .oo-ui-fieldsetLayout {
 }
 .oo-ui-panelLayout-scrollable {
   overflow-y: auto;
+  /* Make scrolling smooth */
+  -webkit-transform: translate3d(0, 0, 0);
 }
 .oo-ui-panelLayout-expanded {
   position: absolute;
@@ -713,7 +715,6 @@ body:not( :-moz-handler-blocked ) .oo-ui-fieldsetLayout {
   position: relative;
 }
 .oo-ui-popupButtonWidget .oo-ui-popupWidget {
-  position: absolute;
   cursor: auto;
 }
 .oo-ui-popupButtonWidget.oo-ui-buttonElement-frameless > .oo-ui-popupWidget {
@@ -1169,9 +1170,9 @@ body:not( :-moz-handler-blocked ) .oo-ui-fieldsetLayout {
 .oo-ui-progressBarWidget-bar {
   height: 1em;
   border-right: 1px solid #ccc;
-  -webkit-transition: width 250ms ease, margin-left 250ms ease;
-     -moz-transition: width 250ms ease, margin-left 250ms ease;
-          transition: width 250ms ease, margin-left 250ms ease;
+  -webkit-transition: width 250ms ease;
+     -moz-transition: width 250ms ease;
+          transition: width 250ms ease;
   background-color: #cde7f4;
   background-image: -webkit-gradient(linear, right top, right bottom, color-stop(0, #eaf4fa), color-stop(100%, #b0d9ee));
   background-image: -webkit-linear-gradient(top, #eaf4fa 0, #b0d9ee 100%);
@@ -1184,7 +1185,10 @@ body:not( :-moz-handler-blocked ) .oo-ui-fieldsetLayout {
      -moz-animation: oo-ui-progressBarWidget-slide 2s infinite linear;
           animation: oo-ui-progressBarWidget-slide 2s infinite linear;
   width: 40%;
-  margin-left: -10%;
+  -webkit-transform: translate(-25%);
+     -moz-transform: translate(-25%);
+      -ms-transform: translate(-25%);
+          transform: translate(-25%);
   border-left: 1px solid #a6cee1;
 }
 .oo-ui-progressBarWidget.oo-ui-widget-disabled {
@@ -1192,25 +1196,43 @@ body:not( :-moz-handler-blocked ) .oo-ui-fieldsetLayout {
 }
 @-webkit-keyframes oo-ui-progressBarWidget-slide {
   from {
-    margin-left: -40%;
+    -webkit-transform: translate(-100%);
+       -moz-transform: translate(-100%);
+        -ms-transform: translate(-100%);
+            transform: translate(-100%);
   }
   to {
-    margin-left: 100%;
+    -webkit-transform: translate(350%);
+       -moz-transform: translate(350%);
+        -ms-transform: translate(350%);
+            transform: translate(350%);
   }
 }
 @-moz-keyframes oo-ui-progressBarWidget-slide {
   from {
-    margin-left: -40%;
+    -webkit-transform: translate(-100%);
+       -moz-transform: translate(-100%);
+        -ms-transform: translate(-100%);
+            transform: translate(-100%);
   }
   to {
-    margin-left: 100%;
+    -webkit-transform: translate(350%);
+       -moz-transform: translate(350%);
+        -ms-transform: translate(350%);
+            transform: translate(350%);
   }
 }
 @keyframes oo-ui-progressBarWidget-slide {
   from {
-    margin-left: -40%;
+    -webkit-transform: translate(-100%);
+       -moz-transform: translate(-100%);
+        -ms-transform: translate(-100%);
+            transform: translate(-100%);
   }
   to {
-    margin-left: 100%;
+    -webkit-transform: translate(350%);
+       -moz-transform: translate(350%);
+        -ms-transform: translate(350%);
+            transform: translate(350%);
   }
 }
index bab34b8..68d6413 100644 (file)
@@ -1,12 +1,12 @@
 /*!
- * OOjs UI v0.18.2
+ * OOjs UI v0.18.3
  * https://www.mediawiki.org/wiki/OOjs_UI
  *
- * Copyright 2011–2016 OOjs UI Team and other contributors.
+ * Copyright 2011–2017 OOjs UI Team and other contributors.
  * Released under the MIT license
  * http://oojs.mit-license.org
  *
- * Date: 2016-12-06T23:32:57Z
+ * Date: 2017-01-04T00:22:45Z
  */
 .oo-ui-element-hidden {
   display: none !important;
   color: #000;
   box-shadow: none;
 }
-.oo-ui-buttonElement-frameless.oo-ui-widget-enabled.oo-ui-flaggedElement-progressive > .oo-ui-buttonElement-button > .oo-ui-labelElement-label {
+.oo-ui-buttonElement-frameless.oo-ui-widget-enabled.oo-ui-flaggedElement-progressive > .oo-ui-buttonElement-button {
   color: #36c;
 }
-.oo-ui-buttonElement-frameless.oo-ui-widget-enabled.oo-ui-flaggedElement-progressive > .oo-ui-buttonElement-button:hover > .oo-ui-labelElement-label {
+.oo-ui-buttonElement-frameless.oo-ui-widget-enabled.oo-ui-flaggedElement-progressive > .oo-ui-buttonElement-button:hover {
   color: #447ff5;
 }
-.oo-ui-buttonElement-frameless.oo-ui-widget-enabled.oo-ui-flaggedElement-progressive > .oo-ui-buttonElement-button:active > .oo-ui-labelElement-label,
-.oo-ui-buttonElement-frameless.oo-ui-widget-enabled.oo-ui-flaggedElement-progressive > .oo-ui-buttonElement-button:active:focus > .oo-ui-labelElement-label,
-.oo-ui-buttonElement-frameless.oo-ui-widget-enabled.oo-ui-flaggedElement-progressive.oo-ui-buttonElement-pressed > .oo-ui-buttonElement-button > .oo-ui-labelElement-label {
+.oo-ui-buttonElement-frameless.oo-ui-widget-enabled.oo-ui-flaggedElement-progressive > .oo-ui-buttonElement-button:active,
+.oo-ui-buttonElement-frameless.oo-ui-widget-enabled.oo-ui-flaggedElement-progressive > .oo-ui-buttonElement-button:active:focus,
+.oo-ui-buttonElement-frameless.oo-ui-widget-enabled.oo-ui-flaggedElement-progressive.oo-ui-buttonElement-pressed > .oo-ui-buttonElement-button {
   color: #2a4b8d;
   box-shadow: none;
 }
-.oo-ui-buttonElement-frameless.oo-ui-widget-enabled.oo-ui-flaggedElement-constructive > .oo-ui-buttonElement-button > .oo-ui-labelElement-label {
+.oo-ui-buttonElement-frameless.oo-ui-widget-enabled.oo-ui-flaggedElement-constructive > .oo-ui-buttonElement-button {
   color: #36c;
 }
-.oo-ui-buttonElement-frameless.oo-ui-widget-enabled.oo-ui-flaggedElement-constructive > .oo-ui-buttonElement-button:hover > .oo-ui-labelElement-label {
+.oo-ui-buttonElement-frameless.oo-ui-widget-enabled.oo-ui-flaggedElement-constructive > .oo-ui-buttonElement-button:hover {
   color: #447ff5;
 }
-.oo-ui-buttonElement-frameless.oo-ui-widget-enabled.oo-ui-flaggedElement-constructive > .oo-ui-buttonElement-button:active > .oo-ui-labelElement-label,
-.oo-ui-buttonElement-frameless.oo-ui-widget-enabled.oo-ui-flaggedElement-constructive > .oo-ui-buttonElement-button:active:focus > .oo-ui-labelElement-label,
-.oo-ui-buttonElement-frameless.oo-ui-widget-enabled.oo-ui-flaggedElement-constructive.oo-ui-buttonElement-pressed > .oo-ui-buttonElement-button > .oo-ui-labelElement-label {
+.oo-ui-buttonElement-frameless.oo-ui-widget-enabled.oo-ui-flaggedElement-constructive > .oo-ui-buttonElement-button:active,
+.oo-ui-buttonElement-frameless.oo-ui-widget-enabled.oo-ui-flaggedElement-constructive > .oo-ui-buttonElement-button:active:focus,
+.oo-ui-buttonElement-frameless.oo-ui-widget-enabled.oo-ui-flaggedElement-constructive.oo-ui-buttonElement-pressed > .oo-ui-buttonElement-button {
   color: #2a4b8d;
   box-shadow: none;
 }
-.oo-ui-buttonElement-frameless.oo-ui-widget-enabled.oo-ui-flaggedElement-destructive > .oo-ui-buttonElement-button > .oo-ui-labelElement-label {
+.oo-ui-buttonElement-frameless.oo-ui-widget-enabled.oo-ui-flaggedElement-destructive > .oo-ui-buttonElement-button {
   color: #d33;
 }
-.oo-ui-buttonElement-frameless.oo-ui-widget-enabled.oo-ui-flaggedElement-destructive > .oo-ui-buttonElement-button:hover > .oo-ui-labelElement-label {
+.oo-ui-buttonElement-frameless.oo-ui-widget-enabled.oo-ui-flaggedElement-destructive > .oo-ui-buttonElement-button:hover {
   color: #ff4242;
 }
-.oo-ui-buttonElement-frameless.oo-ui-widget-enabled.oo-ui-flaggedElement-destructive > .oo-ui-buttonElement-button:active > .oo-ui-labelElement-label,
-.oo-ui-buttonElement-frameless.oo-ui-widget-enabled.oo-ui-flaggedElement-destructive > .oo-ui-buttonElement-button:active:focus > .oo-ui-labelElement-label,
-.oo-ui-buttonElement-frameless.oo-ui-widget-enabled.oo-ui-flaggedElement-destructive.oo-ui-buttonElement-pressed > .oo-ui-buttonElement-button > .oo-ui-labelElement-label {
+.oo-ui-buttonElement-frameless.oo-ui-widget-enabled.oo-ui-flaggedElement-destructive > .oo-ui-buttonElement-button:active,
+.oo-ui-buttonElement-frameless.oo-ui-widget-enabled.oo-ui-flaggedElement-destructive > .oo-ui-buttonElement-button:active:focus,
+.oo-ui-buttonElement-frameless.oo-ui-widget-enabled.oo-ui-flaggedElement-destructive.oo-ui-buttonElement-pressed > .oo-ui-buttonElement-button {
   color: #b32424;
   box-shadow: none;
 }
 }
 .oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-progressive > .oo-ui-buttonElement-button:hover {
   background-color: #fff;
-  border-color: #859dcc;
+  border-color: #447ff5;
 }
 .oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-progressive > .oo-ui-buttonElement-button:active,
 .oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-progressive > .oo-ui-buttonElement-button:active:focus,
 }
 .oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-constructive > .oo-ui-buttonElement-button:hover {
   background-color: #fff;
-  border-color: #859dcc;
+  border-color: #447ff5;
 }
 .oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-constructive > .oo-ui-buttonElement-button:active,
 .oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-constructive > .oo-ui-buttonElement-button:active:focus,
 }
 .oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-destructive > .oo-ui-buttonElement-button:hover {
   background-color: #fff;
-  border-color: #b77c79;
+  border-color: #ff4242;
 }
 .oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-destructive > .oo-ui-buttonElement-button:active,
 .oo-ui-buttonElement-framed.oo-ui-widget-enabled.oo-ui-flaggedElement-destructive > .oo-ui-buttonElement-button:active:focus,
      -moz-box-sizing: border-box;
           box-sizing: border-box;
 }
-.oo-ui-floatableElement-hidden {
-  display: none;
-}
 .oo-ui-iconElement .oo-ui-iconElement-icon,
 .oo-ui-iconElement.oo-ui-iconElement-icon {
   background-size: contain;
 }
 .oo-ui-fieldLayout.oo-ui-labelElement > .oo-ui-fieldLayout-body > .oo-ui-labelElement-label {
   padding-bottom: 0.3125em;
+  line-height: 1.4;
 }
 .oo-ui-fieldLayout.oo-ui-labelElement.oo-ui-fieldLayout-align-inline > .oo-ui-fieldLayout-body > .oo-ui-labelElement-label {
   padding: 0.3125em 0.46875em;
 .oo-ui-fieldLayout-messages .oo-ui-labelWidget {
   display: table-cell;
   padding: 0.1em 0 0.1em 0.3125em;
-  line-height: 1.5;
+  line-height: 1.4;
   vertical-align: middle;
 }
 .oo-ui-actionFieldLayout {
@@ -541,6 +539,9 @@ body:not( :-moz-handler-blocked ) .oo-ui-fieldsetLayout {
   white-space: normal;
   float: left;
 }
+.oo-ui-fieldsetLayout.oo-ui-labelElement > .oo-ui-labelElement-label:empty {
+  display: none;
+}
 .oo-ui-fieldsetLayout-group {
   clear: both;
 }
@@ -552,7 +553,7 @@ body:not( :-moz-handler-blocked ) .oo-ui-fieldsetLayout {
 }
 .oo-ui-fieldsetLayout > .oo-ui-fieldsetLayout-help .oo-ui-fieldsetLayout-help-content {
   padding: 0.5em 0.75em;
-  line-height: 1.5;
+  line-height: 1.4;
 }
 .oo-ui-fieldsetLayout + .oo-ui-fieldsetLayout,
 .oo-ui-fieldsetLayout + .oo-ui-formLayout {
@@ -562,6 +563,7 @@ body:not( :-moz-handler-blocked ) .oo-ui-fieldsetLayout {
   margin-bottom: 0.56818em;
   font-size: 1.1em;
   font-weight: bold;
+  line-height: 1.4;
 }
 .oo-ui-fieldsetLayout.oo-ui-iconElement > .oo-ui-labelElement-label {
   padding-left: 2em;
@@ -586,6 +588,8 @@ body:not( :-moz-handler-blocked ) .oo-ui-fieldsetLayout {
 }
 .oo-ui-panelLayout-scrollable {
   overflow-y: auto;
+  /* Make scrolling smooth */
+  -webkit-transform: translate3d(0, 0, 0);
 }
 .oo-ui-panelLayout-expanded {
   position: absolute;
@@ -642,7 +646,7 @@ body:not( :-moz-handler-blocked ) .oo-ui-fieldsetLayout {
   overflow: hidden;
 }
 .oo-ui-optionWidget .oo-ui-labelElement-label {
-  line-height: 1.5;
+  line-height: 1.6;
 }
 .oo-ui-optionWidget-selected .oo-ui-buttonElement-button > .oo-ui-iconElement-icon {
   opacity: 1;
@@ -863,7 +867,6 @@ body:not( :-moz-handler-blocked ) .oo-ui-fieldsetLayout {
   position: relative;
 }
 .oo-ui-popupButtonWidget .oo-ui-popupWidget {
-  position: absolute;
   cursor: auto;
 }
 .oo-ui-popupButtonWidget.oo-ui-buttonElement-frameless > .oo-ui-popupWidget {
@@ -980,7 +983,7 @@ body:not( :-moz-handler-blocked ) .oo-ui-fieldsetLayout {
   box-shadow: inset 0 0 0 1px #36c, inset 0 0 0 2px #fff;
 }
 .oo-ui-checkboxMultiselectInputWidget .oo-ui-fieldLayout {
-  margin-bottom: 0;
+  margin-top: 0;
 }
 .oo-ui-checkboxMultiselectInputWidget .oo-ui-fieldLayout .oo-ui-fieldLayout-body {
   padding: 0.25em 0;
@@ -1136,7 +1139,7 @@ body:not( :-moz-handler-blocked ) .oo-ui-fieldsetLayout {
   left: -3px;
 }
 .oo-ui-radioSelectInputWidget .oo-ui-fieldLayout {
-  margin-bottom: 0;
+  margin-top: 0;
 }
 .oo-ui-radioSelectInputWidget .oo-ui-fieldLayout .oo-ui-fieldLayout-body {
   padding: 0.25em 0;
@@ -1251,7 +1254,7 @@ body:not( :-moz-handler-blocked ) .oo-ui-fieldsetLayout {
 }
 .oo-ui-textInputWidget.oo-ui-widget-enabled input,
 .oo-ui-textInputWidget.oo-ui-widget-enabled textarea {
-  box-shadow: inset 0 0 0 0.1em #fff;
+  box-shadow: inset 0 0 0 1px #fff;
   -webkit-transition: border-color 200ms cubic-bezier(0.39, 0.575, 0.565, 1), box-shadow 200ms cubic-bezier(0.39, 0.575, 0.565, 1);
      -moz-transition: border-color 200ms cubic-bezier(0.39, 0.575, 0.565, 1), box-shadow 200ms cubic-bezier(0.39, 0.575, 0.565, 1);
           transition: border-color 200ms cubic-bezier(0.39, 0.575, 0.565, 1), box-shadow 200ms cubic-bezier(0.39, 0.575, 0.565, 1);
@@ -1298,16 +1301,16 @@ body:not( :-moz-handler-blocked ) .oo-ui-fieldsetLayout {
 }
 .oo-ui-textInputWidget.oo-ui-widget-enabled.oo-ui-flaggedElement-invalid input,
 .oo-ui-textInputWidget.oo-ui-widget-enabled.oo-ui-flaggedElement-invalid textarea {
-  border-color: #f00;
+  border-color: #d33;
 }
 .oo-ui-textInputWidget.oo-ui-widget-enabled.oo-ui-flaggedElement-invalid input:hover,
 .oo-ui-textInputWidget.oo-ui-widget-enabled.oo-ui-flaggedElement-invalid textarea:hover {
-  border-color: #f00;
+  border-color: #d33;
 }
 .oo-ui-textInputWidget.oo-ui-widget-enabled.oo-ui-flaggedElement-invalid input:focus,
 .oo-ui-textInputWidget.oo-ui-widget-enabled.oo-ui-flaggedElement-invalid textarea:focus {
-  border-color: #f00;
-  box-shadow: inset 0 0 0 0.1em #f00;
+  border-color: #d33;
+  box-shadow: inset 0 0 0 1px #d33;
 }
 .oo-ui-textInputWidget.oo-ui-iconElement input,
 .oo-ui-textInputWidget.oo-ui-iconElement textarea {
@@ -1597,9 +1600,6 @@ body:not( :-moz-handler-blocked ) .oo-ui-fieldsetLayout {
   text-overflow: ellipsis;
   overflow: hidden;
 }
-.oo-ui-multioptionWidget .oo-ui-labelElement-label {
-  line-height: 1.5;
-}
 .oo-ui-multioptionWidget.oo-ui-widget-disabled {
   color: #72777d;
 }
@@ -1628,16 +1628,19 @@ body:not( :-moz-handler-blocked ) .oo-ui-fieldsetLayout {
 .oo-ui-progressBarWidget-bar {
   background-color: #36c;
   height: 1em;
-  -webkit-transition: width 200ms, margin-left 200ms;
-     -moz-transition: width 200ms, margin-left 200ms;
-          transition: width 200ms, margin-left 200ms;
+  -webkit-transition: width 200ms;
+     -moz-transition: width 200ms;
+          transition: width 200ms;
 }
 .oo-ui-progressBarWidget-indeterminate .oo-ui-progressBarWidget-bar {
   -webkit-animation: oo-ui-progressBarWidget-slide 2s infinite linear;
      -moz-animation: oo-ui-progressBarWidget-slide 2s infinite linear;
           animation: oo-ui-progressBarWidget-slide 2s infinite linear;
   width: 40%;
-  margin-left: -10%;
+  -webkit-transform: translate(-25%);
+     -moz-transform: translate(-25%);
+      -ms-transform: translate(-25%);
+          transform: translate(-25%);
   border-left-width: 1px;
 }
 .oo-ui-progressBarWidget.oo-ui-widget-disabled {
@@ -1645,25 +1648,43 @@ body:not( :-moz-handler-blocked ) .oo-ui-fieldsetLayout {
 }
 @-webkit-keyframes oo-ui-progressBarWidget-slide {
   from {
-    margin-left: -40%;
+    -webkit-transform: translate(-100%);
+       -moz-transform: translate(-100%);
+        -ms-transform: translate(-100%);
+            transform: translate(-100%);
   }
   to {
-    margin-left: 100%;
+    -webkit-transform: translate(350%);
+       -moz-transform: translate(350%);
+        -ms-transform: translate(350%);
+            transform: translate(350%);
   }
 }
 @-moz-keyframes oo-ui-progressBarWidget-slide {
   from {
-    margin-left: -40%;
+    -webkit-transform: translate(-100%);
+       -moz-transform: translate(-100%);
+        -ms-transform: translate(-100%);
+            transform: translate(-100%);
   }
   to {
-    margin-left: 100%;
+    -webkit-transform: translate(350%);
+       -moz-transform: translate(350%);
+        -ms-transform: translate(350%);
+            transform: translate(350%);
   }
 }
 @keyframes oo-ui-progressBarWidget-slide {
   from {
-    margin-left: -40%;
+    -webkit-transform: translate(-100%);
+       -moz-transform: translate(-100%);
+        -ms-transform: translate(-100%);
+            transform: translate(-100%);
   }
   to {
-    margin-left: 100%;
+    -webkit-transform: translate(350%);
+       -moz-transform: translate(350%);
+        -ms-transform: translate(350%);
+            transform: translate(350%);
   }
 }
index b92094c..872d81f 100644 (file)
@@ -1,12 +1,12 @@
 /*!
- * OOjs UI v0.18.2
+ * OOjs UI v0.18.3
  * https://www.mediawiki.org/wiki/OOjs_UI
  *
- * Copyright 2011–2016 OOjs UI Team and other contributors.
+ * Copyright 2011–2017 OOjs UI Team and other contributors.
  * Released under the MIT license
  * http://oojs.mit-license.org
  *
- * Date: 2016-12-06T23:32:53Z
+ * Date: 2017-01-04T00:22:40Z
  */
 ( function ( OO ) {
 
@@ -486,6 +486,22 @@ OO.ui.isSafeUrl = function ( url ) {
        return false;
 };
 
+/**
+ * Check if the user has a 'mobile' device.
+ *
+ * For our purposes this means the user is primarily using an
+ * on-screen keyboard, touch input instead of a mouse and may
+ * have a physically small display.
+ *
+ * It is left up to implementors to decide how to compute this
+ * so the default implementation always returns false.
+ *
+ * @return {boolean} Use is on a mobile device
+ */
+OO.ui.isMobile = function () {
+       return false;
+};
+
 /*!
  * Mixin namespace.
  */
@@ -1368,6 +1384,13 @@ OO.ui.Element.prototype.setElementGroup = function ( group ) {
  * @return {jQuery.Promise} Promise which resolves when the scroll is complete
  */
 OO.ui.Element.prototype.scrollElementIntoView = function ( config ) {
+       if (
+               !this.isElementAttached() ||
+               !this.isVisible() ||
+               ( this.getElementGroup() && !this.getElementGroup().isVisible() )
+       ) {
+               return $.Deferred().resolve();
+       }
        return OO.ui.Element.static.scrollIntoView( this.$element[ 0 ], config );
 };
 
@@ -4103,9 +4126,13 @@ OO.ui.mixin.ClippableElement.prototype.clip = function () {
        extraHeight = $container.outerHeight() - this.$clippable.outerHeight();
        extraWidth = $container.outerWidth() - this.$clippable.outerWidth();
        ccOffset = $container.offset();
-       $scrollableContainer = this.$clippableScrollableContainer.is( 'html, body' ) ?
-               this.$clippableWindow : this.$clippableScrollableContainer;
-       scOffset = $scrollableContainer.offset() || { top: 0, left: 0 };
+       if ( this.$clippableScrollableContainer.is( 'html, body' ) ) {
+               $scrollableContainer = this.$clippableWindow;
+               scOffset = { top: 0, left: 0 };
+       } else {
+               $scrollableContainer = this.$clippableScrollableContainer;
+               scOffset = $scrollableContainer.offset();
+       }
        scHeight = $scrollableContainer.innerHeight() - buffer;
        scWidth = $scrollableContainer.innerWidth() - buffer;
        ccWidth = $container.outerWidth() + buffer;
@@ -7197,10 +7224,10 @@ OO.ui.mixin.FloatableElement.prototype.position = function () {
        }
 
        if ( !this.isElementInViewport( this.$floatableContainer, this.$floatableClosestScrollable ) ) {
-               this.$floatable.addClass( 'oo-ui-floatableElement-hidden' );
+               this.$floatable.addClass( 'oo-ui-element-hidden' );
                return;
        } else {
-               this.$floatable.removeClass( 'oo-ui-floatableElement-hidden' );
+               this.$floatable.removeClass( 'oo-ui-element-hidden' );
        }
 
        if ( !this.needsCustomPosition ) {
@@ -8657,9 +8684,6 @@ OO.ui.TextInputWidget = function OoUiTextInputWidget( config ) {
                blur: this.onBlur.bind( this ),
                focus: this.onFocus.bind( this )
        } );
-       this.$input.one( {
-               focus: this.onElementAttach.bind( this )
-       } );
        this.$icon.on( 'mousedown', this.onIconMouseDown.bind( this ) );
        this.$indicator.on( 'mousedown', this.onIndicatorMouseDown.bind( this ) );
        this.on( 'labelChange', this.updatePosition.bind( this ) );
@@ -8704,6 +8728,7 @@ OO.ui.TextInputWidget = function OoUiTextInputWidget( config ) {
                this.$input.attr( 'rows', config.rows );
        }
        if ( this.label || config.autosize ) {
+               this.isWaitingToBeAttached = true;
                this.installParentChangeDetector();
        }
 };
@@ -8814,6 +8839,11 @@ OO.ui.TextInputWidget.prototype.onBlur = function () {
  * @param {jQuery.Event} e Focus event
  */
 OO.ui.TextInputWidget.prototype.onFocus = function () {
+       if ( this.isWaitingToBeAttached ) {
+               // If we've received focus, then we must be attached to the document, and if
+               // isWaitingToBeAttached is still true, that means the handler never fired. Fire it now.
+               this.onElementAttach();
+       }
        this.setValidityFlag( true );
 };
 
@@ -8824,6 +8854,7 @@ OO.ui.TextInputWidget.prototype.onFocus = function () {
  * @param {jQuery.Event} e Element attach event
  */
 OO.ui.TextInputWidget.prototype.onElementAttach = function () {
+       this.isWaitingToBeAttached = false;
        // Any previously calculated size is now probably invalid if we reattached elsewhere
        this.valCache = null;
        this.adjustSize();
@@ -8936,7 +8967,7 @@ OO.ui.TextInputWidget.prototype.installParentChangeDetector = function () {
        if ( MutationObserver ) {
                // The new way. If only it wasn't so ugly.
 
-               if ( this.$element.closest( 'html' ).length ) {
+               if ( this.isElementAttached() ) {
                        // Widget is attached already, do nothing. This breaks the functionality of this function when
                        // the widget is detached and reattached. Alas, doing this correctly with MutationObserver
                        // would require observation of the whole document, which would hurt performance of other,
@@ -8971,7 +9002,7 @@ OO.ui.TextInputWidget.prototype.installParentChangeDetector = function () {
 
                onRemove = function () {
                        // If the node was attached somewhere else, report it
-                       if ( widget.$element.closest( 'html' ).length ) {
+                       if ( widget.isElementAttached() ) {
                                widget.onElementAttach();
                        }
                        mutationObserver.disconnect();
@@ -9000,6 +9031,11 @@ OO.ui.TextInputWidget.prototype.adjustSize = function () {
        var scrollHeight, innerHeight, outerHeight, maxInnerHeight, measurementError,
                idealHeight, newHeight, scrollWidth, property;
 
+       if ( this.isWaitingToBeAttached ) {
+               // #onElementAttach will be called soon, which calls this method
+               return this;
+       }
+
        if ( this.multiline && this.$input.val() !== this.valCache ) {
                if ( this.autosize ) {
                        this.$clone
@@ -9386,6 +9422,12 @@ OO.ui.TextInputWidget.prototype.updateSearchIndicator = function () {
  */
 OO.ui.TextInputWidget.prototype.positionLabel = function () {
        var after, rtl, property;
+
+       if ( this.isWaitingToBeAttached ) {
+               // #onElementAttach will be called soon, which calls this method
+               return this;
+       }
+
        // Clear old values
        this.$input
                // Clear old values if present
@@ -9578,6 +9620,9 @@ OO.ui.ComboBoxInputWidget = function OoUiComboBoxInputWidget( config ) {
                autocomplete: false
        }, config );
 
+       // ComboBoxInputWidget shouldn't support multiline
+       config.multiline = false;
+
        // Parent constructor
        OO.ui.ComboBoxInputWidget.parent.call( this, config );
 
index 7dc6bef..c2ea652 100644 (file)
@@ -1,12 +1,12 @@
 /*!
- * OOjs UI v0.18.2
+ * OOjs UI v0.18.3
  * https://www.mediawiki.org/wiki/OOjs_UI
  *
- * Copyright 2011–2016 OOjs UI Team and other contributors.
+ * Copyright 2011–2017 OOjs UI Team and other contributors.
  * Released under the MIT license
  * http://oojs.mit-license.org
  *
- * Date: 2016-12-06T23:32:53Z
+ * Date: 2017-01-04T00:22:40Z
  */
 ( function ( OO ) {
 
index baf8833..a367301 100644 (file)
@@ -1,12 +1,12 @@
 /*!
- * OOjs UI v0.18.2
+ * OOjs UI v0.18.3
  * https://www.mediawiki.org/wiki/OOjs_UI
  *
- * Copyright 2011–2016 OOjs UI Team and other contributors.
+ * Copyright 2011–2017 OOjs UI Team and other contributors.
  * Released under the MIT license
  * http://oojs.mit-license.org
  *
- * Date: 2016-12-06T23:32:57Z
+ * Date: 2017-01-04T00:22:45Z
  */
 .oo-ui-popupTool .oo-ui-popupWidget-popup,
 .oo-ui-popupTool .oo-ui-popupWidget-anchor {
 .oo-ui-toolGroup.oo-ui-widget-enabled .oo-ui-tool-link .oo-ui-tool-title {
   color: #000;
 }
-.oo-ui-barToolGroup > .oo-ui-iconElement-icon,
-.oo-ui-barToolGroup > .oo-ui-labelElement-label {
-  display: none;
-}
 .oo-ui-barToolGroup > .oo-ui-toolGroup-tools > .oo-ui-tool {
   display: inline-block;
   position: relative;
index 99a1f5e..0610822 100644 (file)
@@ -1,12 +1,12 @@
 /*!
- * OOjs UI v0.18.2
+ * OOjs UI v0.18.3
  * https://www.mediawiki.org/wiki/OOjs_UI
  *
- * Copyright 2011–2016 OOjs UI Team and other contributors.
+ * Copyright 2011–2017 OOjs UI Team and other contributors.
  * Released under the MIT license
  * http://oojs.mit-license.org
  *
- * Date: 2016-12-06T23:32:57Z
+ * Date: 2017-01-04T00:22:45Z
  */
 .oo-ui-tool.oo-ui-widget-enabled {
   -webkit-transition: background-color 100ms;
 .oo-ui-toolbar-narrow .oo-ui-toolGroup + .oo-ui-toolGroup {
   margin-left: 0;
 }
-.oo-ui-barToolGroup > .oo-ui-iconElement-icon,
-.oo-ui-barToolGroup > .oo-ui-labelElement-label {
-  display: none;
-}
 .oo-ui-barToolGroup > .oo-ui-toolGroup-tools > .oo-ui-tool {
   display: inline-block;
   position: relative;
index e45ca29..5280a9f 100644 (file)
@@ -1,12 +1,12 @@
 /*!
- * OOjs UI v0.18.2
+ * OOjs UI v0.18.3
  * https://www.mediawiki.org/wiki/OOjs_UI
  *
- * Copyright 2011–2016 OOjs UI Team and other contributors.
+ * Copyright 2011–2017 OOjs UI Team and other contributors.
  * Released under the MIT license
  * http://oojs.mit-license.org
  *
- * Date: 2016-12-06T23:32:53Z
+ * Date: 2017-01-04T00:22:40Z
  */
 ( function ( OO ) {
 
index 318bf82..941eb37 100644 (file)
@@ -1,12 +1,12 @@
 /*!
- * OOjs UI v0.18.2
+ * OOjs UI v0.18.3
  * https://www.mediawiki.org/wiki/OOjs_UI
  *
- * Copyright 2011–2016 OOjs UI Team and other contributors.
+ * Copyright 2011–2017 OOjs UI Team and other contributors.
  * Released under the MIT license
  * http://oojs.mit-license.org
  *
- * Date: 2016-12-06T23:32:57Z
+ * Date: 2017-01-04T00:22:45Z
  */
 .oo-ui-draggableElement-handle,
 .oo-ui-draggableElement-handle.oo-ui-widget {
   -webkit-box-sizing: border-box;
      -moz-box-sizing: border-box;
           box-sizing: border-box;
-  -webkit-transform: translateZ(0);
-     -moz-transform: translateZ(0);
-      -ms-transform: translateZ(0);
-          transform: translateZ(0);
+  -webkit-transform: translate3d(0, 0, 0);
   height: 2em;
   width: 4em;
   border-radius: 1em;
index a4db2a3..37eee66 100644 (file)
@@ -1,12 +1,12 @@
 /*!
- * OOjs UI v0.18.2
+ * OOjs UI v0.18.3
  * https://www.mediawiki.org/wiki/OOjs_UI
  *
- * Copyright 2011–2016 OOjs UI Team and other contributors.
+ * Copyright 2011–2017 OOjs UI Team and other contributors.
  * Released under the MIT license
  * http://oojs.mit-license.org
  *
- * Date: 2016-12-06T23:32:57Z
+ * Date: 2017-01-04T00:22:45Z
  */
 .oo-ui-draggableElement-handle,
 .oo-ui-draggableElement-handle.oo-ui-widget {
   -webkit-box-sizing: border-box;
      -moz-box-sizing: border-box;
           box-sizing: border-box;
-  -webkit-transform: translateZ(0);
-     -moz-transform: translateZ(0);
-      -ms-transform: translateZ(0);
-          transform: translateZ(0);
+  -webkit-transform: translate3d(0, 0, 0);
   background-color: #f8f9fa;
   width: 3.5em;
   min-height: 26px;
index 1185fc1..d7e92c2 100644 (file)
@@ -1,12 +1,12 @@
 /*!
- * OOjs UI v0.18.2
+ * OOjs UI v0.18.3
  * https://www.mediawiki.org/wiki/OOjs_UI
  *
- * Copyright 2011–2016 OOjs UI Team and other contributors.
+ * Copyright 2011–2017 OOjs UI Team and other contributors.
  * Released under the MIT license
  * http://oojs.mit-license.org
  *
- * Date: 2016-12-06T23:32:53Z
+ * Date: 2017-01-04T00:22:40Z
  */
 ( function ( OO ) {
 
@@ -1642,7 +1642,7 @@ OO.ui.MenuLayout.prototype.getMenuPosition = function () {
  * @constructor
  * @param {Object} [config] Configuration options
  * @cfg {boolean} [continuous=false] Show all pages, one after another
- * @cfg {boolean} [autoFocus=true] Focus on the first focusable element when a new page is displayed.
+ * @cfg {boolean} [autoFocus=true] Focus on the first focusable element when a new page is displayed. Disabled on mobile.
  * @cfg {boolean} [outlined=false] Show the outline. The outline is used to navigate through the pages of the booklet.
  * @cfg {boolean} [editable=false] Show controls for adding, removing and reordering pages
  */
@@ -1781,7 +1781,7 @@ OO.ui.BookletLayout.prototype.onStackLayoutSet = function ( page ) {
        if ( !this.scrolling && page ) {
                page.scrollElementIntoView( {
                        complete: function () {
-                               if ( layout.autoFocus ) {
+                               if ( layout.autoFocus && !OO.ui.isMobile() ) {
                                        layout.focus();
                                }
                        }
@@ -2112,6 +2112,7 @@ OO.ui.BookletLayout.prototype.setPage = function ( name ) {
                                // meaningless because the next page is not visible yet and thus can't hold focus.
                                if (
                                        this.autoFocus &&
+                                       !OO.ui.isMobile() &&
                                        this.stackLayout.continuous &&
                                        OO.ui.findFocusable( page.$element ).length !== 0
                                ) {
@@ -2188,7 +2189,7 @@ OO.ui.BookletLayout.prototype.selectFirstSelectablePage = function () {
  * @param {Object} [config] Configuration options
  * @cfg {boolean} [continuous=false] Show all cards, one after another
  * @cfg {boolean} [expanded=true] Expand the content panel to fill the entire parent element.
- * @cfg {boolean} [autoFocus=true] Focus on the first focusable element when a new card is displayed.
+ * @cfg {boolean} [autoFocus=true] Focus on the first focusable element when a new card is displayed. Disabled on mobile.
  */
 OO.ui.IndexLayout = function OoUiIndexLayout( config ) {
        // Configuration initialization
@@ -2291,7 +2292,7 @@ OO.ui.IndexLayout.prototype.onStackLayoutSet = function ( card ) {
        if ( card ) {
                card.scrollElementIntoView( {
                        complete: function () {
-                               if ( layout.autoFocus ) {
+                               if ( layout.autoFocus && !OO.ui.isMobile() ) {
                                        layout.focus();
                                }
                        }
@@ -2556,6 +2557,7 @@ OO.ui.IndexLayout.prototype.setCard = function ( name ) {
                                // meaningless because the next card is not visible yet and thus can't hold focus.
                                if (
                                        this.autoFocus &&
+                                       !OO.ui.isMobile() &&
                                        this.stackLayout.continuous &&
                                        OO.ui.findFocusable( card.$element ).length !== 0
                                ) {
@@ -5234,11 +5236,9 @@ OO.ui.NumberInputWidget.prototype.validateNumber = function ( value ) {
                return false;
        }
 
-       /* eslint-disable no-bitwise */
-       if ( this.isInteger && ( n | 0 ) !== n ) {
+       if ( this.isInteger && Math.floor( n ) !== n ) {
                return false;
        }
-       /* eslint-enable no-bitwise */
 
        if ( n < this.min || n > this.max ) {
                return false;
index ad0e7ab..ff013a0 100644 (file)
@@ -1,12 +1,12 @@
 /*!
- * OOjs UI v0.18.2
+ * OOjs UI v0.18.3
  * https://www.mediawiki.org/wiki/OOjs_UI
  *
- * Copyright 2011–2016 OOjs UI Team and other contributors.
+ * Copyright 2011–2017 OOjs UI Team and other contributors.
  * Released under the MIT license
  * http://oojs.mit-license.org
  *
- * Date: 2016-12-06T23:32:57Z
+ * Date: 2017-01-04T00:22:45Z
  */
 .oo-ui-actionWidget.oo-ui-pendingElement-pending {
   background-image: /* @embed */ url(themes/apex/images/textures/pending.gif);
index ecc0004..de26ac0 100644 (file)
@@ -1,12 +1,12 @@
 /*!
- * OOjs UI v0.18.2
+ * OOjs UI v0.18.3
  * https://www.mediawiki.org/wiki/OOjs_UI
  *
- * Copyright 2011–2016 OOjs UI Team and other contributors.
+ * Copyright 2011–2017 OOjs UI Team and other contributors.
  * Released under the MIT license
  * http://oojs.mit-license.org
  *
- * Date: 2016-12-06T23:32:57Z
+ * Date: 2017-01-04T00:22:45Z
  */
 .oo-ui-window {
   background: transparent;
 }
 .oo-ui-messageDialog-message-verbose {
   font-size: 1.1em;
-  line-height: 1.5;
+  line-height: 1.4;
   text-align: left;
 }
 .oo-ui-messageDialog-actions-horizontal .oo-ui-actionWidget {
   text-align: left;
   margin: 1em;
   padding: 1em;
-  border: 1px solid #ff9e9e;
+  border: 1px solid #d33;
   background-color: #fff7f7;
   border-radius: 2px;
 }
index b47b0c8..be81841 100644 (file)
@@ -1,12 +1,12 @@
 /*!
- * OOjs UI v0.18.2
+ * OOjs UI v0.18.3
  * https://www.mediawiki.org/wiki/OOjs_UI
  *
- * Copyright 2011–2016 OOjs UI Team and other contributors.
+ * Copyright 2011–2017 OOjs UI Team and other contributors.
  * Released under the MIT license
  * http://oojs.mit-license.org
  *
- * Date: 2016-12-06T23:32:53Z
+ * Date: 2017-01-04T00:22:40Z
  */
 ( function ( OO ) {
 
@@ -1987,7 +1987,7 @@ OO.ui.Window.prototype.getReadyProcess = function () {
 /**
  * Get the 'hold' process.
  *
- * The hold proccess is used to keep a window from being used in a particular context,
+ * The hold process is used to keep a window from being used in a particular context,
  * based on the `data` argument. This method is called during the closing phase of the window’s
  * lifecycle.
  *
@@ -2881,11 +2881,19 @@ OO.ui.MessageDialog.prototype.setDimensions = function ( dim ) {
        // Twiddle the overflow property, otherwise an unnecessary scrollbar will be produced.
        // Need to do it after transition completes (250ms), add 50ms just in case.
        setTimeout( function () {
-               var oldOverflow = $scrollable[ 0 ].style.overflow;
+               var oldOverflow = $scrollable[ 0 ].style.overflow,
+                       activeElement = document.activeElement;
+
                $scrollable[ 0 ].style.overflow = 'hidden';
 
                OO.ui.Element.static.reconsiderScrollbars( $scrollable[ 0 ] );
 
+               // Check reconsiderScrollbars didn't destroy our focus, as we
+               // are doing this after the ready process.
+               if ( activeElement && activeElement !== document.activeElement && activeElement.focus ) {
+                       activeElement.focus();
+               }
+
                $scrollable[ 0 ].style.overflow = oldOverflow;
        }, 300 );
 
@@ -3153,10 +3161,20 @@ OO.ui.ProcessDialog.prototype.initialize = function () {
  * @inheritdoc
  */
 OO.ui.ProcessDialog.prototype.getActionWidgets = function ( actions ) {
-       var i, len, widgets = [];
+       var i, len, config,
+               isMobile = OO.ui.isMobile(),
+               widgets = [];
+
        for ( i = 0, len = actions.length; i < len; i++ ) {
+               config = $.extend( { framed: !OO.ui.isMobile() }, actions[ i ] );
+               if ( isMobile && ( config.flags === 'back' || config.flags.indexOf( 'back' ) !== -1 ) ) {
+                       $.extend( config, {
+                               icon: 'previous',
+                               label: ''
+                       } );
+               }
                widgets.push(
-                       new OO.ui.ActionWidget( $.extend( { framed: true }, actions[ i ] ) )
+                       new OO.ui.ActionWidget( config )
                );
        }
        return widgets;
@@ -3426,4 +3444,55 @@ OO.ui.confirm = function ( text, options ) {
        } );
 };
 
+/**
+ * Display a quick modal prompt dialog, using a OO.ui.MessageDialog. While the dialog is open,
+ * the rest of the page will be dimmed out and the user won't be able to interact with it. The
+ * dialog has a text input widget and two action buttons, one to confirm an operation (labelled "OK")
+ * and one to cancel it (labelled "Cancel").
+ *
+ * A window manager is created automatically when this function is called for the first time.
+ *
+ *     @example
+ *     OO.ui.prompt( 'Choose a line to go to', { textInput: { placeholder: 'Line number' } } ).done( function ( result ) {
+ *         if ( result !== null ) {
+ *             console.log( 'User typed "' + result + '" then clicked "OK".' );
+ *         } else {
+ *             console.log( 'User clicked "Cancel" or closed the dialog.' );
+ *         }
+ *     } );
+ *
+ * @param {jQuery|string} text Message text to display
+ * @param {Object} [options] Additional options, see OO.ui.MessageDialog#getSetupProcess
+ * @cfg {Object} [textInput] Additional options for text input widget, see OO.ui.TextInputWidget
+ * @return {jQuery.Promise} Promise resolved when the user closes the dialog. If the user chose to
+ *  confirm, the promise will resolve with the value of the text input widget; otherwise, it will
+ *  resolve to `null`.
+ */
+OO.ui.prompt = function ( text, options ) {
+       var manager = OO.ui.getWindowManager(),
+               textInput = new OO.ui.TextInputWidget( ( options && options.textInput ) || {} ),
+               textField = new OO.ui.FieldLayout( textInput, {
+                       align: 'top',
+                       label: text
+               } );
+
+       // TODO: This is a little hacky, and could be done by extending MessageDialog instead.
+
+       return manager.openWindow( 'messageDialog', $.extend( {
+               message: textField.$element,
+               verbose: true
+       }, options ) ).then( function ( opened ) {
+               // After ready
+               textInput.on( 'enter', function () {
+                       manager.getCurrentWindow().close( { action: 'accept' } );
+               } );
+               textInput.focus();
+               return opened.then( function ( closing ) {
+                       return closing.then( function ( data ) {
+                               return $.Deferred().resolve( data && data.action === 'accept' ? textInput.getValue() : null );
+                       } );
+               } );
+       } );
+};
+
 }( OO ) );
index 02dfffa..449cb77 100644 (file)
@@ -9,7 +9,7 @@
        },
        "images": {
                "beta": { "file": "images/icons/beta.svg" },
-               "betaLaunch": { "file": "images/icons/betaLaunch.svg" },
+               "betaLaunch": { "file": "images/icons/logo-wikimediaDiscovery.svg" },
                "bookmark": { "file": {
                        "ltr": "images/icons/bookmark-ltr.svg",
                        "rtl": "images/icons/bookmark-rtl.svg"
index f904cc2..b5dff27 100644 (file)
@@ -4,30 +4,46 @@
        "images": {
                "block": { "file": "images/icons/block.svg" },
                "blockUndo": { "file": {
-                       "ltr": "images/icons/blockUndo-ltr.svg",
-                       "rtl": "images/icons/blockUndo-rtl.svg"
+                       "ltr": "images/icons/unBlock-ltr.svg",
+                       "rtl": "images/icons/unBlock-rtl.svg"
+               } },
+               "unBlock": { "file": {
+                       "ltr": "images/icons/unBlock-ltr.svg",
+                       "rtl": "images/icons/unBlock-rtl.svg"
                } },
                "flag": { "file": {
                        "ltr": "images/icons/flag-ltr.svg",
                        "rtl": "images/icons/flag-rtl.svg"
                } },
                "flagUndo": { "file": {
-                       "ltr": "images/icons/flagUndo-ltr.svg",
-                       "rtl": "images/icons/flagUndo-rtl.svg"
+                       "ltr": "images/icons/unFlag-ltr.svg",
+                       "rtl": "images/icons/unFlag-rtl.svg"
                } },
-               "lock": { "file": "images/icons/lock.svg" },
-               "star": { "file": "images/icons/star.svg" },
-               "trash": { "file": "images/icons/trash.svg" },
-               "trashUndo": { "file": {
-                       "ltr": "images/icons/trashUndo-ltr.svg",
-                       "rtl": "images/icons/trashUndo-rtl.svg"
+               "unFlag": { "file": {
+                       "ltr": "images/icons/unFlag-ltr.svg",
+                       "rtl": "images/icons/unFlag-rtl.svg"
                } },
+               "lock": { "file": "images/icons/lock.svg" },
                "unLock": { "file": {
                        "ltr": "images/icons/unLock-ltr.svg",
                        "rtl": "images/icons/unLock-rtl.svg"
                } },
-               "unStar": { "file": "images/icons/unStar.svg" }
-
-
+               "star": { "file": "images/icons/star.svg" },
+               "unStar": { "file": "images/icons/unStar.svg" },
+               "trash": { "file": "images/icons/trash.svg" },
+               "unTrash": { "file": {
+                       "ltr": "images/icons/unTrash-ltr.svg",
+                       "rtl": "images/icons/unTrash-rtl.svg"
+               } },
+               "trashUndo": { "file": {
+                       "ltr": "images/icons/unTrash-ltr.svg",
+                       "rtl": "images/icons/unTrash-rtl.svg"
+               } },
+               "ongoingConversation": {
+                       "file": {
+                               "ltr": "images/icons/ongoingConversation-ltr.svg",
+                               "rtl": "images/icons/ongoingConversation-rtl.svg"
+                       }
+               }
        }
 }
diff --git a/resources/lib/oojs-ui/themes/apex/images/icons/betaLaunch-invert.png b/resources/lib/oojs-ui/themes/apex/images/icons/betaLaunch-invert.png
deleted file mode 100644 (file)
index 0963538..0000000
Binary files a/resources/lib/oojs-ui/themes/apex/images/icons/betaLaunch-invert.png and /dev/null differ
diff --git a/resources/lib/oojs-ui/themes/apex/images/icons/betaLaunch-invert.svg b/resources/lib/oojs-ui/themes/apex/images/icons/betaLaunch-invert.svg
deleted file mode 100644 (file)
index 5058629..0000000
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #FFFFFF }</style>
-    <path d="M15.3 14.7C16.1 10.9 14.7 4 12 4c-2.7 0-4.2 6.7-3.4 10.5L7 18h2.7l.3 1h4c.2-.3.1-.5.3-1H17l-1.7-3.3zM12 10c-.8 0-1.5-.7-1.5-1.5S11.2 7 12 7s1.5.7 1.5 1.5S12.8 10 12 10zm2 10c0 1.1-2 2-2 2s-2-.9-2-2"/>
-</svg>
diff --git a/resources/lib/oojs-ui/themes/apex/images/icons/betaLaunch.png b/resources/lib/oojs-ui/themes/apex/images/icons/betaLaunch.png
deleted file mode 100644 (file)
index 6d3c067..0000000
Binary files a/resources/lib/oojs-ui/themes/apex/images/icons/betaLaunch.png and /dev/null differ
diff --git a/resources/lib/oojs-ui/themes/apex/images/icons/betaLaunch.svg b/resources/lib/oojs-ui/themes/apex/images/icons/betaLaunch.svg
deleted file mode 100644 (file)
index c3f99d6..0000000
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
-    <path d="M15.3 14.7C16.1 10.9 14.7 4 12 4c-2.7 0-4.2 6.7-3.4 10.5L7 18h2.7l.3 1h4c.2-.3.1-.5.3-1H17l-1.7-3.3zM12 10c-.8 0-1.5-.7-1.5-1.5S11.2 7 12 7s1.5.7 1.5 1.5S12.8 10 12 10zm2 10c0 1.1-2 2-2 2s-2-.9-2-2"/>
-</svg>
diff --git a/resources/lib/oojs-ui/themes/apex/images/icons/blockUndo-ltr.png b/resources/lib/oojs-ui/themes/apex/images/icons/blockUndo-ltr.png
deleted file mode 100644 (file)
index 640bb2a..0000000
Binary files a/resources/lib/oojs-ui/themes/apex/images/icons/blockUndo-ltr.png and /dev/null differ
diff --git a/resources/lib/oojs-ui/themes/apex/images/icons/blockUndo-ltr.svg b/resources/lib/oojs-ui/themes/apex/images/icons/blockUndo-ltr.svg
deleted file mode 100644 (file)
index 160219c..0000000
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
-    <path d="M17 11v2h-2l3.6 3.6c.9-1.3 1.4-2.9 1.4-4.6 0-4.4-3.6-8-8-8-1.7 0-3.3.5-4.6 1.4L13 11h4zM4 4L3 5l2.4 2.4C4.5 8.7 4 10.3 4 12c0 4.4 3.6 8 8 8 1.7 0 3.3-.5 4.6-1.4L19 21l1-1L4 4zm3 9v-2h2l2 2H7z"/>
-</svg>
diff --git a/resources/lib/oojs-ui/themes/apex/images/icons/blockUndo-rtl.png b/resources/lib/oojs-ui/themes/apex/images/icons/blockUndo-rtl.png
deleted file mode 100644 (file)
index 2475b06..0000000
Binary files a/resources/lib/oojs-ui/themes/apex/images/icons/blockUndo-rtl.png and /dev/null differ
diff --git a/resources/lib/oojs-ui/themes/apex/images/icons/blockUndo-rtl.svg b/resources/lib/oojs-ui/themes/apex/images/icons/blockUndo-rtl.svg
deleted file mode 100644 (file)
index 90fe46a..0000000
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
-    <path d="M7 11v2h2l-3.6 3.6C4.5 15.3 4 13.7 4 12c0-4.4 3.6-8 8-8 1.7 0 3.3.5 4.6 1.4L11 11H7zm13-7l1 1-2.4 2.4c.9 1.3 1.4 2.9 1.4 4.6 0 4.4-3.6 8-8 8-1.7 0-3.3-.5-4.6-1.4L5 21l-1-1L20 4zm-3 9v-2h-2l-2 2h4z"/>
-</svg>
diff --git a/resources/lib/oojs-ui/themes/apex/images/icons/flagUndo-ltr.png b/resources/lib/oojs-ui/themes/apex/images/icons/flagUndo-ltr.png
deleted file mode 100644 (file)
index 780cb87..0000000
Binary files a/resources/lib/oojs-ui/themes/apex/images/icons/flagUndo-ltr.png and /dev/null differ
diff --git a/resources/lib/oojs-ui/themes/apex/images/icons/flagUndo-ltr.svg b/resources/lib/oojs-ui/themes/apex/images/icons/flagUndo-ltr.svg
deleted file mode 100644 (file)
index 4bbd61c..0000000
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
-       <path d="M19.9 19.6l-16-16-1.1 1.1L6 7.9V20h1v-7c.6-.6 2-.8 3.4-.7l8.4 8.4 1.1-1.1zM17 14V7c-.7.7-2.7.9-4 .5V6c-1.2-1.3-3.9-1.3-5.4-.5l8.9 9c.3-.2.4-.3.5-.5z"/>
-</svg>
\ No newline at end of file
diff --git a/resources/lib/oojs-ui/themes/apex/images/icons/flagUndo-rtl.png b/resources/lib/oojs-ui/themes/apex/images/icons/flagUndo-rtl.png
deleted file mode 100644 (file)
index fa3696a..0000000
Binary files a/resources/lib/oojs-ui/themes/apex/images/icons/flagUndo-rtl.png and /dev/null differ
diff --git a/resources/lib/oojs-ui/themes/apex/images/icons/flagUndo-rtl.svg b/resources/lib/oojs-ui/themes/apex/images/icons/flagUndo-rtl.svg
deleted file mode 100644 (file)
index 5d94425..0000000
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
-       <path d="M3.5 19.6l16-16 1.1 1.1-3.2 3.2V20h-1v-7c-.6-.6-2-.8-3.4-.7l-8.4 8.4-1.1-1.1zM6.3 14V7c.7.7 2.7.9 4 .5V6c1.2-1.3 3.9-1.3 5.4-.5l-8.9 9c-.3-.2-.4-.3-.5-.5z"/>
-</svg>
\ No newline at end of file
diff --git a/resources/lib/oojs-ui/themes/apex/images/icons/logo-wikimediaDiscovery-invert.png b/resources/lib/oojs-ui/themes/apex/images/icons/logo-wikimediaDiscovery-invert.png
new file mode 100644 (file)
index 0000000..0963538
Binary files /dev/null and b/resources/lib/oojs-ui/themes/apex/images/icons/logo-wikimediaDiscovery-invert.png differ
diff --git a/resources/lib/oojs-ui/themes/apex/images/icons/logo-wikimediaDiscovery-invert.svg b/resources/lib/oojs-ui/themes/apex/images/icons/logo-wikimediaDiscovery-invert.svg
new file mode 100644 (file)
index 0000000..5058629
--- /dev/null
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #FFFFFF }</style>
+    <path d="M15.3 14.7C16.1 10.9 14.7 4 12 4c-2.7 0-4.2 6.7-3.4 10.5L7 18h2.7l.3 1h4c.2-.3.1-.5.3-1H17l-1.7-3.3zM12 10c-.8 0-1.5-.7-1.5-1.5S11.2 7 12 7s1.5.7 1.5 1.5S12.8 10 12 10zm2 10c0 1.1-2 2-2 2s-2-.9-2-2"/>
+</svg>
diff --git a/resources/lib/oojs-ui/themes/apex/images/icons/logo-wikimediaDiscovery.png b/resources/lib/oojs-ui/themes/apex/images/icons/logo-wikimediaDiscovery.png
new file mode 100644 (file)
index 0000000..6d3c067
Binary files /dev/null and b/resources/lib/oojs-ui/themes/apex/images/icons/logo-wikimediaDiscovery.png differ
diff --git a/resources/lib/oojs-ui/themes/apex/images/icons/logo-wikimediaDiscovery.svg b/resources/lib/oojs-ui/themes/apex/images/icons/logo-wikimediaDiscovery.svg
new file mode 100644 (file)
index 0000000..c3f99d6
--- /dev/null
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
+    <path d="M15.3 14.7C16.1 10.9 14.7 4 12 4c-2.7 0-4.2 6.7-3.4 10.5L7 18h2.7l.3 1h4c.2-.3.1-.5.3-1H17l-1.7-3.3zM12 10c-.8 0-1.5-.7-1.5-1.5S11.2 7 12 7s1.5.7 1.5 1.5S12.8 10 12 10zm2 10c0 1.1-2 2-2 2s-2-.9-2-2"/>
+</svg>
diff --git a/resources/lib/oojs-ui/themes/apex/images/icons/ongoingConversation-ltr.png b/resources/lib/oojs-ui/themes/apex/images/icons/ongoingConversation-ltr.png
new file mode 100644 (file)
index 0000000..df49095
Binary files /dev/null and b/resources/lib/oojs-ui/themes/apex/images/icons/ongoingConversation-ltr.png differ
diff --git a/resources/lib/oojs-ui/themes/apex/images/icons/ongoingConversation-ltr.svg b/resources/lib/oojs-ui/themes/apex/images/icons/ongoingConversation-ltr.svg
new file mode 100644 (file)
index 0000000..658809d
--- /dev/null
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?>
+<svg width="24" height="24" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
+    <path d="M17.8 18.6H2.5l2.7-2.7V6h15.3v9.9c0 1.53-1.17 2.7-2.7 2.7zm-7.542-4.95c0 .405-.135.675-.405.945-.27.27-.607.405-.945.405-.405 0-.675-.135-.945-.405a1.332 1.332 0 0 1-.405-.945c0-.338.135-.675.405-.945.27-.27.608-.405.945-.405.338 0 .675.135.945.405.27.27.405.607.405.945zm4.05 0c0 .405-.135.675-.405.945-.27.27-.607.405-.945.405-.405 0-.675-.135-.945-.405a1.332 1.332 0 0 1-.405-.945c0-.338.135-.675.405-.945.27-.27.608-.405.945-.405.338 0 .675.135.945.405.27.27.405.607.405.945zm4.05 0c0 .405-.135.675-.405.945-.27.27-.607.405-.945.405-.405 0-.675-.135-.945-.405a1.332 1.332 0 0 1-.405-.945c0-.338.135-.675.405-.945.27-.27.608-.405.945-.405.338 0 .675.135.945.405.27.27.405.607.405.945z" id="ongoing-conversation" fill-rule="evenodd"/>
+</svg>
diff --git a/resources/lib/oojs-ui/themes/apex/images/icons/ongoingConversation-rtl.png b/resources/lib/oojs-ui/themes/apex/images/icons/ongoingConversation-rtl.png
new file mode 100644 (file)
index 0000000..3d7e9bd
Binary files /dev/null and b/resources/lib/oojs-ui/themes/apex/images/icons/ongoingConversation-rtl.png differ
diff --git a/resources/lib/oojs-ui/themes/apex/images/icons/ongoingConversation-rtl.svg b/resources/lib/oojs-ui/themes/apex/images/icons/ongoingConversation-rtl.svg
new file mode 100644 (file)
index 0000000..648ce55
--- /dev/null
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?>
+<svg width="24" height="24" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
+    <path d="M5.2 18.6h15.3l-2.7-2.7V6H2.5v9.9c0 1.53 1.17 2.7 2.7 2.7zm7.542-4.95c0 .405.135.675.405.945.27.27.607.405.945.405.405 0 .675-.135.945-.405.27-.27.405-.607.405-.945 0-.337-.135-.675-.405-.945a1.334 1.334 0 0 0-.945-.405c-.338 0-.675.135-.945.405-.27.27-.405.607-.405.945zm-4.05 0c0 .405.135.675.405.945.27.27.608.405.945.405.405 0 .675-.135.945-.405.27-.27.405-.607.405-.945 0-.337-.135-.675-.405-.945a1.334 1.334 0 0 0-.945-.405c-.338 0-.675.135-.945.405-.27.27-.405.608-.405.945zm-4.05 0c0 .405.135.675.405.945.27.27.608.405.945.405.405 0 .675-.135.945-.405.27-.27.405-.607.405-.945 0-.337-.135-.675-.405-.945a1.332 1.332 0 0 0-.945-.405c-.337 0-.675.135-.945.405-.27.27-.405.608-.405.945z" id="ongoing-conversation" fill-rule="evenodd"/>
+</svg>
diff --git a/resources/lib/oojs-ui/themes/apex/images/icons/trashUndo-ltr.png b/resources/lib/oojs-ui/themes/apex/images/icons/trashUndo-ltr.png
deleted file mode 100644 (file)
index 87590fa..0000000
Binary files a/resources/lib/oojs-ui/themes/apex/images/icons/trashUndo-ltr.png and /dev/null differ
diff --git a/resources/lib/oojs-ui/themes/apex/images/icons/trashUndo-ltr.svg b/resources/lib/oojs-ui/themes/apex/images/icons/trashUndo-ltr.svg
deleted file mode 100644 (file)
index 9a625b8..0000000
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
-    <path d="M4.5 3.5l-1 1L6 7v2h1v7.97L8 18h6.97l.03-.03 1-.97 2.5 2.5 1-1L16 15l-1-1-1-1-1-1-1-1-1-1-1-1-1-1-1-1-1-1zM9 5v1l1 1h6v1h-5l1 1h3v3l1 1V9h1V6h-3V5zM8 9l1 1v6h1v-5l1 1v4h1v-3l1 1v2h1v-1l1 1v1H8zm5 1l1 1v-1z" id="trash-can-undo"/>
-</svg>
diff --git a/resources/lib/oojs-ui/themes/apex/images/icons/trashUndo-rtl.png b/resources/lib/oojs-ui/themes/apex/images/icons/trashUndo-rtl.png
deleted file mode 100644 (file)
index dd35023..0000000
Binary files a/resources/lib/oojs-ui/themes/apex/images/icons/trashUndo-rtl.png and /dev/null differ
diff --git a/resources/lib/oojs-ui/themes/apex/images/icons/trashUndo-rtl.svg b/resources/lib/oojs-ui/themes/apex/images/icons/trashUndo-rtl.svg
deleted file mode 100644 (file)
index 17ca8dc..0000000
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
-    <path d="M18.5 3.5l1 1L17 7v2h-1v7.97L15 18H8.03L8 17.97 7 17l-2.5 2.5-1-1L7 15l1-1 1-1 1-1 1-1 1-1 1-1 1-1 1-1 1-1zM14 5v1l-1 1H7v1h5l-1 1H8v3l-1 1V9H6V6h3V5zm1 4l-1 1v6h-1v-5l-1 1v4h-1v-3l-1 1v2H9v-1l-1 1v1h7zm-5 1l-1 1v-1z" id="trash-can-undo"/>
-</svg>
diff --git a/resources/lib/oojs-ui/themes/apex/images/icons/unBlock-ltr.png b/resources/lib/oojs-ui/themes/apex/images/icons/unBlock-ltr.png
new file mode 100644 (file)
index 0000000..640bb2a
Binary files /dev/null and b/resources/lib/oojs-ui/themes/apex/images/icons/unBlock-ltr.png differ
diff --git a/resources/lib/oojs-ui/themes/apex/images/icons/unBlock-ltr.svg b/resources/lib/oojs-ui/themes/apex/images/icons/unBlock-ltr.svg
new file mode 100644 (file)
index 0000000..160219c
--- /dev/null
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
+    <path d="M17 11v2h-2l3.6 3.6c.9-1.3 1.4-2.9 1.4-4.6 0-4.4-3.6-8-8-8-1.7 0-3.3.5-4.6 1.4L13 11h4zM4 4L3 5l2.4 2.4C4.5 8.7 4 10.3 4 12c0 4.4 3.6 8 8 8 1.7 0 3.3-.5 4.6-1.4L19 21l1-1L4 4zm3 9v-2h2l2 2H7z"/>
+</svg>
diff --git a/resources/lib/oojs-ui/themes/apex/images/icons/unBlock-rtl.png b/resources/lib/oojs-ui/themes/apex/images/icons/unBlock-rtl.png
new file mode 100644 (file)
index 0000000..2475b06
Binary files /dev/null and b/resources/lib/oojs-ui/themes/apex/images/icons/unBlock-rtl.png differ
diff --git a/resources/lib/oojs-ui/themes/apex/images/icons/unBlock-rtl.svg b/resources/lib/oojs-ui/themes/apex/images/icons/unBlock-rtl.svg
new file mode 100644 (file)
index 0000000..90fe46a
--- /dev/null
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
+    <path d="M7 11v2h2l-3.6 3.6C4.5 15.3 4 13.7 4 12c0-4.4 3.6-8 8-8 1.7 0 3.3.5 4.6 1.4L11 11H7zm13-7l1 1-2.4 2.4c.9 1.3 1.4 2.9 1.4 4.6 0 4.4-3.6 8-8 8-1.7 0-3.3-.5-4.6-1.4L5 21l-1-1L20 4zm-3 9v-2h-2l-2 2h4z"/>
+</svg>
diff --git a/resources/lib/oojs-ui/themes/apex/images/icons/unFlag-ltr.png b/resources/lib/oojs-ui/themes/apex/images/icons/unFlag-ltr.png
new file mode 100644 (file)
index 0000000..780cb87
Binary files /dev/null and b/resources/lib/oojs-ui/themes/apex/images/icons/unFlag-ltr.png differ
diff --git a/resources/lib/oojs-ui/themes/apex/images/icons/unFlag-ltr.svg b/resources/lib/oojs-ui/themes/apex/images/icons/unFlag-ltr.svg
new file mode 100644 (file)
index 0000000..4bbd61c
--- /dev/null
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
+       <path d="M19.9 19.6l-16-16-1.1 1.1L6 7.9V20h1v-7c.6-.6 2-.8 3.4-.7l8.4 8.4 1.1-1.1zM17 14V7c-.7.7-2.7.9-4 .5V6c-1.2-1.3-3.9-1.3-5.4-.5l8.9 9c.3-.2.4-.3.5-.5z"/>
+</svg>
\ No newline at end of file
diff --git a/resources/lib/oojs-ui/themes/apex/images/icons/unFlag-rtl.png b/resources/lib/oojs-ui/themes/apex/images/icons/unFlag-rtl.png
new file mode 100644 (file)
index 0000000..fa3696a
Binary files /dev/null and b/resources/lib/oojs-ui/themes/apex/images/icons/unFlag-rtl.png differ
diff --git a/resources/lib/oojs-ui/themes/apex/images/icons/unFlag-rtl.svg b/resources/lib/oojs-ui/themes/apex/images/icons/unFlag-rtl.svg
new file mode 100644 (file)
index 0000000..5d94425
--- /dev/null
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
+       <path d="M3.5 19.6l16-16 1.1 1.1-3.2 3.2V20h-1v-7c-.6-.6-2-.8-3.4-.7l-8.4 8.4-1.1-1.1zM6.3 14V7c.7.7 2.7.9 4 .5V6c1.2-1.3 3.9-1.3 5.4-.5l-8.9 9c-.3-.2-.4-.3-.5-.5z"/>
+</svg>
\ No newline at end of file
diff --git a/resources/lib/oojs-ui/themes/apex/images/icons/unTrash-ltr.png b/resources/lib/oojs-ui/themes/apex/images/icons/unTrash-ltr.png
new file mode 100644 (file)
index 0000000..87590fa
Binary files /dev/null and b/resources/lib/oojs-ui/themes/apex/images/icons/unTrash-ltr.png differ
diff --git a/resources/lib/oojs-ui/themes/apex/images/icons/unTrash-ltr.svg b/resources/lib/oojs-ui/themes/apex/images/icons/unTrash-ltr.svg
new file mode 100644 (file)
index 0000000..9a625b8
--- /dev/null
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
+    <path d="M4.5 3.5l-1 1L6 7v2h1v7.97L8 18h6.97l.03-.03 1-.97 2.5 2.5 1-1L16 15l-1-1-1-1-1-1-1-1-1-1-1-1-1-1-1-1-1-1zM9 5v1l1 1h6v1h-5l1 1h3v3l1 1V9h1V6h-3V5zM8 9l1 1v6h1v-5l1 1v4h1v-3l1 1v2h1v-1l1 1v1H8zm5 1l1 1v-1z" id="trash-can-undo"/>
+</svg>
diff --git a/resources/lib/oojs-ui/themes/apex/images/icons/unTrash-rtl.png b/resources/lib/oojs-ui/themes/apex/images/icons/unTrash-rtl.png
new file mode 100644 (file)
index 0000000..dd35023
Binary files /dev/null and b/resources/lib/oojs-ui/themes/apex/images/icons/unTrash-rtl.png differ
diff --git a/resources/lib/oojs-ui/themes/apex/images/icons/unTrash-rtl.svg b/resources/lib/oojs-ui/themes/apex/images/icons/unTrash-rtl.svg
new file mode 100644 (file)
index 0000000..17ca8dc
--- /dev/null
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
+    <path d="M18.5 3.5l1 1L17 7v2h-1v7.97L15 18H8.03L8 17.97 7 17l-2.5 2.5-1-1L7 15l1-1 1-1 1-1 1-1 1-1 1-1 1-1 1-1 1-1zM14 5v1l-1 1H7v1h5l-1 1H8v3l-1 1V9H6V6h3V5zm1 4l-1 1v6h-1v-5l-1 1v4h-1v-3l-1 1v2H9v-1l-1 1v1h7zm-5 1l-1 1v-1z" id="trash-can-undo"/>
+</svg>
index f110a04..e040ffb 100644 (file)
@@ -23,7 +23,7 @@
        },
        "images": {
                "beta": { "file": "images/icons/beta.svg" },
-               "betaLaunch": { "file": "images/icons/betaLaunch.svg" },
+               "betaLaunch": { "file": "images/icons/logo-wikimediaDiscovery.svg" },
                "bookmark": { "file": {
                        "ltr": "images/icons/bookmark-ltr.svg",
                        "rtl": "images/icons/bookmark-rtl.svg"
index 3779ae3..9cc0f32 100644 (file)
        "images": {
                "block": { "file": "images/icons/block.svg", "variants": [ "destructive" ] },
                "blockUndo": { "file": {
-                       "ltr": "images/icons/blockUndo-ltr.svg",
-                       "rtl": "images/icons/blockUndo-rtl.svg"
+                       "ltr": "images/icons/unBlock-ltr.svg",
+                       "rtl": "images/icons/unBlock-rtl.svg"
+               } },
+               "unBlock": { "file": {
+                       "ltr": "images/icons/unBlock-ltr.svg",
+                       "rtl": "images/icons/unBlock-rtl.svg"
                } },
                "flag": { "file": {
                        "ltr": "images/icons/flag-ltr.svg",
                        "rtl": "images/icons/flag-rtl.svg"
                } },
+               "unFlag": { "file": {
+                       "ltr": "images/icons/unFlag-ltr.svg",
+                       "rtl": "images/icons/unFlag-rtl.svg"
+               } },
                "flagUndo": { "file": {
-                       "ltr": "images/icons/flagUndo-ltr.svg",
-                       "rtl": "images/icons/flagUndo-rtl.svg"
+                       "ltr": "images/icons/unFlag-ltr.svg",
+                       "rtl": "images/icons/unFlag-rtl.svg"
                } },
                "lock": { "file": {
                        "ltr": "images/icons/lock-ltr.svg",
                        "rtl": "images/icons/lock-rtl.svg"
                }, "variants": [ "destructive" ] },
+               "unLock": { "file": {
+                       "ltr": "images/icons/unLock-ltr.svg",
+                       "rtl": "images/icons/unLock-rtl.svg"
+               }, "variants": [ "destructive" ] },
+               "star": { "file": "images/icons/star.svg", "variants": [ "constructive", "progressive" ] },
+               "unStar": { "file": "images/icons/unStar.svg", "variants": [ "constructive", "progressive" ] },
+               "trash": { "file": "images/icons/trash.svg" },
+               "unTrash": { "file": {
+                       "ltr": "images/icons/unTrash-ltr.svg",
+                       "rtl": "images/icons/unTrash-rtl.svg"
+               } },
+               "trashUndo": { "file": {
+                       "ltr": "images/icons/unTrash-ltr.svg",
+                       "rtl": "images/icons/unTrash-rtl.svg"
+               } },
                "ongoingConversation": {
                        "file": {
                                "ltr": "images/icons/ongoingConversation-ltr.svg",
                                "rtl": "images/icons/ongoingConversation-rtl.svg"
                        },
                        "variants": [ "progressive" ]
-               },
-               "star": { "file": "images/icons/star.svg", "variants": [ "constructive", "progressive" ] },
-               "trash": { "file": "images/icons/trash.svg" },
-               "trashUndo": { "file": {
-                       "ltr": "images/icons/trashUndo-ltr.svg",
-                       "rtl": "images/icons/trashUndo-rtl.svg"
-               } },
-               "unLock": { "file": {
-                       "ltr": "images/icons/unLock-ltr.svg",
-                       "rtl": "images/icons/unLock-rtl.svg"
-               }, "variants": [ "destructive" ] },
-               "unStar": { "file": "images/icons/unStar.svg", "variants": [ "constructive", "progressive" ] }
+               }
        }
 }
index 61aec85..14f6b18 100644 (file)
@@ -24,6 +24,7 @@
        "images": {
                "logoCC": { "file": "images/icons/logo-cc.svg" },
                "logoWikimediaCommons": { "file": "images/icons/logo-wikimediaCommons.svg" },
+               "logoWikimediaDiscovery": { "file": "images/icons/logo-wikimediaDiscovery.svg" },
                "logoWikipedia": { "file": "images/icons/logo-wikipedia.svg" }
        }
 }
diff --git a/resources/lib/oojs-ui/themes/mediawiki/images/icons/betaLaunch-invert.png b/resources/lib/oojs-ui/themes/mediawiki/images/icons/betaLaunch-invert.png
deleted file mode 100644 (file)
index 0963538..0000000
Binary files a/resources/lib/oojs-ui/themes/mediawiki/images/icons/betaLaunch-invert.png and /dev/null differ
diff --git a/resources/lib/oojs-ui/themes/mediawiki/images/icons/betaLaunch-invert.svg b/resources/lib/oojs-ui/themes/mediawiki/images/icons/betaLaunch-invert.svg
deleted file mode 100644 (file)
index 21548d9..0000000
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #fff }</style>
-    <path d="M15.3 14.7C16.1 10.9 14.7 4 12 4c-2.7 0-4.2 6.7-3.4 10.5L7 18h2.7l.3 1h4c.2-.3.1-.5.3-1H17l-1.7-3.3zM12 10c-.8 0-1.5-.7-1.5-1.5S11.2 7 12 7s1.5.7 1.5 1.5S12.8 10 12 10zm2 10c0 1.1-2 2-2 2s-2-.9-2-2"/>
-</svg>
diff --git a/resources/lib/oojs-ui/themes/mediawiki/images/icons/betaLaunch-progressive.png b/resources/lib/oojs-ui/themes/mediawiki/images/icons/betaLaunch-progressive.png
deleted file mode 100644 (file)
index 6afb2bd..0000000
Binary files a/resources/lib/oojs-ui/themes/mediawiki/images/icons/betaLaunch-progressive.png and /dev/null differ
diff --git a/resources/lib/oojs-ui/themes/mediawiki/images/icons/betaLaunch-progressive.svg b/resources/lib/oojs-ui/themes/mediawiki/images/icons/betaLaunch-progressive.svg
deleted file mode 100644 (file)
index 359d032..0000000
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #36c }</style>
-    <path d="M15.3 14.7C16.1 10.9 14.7 4 12 4c-2.7 0-4.2 6.7-3.4 10.5L7 18h2.7l.3 1h4c.2-.3.1-.5.3-1H17l-1.7-3.3zM12 10c-.8 0-1.5-.7-1.5-1.5S11.2 7 12 7s1.5.7 1.5 1.5S12.8 10 12 10zm2 10c0 1.1-2 2-2 2s-2-.9-2-2"/>
-</svg>
diff --git a/resources/lib/oojs-ui/themes/mediawiki/images/icons/betaLaunch.png b/resources/lib/oojs-ui/themes/mediawiki/images/icons/betaLaunch.png
deleted file mode 100644 (file)
index 6d3c067..0000000
Binary files a/resources/lib/oojs-ui/themes/mediawiki/images/icons/betaLaunch.png and /dev/null differ
diff --git a/resources/lib/oojs-ui/themes/mediawiki/images/icons/betaLaunch.svg b/resources/lib/oojs-ui/themes/mediawiki/images/icons/betaLaunch.svg
deleted file mode 100644 (file)
index c3f99d6..0000000
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
-    <path d="M15.3 14.7C16.1 10.9 14.7 4 12 4c-2.7 0-4.2 6.7-3.4 10.5L7 18h2.7l.3 1h4c.2-.3.1-.5.3-1H17l-1.7-3.3zM12 10c-.8 0-1.5-.7-1.5-1.5S11.2 7 12 7s1.5.7 1.5 1.5S12.8 10 12 10zm2 10c0 1.1-2 2-2 2s-2-.9-2-2"/>
-</svg>
diff --git a/resources/lib/oojs-ui/themes/mediawiki/images/icons/blockUndo-ltr-invert.png b/resources/lib/oojs-ui/themes/mediawiki/images/icons/blockUndo-ltr-invert.png
deleted file mode 100644 (file)
index 7426f56..0000000
Binary files a/resources/lib/oojs-ui/themes/mediawiki/images/icons/blockUndo-ltr-invert.png and /dev/null differ
diff --git a/resources/lib/oojs-ui/themes/mediawiki/images/icons/blockUndo-ltr-invert.svg b/resources/lib/oojs-ui/themes/mediawiki/images/icons/blockUndo-ltr-invert.svg
deleted file mode 100644 (file)
index 36fd719..0000000
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #fff }</style>
-    <path d="M17 11v2h-2l3.6 3.6c.9-1.3 1.4-2.9 1.4-4.6 0-4.4-3.6-8-8-8-1.7 0-3.3.5-4.6 1.4L13 11h4zM4 4L3 5l2.4 2.4C4.5 8.7 4 10.3 4 12c0 4.4 3.6 8 8 8 1.7 0 3.3-.5 4.6-1.4L19 21l1-1L4 4zm3 9v-2h2l2 2H7z"/>
-</svg>
diff --git a/resources/lib/oojs-ui/themes/mediawiki/images/icons/blockUndo-ltr-progressive.png b/resources/lib/oojs-ui/themes/mediawiki/images/icons/blockUndo-ltr-progressive.png
deleted file mode 100644 (file)
index d797f3e..0000000
Binary files a/resources/lib/oojs-ui/themes/mediawiki/images/icons/blockUndo-ltr-progressive.png and /dev/null differ
diff --git a/resources/lib/oojs-ui/themes/mediawiki/images/icons/blockUndo-ltr-progressive.svg b/resources/lib/oojs-ui/themes/mediawiki/images/icons/blockUndo-ltr-progressive.svg
deleted file mode 100644 (file)
index bc96e99..0000000
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #36c }</style>
-    <path d="M17 11v2h-2l3.6 3.6c.9-1.3 1.4-2.9 1.4-4.6 0-4.4-3.6-8-8-8-1.7 0-3.3.5-4.6 1.4L13 11h4zM4 4L3 5l2.4 2.4C4.5 8.7 4 10.3 4 12c0 4.4 3.6 8 8 8 1.7 0 3.3-.5 4.6-1.4L19 21l1-1L4 4zm3 9v-2h2l2 2H7z"/>
-</svg>
diff --git a/resources/lib/oojs-ui/themes/mediawiki/images/icons/blockUndo-ltr.png b/resources/lib/oojs-ui/themes/mediawiki/images/icons/blockUndo-ltr.png
deleted file mode 100644 (file)
index 640bb2a..0000000
Binary files a/resources/lib/oojs-ui/themes/mediawiki/images/icons/blockUndo-ltr.png and /dev/null differ
diff --git a/resources/lib/oojs-ui/themes/mediawiki/images/icons/blockUndo-ltr.svg b/resources/lib/oojs-ui/themes/mediawiki/images/icons/blockUndo-ltr.svg
deleted file mode 100644 (file)
index 160219c..0000000
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
-    <path d="M17 11v2h-2l3.6 3.6c.9-1.3 1.4-2.9 1.4-4.6 0-4.4-3.6-8-8-8-1.7 0-3.3.5-4.6 1.4L13 11h4zM4 4L3 5l2.4 2.4C4.5 8.7 4 10.3 4 12c0 4.4 3.6 8 8 8 1.7 0 3.3-.5 4.6-1.4L19 21l1-1L4 4zm3 9v-2h2l2 2H7z"/>
-</svg>
diff --git a/resources/lib/oojs-ui/themes/mediawiki/images/icons/blockUndo-rtl-invert.png b/resources/lib/oojs-ui/themes/mediawiki/images/icons/blockUndo-rtl-invert.png
deleted file mode 100644 (file)
index a02e2e0..0000000
Binary files a/resources/lib/oojs-ui/themes/mediawiki/images/icons/blockUndo-rtl-invert.png and /dev/null differ
diff --git a/resources/lib/oojs-ui/themes/mediawiki/images/icons/blockUndo-rtl-invert.svg b/resources/lib/oojs-ui/themes/mediawiki/images/icons/blockUndo-rtl-invert.svg
deleted file mode 100644 (file)
index b6f1610..0000000
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #fff }</style>
-    <path d="M7 11v2h2l-3.6 3.6C4.5 15.3 4 13.7 4 12c0-4.4 3.6-8 8-8 1.7 0 3.3.5 4.6 1.4L11 11H7zm13-7l1 1-2.4 2.4c.9 1.3 1.4 2.9 1.4 4.6 0 4.4-3.6 8-8 8-1.7 0-3.3-.5-4.6-1.4L5 21l-1-1L20 4zm-3 9v-2h-2l-2 2h4z"/>
-</svg>
diff --git a/resources/lib/oojs-ui/themes/mediawiki/images/icons/blockUndo-rtl-progressive.png b/resources/lib/oojs-ui/themes/mediawiki/images/icons/blockUndo-rtl-progressive.png
deleted file mode 100644 (file)
index 4d062cb..0000000
Binary files a/resources/lib/oojs-ui/themes/mediawiki/images/icons/blockUndo-rtl-progressive.png and /dev/null differ
diff --git a/resources/lib/oojs-ui/themes/mediawiki/images/icons/blockUndo-rtl-progressive.svg b/resources/lib/oojs-ui/themes/mediawiki/images/icons/blockUndo-rtl-progressive.svg
deleted file mode 100644 (file)
index dc03220..0000000
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #36c }</style>
-    <path d="M7 11v2h2l-3.6 3.6C4.5 15.3 4 13.7 4 12c0-4.4 3.6-8 8-8 1.7 0 3.3.5 4.6 1.4L11 11H7zm13-7l1 1-2.4 2.4c.9 1.3 1.4 2.9 1.4 4.6 0 4.4-3.6 8-8 8-1.7 0-3.3-.5-4.6-1.4L5 21l-1-1L20 4zm-3 9v-2h-2l-2 2h4z"/>
-</svg>
diff --git a/resources/lib/oojs-ui/themes/mediawiki/images/icons/blockUndo-rtl.png b/resources/lib/oojs-ui/themes/mediawiki/images/icons/blockUndo-rtl.png
deleted file mode 100644 (file)
index 2475b06..0000000
Binary files a/resources/lib/oojs-ui/themes/mediawiki/images/icons/blockUndo-rtl.png and /dev/null differ
diff --git a/resources/lib/oojs-ui/themes/mediawiki/images/icons/blockUndo-rtl.svg b/resources/lib/oojs-ui/themes/mediawiki/images/icons/blockUndo-rtl.svg
deleted file mode 100644 (file)
index 90fe46a..0000000
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
-    <path d="M7 11v2h2l-3.6 3.6C4.5 15.3 4 13.7 4 12c0-4.4 3.6-8 8-8 1.7 0 3.3.5 4.6 1.4L11 11H7zm13-7l1 1-2.4 2.4c.9 1.3 1.4 2.9 1.4 4.6 0 4.4-3.6 8-8 8-1.7 0-3.3-.5-4.6-1.4L5 21l-1-1L20 4zm-3 9v-2h-2l-2 2h4z"/>
-</svg>
diff --git a/resources/lib/oojs-ui/themes/mediawiki/images/icons/flagUndo-ltr-invert.png b/resources/lib/oojs-ui/themes/mediawiki/images/icons/flagUndo-ltr-invert.png
deleted file mode 100644 (file)
index 8338017..0000000
Binary files a/resources/lib/oojs-ui/themes/mediawiki/images/icons/flagUndo-ltr-invert.png and /dev/null differ
diff --git a/resources/lib/oojs-ui/themes/mediawiki/images/icons/flagUndo-ltr-invert.svg b/resources/lib/oojs-ui/themes/mediawiki/images/icons/flagUndo-ltr-invert.svg
deleted file mode 100644 (file)
index c73d23f..0000000
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #fff }</style>
-       <path d="M19.9 19.6l-16-16-1.1 1.1L6 7.9V20h1v-7c.6-.6 2-.8 3.4-.7l8.4 8.4 1.1-1.1zM17 14V7c-.7.7-2.7.9-4 .5V6c-1.2-1.3-3.9-1.3-5.4-.5l8.9 9c.3-.2.4-.3.5-.5z"/>
-</svg>
\ No newline at end of file
diff --git a/resources/lib/oojs-ui/themes/mediawiki/images/icons/flagUndo-ltr-progressive.png b/resources/lib/oojs-ui/themes/mediawiki/images/icons/flagUndo-ltr-progressive.png
deleted file mode 100644 (file)
index bf1a6e0..0000000
Binary files a/resources/lib/oojs-ui/themes/mediawiki/images/icons/flagUndo-ltr-progressive.png and /dev/null differ
diff --git a/resources/lib/oojs-ui/themes/mediawiki/images/icons/flagUndo-ltr-progressive.svg b/resources/lib/oojs-ui/themes/mediawiki/images/icons/flagUndo-ltr-progressive.svg
deleted file mode 100644 (file)
index 16b6d3a..0000000
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #36c }</style>
-       <path d="M19.9 19.6l-16-16-1.1 1.1L6 7.9V20h1v-7c.6-.6 2-.8 3.4-.7l8.4 8.4 1.1-1.1zM17 14V7c-.7.7-2.7.9-4 .5V6c-1.2-1.3-3.9-1.3-5.4-.5l8.9 9c.3-.2.4-.3.5-.5z"/>
-</svg>
\ No newline at end of file
diff --git a/resources/lib/oojs-ui/themes/mediawiki/images/icons/flagUndo-ltr.png b/resources/lib/oojs-ui/themes/mediawiki/images/icons/flagUndo-ltr.png
deleted file mode 100644 (file)
index 780cb87..0000000
Binary files a/resources/lib/oojs-ui/themes/mediawiki/images/icons/flagUndo-ltr.png and /dev/null differ
diff --git a/resources/lib/oojs-ui/themes/mediawiki/images/icons/flagUndo-ltr.svg b/resources/lib/oojs-ui/themes/mediawiki/images/icons/flagUndo-ltr.svg
deleted file mode 100644 (file)
index 4bbd61c..0000000
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
-       <path d="M19.9 19.6l-16-16-1.1 1.1L6 7.9V20h1v-7c.6-.6 2-.8 3.4-.7l8.4 8.4 1.1-1.1zM17 14V7c-.7.7-2.7.9-4 .5V6c-1.2-1.3-3.9-1.3-5.4-.5l8.9 9c.3-.2.4-.3.5-.5z"/>
-</svg>
\ No newline at end of file
diff --git a/resources/lib/oojs-ui/themes/mediawiki/images/icons/flagUndo-rtl-invert.png b/resources/lib/oojs-ui/themes/mediawiki/images/icons/flagUndo-rtl-invert.png
deleted file mode 100644 (file)
index 4f9c3ad..0000000
Binary files a/resources/lib/oojs-ui/themes/mediawiki/images/icons/flagUndo-rtl-invert.png and /dev/null differ
diff --git a/resources/lib/oojs-ui/themes/mediawiki/images/icons/flagUndo-rtl-invert.svg b/resources/lib/oojs-ui/themes/mediawiki/images/icons/flagUndo-rtl-invert.svg
deleted file mode 100644 (file)
index 440390e..0000000
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #fff }</style>
-       <path d="M3.5 19.6l16-16 1.1 1.1-3.2 3.2V20h-1v-7c-.6-.6-2-.8-3.4-.7l-8.4 8.4-1.1-1.1zM6.3 14V7c.7.7 2.7.9 4 .5V6c1.2-1.3 3.9-1.3 5.4-.5l-8.9 9c-.3-.2-.4-.3-.5-.5z"/>
-</svg>
\ No newline at end of file
diff --git a/resources/lib/oojs-ui/themes/mediawiki/images/icons/flagUndo-rtl-progressive.png b/resources/lib/oojs-ui/themes/mediawiki/images/icons/flagUndo-rtl-progressive.png
deleted file mode 100644 (file)
index 4abe9c8..0000000
Binary files a/resources/lib/oojs-ui/themes/mediawiki/images/icons/flagUndo-rtl-progressive.png and /dev/null differ
diff --git a/resources/lib/oojs-ui/themes/mediawiki/images/icons/flagUndo-rtl-progressive.svg b/resources/lib/oojs-ui/themes/mediawiki/images/icons/flagUndo-rtl-progressive.svg
deleted file mode 100644 (file)
index 7f45734..0000000
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #36c }</style>
-       <path d="M3.5 19.6l16-16 1.1 1.1-3.2 3.2V20h-1v-7c-.6-.6-2-.8-3.4-.7l-8.4 8.4-1.1-1.1zM6.3 14V7c.7.7 2.7.9 4 .5V6c1.2-1.3 3.9-1.3 5.4-.5l-8.9 9c-.3-.2-.4-.3-.5-.5z"/>
-</svg>
\ No newline at end of file
diff --git a/resources/lib/oojs-ui/themes/mediawiki/images/icons/flagUndo-rtl.png b/resources/lib/oojs-ui/themes/mediawiki/images/icons/flagUndo-rtl.png
deleted file mode 100644 (file)
index fa3696a..0000000
Binary files a/resources/lib/oojs-ui/themes/mediawiki/images/icons/flagUndo-rtl.png and /dev/null differ
diff --git a/resources/lib/oojs-ui/themes/mediawiki/images/icons/flagUndo-rtl.svg b/resources/lib/oojs-ui/themes/mediawiki/images/icons/flagUndo-rtl.svg
deleted file mode 100644 (file)
index 5d94425..0000000
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
-       <path d="M3.5 19.6l16-16 1.1 1.1-3.2 3.2V20h-1v-7c-.6-.6-2-.8-3.4-.7l-8.4 8.4-1.1-1.1zM6.3 14V7c.7.7 2.7.9 4 .5V6c1.2-1.3 3.9-1.3 5.4-.5l-8.9 9c-.3-.2-.4-.3-.5-.5z"/>
-</svg>
\ No newline at end of file
diff --git a/resources/lib/oojs-ui/themes/mediawiki/images/icons/logo-wikimediaDiscovery-invert.png b/resources/lib/oojs-ui/themes/mediawiki/images/icons/logo-wikimediaDiscovery-invert.png
new file mode 100644 (file)
index 0000000..0963538
Binary files /dev/null and b/resources/lib/oojs-ui/themes/mediawiki/images/icons/logo-wikimediaDiscovery-invert.png differ
diff --git a/resources/lib/oojs-ui/themes/mediawiki/images/icons/logo-wikimediaDiscovery-invert.svg b/resources/lib/oojs-ui/themes/mediawiki/images/icons/logo-wikimediaDiscovery-invert.svg
new file mode 100644 (file)
index 0000000..21548d9
--- /dev/null
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #fff }</style>
+    <path d="M15.3 14.7C16.1 10.9 14.7 4 12 4c-2.7 0-4.2 6.7-3.4 10.5L7 18h2.7l.3 1h4c.2-.3.1-.5.3-1H17l-1.7-3.3zM12 10c-.8 0-1.5-.7-1.5-1.5S11.2 7 12 7s1.5.7 1.5 1.5S12.8 10 12 10zm2 10c0 1.1-2 2-2 2s-2-.9-2-2"/>
+</svg>
diff --git a/resources/lib/oojs-ui/themes/mediawiki/images/icons/logo-wikimediaDiscovery-progressive.png b/resources/lib/oojs-ui/themes/mediawiki/images/icons/logo-wikimediaDiscovery-progressive.png
new file mode 100644 (file)
index 0000000..6afb2bd
Binary files /dev/null and b/resources/lib/oojs-ui/themes/mediawiki/images/icons/logo-wikimediaDiscovery-progressive.png differ
diff --git a/resources/lib/oojs-ui/themes/mediawiki/images/icons/logo-wikimediaDiscovery-progressive.svg b/resources/lib/oojs-ui/themes/mediawiki/images/icons/logo-wikimediaDiscovery-progressive.svg
new file mode 100644 (file)
index 0000000..359d032
--- /dev/null
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #36c }</style>
+    <path d="M15.3 14.7C16.1 10.9 14.7 4 12 4c-2.7 0-4.2 6.7-3.4 10.5L7 18h2.7l.3 1h4c.2-.3.1-.5.3-1H17l-1.7-3.3zM12 10c-.8 0-1.5-.7-1.5-1.5S11.2 7 12 7s1.5.7 1.5 1.5S12.8 10 12 10zm2 10c0 1.1-2 2-2 2s-2-.9-2-2"/>
+</svg>
diff --git a/resources/lib/oojs-ui/themes/mediawiki/images/icons/logo-wikimediaDiscovery.png b/resources/lib/oojs-ui/themes/mediawiki/images/icons/logo-wikimediaDiscovery.png
new file mode 100644 (file)
index 0000000..6d3c067
Binary files /dev/null and b/resources/lib/oojs-ui/themes/mediawiki/images/icons/logo-wikimediaDiscovery.png differ
diff --git a/resources/lib/oojs-ui/themes/mediawiki/images/icons/logo-wikimediaDiscovery.svg b/resources/lib/oojs-ui/themes/mediawiki/images/icons/logo-wikimediaDiscovery.svg
new file mode 100644 (file)
index 0000000..c3f99d6
--- /dev/null
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
+    <path d="M15.3 14.7C16.1 10.9 14.7 4 12 4c-2.7 0-4.2 6.7-3.4 10.5L7 18h2.7l.3 1h4c.2-.3.1-.5.3-1H17l-1.7-3.3zM12 10c-.8 0-1.5-.7-1.5-1.5S11.2 7 12 7s1.5.7 1.5 1.5S12.8 10 12 10zm2 10c0 1.1-2 2-2 2s-2-.9-2-2"/>
+</svg>
diff --git a/resources/lib/oojs-ui/themes/mediawiki/images/icons/trashUndo-ltr-invert.png b/resources/lib/oojs-ui/themes/mediawiki/images/icons/trashUndo-ltr-invert.png
deleted file mode 100644 (file)
index af3f0e9..0000000
Binary files a/resources/lib/oojs-ui/themes/mediawiki/images/icons/trashUndo-ltr-invert.png and /dev/null differ
diff --git a/resources/lib/oojs-ui/themes/mediawiki/images/icons/trashUndo-ltr-invert.svg b/resources/lib/oojs-ui/themes/mediawiki/images/icons/trashUndo-ltr-invert.svg
deleted file mode 100644 (file)
index 0763ff8..0000000
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #fff }</style>
-    <path d="M20.5 20.5L5 5 4 6l3 3 1 11h8l.2-1.8 3.3 3.3zM17 9h-6l5.5 5.5zm1-1c0-1.1-.9-2-2-2h-2l-1-1h-2l-1 1H8l2 2h8z"/>
-</svg>
diff --git a/resources/lib/oojs-ui/themes/mediawiki/images/icons/trashUndo-ltr-progressive.png b/resources/lib/oojs-ui/themes/mediawiki/images/icons/trashUndo-ltr-progressive.png
deleted file mode 100644 (file)
index 2f09eb6..0000000
Binary files a/resources/lib/oojs-ui/themes/mediawiki/images/icons/trashUndo-ltr-progressive.png and /dev/null differ
diff --git a/resources/lib/oojs-ui/themes/mediawiki/images/icons/trashUndo-ltr-progressive.svg b/resources/lib/oojs-ui/themes/mediawiki/images/icons/trashUndo-ltr-progressive.svg
deleted file mode 100644 (file)
index 6d1fdd9..0000000
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #36c }</style>
-    <path d="M20.5 20.5L5 5 4 6l3 3 1 11h8l.2-1.8 3.3 3.3zM17 9h-6l5.5 5.5zm1-1c0-1.1-.9-2-2-2h-2l-1-1h-2l-1 1H8l2 2h8z"/>
-</svg>
diff --git a/resources/lib/oojs-ui/themes/mediawiki/images/icons/trashUndo-ltr.png b/resources/lib/oojs-ui/themes/mediawiki/images/icons/trashUndo-ltr.png
deleted file mode 100644 (file)
index 3b5231f..0000000
Binary files a/resources/lib/oojs-ui/themes/mediawiki/images/icons/trashUndo-ltr.png and /dev/null differ
diff --git a/resources/lib/oojs-ui/themes/mediawiki/images/icons/trashUndo-ltr.svg b/resources/lib/oojs-ui/themes/mediawiki/images/icons/trashUndo-ltr.svg
deleted file mode 100644 (file)
index 64b3b71..0000000
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
-    <path d="M20.5 20.5L5 5 4 6l3 3 1 11h8l.2-1.8 3.3 3.3zM17 9h-6l5.5 5.5zm1-1c0-1.1-.9-2-2-2h-2l-1-1h-2l-1 1H8l2 2h8z"/>
-</svg>
diff --git a/resources/lib/oojs-ui/themes/mediawiki/images/icons/trashUndo-rtl-invert.png b/resources/lib/oojs-ui/themes/mediawiki/images/icons/trashUndo-rtl-invert.png
deleted file mode 100644 (file)
index 1cb5449..0000000
Binary files a/resources/lib/oojs-ui/themes/mediawiki/images/icons/trashUndo-rtl-invert.png and /dev/null differ
diff --git a/resources/lib/oojs-ui/themes/mediawiki/images/icons/trashUndo-rtl-invert.svg b/resources/lib/oojs-ui/themes/mediawiki/images/icons/trashUndo-rtl-invert.svg
deleted file mode 100644 (file)
index 12e57b2..0000000
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #fff }</style>
-    <path d="M4 20.5L19.5 5l1 1-3 3-1 11h-8l-.2-1.8L5 21.5zM7.5 9h6L8 14.5zm-1-1c0-1.1.9-2 2-2h2l1-1h2l1 1h2l-2 2h-8z"/>
-</svg>
diff --git a/resources/lib/oojs-ui/themes/mediawiki/images/icons/trashUndo-rtl-progressive.png b/resources/lib/oojs-ui/themes/mediawiki/images/icons/trashUndo-rtl-progressive.png
deleted file mode 100644 (file)
index e828b36..0000000
Binary files a/resources/lib/oojs-ui/themes/mediawiki/images/icons/trashUndo-rtl-progressive.png and /dev/null differ
diff --git a/resources/lib/oojs-ui/themes/mediawiki/images/icons/trashUndo-rtl-progressive.svg b/resources/lib/oojs-ui/themes/mediawiki/images/icons/trashUndo-rtl-progressive.svg
deleted file mode 100644 (file)
index 6395968..0000000
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #36c }</style>
-    <path d="M4 20.5L19.5 5l1 1-3 3-1 11h-8l-.2-1.8L5 21.5zM7.5 9h6L8 14.5zm-1-1c0-1.1.9-2 2-2h2l1-1h2l1 1h2l-2 2h-8z"/>
-</svg>
diff --git a/resources/lib/oojs-ui/themes/mediawiki/images/icons/trashUndo-rtl.png b/resources/lib/oojs-ui/themes/mediawiki/images/icons/trashUndo-rtl.png
deleted file mode 100644 (file)
index a1d2388..0000000
Binary files a/resources/lib/oojs-ui/themes/mediawiki/images/icons/trashUndo-rtl.png and /dev/null differ
diff --git a/resources/lib/oojs-ui/themes/mediawiki/images/icons/trashUndo-rtl.svg b/resources/lib/oojs-ui/themes/mediawiki/images/icons/trashUndo-rtl.svg
deleted file mode 100644 (file)
index e5e4032..0000000
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
-    <path d="M4 20.5L19.5 5l1 1-3 3-1 11h-8l-.2-1.8L5 21.5zM7.5 9h6L8 14.5zm-1-1c0-1.1.9-2 2-2h2l1-1h2l1 1h2l-2 2h-8z"/>
-</svg>
diff --git a/resources/lib/oojs-ui/themes/mediawiki/images/icons/unBlock-ltr-invert.png b/resources/lib/oojs-ui/themes/mediawiki/images/icons/unBlock-ltr-invert.png
new file mode 100644 (file)
index 0000000..7426f56
Binary files /dev/null and b/resources/lib/oojs-ui/themes/mediawiki/images/icons/unBlock-ltr-invert.png differ
diff --git a/resources/lib/oojs-ui/themes/mediawiki/images/icons/unBlock-ltr-invert.svg b/resources/lib/oojs-ui/themes/mediawiki/images/icons/unBlock-ltr-invert.svg
new file mode 100644 (file)
index 0000000..36fd719
--- /dev/null
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #fff }</style>
+    <path d="M17 11v2h-2l3.6 3.6c.9-1.3 1.4-2.9 1.4-4.6 0-4.4-3.6-8-8-8-1.7 0-3.3.5-4.6 1.4L13 11h4zM4 4L3 5l2.4 2.4C4.5 8.7 4 10.3 4 12c0 4.4 3.6 8 8 8 1.7 0 3.3-.5 4.6-1.4L19 21l1-1L4 4zm3 9v-2h2l2 2H7z"/>
+</svg>
diff --git a/resources/lib/oojs-ui/themes/mediawiki/images/icons/unBlock-ltr-progressive.png b/resources/lib/oojs-ui/themes/mediawiki/images/icons/unBlock-ltr-progressive.png
new file mode 100644 (file)
index 0000000..d797f3e
Binary files /dev/null and b/resources/lib/oojs-ui/themes/mediawiki/images/icons/unBlock-ltr-progressive.png differ
diff --git a/resources/lib/oojs-ui/themes/mediawiki/images/icons/unBlock-ltr-progressive.svg b/resources/lib/oojs-ui/themes/mediawiki/images/icons/unBlock-ltr-progressive.svg
new file mode 100644 (file)
index 0000000..bc96e99
--- /dev/null
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #36c }</style>
+    <path d="M17 11v2h-2l3.6 3.6c.9-1.3 1.4-2.9 1.4-4.6 0-4.4-3.6-8-8-8-1.7 0-3.3.5-4.6 1.4L13 11h4zM4 4L3 5l2.4 2.4C4.5 8.7 4 10.3 4 12c0 4.4 3.6 8 8 8 1.7 0 3.3-.5 4.6-1.4L19 21l1-1L4 4zm3 9v-2h2l2 2H7z"/>
+</svg>
diff --git a/resources/lib/oojs-ui/themes/mediawiki/images/icons/unBlock-ltr.png b/resources/lib/oojs-ui/themes/mediawiki/images/icons/unBlock-ltr.png
new file mode 100644 (file)
index 0000000..640bb2a
Binary files /dev/null and b/resources/lib/oojs-ui/themes/mediawiki/images/icons/unBlock-ltr.png differ
diff --git a/resources/lib/oojs-ui/themes/mediawiki/images/icons/unBlock-ltr.svg b/resources/lib/oojs-ui/themes/mediawiki/images/icons/unBlock-ltr.svg
new file mode 100644 (file)
index 0000000..160219c
--- /dev/null
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
+    <path d="M17 11v2h-2l3.6 3.6c.9-1.3 1.4-2.9 1.4-4.6 0-4.4-3.6-8-8-8-1.7 0-3.3.5-4.6 1.4L13 11h4zM4 4L3 5l2.4 2.4C4.5 8.7 4 10.3 4 12c0 4.4 3.6 8 8 8 1.7 0 3.3-.5 4.6-1.4L19 21l1-1L4 4zm3 9v-2h2l2 2H7z"/>
+</svg>
diff --git a/resources/lib/oojs-ui/themes/mediawiki/images/icons/unBlock-rtl-invert.png b/resources/lib/oojs-ui/themes/mediawiki/images/icons/unBlock-rtl-invert.png
new file mode 100644 (file)
index 0000000..a02e2e0
Binary files /dev/null and b/resources/lib/oojs-ui/themes/mediawiki/images/icons/unBlock-rtl-invert.png differ
diff --git a/resources/lib/oojs-ui/themes/mediawiki/images/icons/unBlock-rtl-invert.svg b/resources/lib/oojs-ui/themes/mediawiki/images/icons/unBlock-rtl-invert.svg
new file mode 100644 (file)
index 0000000..b6f1610
--- /dev/null
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #fff }</style>
+    <path d="M7 11v2h2l-3.6 3.6C4.5 15.3 4 13.7 4 12c0-4.4 3.6-8 8-8 1.7 0 3.3.5 4.6 1.4L11 11H7zm13-7l1 1-2.4 2.4c.9 1.3 1.4 2.9 1.4 4.6 0 4.4-3.6 8-8 8-1.7 0-3.3-.5-4.6-1.4L5 21l-1-1L20 4zm-3 9v-2h-2l-2 2h4z"/>
+</svg>
diff --git a/resources/lib/oojs-ui/themes/mediawiki/images/icons/unBlock-rtl-progressive.png b/resources/lib/oojs-ui/themes/mediawiki/images/icons/unBlock-rtl-progressive.png
new file mode 100644 (file)
index 0000000..4d062cb
Binary files /dev/null and b/resources/lib/oojs-ui/themes/mediawiki/images/icons/unBlock-rtl-progressive.png differ
diff --git a/resources/lib/oojs-ui/themes/mediawiki/images/icons/unBlock-rtl-progressive.svg b/resources/lib/oojs-ui/themes/mediawiki/images/icons/unBlock-rtl-progressive.svg
new file mode 100644 (file)
index 0000000..dc03220
--- /dev/null
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #36c }</style>
+    <path d="M7 11v2h2l-3.6 3.6C4.5 15.3 4 13.7 4 12c0-4.4 3.6-8 8-8 1.7 0 3.3.5 4.6 1.4L11 11H7zm13-7l1 1-2.4 2.4c.9 1.3 1.4 2.9 1.4 4.6 0 4.4-3.6 8-8 8-1.7 0-3.3-.5-4.6-1.4L5 21l-1-1L20 4zm-3 9v-2h-2l-2 2h4z"/>
+</svg>
diff --git a/resources/lib/oojs-ui/themes/mediawiki/images/icons/unBlock-rtl.png b/resources/lib/oojs-ui/themes/mediawiki/images/icons/unBlock-rtl.png
new file mode 100644 (file)
index 0000000..2475b06
Binary files /dev/null and b/resources/lib/oojs-ui/themes/mediawiki/images/icons/unBlock-rtl.png differ
diff --git a/resources/lib/oojs-ui/themes/mediawiki/images/icons/unBlock-rtl.svg b/resources/lib/oojs-ui/themes/mediawiki/images/icons/unBlock-rtl.svg
new file mode 100644 (file)
index 0000000..90fe46a
--- /dev/null
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
+    <path d="M7 11v2h2l-3.6 3.6C4.5 15.3 4 13.7 4 12c0-4.4 3.6-8 8-8 1.7 0 3.3.5 4.6 1.4L11 11H7zm13-7l1 1-2.4 2.4c.9 1.3 1.4 2.9 1.4 4.6 0 4.4-3.6 8-8 8-1.7 0-3.3-.5-4.6-1.4L5 21l-1-1L20 4zm-3 9v-2h-2l-2 2h4z"/>
+</svg>
diff --git a/resources/lib/oojs-ui/themes/mediawiki/images/icons/unFlag-ltr-invert.png b/resources/lib/oojs-ui/themes/mediawiki/images/icons/unFlag-ltr-invert.png
new file mode 100644 (file)
index 0000000..8338017
Binary files /dev/null and b/resources/lib/oojs-ui/themes/mediawiki/images/icons/unFlag-ltr-invert.png differ
diff --git a/resources/lib/oojs-ui/themes/mediawiki/images/icons/unFlag-ltr-invert.svg b/resources/lib/oojs-ui/themes/mediawiki/images/icons/unFlag-ltr-invert.svg
new file mode 100644 (file)
index 0000000..c73d23f
--- /dev/null
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #fff }</style>
+       <path d="M19.9 19.6l-16-16-1.1 1.1L6 7.9V20h1v-7c.6-.6 2-.8 3.4-.7l8.4 8.4 1.1-1.1zM17 14V7c-.7.7-2.7.9-4 .5V6c-1.2-1.3-3.9-1.3-5.4-.5l8.9 9c.3-.2.4-.3.5-.5z"/>
+</svg>
\ No newline at end of file
diff --git a/resources/lib/oojs-ui/themes/mediawiki/images/icons/unFlag-ltr-progressive.png b/resources/lib/oojs-ui/themes/mediawiki/images/icons/unFlag-ltr-progressive.png
new file mode 100644 (file)
index 0000000..bf1a6e0
Binary files /dev/null and b/resources/lib/oojs-ui/themes/mediawiki/images/icons/unFlag-ltr-progressive.png differ
diff --git a/resources/lib/oojs-ui/themes/mediawiki/images/icons/unFlag-ltr-progressive.svg b/resources/lib/oojs-ui/themes/mediawiki/images/icons/unFlag-ltr-progressive.svg
new file mode 100644 (file)
index 0000000..16b6d3a
--- /dev/null
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #36c }</style>
+       <path d="M19.9 19.6l-16-16-1.1 1.1L6 7.9V20h1v-7c.6-.6 2-.8 3.4-.7l8.4 8.4 1.1-1.1zM17 14V7c-.7.7-2.7.9-4 .5V6c-1.2-1.3-3.9-1.3-5.4-.5l8.9 9c.3-.2.4-.3.5-.5z"/>
+</svg>
\ No newline at end of file
diff --git a/resources/lib/oojs-ui/themes/mediawiki/images/icons/unFlag-ltr.png b/resources/lib/oojs-ui/themes/mediawiki/images/icons/unFlag-ltr.png
new file mode 100644 (file)
index 0000000..780cb87
Binary files /dev/null and b/resources/lib/oojs-ui/themes/mediawiki/images/icons/unFlag-ltr.png differ
diff --git a/resources/lib/oojs-ui/themes/mediawiki/images/icons/unFlag-ltr.svg b/resources/lib/oojs-ui/themes/mediawiki/images/icons/unFlag-ltr.svg
new file mode 100644 (file)
index 0000000..4bbd61c
--- /dev/null
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
+       <path d="M19.9 19.6l-16-16-1.1 1.1L6 7.9V20h1v-7c.6-.6 2-.8 3.4-.7l8.4 8.4 1.1-1.1zM17 14V7c-.7.7-2.7.9-4 .5V6c-1.2-1.3-3.9-1.3-5.4-.5l8.9 9c.3-.2.4-.3.5-.5z"/>
+</svg>
\ No newline at end of file
diff --git a/resources/lib/oojs-ui/themes/mediawiki/images/icons/unFlag-rtl-invert.png b/resources/lib/oojs-ui/themes/mediawiki/images/icons/unFlag-rtl-invert.png
new file mode 100644 (file)
index 0000000..4f9c3ad
Binary files /dev/null and b/resources/lib/oojs-ui/themes/mediawiki/images/icons/unFlag-rtl-invert.png differ
diff --git a/resources/lib/oojs-ui/themes/mediawiki/images/icons/unFlag-rtl-invert.svg b/resources/lib/oojs-ui/themes/mediawiki/images/icons/unFlag-rtl-invert.svg
new file mode 100644 (file)
index 0000000..440390e
--- /dev/null
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #fff }</style>
+       <path d="M3.5 19.6l16-16 1.1 1.1-3.2 3.2V20h-1v-7c-.6-.6-2-.8-3.4-.7l-8.4 8.4-1.1-1.1zM6.3 14V7c.7.7 2.7.9 4 .5V6c1.2-1.3 3.9-1.3 5.4-.5l-8.9 9c-.3-.2-.4-.3-.5-.5z"/>
+</svg>
\ No newline at end of file
diff --git a/resources/lib/oojs-ui/themes/mediawiki/images/icons/unFlag-rtl-progressive.png b/resources/lib/oojs-ui/themes/mediawiki/images/icons/unFlag-rtl-progressive.png
new file mode 100644 (file)
index 0000000..4abe9c8
Binary files /dev/null and b/resources/lib/oojs-ui/themes/mediawiki/images/icons/unFlag-rtl-progressive.png differ
diff --git a/resources/lib/oojs-ui/themes/mediawiki/images/icons/unFlag-rtl-progressive.svg b/resources/lib/oojs-ui/themes/mediawiki/images/icons/unFlag-rtl-progressive.svg
new file mode 100644 (file)
index 0000000..7f45734
--- /dev/null
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #36c }</style>
+       <path d="M3.5 19.6l16-16 1.1 1.1-3.2 3.2V20h-1v-7c-.6-.6-2-.8-3.4-.7l-8.4 8.4-1.1-1.1zM6.3 14V7c.7.7 2.7.9 4 .5V6c1.2-1.3 3.9-1.3 5.4-.5l-8.9 9c-.3-.2-.4-.3-.5-.5z"/>
+</svg>
\ No newline at end of file
diff --git a/resources/lib/oojs-ui/themes/mediawiki/images/icons/unFlag-rtl.png b/resources/lib/oojs-ui/themes/mediawiki/images/icons/unFlag-rtl.png
new file mode 100644 (file)
index 0000000..fa3696a
Binary files /dev/null and b/resources/lib/oojs-ui/themes/mediawiki/images/icons/unFlag-rtl.png differ
diff --git a/resources/lib/oojs-ui/themes/mediawiki/images/icons/unFlag-rtl.svg b/resources/lib/oojs-ui/themes/mediawiki/images/icons/unFlag-rtl.svg
new file mode 100644 (file)
index 0000000..5d94425
--- /dev/null
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
+       <path d="M3.5 19.6l16-16 1.1 1.1-3.2 3.2V20h-1v-7c-.6-.6-2-.8-3.4-.7l-8.4 8.4-1.1-1.1zM6.3 14V7c.7.7 2.7.9 4 .5V6c1.2-1.3 3.9-1.3 5.4-.5l-8.9 9c-.3-.2-.4-.3-.5-.5z"/>
+</svg>
\ No newline at end of file
diff --git a/resources/lib/oojs-ui/themes/mediawiki/images/icons/unTrash-ltr-invert.png b/resources/lib/oojs-ui/themes/mediawiki/images/icons/unTrash-ltr-invert.png
new file mode 100644 (file)
index 0000000..af3f0e9
Binary files /dev/null and b/resources/lib/oojs-ui/themes/mediawiki/images/icons/unTrash-ltr-invert.png differ
diff --git a/resources/lib/oojs-ui/themes/mediawiki/images/icons/unTrash-ltr-invert.svg b/resources/lib/oojs-ui/themes/mediawiki/images/icons/unTrash-ltr-invert.svg
new file mode 100644 (file)
index 0000000..0763ff8
--- /dev/null
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #fff }</style>
+    <path d="M20.5 20.5L5 5 4 6l3 3 1 11h8l.2-1.8 3.3 3.3zM17 9h-6l5.5 5.5zm1-1c0-1.1-.9-2-2-2h-2l-1-1h-2l-1 1H8l2 2h8z"/>
+</svg>
diff --git a/resources/lib/oojs-ui/themes/mediawiki/images/icons/unTrash-ltr-progressive.png b/resources/lib/oojs-ui/themes/mediawiki/images/icons/unTrash-ltr-progressive.png
new file mode 100644 (file)
index 0000000..2f09eb6
Binary files /dev/null and b/resources/lib/oojs-ui/themes/mediawiki/images/icons/unTrash-ltr-progressive.png differ
diff --git a/resources/lib/oojs-ui/themes/mediawiki/images/icons/unTrash-ltr-progressive.svg b/resources/lib/oojs-ui/themes/mediawiki/images/icons/unTrash-ltr-progressive.svg
new file mode 100644 (file)
index 0000000..6d1fdd9
--- /dev/null
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #36c }</style>
+    <path d="M20.5 20.5L5 5 4 6l3 3 1 11h8l.2-1.8 3.3 3.3zM17 9h-6l5.5 5.5zm1-1c0-1.1-.9-2-2-2h-2l-1-1h-2l-1 1H8l2 2h8z"/>
+</svg>
diff --git a/resources/lib/oojs-ui/themes/mediawiki/images/icons/unTrash-ltr.png b/resources/lib/oojs-ui/themes/mediawiki/images/icons/unTrash-ltr.png
new file mode 100644 (file)
index 0000000..3b5231f
Binary files /dev/null and b/resources/lib/oojs-ui/themes/mediawiki/images/icons/unTrash-ltr.png differ
diff --git a/resources/lib/oojs-ui/themes/mediawiki/images/icons/unTrash-ltr.svg b/resources/lib/oojs-ui/themes/mediawiki/images/icons/unTrash-ltr.svg
new file mode 100644 (file)
index 0000000..64b3b71
--- /dev/null
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
+    <path d="M20.5 20.5L5 5 4 6l3 3 1 11h8l.2-1.8 3.3 3.3zM17 9h-6l5.5 5.5zm1-1c0-1.1-.9-2-2-2h-2l-1-1h-2l-1 1H8l2 2h8z"/>
+</svg>
diff --git a/resources/lib/oojs-ui/themes/mediawiki/images/icons/unTrash-rtl-invert.png b/resources/lib/oojs-ui/themes/mediawiki/images/icons/unTrash-rtl-invert.png
new file mode 100644 (file)
index 0000000..1cb5449
Binary files /dev/null and b/resources/lib/oojs-ui/themes/mediawiki/images/icons/unTrash-rtl-invert.png differ
diff --git a/resources/lib/oojs-ui/themes/mediawiki/images/icons/unTrash-rtl-invert.svg b/resources/lib/oojs-ui/themes/mediawiki/images/icons/unTrash-rtl-invert.svg
new file mode 100644 (file)
index 0000000..12e57b2
--- /dev/null
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #fff }</style>
+    <path d="M4 20.5L19.5 5l1 1-3 3-1 11h-8l-.2-1.8L5 21.5zM7.5 9h6L8 14.5zm-1-1c0-1.1.9-2 2-2h2l1-1h2l1 1h2l-2 2h-8z"/>
+</svg>
diff --git a/resources/lib/oojs-ui/themes/mediawiki/images/icons/unTrash-rtl-progressive.png b/resources/lib/oojs-ui/themes/mediawiki/images/icons/unTrash-rtl-progressive.png
new file mode 100644 (file)
index 0000000..e828b36
Binary files /dev/null and b/resources/lib/oojs-ui/themes/mediawiki/images/icons/unTrash-rtl-progressive.png differ
diff --git a/resources/lib/oojs-ui/themes/mediawiki/images/icons/unTrash-rtl-progressive.svg b/resources/lib/oojs-ui/themes/mediawiki/images/icons/unTrash-rtl-progressive.svg
new file mode 100644 (file)
index 0000000..6395968
--- /dev/null
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><style>* { fill: #36c }</style>
+    <path d="M4 20.5L19.5 5l1 1-3 3-1 11h-8l-.2-1.8L5 21.5zM7.5 9h6L8 14.5zm-1-1c0-1.1.9-2 2-2h2l1-1h2l1 1h2l-2 2h-8z"/>
+</svg>
diff --git a/resources/lib/oojs-ui/themes/mediawiki/images/icons/unTrash-rtl.png b/resources/lib/oojs-ui/themes/mediawiki/images/icons/unTrash-rtl.png
new file mode 100644 (file)
index 0000000..a1d2388
Binary files /dev/null and b/resources/lib/oojs-ui/themes/mediawiki/images/icons/unTrash-rtl.png differ
diff --git a/resources/lib/oojs-ui/themes/mediawiki/images/icons/unTrash-rtl.svg b/resources/lib/oojs-ui/themes/mediawiki/images/icons/unTrash-rtl.svg
new file mode 100644 (file)
index 0000000..e5e4032
--- /dev/null
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
+    <path d="M4 20.5L19.5 5l1 1-3 3-1 11h-8l-.2-1.8L5 21.5zM7.5 9h6L8 14.5zm-1-1c0-1.1.9-2 2-2h2l1-1h2l1 1h2l-2 2h-8z"/>
+</svg>
index 81896de..befe957 100644 (file)
@@ -303,7 +303,7 @@ p.mw-delete-editreasons {
 div.mw-warning-with-logexcerpt {
        padding: 3px;
        margin-bottom: 3px;
-       border: 2px solid #2f6fab;
+       border: 2px solid #2a4b8d;
        clear: both;
 }
 
diff --git a/resources/src/mediawiki.rcfilters/dm/mw.rcfilters.dm.FilterItem.js b/resources/src/mediawiki.rcfilters/dm/mw.rcfilters.dm.FilterItem.js
new file mode 100644 (file)
index 0000000..63db0ea
--- /dev/null
@@ -0,0 +1,103 @@
+( function ( mw ) {
+       /**
+        * Filter item model
+        *
+        * @mixins OO.EventEmitter
+        *
+        * @constructor
+        * @param {string} name Filter name
+        * @param {Object} config Configuration object
+        * @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
+        */
+       mw.rcfilters.dm.FilterItem = function MwRcfiltersDmFilterItem( name, config ) {
+               config = config || {};
+
+               // Mixin constructor
+               OO.EventEmitter.call( this );
+
+               this.name = name;
+               this.group = config.group || '';
+               this.label = config.label || this.name;
+               this.description = config.description;
+
+               this.selected = !!config.selected;
+       };
+
+       /* Initialization */
+
+       OO.initClass( mw.rcfilters.dm.FilterItem );
+       OO.mixinClass( mw.rcfilters.dm.FilterItem, OO.EventEmitter );
+
+       /* Events */
+
+       /**
+        * @event update
+        *
+        * The state of this filter has changed
+        */
+
+       /* Methods */
+
+       /**
+        * Get the name of this filter
+        *
+        * @return {string} Filter name
+        */
+       mw.rcfilters.dm.FilterItem.prototype.getName = function () {
+               return this.name;
+       };
+
+       /**
+        * Get the group name this filter belongs to
+        *
+        * @return {string} Filter group name
+        */
+       mw.rcfilters.dm.FilterItem.prototype.getGroup = function () {
+               return this.group;
+       };
+
+       /**
+        * Get the label of this filter
+        *
+        * @return {string} Filter label
+        */
+       mw.rcfilters.dm.FilterItem.prototype.getLabel = function () {
+               return this.label;
+       };
+
+       /**
+        * Get the description of this filter
+        *
+        * @return {string} Filter description
+        */
+       mw.rcfilters.dm.FilterItem.prototype.getDescription = function () {
+               return this.description;
+       };
+
+       /**
+        * Get the selected state of this filter
+        *
+        * @return {boolean} Filter is selected
+        */
+       mw.rcfilters.dm.FilterItem.prototype.isSelected = function () {
+               return this.selected;
+       };
+
+       /**
+        * Toggle the selected state of the item
+        *
+        * @param {boolean} [isSelected] Filter is selected
+        * @fires update
+        */
+       mw.rcfilters.dm.FilterItem.prototype.toggleSelected = function ( isSelected ) {
+               isSelected = isSelected === undefined ? !this.selected : isSelected;
+
+               if ( this.selected !== isSelected ) {
+                       this.selected = isSelected;
+                       this.emit( 'update' );
+               }
+       };
+}( mediaWiki ) );
diff --git a/resources/src/mediawiki.rcfilters/dm/mw.rcfilters.dm.FiltersViewModel.js b/resources/src/mediawiki.rcfilters/dm/mw.rcfilters.dm.FiltersViewModel.js
new file mode 100644 (file)
index 0000000..3217d0d
--- /dev/null
@@ -0,0 +1,342 @@
+( function ( mw, $ ) {
+       /**
+        * View model for the filters selection and display
+        *
+        * @mixins OO.EventEmitter
+        * @mixins OO.EmitterList
+        *
+        * @constructor
+        */
+       mw.rcfilters.dm.FiltersViewModel = function MwRcfiltersDmFiltersViewModel() {
+               // Mixin constructor
+               OO.EventEmitter.call( this );
+               OO.EmitterList.call( this );
+
+               this.groups = {};
+
+               // Events
+               this.aggregate( { update: 'itemUpdate' } );
+       };
+
+       /* Initialization */
+       OO.initClass( mw.rcfilters.dm.FiltersViewModel );
+       OO.mixinClass( mw.rcfilters.dm.FiltersViewModel, OO.EventEmitter );
+       OO.mixinClass( mw.rcfilters.dm.FiltersViewModel, OO.EmitterList );
+
+       /* Events */
+
+       /**
+        * @event initialize
+        *
+        * Filter list is initialized
+        */
+
+       /**
+        * @event itemUpdate
+        * @param {mw.rcfilters.dm.FilterItem} item Filter item updated
+        *
+        * Filter item has changed
+        */
+
+       /* Methods */
+
+       /**
+        * 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,
+                       model = this,
+                       items = [];
+
+               // Reset
+               this.clearItems();
+               this.groups = {};
+
+               $.each( filters, function ( group, data ) {
+                       model.groups[ group ] = model.groups[ group ] || {};
+                       model.groups[ group ].filters = model.groups[ group ].filters || [];
+
+                       model.groups[ group ].title = data.title;
+                       model.groups[ group ].type = data.type;
+                       model.groups[ group ].separator = data.separator || '|';
+
+                       for ( i = 0; i < data.filters.length; i++ ) {
+                               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
+                               } );
+
+                               model.groups[ group ].filters.push( filterItem );
+                               items.push( filterItem );
+                       }
+               } );
+
+               this.addItems( items );
+               this.emit( 'initialize' );
+       };
+
+       /**
+        * Get the names of all available filters
+        *
+        * @return {string[]} An array of filter names
+        */
+       mw.rcfilters.dm.FiltersViewModel.prototype.getFilterNames = function () {
+               return this.getItems().map( function ( item ) { return item.getName(); } );
+       };
+
+       /**
+        * Get the object that defines groups and their filter items.
+        * The structure of this response:
+        * {
+        *   groupName: {
+        *     title: {string} Group title
+        *     type: {string} Group type
+        *     filters: {string[]} Filters in the group
+        *   }
+        * }
+        *
+        * @return {Object} Filter groups
+        */
+       mw.rcfilters.dm.FiltersViewModel.prototype.getFilterGroups = function () {
+               return this.groups;
+       };
+
+       /**
+        * Get the current state of the filters
+        *
+        * @return {Object} Filters current state
+        */
+       mw.rcfilters.dm.FiltersViewModel.prototype.getState = function () {
+               var i,
+                       items = this.getItems(),
+                       result = {};
+
+               for ( i = 0; i < items.length; i++ ) {
+                       result[ items[ i ].getName() ] = items[ i ].isSelected();
+               }
+
+               return result;
+       };
+
+       /**
+        * Analyze the groups and their filters and output an object representing
+        * the state of the parameters they represent.
+        *
+        * @return {Object} Parameter state object
+        */
+       mw.rcfilters.dm.FiltersViewModel.prototype.getParametersFromFilters = function () {
+               var i, filterItems, anySelected, values,
+                       result = {},
+                       groupItems = this.getFilterGroups();
+
+               $.each( groupItems, function ( group, data ) {
+                       filterItems = data.filters;
+
+                       if ( data.type === 'send_unselected_if_any' ) {
+                               // First, check if any of the items are selected at all.
+                               // If none is selected, we're treating it as if they are
+                               // all false
+                               anySelected = filterItems.some( function ( filterItem ) {
+                                       return filterItem.isSelected();
+                               } );
+
+                               // Go over the items and define the correct values
+                               for ( i = 0; i < filterItems.length; i++ ) {
+                                       result[ filterItems[ i ].getName() ] = anySelected ?
+                                               Number( !filterItems[ i ].isSelected() ) : 0;
+                               }
+                       } else if ( data.type === 'string_options' ) {
+                               values = [];
+                               for ( i = 0; i < filterItems.length; i++ ) {
+                                       if ( filterItems[ i ].isSelected() ) {
+                                               values.push( filterItems[ i ].getName() );
+                                       }
+                               }
+
+                               if ( values.length === 0 || values.length === filterItems.length ) {
+                                       result[ group ] = 'all';
+                               } else {
+                                       result[ group ] = values.join( data.separator );
+                               }
+                       }
+               } );
+
+               return result;
+       };
+
+       /**
+        * Sanitize value group of a string_option groups type
+        * Remove duplicates and make sure to only use valid
+        * values.
+        *
+        * @param {string} groupName Group name
+        * @param {string[]} valueArray Array of values
+        * @return {string[]} Array of valid values
+        */
+       mw.rcfilters.dm.FiltersViewModel.prototype.sanitizeStringOptionGroup = function( groupName, valueArray ) {
+               var result = [],
+                       validNames = this.groups[ groupName ].filters.map( function ( filterItem ) {
+                               return filterItem.getName();
+                       } );
+
+               if ( valueArray.indexOf( 'all' ) > -1 ) {
+                       // If anywhere in the values there's 'all', we
+                       // treat it as if only 'all' was selected.
+                       // Example: param=valid1,valid2,all
+                       // Result: param=all
+                       return [ 'all' ];
+               }
+
+               // Get rid of any dupe and invalid parameter, only output
+               // valid ones
+               // Example: param=valid1,valid2,invalid1,valid1
+               // Result: param=valid1,valid2
+               valueArray.forEach( function ( value ) {
+                       if (
+                               validNames.indexOf( value ) > -1 &&
+                               result.indexOf( value ) === -1
+                       ) {
+                               result.push( value );
+                       }
+               } );
+
+               return result;
+       };
+
+       /**
+        * This is the opposite of the #getParametersFromFilters method; this goes over
+        * the parameters and translates into a selected/unselected value in the filters.
+        *
+        * @param {Object} params Parameters query object
+        * @return {Object} Filter state object
+        */
+       mw.rcfilters.dm.FiltersViewModel.prototype.getFiltersFromParameters = function ( params ) {
+               var i, filterItem,
+                       groupMap = {},
+                       model = this,
+                       base = this.getParametersFromFilters(),
+                       // Start with current state
+                       result = this.getState();
+
+               params = $.extend( {}, base, params );
+
+               $.each( params, function ( paramName, paramValue ) {
+                       // Find the filter item
+                       filterItem = model.getItemByName( paramName );
+                       // Ignore if no filter item exists
+                       if ( filterItem ) {
+                               groupMap[ filterItem.getGroup() ] = groupMap[ filterItem.getGroup() ] || {};
+
+                               // Mark the group if it has any items that are selected
+                               groupMap[ filterItem.getGroup() ].hasSelected = (
+                                       groupMap[ filterItem.getGroup() ].hasSelected ||
+                                       !!Number( paramValue )
+                               );
+
+                               // Add the relevant filter into the group map
+                               groupMap[ filterItem.getGroup() ].filters = groupMap[ filterItem.getGroup() ].filters || [];
+                               groupMap[ filterItem.getGroup() ].filters.push( filterItem );
+                       } else if ( model.groups.hasOwnProperty( paramName ) ) {
+                               // This parameter represents a group (values are the filters)
+                               // this is equivalent to checking if the group is 'string_options'
+                               groupMap[ paramName ] = { filters: model.groups[ paramName ].filters };
+                       }
+               } );
+
+               // Now that we know the groups' selection states, we need to go over
+               // the filters in the groups and mark their selected states appropriately
+               $.each( groupMap, function ( group, data ) {
+                       var paramValues, filterItem,
+                               allItemsInGroup = data.filters;
+
+                       if ( model.groups[ group ].type === 'send_unselected_if_any' ) {
+                               for ( i = 0; i < allItemsInGroup.length; i++ ) {
+                                       filterItem = allItemsInGroup[ i ];
+
+                                       result[ filterItem.getName() ] = data.hasSelected ?
+                                               // Flip the definition between the parameter
+                                               // state and the filter state
+                                               // This is what the 'toggleSelected' value of the filter is
+                                               !Number( params[ filterItem.getName() ] ) :
+                                               // Otherwise, there are no selected items in the
+                                               // group, which means the state is false
+                                               false;
+                               }
+                       } else if ( model.groups[ group ].type === 'string_options' ) {
+                               paramValues = model.sanitizeStringOptionGroup( group, params[ group ].split( model.groups[ group ].separator ) );
+
+                               for ( i = 0; i < allItemsInGroup.length; i++ ) {
+                                       filterItem = allItemsInGroup[ i ];
+
+                                       result[ filterItem.getName() ] = (
+                                                       // If it is the word 'all'
+                                                       paramValues.length === 1 && paramValues[ 0 ] === 'all' ||
+                                                       // All values are written
+                                                       paramValues.length === model.groups[ group ].filters.length
+                                               ) ?
+                                               // All true (either because all values are written or the term 'all' is written)
+                                               // is the same as all filters set to false
+                                               false :
+                                               // Otherwise, the filter is selected only if it appears in the parameter values
+                                               paramValues.indexOf( filterItem.getName() ) > -1;
+                               }
+                       }
+               } );
+               return result;
+       };
+
+       /**
+        * Get the item that matches the given name
+        *
+        * @param {string} name Filter name
+        * @return {mw.rcfilters.dm.FilterItem} Filter item
+        */
+       mw.rcfilters.dm.FiltersViewModel.prototype.getItemByName = function ( name ) {
+               return this.getItems().filter( function ( item ) {
+                       return name === item.getName();
+               } )[ 0 ];
+       };
+
+       /**
+        * Toggle selected state of items by their names
+        *
+        * @param {Object} filterDef Filter definitions
+        */
+       mw.rcfilters.dm.FiltersViewModel.prototype.updateFilters = function ( filterDef ) {
+               var name, filterItem;
+
+               for ( name in filterDef ) {
+                       filterItem = this.getItemByName( name );
+                       filterItem.toggleSelected( filterDef[ name ] );
+               }
+       };
+
+       /**
+        * Find items whose labels match the given string
+        *
+        * @param {string} str Search string
+        * @return {Object} An object of items to show
+        *  arranged by their group names
+        */
+       mw.rcfilters.dm.FiltersViewModel.prototype.findMatches = function ( str ) {
+               var i,
+                       result = {},
+                       items = this.getItems();
+
+               // Normalize so we can search strings regardless of case
+               str = str.toLowerCase();
+               for ( i = 0; i < items.length; i++ ) {
+                       if ( items[ i ].getLabel().toLowerCase().indexOf( str ) > -1 ) {
+                               result[ items[ i ].getGroup() ] = result[ items[ i ].getGroup() ] || [];
+                               result[ items[ i ].getGroup() ].push( items[ i ] );
+                       }
+               }
+               return result;
+       };
+
+}( mediaWiki, jQuery ) );
diff --git a/resources/src/mediawiki.rcfilters/mw.rcfilters.Controller.js b/resources/src/mediawiki.rcfilters/mw.rcfilters.Controller.js
new file mode 100644 (file)
index 0000000..ea44b8b
--- /dev/null
@@ -0,0 +1,57 @@
+( function ( mw ) {
+       /**
+        * Controller for the filters in Recent Changes
+        *
+        * @param {mw.rcfilters.dm.FiltersViewModel} model View model
+        */
+       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' } );
+       };
+
+       /* Initialization */
+       OO.initClass( mw.rcfilters.Controller );
+
+       /**
+        * Initialize the filter and parameter states
+        */
+       mw.rcfilters.Controller.prototype.initialize = function () {
+               var uri = new mw.Uri();
+
+               this.model.updateFilters(
+                       // Translate the url params to filter select states
+                       this.model.getFiltersFromParameters( uri.query )
+               );
+       };
+
+       /**
+        * Update the state of a filter
+        *
+        * @param {string} filterName Filter name
+        * @param {boolean} isSelected Filter selected state
+        */
+       mw.rcfilters.Controller.prototype.updateFilter = function ( filterName, isSelected ) {
+               var obj = {};
+
+               obj[ filterName ] = isSelected;
+               this.model.updateFilters( obj );
+       };
+
+       /**
+        * Update the URL of the page to reflect current filters
+        */
+       mw.rcfilters.Controller.prototype.updateURL = function () {
+               var uri = new mw.Uri();
+
+               // Add to existing queries in URL
+               // TODO: Clean up the list of filters; perhaps 'falsy' filters
+               // shouldn't appear at all? Or compare to existing query string
+               // and see if current state of a specific filter is needed?
+               uri.extend( this.model.getParametersFromFilters() );
+
+               // Update the URL itself
+               window.history.pushState( { tag: 'rcfilters' }, document.title, uri.toString() );
+       };
+}( mediaWiki ) );
diff --git a/resources/src/mediawiki.rcfilters/mw.rcfilters.init.js b/resources/src/mediawiki.rcfilters/mw.rcfilters.init.js
new file mode 100644 (file)
index 0000000..679215b
--- /dev/null
@@ -0,0 +1,108 @@
+/*!
+ * JavaScript for Special:RecentChanges
+ */
+( function ( mw, $ ) {
+       /**
+        * @class mw.rcfilters
+        * @singleton
+        */
+       var rcfilters = {
+               /** */
+               init: function () {
+                       var model = new mw.rcfilters.dm.FiltersViewModel(),
+                               controller = new mw.rcfilters.Controller( model ),
+                               widget = new mw.rcfilters.ui.FilterWrapperWidget( controller, model );
+
+                       model.initializeFilters( {
+                               authorship: {
+                                       title: mw.msg( 'rcfilters-filtergroup-authorship' ),
+                                       // Type 'send_unselected_if_any' means that the controller will go over
+                                       // all unselected filters in the group and use their parameters
+                                       // as truthy in the query string.
+                                       // This is to handle the "negative" filters. We are showing users
+                                       // a positive message ("Show xxx") but the filters themselves are
+                                       // based on "hide YYY". The purpose of this is to correctly map
+                                       // the functionality to the UI, whether we are dealing with 2
+                                       // parameters in the group or more.
+                                       type: 'send_unselected_if_any',
+                                       filters: [
+                                               {
+                                                       name: 'hidemyself',
+                                                       label: mw.msg( 'rcfilters-filter-editsbyself-label' ),
+                                                       description: mw.msg( 'rcfilters-filter-editsbyself-description' )
+                                               },
+                                               {
+                                                       name: 'hidebyothers',
+                                                       label: mw.msg( 'rcfilters-filter-editsbyother-label' ),
+                                                       description: mw.msg( 'rcfilters-filter-editsbyother-description' )
+                                               }
+                                       ]
+                               },
+                               userExpLevel: {
+                                       title: mw.msg( 'rcfilters-filtergroup-userExpLevel' ),
+                                       // Type 'string_options' means that the group is evaluated by
+                                       // string values separated by comma; for example, param=opt1,opt2
+                                       // If all options are selected they are replaced by the term "all".
+                                       // The filters are the values for the parameter defined by the group.
+                                       // ** In this case, the parameter name is the group name. **
+                                       type: 'string_options',
+                                       separator: ',',
+                                       filters: [
+                                               {
+                                                       name: 'newcomer',
+                                                       label: mw.msg( 'rcfilters-filter-userExpLevel-newcomer-label' ),
+                                                       description: mw.msg( 'rcfilters-filter-userExpLevel-newcomer-description' )
+                                               },
+                                               {
+                                                       name: 'learner',
+                                                       label: mw.msg( 'rcfilters-filter-userExpLevel-learner-label' ),
+                                                       description: mw.msg( 'rcfilters-filter-userExpLevel-learner-description' )
+                                               },
+                                               {
+                                                       name: 'experienced',
+                                                       label: mw.msg( 'rcfilters-filter-userExpLevel-experienced-label' ),
+                                                       description: mw.msg( 'rcfilters-filter-userExpLevel-experienced-description' )
+                                               }
+                                       ]
+                               }
+                       } );
+
+                       $( '.rcoptions' ).before( widget.$element );
+
+                       // Initialize values
+                       controller.initialize();
+
+                       $( '.rcoptions form' ).submit( function () {
+                               var $form = $( this );
+
+                               // Get current filter values
+                               $.each( model.getParametersFromFilters(), function ( paramName, paramValue ) {
+                                       var $existingInput = $form.find( 'input[name=' + paramName + ']' );
+                                       // Check if the hidden input already exists
+                                       // This happens if the parameter was already given
+                                       // on load
+                                       if ( $existingInput.length ) {
+                                               // Update the value
+                                               $existingInput.val( paramValue );
+                                       } else {
+                                               // Append hidden fields with filter values
+                                               $form.append(
+                                                       $( '<input>' )
+                                                               .attr( 'type', 'hidden' )
+                                                               .attr( 'name', paramName )
+                                                               .val( paramValue )
+                                               );
+                                       }
+                               } );
+
+                               // Continue the submission process
+                               return true;
+                       } );
+               }
+       };
+
+       $( rcfilters.init );
+
+       module.exports = rcfilters;
+
+}( mediaWiki, jQuery ) );
diff --git a/resources/src/mediawiki.rcfilters/mw.rcfilters.js b/resources/src/mediawiki.rcfilters/mw.rcfilters.js
new file mode 100644 (file)
index 0000000..3ddb5a0
--- /dev/null
@@ -0,0 +1,3 @@
+( function ( mw ) {
+       mw.rcfilters = { dm: {}, ui: {} };
+}( mediaWiki ) );
diff --git a/resources/src/mediawiki.rcfilters/styles/mw.rcfilters.less b/resources/src/mediawiki.rcfilters/styles/mw.rcfilters.less
new file mode 100644 (file)
index 0000000..7f71c0c
--- /dev/null
@@ -0,0 +1,5 @@
+.rcshowhidemine {
+       // HACK: Hide this filter since it already appears in
+       // the new filter drop-down.
+       display: none;
+}
diff --git a/resources/src/mediawiki.rcfilters/styles/mw.rcfilters.ui.FilterCapsuleMultiselectWidget.less b/resources/src/mediawiki.rcfilters/styles/mw.rcfilters.ui.FilterCapsuleMultiselectWidget.less
new file mode 100644 (file)
index 0000000..4e55add
--- /dev/null
@@ -0,0 +1,11 @@
+.mw-rcfilters-ui-filterCapsuleMultiselectWidget {
+       &-content-title {
+               font-weight: bold;
+               color: #54595d;
+       }
+
+       .oo-ui-capsuleItemWidget {
+               color: #222;
+               background-color: #fff;
+       }
+}
diff --git a/resources/src/mediawiki.rcfilters/styles/mw.rcfilters.ui.FilterGroupWidget.less b/resources/src/mediawiki.rcfilters/styles/mw.rcfilters.ui.FilterGroupWidget.less
new file mode 100644 (file)
index 0000000..70982d4
--- /dev/null
@@ -0,0 +1,20 @@
+.mw-rcfilters-ui-filterGroupWidget {
+       padding-bottom: 0.5em;
+
+       &-title {
+               // TODO: Unify colors with official design palette
+               background: #eaecf0;
+               padding: 0.5em 0.75em;
+               color: #555a5d;
+       }
+
+       &-invalid-notice {
+               padding: 0.5em;
+               font-style: italic;
+               display: none;
+
+               .mw-rcfilters-ui-filterGroupWidget-invalid & {
+                       display: block;
+               }
+       }
+}
diff --git a/resources/src/mediawiki.rcfilters/styles/mw.rcfilters.ui.FilterItemWidget.less b/resources/src/mediawiki.rcfilters/styles/mw.rcfilters.ui.FilterItemWidget.less
new file mode 100644 (file)
index 0000000..ad0b816
--- /dev/null
@@ -0,0 +1,18 @@
+.mw-rcfilters-ui-filterItemWidget {
+       padding-left: 0.5em;
+
+       &-label {
+               &-title {
+                       font-weight: bold;
+                       font-size: 1.2em;
+                       color: #222;
+               }
+               &-desc {
+                       color: #464a4f;
+               }
+       }
+
+       .oo-ui-fieldLayout.oo-ui-fieldLayout-align-inline {
+               margin-bottom: 0 !important;
+       }
+}
diff --git a/resources/src/mediawiki.rcfilters/styles/mw.rcfilters.ui.FilterWrapperWidget.less b/resources/src/mediawiki.rcfilters/styles/mw.rcfilters.ui.FilterWrapperWidget.less
new file mode 100644 (file)
index 0000000..a610e8f
--- /dev/null
@@ -0,0 +1,33 @@
+.mw-rcfilters-ui-filterWrapperWidget {
+       width: 100%;
+
+       .oo-ui-capsuleMultiselectWidget {
+               max-width: none;
+
+               &.oo-ui-widget-enabled .oo-ui-capsuleMultiselectWidget-handle {
+                       // TODO: Unify colors with official design palette
+                       background-color: #f8f9fa;
+                       border: 1px solid #a2a9b1;
+                       min-height: 5.5em;
+                       padding: 0.75em;
+
+               }
+       }
+
+       &-popup {
+               // We have to override OOUI's definition, which is set
+               // on the inline style of the popup
+               margin-top: 2em !important;
+               max-width: 650px;
+       }
+
+       &-search {
+               max-width: none;
+               margin-top: -0.5em;
+       }
+
+       &-capsule-invalid-filter {
+               // TODO: Unify colors with official design palette
+               background: red;
+       }
+}
diff --git a/resources/src/mediawiki.rcfilters/styles/mw.rcfilters.ui.FiltersListWidget.less b/resources/src/mediawiki.rcfilters/styles/mw.rcfilters.ui.FiltersListWidget.less
new file mode 100644 (file)
index 0000000..b874e0f
--- /dev/null
@@ -0,0 +1,16 @@
+.mw-rcfilters-ui-filtersListWidget {
+       &-title {
+               font-size: 1.2em;
+               padding: 0.75em;
+               // TODO: Unify colors with official design palette
+               color: #54595d;
+               border-bottom: 1px solid #c8ccd1;
+               background: #f8f9fa;
+       }
+
+       &-noresults {
+               padding: 0.5em;
+               // TODO: Unify colors with official design palette
+               color: #666;
+       }
+}
diff --git a/resources/src/mediawiki.rcfilters/ui/mw.rcfilters.ui.FilterCapsuleMultiselectWidget.js b/resources/src/mediawiki.rcfilters/ui/mw.rcfilters.ui.FilterCapsuleMultiselectWidget.js
new file mode 100644 (file)
index 0000000..df6cf8b
--- /dev/null
@@ -0,0 +1,91 @@
+( function ( mw, $ ) {
+       /**
+        * Filter-specific CapsuleMultiselectWidget
+        *
+        * @extends OO.ui.CapsuleMultiselectWidget
+        *
+        * @constructor
+        * @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 ) {
+               // Parent
+               mw.rcfilters.ui.FilterCapsuleMultiselectWidget.parent.call( this, $.extend( {
+                       $autoCloseIgnore: filterInput.$element
+               }, config ) );
+
+               this.filterInput = filterInput;
+
+               this.$content.prepend(
+                       $( '<div>' )
+                               .addClass( 'mw-rcfilters-ui-filterCapsuleMultiselectWidget-content-title' )
+                               .text( mw.msg( 'rcfilters-activefilters' ) )
+               );
+
+               // Events
+               // Add the filterInput as trigger
+               this.filterInput.$input
+                       .on( 'focus', this.onFocusForPopup.bind( this ) );
+
+               this.$element
+                       .addClass( 'mw-rcfilters-ui-filterCapsuleMultiselectWidget' );
+       };
+
+       /* Initialization */
+
+       OO.inheritClass( mw.rcfilters.ui.FilterCapsuleMultiselectWidget, OO.ui.CapsuleMultiselectWidget );
+
+       /* Events */
+
+       /**
+        * @event remove
+        * @param {string[]} filters Array of names of removed filters
+        *
+        * Filters were removed
+        */
+
+       /* Methods */
+
+       /**
+        * @inheritdoc
+        */
+       mw.rcfilters.ui.FilterCapsuleMultiselectWidget.prototype.onFocusForPopup = function () {
+               // Override this method; we don't want to focus on the popup, and we
+               // don't want to bind the size to the handle.
+               if ( !this.isDisabled() ) {
+                       this.popup.toggle( true );
+               }
+       };
+
+       /**
+        * @inheritdoc
+        */
+       mw.rcfilters.ui.FilterCapsuleMultiselectWidget.prototype.removeItems = function ( items ) {
+               // Parent
+               mw.rcfilters.ui.FilterCapsuleMultiselectWidget.parent.prototype.removeItems.call( this, items );
+
+               this.emit( 'remove', items.map( function ( item ) { return item.getData(); } ) );
+       };
+
+       /**
+        * @inheritdoc
+        */
+       mw.rcfilters.ui.FilterCapsuleMultiselectWidget.prototype.onKeyDown = function () {};
+
+       /**
+        * @inheritdoc
+        */
+       mw.rcfilters.ui.FilterCapsuleMultiselectWidget.prototype.onPopupFocusOut = function () {};
+
+       /**
+        * @inheritdoc
+        */
+       mw.rcfilters.ui.FilterCapsuleMultiselectWidget.prototype.clearInput = function () {
+               if ( this.filterInput ) {
+                       this.filterInput.setValue( '' );
+               }
+               this.menu.toggle( false );
+               this.menu.selectItem();
+               this.menu.highlightItem();
+       };
+}( mediaWiki, jQuery ) );
diff --git a/resources/src/mediawiki.rcfilters/ui/mw.rcfilters.ui.FilterGroupWidget.js b/resources/src/mediawiki.rcfilters/ui/mw.rcfilters.ui.FilterGroupWidget.js
new file mode 100644 (file)
index 0000000..92ae4d1
--- /dev/null
@@ -0,0 +1,51 @@
+( function ( mw, $ ) {
+       /**
+        * A group of filters
+        *
+        * @extends OO.ui.Widget
+        * @mixins OO.ui.mixin.GroupWidget
+        * @mixins OO.ui.mixin.LabelElement
+        *
+        * @constructor
+        * @param {string} name Group name
+        * @param {Object} config Configuration object
+        */
+       mw.rcfilters.ui.FilterGroupWidget = function MwRcfiltersUiFilterGroupWidget( name, config ) {
+               config = config || {};
+
+               // Parent
+               mw.rcfilters.ui.FilterGroupWidget.parent.call( this, config );
+               // Mixin constructors
+               OO.ui.mixin.GroupWidget.call( this, config );
+               OO.ui.mixin.LabelElement.call( this, $.extend( {}, config, {
+                       $label: $( '<div>' )
+                               .addClass( 'mw-rcfilters-ui-filterGroupWidget-title' )
+               } ) );
+
+               this.name = name;
+
+               this.$element
+                       .addClass( 'mw-rcfilters-ui-filterGroupWidget' )
+                       .append(
+                               this.$label,
+                               this.$group
+                                       .addClass( 'mw-rcfilters-ui-filterGroupWidget-group' )
+                       );
+       };
+
+       /* Initialization */
+
+       OO.inheritClass( mw.rcfilters.ui.FilterGroupWidget, OO.ui.Widget );
+       OO.mixinClass( mw.rcfilters.ui.FilterGroupWidget, OO.ui.mixin.GroupWidget );
+       OO.mixinClass( mw.rcfilters.ui.FilterGroupWidget, OO.ui.mixin.LabelElement );
+
+       /**
+        * Get the group name
+        *
+        * @return {string} Group name
+        */
+       mw.rcfilters.ui.FilterGroupWidget.prototype.getName = function () {
+               return this.name;
+       };
+
+}( mediaWiki, jQuery ) );
diff --git a/resources/src/mediawiki.rcfilters/ui/mw.rcfilters.ui.FilterItemWidget.js b/resources/src/mediawiki.rcfilters/ui/mw.rcfilters.ui.FilterItemWidget.js
new file mode 100644 (file)
index 0000000..b77df3b
--- /dev/null
@@ -0,0 +1,92 @@
+( function ( mw, $ ) {
+       /**
+        * A widget representing a single toggle filter
+        *
+        * @extends OO.ui.Widget
+        *
+        * @constructor
+        * @param {mw.rcfilters.Controller} controller RCFilters controller
+        * @param {mw.rcfilters.dm.FilterItem} model Filter item model
+        * @param {Object} config Configuration object
+        */
+       mw.rcfilters.ui.FilterItemWidget = function MwRcfiltersUiFilterItemWidget( controller, model, config ) {
+               var layout,
+                       $label = $( '<div>' )
+                               .addClass( 'mw-rcfilters-ui-filterItemWidget-label' );
+
+               config = config || {};
+
+               // Parent
+               mw.rcfilters.ui.FilterItemWidget.parent.call( this, config );
+
+               this.controller = controller;
+               this.model = model;
+
+               this.checkboxWidget = new OO.ui.CheckboxInputWidget( {
+                       value: this.model.getName(),
+                       selected: this.model.isSelected()
+               } );
+
+               $label.append(
+                       $( '<div>' )
+                               .addClass( 'mw-rcfilters-ui-filterItemWidget-label-title' )
+                               .text( this.model.getLabel() )
+               );
+               if ( this.model.getDescription() ) {
+                       $label.append(
+                               $( '<div>' )
+                                       .addClass( 'mw-rcfilters-ui-filterItemWidget-label-desc' )
+                                       .text( this.model.getDescription() )
+                       );
+               }
+
+               layout = new OO.ui.FieldLayout( this.checkboxWidget, {
+                       label: $label,
+                       align: 'inline'
+               } );
+
+               // Event
+               this.checkboxWidget.connect( this, { change: 'onCheckboxChange' } );
+               this.model.connect( this, { update: 'onModelUpdate' } );
+
+               this.$element
+                       .addClass( 'mw-rcfilters-ui-filterItemWidget' )
+                       .append(
+                               layout.$element
+                       );
+       };
+
+       /* Initialization */
+
+       OO.inheritClass( mw.rcfilters.ui.FilterItemWidget, OO.ui.Widget );
+
+       /* Methods */
+
+       /**
+        * Respond to checkbox change.
+        * NOTE: This event is emitted both for deliberate user action and for
+        * a change that the code requests ('setSelected')
+        *
+        * @param {boolean} isSelected The checkbox is selected
+        */
+       mw.rcfilters.ui.FilterItemWidget.prototype.onCheckboxChange = function ( isSelected ) {
+               this.controller.updateFilter( this.model.getName(), isSelected );
+       };
+
+       /**
+        * Respond to item model update event
+        */
+       mw.rcfilters.ui.FilterItemWidget.prototype.onModelUpdate = function () {
+               this.checkboxWidget.setSelected( this.model.isSelected() );
+       };
+
+       /**
+        * Get the name of this filter
+        *
+        * @return {string} Filter name
+        */
+       mw.rcfilters.ui.FilterItemWidget.prototype.getName = function () {
+               return this.model.getName();
+       };
+
+}( mediaWiki, jQuery ) );
diff --git a/resources/src/mediawiki.rcfilters/ui/mw.rcfilters.ui.FilterWrapperWidget.js b/resources/src/mediawiki.rcfilters/ui/mw.rcfilters.ui.FilterWrapperWidget.js
new file mode 100644 (file)
index 0000000..3fcfc47
--- /dev/null
@@ -0,0 +1,130 @@
+( function ( mw ) {
+       /**
+        * List displaying all filter groups
+        *
+        * @extends OO.ui.Widget
+        * @mixins OO.ui.mixin.PendingElement
+        *
+        * @constructor
+        * @param {mw.rcfilters.Controller} controller Controller
+        * @param {mw.rcfilters.dm.FiltersViewModel} model View model
+        * @param {Object} config Configuration object
+        * @cfg {Object} [filters] A definition of the filter groups in this list
+        */
+       mw.rcfilters.ui.FilterWrapperWidget = function MwRcfiltersUiFilterWrapperWidget( controller, model, config ) {
+               config = config || {};
+
+               // Parent
+               mw.rcfilters.ui.FilterWrapperWidget.parent.call( this, config );
+               // Mixin constructors
+               OO.ui.mixin.PendingElement.call( this, config );
+
+               this.controller = controller;
+               this.model = model;
+               this.filtersInCapsule = [];
+
+               this.filterPopup = new mw.rcfilters.ui.FiltersListWidget(
+                       this.controller,
+                       this.model,
+                       {
+                               label: mw.msg( 'rcfilters-filterlist-title' )
+                       }
+               );
+
+               this.textInput = new OO.ui.TextInputWidget( {
+                       classes: [ 'mw-rcfilters-ui-filterWrapperWidget-search' ],
+                       icon: 'search',
+                       placeholder: mw.msg( 'rcfilters-search-placeholder' )
+               } );
+
+               this.capsule = new mw.rcfilters.ui.FilterCapsuleMultiselectWidget( this.textInput, {
+                       popup: {
+                               $content: this.filterPopup.$element,
+                               classes: [ 'mw-rcfilters-ui-filterWrapperWidget-popup' ]
+                       }
+               } );
+
+               // Events
+               this.model.connect( this, {
+                       initialize: 'onModelInitialize',
+                       itemUpdate: 'onModelItemUpdate'
+               } );
+               this.textInput.connect( this, {
+                       change: 'onTextInputChange'
+               } );
+               this.capsule.connect( this, {
+                       remove: 'onCapsuleRemoveItem'
+               } );
+
+               this.$element
+                       .addClass( 'mw-rcfilters-ui-filterWrapperWidget' )
+                       .append( this.capsule.$element, this.textInput.$element );
+       };
+
+       /* Initialization */
+
+       OO.inheritClass( mw.rcfilters.ui.FilterWrapperWidget, OO.ui.Widget );
+       OO.mixinClass( mw.rcfilters.ui.FilterWrapperWidget, OO.ui.mixin.PendingElement );
+
+       /**
+        * Respond to text input change
+        *
+        * @param {string} newValue Current value
+        */
+       mw.rcfilters.ui.FilterWrapperWidget.prototype.onTextInputChange = function ( newValue ) {
+               // Filter the results
+               this.filterPopup.filter( this.model.findMatches( newValue ) );
+       };
+
+       /**
+        * Respond to an event where an item is removed from the capsule.
+        * This is the case where a user actively removes a filter box from the capsule widget.
+        *
+        * @param {string[]} filterNames An array of filter names that were removed
+        */
+       mw.rcfilters.ui.FilterWrapperWidget.prototype.onCapsuleRemoveItem = function ( filterNames ) {
+               var filterItem,
+                       widget = this;
+
+               filterNames.forEach( function ( filterName ) {
+                       // Go over filters
+                       filterItem = widget.model.getItemByName( filterName );
+                       filterItem.toggleSelected( false );
+               } );
+       };
+
+       /**
+        * Respond to model update event and set up the available filters to choose
+        * from.
+        */
+       mw.rcfilters.ui.FilterWrapperWidget.prototype.onModelInitialize = function () {
+               var items,
+                       filters = this.model.getItems();
+
+               // Reset
+               this.capsule.getMenu().clearItems();
+
+               // Insert hidden options for the capsule to get its item data from
+               items = filters.map( function ( filterItem ) {
+                       return new OO.ui.MenuOptionWidget( {
+                               data: filterItem.getName(),
+                               label: filterItem.getLabel()
+                       } );
+               } );
+
+               this.capsule.getMenu().addItems( items );
+       };
+
+       /**
+        * Respond to model item update
+        *
+        * @param {mw.rcfilters.dm.FilterItem} item Filter item that was updated
+        */
+       mw.rcfilters.ui.FilterWrapperWidget.prototype.onModelItemUpdate = function ( item ) {
+               if ( item.isSelected() ) {
+                       this.capsule.addItemsFromData( [ item.getName() ] );
+               } else {
+                       this.capsule.removeItemsFromData( [ item.getName() ] );
+               }
+       };
+}( mediaWiki ) );
diff --git a/resources/src/mediawiki.rcfilters/ui/mw.rcfilters.ui.FiltersListWidget.js b/resources/src/mediawiki.rcfilters/ui/mw.rcfilters.ui.FiltersListWidget.js
new file mode 100644 (file)
index 0000000..f5ec1fc
--- /dev/null
@@ -0,0 +1,154 @@
+( function ( mw, $ ) {
+       /**
+        * List displaying all filter groups
+        *
+        * @extends OO.ui.Widget
+        * @mixins OO.ui.mixin.GroupWidget
+        * @mixins OO.ui.mixin.LabelElement
+        *
+        * @constructor
+        * @param {mw.rcfilters.Controller} controller Controller
+        * @param {mw.rcfilters.dm.FiltersViewModel} model View model
+        * @param {Object} config Configuration object
+        */
+       mw.rcfilters.ui.FiltersListWidget = function MwRcfiltersUiFiltersListWidget( controller, model, config ) {
+               config = config || {};
+
+               // Parent
+               mw.rcfilters.ui.FiltersListWidget.parent.call( this, config );
+               // Mixin constructors
+               OO.ui.mixin.GroupWidget.call( this, config );
+               OO.ui.mixin.LabelElement.call( this, $.extend( {}, config, {
+                       $label: $( '<div>' )
+                               .addClass( 'mw-rcfilters-ui-filtersListWidget-title' )
+               } ) );
+
+               this.controller = controller;
+               this.model = model;
+
+               this.noResultsLabel = new OO.ui.LabelWidget( {
+                       label: mw.msg( 'rcfilters-filterlist-noresults' ),
+                       classes: [ 'mw-rcfilters-ui-filtersListWidget-noresults' ]
+               } );
+
+               // Events
+               this.model.connect( this, {
+                       initialize: 'onModelInitialize'
+               } );
+
+               // Initialize
+               this.showNoResultsMessage( false );
+               this.$element
+                       .addClass( 'mw-rcfilters-ui-filtersListWidget' )
+                       .append(
+                               this.$label,
+                               this.$group
+                                       .addClass( 'mw-rcfilters-ui-filtersListWidget-group' ),
+                               this.noResultsLabel.$element
+                       );
+       };
+
+       /* Initialization */
+
+       OO.inheritClass( mw.rcfilters.ui.FiltersListWidget, OO.ui.Widget );
+       OO.mixinClass( mw.rcfilters.ui.FiltersListWidget, OO.ui.mixin.GroupWidget );
+       OO.mixinClass( mw.rcfilters.ui.FiltersListWidget, OO.ui.mixin.LabelElement );
+
+       /* Methods */
+
+       /**
+        * Respond to initialize event from the model
+        */
+       mw.rcfilters.ui.FiltersListWidget.prototype.onModelInitialize = function () {
+               var i, group, groupWidget,
+                       itemWidgets = [],
+                       groupWidgets = [],
+                       groups = this.model.getFilterGroups();
+
+               // Reset
+               this.clearItems();
+
+               for ( group in groups ) {
+                       groupWidget = new mw.rcfilters.ui.FilterGroupWidget( group, {
+                               label: groups[ group ].title
+                       } );
+                       groupWidgets.push( groupWidget );
+
+                       itemWidgets = [];
+                       if ( groups[ group ].filters ) {
+                               for ( i = 0; i < groups[ group ].filters.length; i++ ) {
+                                       itemWidgets.push(
+                                               new mw.rcfilters.ui.FilterItemWidget(
+                                                       this.controller,
+                                                       groups[ group ].filters[ i ],
+                                                       {
+                                                               label: groups[ group ].filters[ i ].getLabel(),
+                                                               description: groups[ group ].filters[ i ].getDescription()
+                                                       }
+                                               )
+                                       );
+                               }
+
+                               groupWidget.addItems( itemWidgets );
+                       }
+               }
+
+               this.addItems( groupWidgets );
+       };
+
+       /**
+        * Switch between showing the 'no results' message for filtering results or the result list.
+        *
+        * @param {boolean} showNoResults Show no results message
+        */
+       mw.rcfilters.ui.FiltersListWidget.prototype.showNoResultsMessage = function ( showNoResults ) {
+               this.noResultsLabel.toggle( !!showNoResults );
+               this.$group.toggleClass( 'oo-ui-element-hidden', !!showNoResults );
+       };
+
+       /**
+        * Show only the items matching with the models in the given list
+        *
+        * @param {Object} groupItems An object of items to show
+        *  arranged by their group names
+        */
+       mw.rcfilters.ui.FiltersListWidget.prototype.filter = function ( groupItems ) {
+               var i, j, groupName, itemWidgets,
+                       groupWidgets = this.getItems(),
+                       hasItemWithName = function ( itemArr, name ) {
+                               return !!itemArr.filter( function ( item ) {
+                                       return item.getName() === name;
+                               } ).length;
+                       };
+
+               if ( $.isEmptyObject( groupItems ) ) {
+                       // No results. Hide everything, show only 'no results'
+                       // message
+                       this.showNoResultsMessage( true );
+                       return;
+               }
+
+               this.showNoResultsMessage( false );
+               for ( i = 0; i < groupWidgets.length; i++ ) {
+                       groupName = groupWidgets[ i ].getName();
+
+                       // If this group widget is in the filtered results,
+                       // show it - otherwise, hide it
+                       groupWidgets[ i ].toggle( !!groupItems[ groupName ] );
+
+                       if ( !groupItems[ groupName ] ) {
+                               // Continue to next group
+                               continue;
+                       }
+
+                       // We have items to show
+                       itemWidgets = groupWidgets[ i ].getItems();
+                       for ( j = 0; j < itemWidgets.length; j++ ) {
+                               // Only show items that are in the filtered list
+                               itemWidgets[ j ].toggle(
+                                       hasItemWithName( groupItems[ groupName ], itemWidgets[ j ].getName() )
+                               );
+                       }
+               }
+       };
+}( mediaWiki, jQuery ) );
index 83b78a8..7d096f9 100644 (file)
@@ -227,7 +227,7 @@ table {
 
 /* Forms */
 fieldset {
-       border: 1px solid #2f6fab;
+       border: 1px solid #2a4b8d;
        margin: 1em 0 1em 0;
        padding: 0 1em 1em;
 }
index 99f6c13..707a579 100644 (file)
 .oo-ui-textInputWidget.oo-ui-widget-enabled > .oo-ui-indicatorElement-indicator.mw-apisandbox-clickable-indicator {
        cursor: pointer;
 }
+
+.mw-apisandbox-textInputCode .oo-ui-inputWidget-input {
+       font-family: monospace, 'Courier';
+       font-size: 0.8125em;
+       -moz-tab-size: 4;
+       -o-tab-size: 4;
+       tab-size: 4;
+}
index 43321fe..f108e50 100644 (file)
                        }
 
                        $.when.apply( $, deferreds ).done( function () {
+                               var jsonInput;
+
                                if ( $.inArray( false, arguments ) !== -1 ) {
                                        windowManager.openWindow( 'errorAlert', {
                                                title: Util.parseMsg( 'apisandbox-submit-invalid-fields-title' ),
                                                                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' )
+                                                       }
+                                               ).$element,
                                                $result
                                        );
                                ApiSandbox.updateUI();
                                booklet.setPage( '|results|' );
 
+                               // Resize the multiline input once visible
+                               jsonInput.adjustSize();
+
                                location.href = oldhash = '#' + query;
 
                                api.post( params, {
index 1793849..ad49a42 100644 (file)
         *  - 'boolean': The field is a boolean.
         *  - 'toggleLocal': The field represents {@link #getLocal this.getLocal()}.
         *    Editing should directly call {@link #toggleLocal this.toggleLocal()}.
+        * @return {boolean} return.calendarComponent Whether this field is part of a calendar, e.g.
+        *  part of the date instead of the time.
         * @return {number} return.size Maximum number of characters in the field (when
         *  the 'intercalary' component is falsey). If 0, the field should be hidden entirely.
         * @return {Object.<string,number>} return.intercalarySize Map from
                                }
                                spec = {
                                        component: null,
+                                       calendarComponent: false,
                                        editable: false,
                                        type: 'static',
                                        value: params.slice( 1 ).join( '|' ),
                                                c = params[ 0 ] === '#' ? '' : ':';
                                                return {
                                                        component: 'zone',
+                                                       calendarComponent: false,
                                                        editable: true,
                                                        type: 'toggleLocal',
                                                        size: 5 + c.length,
                                        case 'full':
                                                spec = {
                                                        component: 'zone',
+                                                       calendarComponent: false,
                                                        editable: true,
                                                        type: 'toggleLocal',
                                                        values: params[ 0 ] === 'short' ? this.shortZones : this.fullZones,
index e9bedf5..3e4c5e2 100644 (file)
                                $field = $( '<span>' )
                                        .width( sz )
                                        .data( 'mw-widgets-datetime-dateTimeInputWidget-placeholder', placeholder );
+                               if ( spec.type !== 'static' ) {
+                                       $field.prop( 'tabIndex', -1 );
+                                       $field.on( 'focus', this.onFieldFocus.bind( this, $field ) );
+                               }
                                if ( spec.type === 'static' ) {
                                        $field.text( spec.value );
                                } else {
         * @param {jQuery.Event} e Focus event
         */
        mw.widgets.datetime.DateTimeInputWidget.prototype.onFieldFocus = function ( $field ) {
+               var spec = $field.data( 'mw-widgets-datetime-dateTimeInputWidget-fieldSpec' );
+
                if ( !this.isDisabled() ) {
                        if ( this.getValueAsDate() === null ) {
                                this.setValue( this.formatter.getDefaultDate() );
                        }
 
                        if ( this.calendar ) {
-                               this.calendar.toggle( true );
+                               this.calendar.toggle( !!spec.calendarComponent );
                        }
                }
        };
index b280ead..6db2d06 100644 (file)
@@ -67,6 +67,7 @@
                        case 'year|#':
                                spec = {
                                        component: 'Year',
+                                       calendarComponent: true,
                                        type: 'number',
                                        size: 4,
                                        zeropad: false
@@ -76,6 +77,7 @@
                        case 'season|#':
                                spec = {
                                        component: 'Season',
+                                       calendarComponent: true,
                                        type: 'number',
                                        size: 1,
                                        intercalarySize: { 1: 0 },
@@ -86,6 +88,7 @@
                        case 'season|full':
                                spec = {
                                        component: 'Season',
+                                       calendarComponent: true,
                                        type: 'string',
                                        intercalarySize: { 1: 0 },
                                        values: {
                        case 'dow|full':
                                spec = {
                                        component: 'DOW',
+                                       calendarComponent: true,
                                        editable: false,
                                        type: 'string',
                                        intercalarySize: { 1: 0 },
                        case 'day|0':
                                spec = {
                                        component: 'Day',
+                                       calendarComponent: true,
                                        type: 'string',
                                        size: 2,
                                        intercalarySize: { 1: 13 },
                        case 'second|0':
                                spec = {
                                        component: tag.charAt( 0 ).toUpperCase() + tag.slice( 1 ),
+                                       calendarComponent: false,
                                        type: 'number',
                                        size: 2,
                                        zeropad: params[ 0 ] === '0'
                        case 'millisecond|0':
                                spec = {
                                        component: 'Millisecond',
+                                       calendarComponent: false,
                                        type: 'number',
                                        size: 3,
                                        zeropad: params[ 0 ] === '0'
index 9e9b15f..877edba 100644 (file)
@@ -2,7 +2,7 @@
 
        /**
         * Provides various methods needed for formatting dates and times. This
-        * implementation implments the proleptic Gregorian calendar over years
+        * implementation implements the proleptic Gregorian calendar over years
         * 0000–9999.
         *
         * @class
                        case 'year|0':
                                spec = {
                                        component: 'year',
+                                       calendarComponent: true,
                                        type: 'number',
                                        size: 4,
                                        zeropad: params[ 0 ] === '0'
                        case 'month|full':
                                spec = {
                                        component: 'month',
+                                       calendarComponent: true,
                                        type: 'string',
                                        values: params[ 0 ] === 'short' ? this.shortMonthNames : this.fullMonthNames
                                };
                        case 'dow|full':
                                spec = {
                                        component: 'dow',
+                                       calendarComponent: true,
                                        editable: false,
                                        type: 'string',
                                        values: params[ 0 ] === 'short' ? this.shortDayNames : this.fullDayNames
                        case 'month|0':
                        case 'day|#':
                        case 'day|0':
+                               spec = {
+                                       component: tag,
+                                       calendarComponent: true,
+                                       type: 'number',
+                                       size: 2,
+                                       zeropad: params[ 0 ] === '0'
+                               };
+                               break;
+
                        case 'hour|#':
                        case 'hour|0':
                        case 'minute|#':
                        case 'second|0':
                                spec = {
                                        component: tag,
+                                       calendarComponent: false,
                                        type: 'number',
                                        size: 2,
                                        zeropad: params[ 0 ] === '0'
                        case 'hour|012':
                                spec = {
                                        component: 'hour12',
+                                       calendarComponent: false,
                                        type: 'number',
                                        size: 2,
                                        zeropad: params[ 0 ] === '012'
                        case 'hour|period':
                                spec = {
                                        component: 'hour12period',
+                                       calendarComponent: false,
                                        type: 'boolean',
                                        values: this.hour12Periods
                                };
                        case 'millisecond|0':
                                spec = {
                                        component: 'millisecond',
+                                       calendarComponent: false,
                                        type: 'number',
                                        size: 3,
                                        zeropad: params[ 0 ] === '0'
index 5dda7e0..7cfe058 100644 (file)
                $links = $links.filter( ':not( #bodyContent *, #content * )' );
 
                $links.click( function ( e ) {
-                       var action, api, $link;
+                       var mwTitle, action, api, $link;
 
+                       mwTitle = mw.Title.newFromText( title );
                        action = mwUriGetAction( this.href );
 
-                       if ( action !== 'watch' && action !== 'unwatch' ) {
+                       if ( !mwTitle || ( action !== 'watch' && action !== 'unwatch' ) ) {
                                // Let native browsing handle the link
                                return true;
                        }
 
                        api[ action ]( title )
                                .done( function ( watchResponse ) {
-                                       var mwTitle, message, otherAction = action === 'watch' ? 'unwatch' : 'watch';
+                                       var message, otherAction = action === 'watch' ? 'unwatch' : 'watch';
 
-                                       mwTitle = mw.Title.newFromText( title );
-                                       if ( mwTitle && mwTitle.getNamespaceId() > 0 && mwTitle.getNamespaceId() % 2 === 1 ) {
+                                       if ( mwTitle.getNamespaceId() > 0 && mwTitle.getNamespaceId() % 2 === 1 ) {
                                                message = action === 'watch' ? 'addedwatchtext-talk' : 'removedwatchtext-talk';
                                        } else {
                                                message = action === 'watch' ? 'addedwatchtext' : 'removedwatchtext';
                                        }
 
-                                       mw.notify( mw.message( message, title ).parseDom(), {
+                                       mw.notify( mw.message( message, mwTitle.getPrefixedText() ).parseDom(), {
                                                tag: 'watch-self'
                                        } );
 
                                        $( '#wpWatchthis' ).prop( 'checked', watchResponse.watched === true );
                                } )
                                .fail( function () {
-                                       var cleanTitle, msg, link;
+                                       var msg, link;
 
                                        // Reset link to non-loading mode
                                        updateWatchLink( $link, action );
 
                                        // Format error message
-                                       cleanTitle = title.replace( /_/g, ' ' );
                                        link = mw.html.element(
                                                'a', {
                                                        href: mw.util.getUrl( title ),
-                                                       title: cleanTitle
-                                               }, cleanTitle
+                                                       title: mwTitle.getPrefixedText()
+                                               }, mwTitle.getPrefixedText()
                                        );
                                        msg = mw.message( 'watcherrortext', link );
 
index b6f2830..16d724d 100644 (file)
@@ -530,6 +530,8 @@ Extra newlines between heading and content are swallowed
 
 !! test
 Heading with line break in nowiki
+!! options
+parsoid=wt2html
 !! wikitext
 == A <nowiki>B
 C</nowiki> ==
@@ -537,6 +539,9 @@ C</nowiki> ==
 <h2><span class="mw-headline" id="A_B.0AC">A B
 C</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&amp;action=edit&amp;section=1" title="Edit section: A B&#10;C">edit</a><span class="mw-editsection-bracket">]</span></span></h2>
 
+!! html/parsoid
+<h2 id="A_B.0AC">A <span typeof="mw:Nowiki">B
+C</span> </h2>
 !! end
 
 !! test
@@ -6476,6 +6481,14 @@ parsoid=wt2html,html2html
 <span typeof="mw:Transclusion" data-mw='{"parts":[{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"ho\">ha&lt;/div>"}},"i":0}}]}'>ho">ha</span>
 !! end
 
+!! test
+Break on | in element attribute name in template
+!! wikitext
+{{echo|<div cla|ss="hiho">ha</div>}}
+!! html/parsoid
+<p about="#mwt1" typeof="mw:Transclusion" data-parsoid='{"pi":[[{"k":"1"},{"k":"ss","named":true}]]}' data-mw='{"parts":[{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"&lt;div cla"},"ss":{"wt":"\"hiho\">ha&lt;/div>"}},"i":0}}]}'>&lt;div cla</p>
+!! end
+
 !! test
 Don't break on | in extension attribute in template
 !! wikitext
@@ -10276,6 +10289,17 @@ Magic Word: {{SITENAME}}
 </p>
 !! end
 
+!! test
+Magic Word: {{PAGELANGUAGE}}
+!! options
+language=fr
+!! wikitext
+{{PAGELANGUAGE}}
+!! html
+<p>fr
+</p>
+!! end
+
 !! test
 Case-sensitive magic words, when cased differently, should just be template transclusions
 !! wikitext
@@ -10933,7 +10957,8 @@ BUG 553: link with two variables in a piped link
 
 !! html/parsoid
 <table>
-<tbody><tr><td>[[<span about="#mwt5" typeof="mw:Param" data-parsoid='{"src":"{{{1}}}"}'>{{{1}}}</span>|<span about="#mwt2" typeof="mw:Param" data-parsoid='{"src":"{{{2}}}"}'>{{{2}}}</span>]]</td></tr>
+<tbody><tr><td>[[<span about="#mwt5" typeof="mw:Param" data-mw='{"parts":[{"templatearg":{"target":{"wt":"1"},"params":{},"i":0}}]}'>{{{1}}}</span>|<span about="#mwt2" typeof="mw:Param" data-mw='{"parts":[{"templatearg":{"target":{"wt":"2"},"params":{},"i":0}}]}'>{{{2}}}</span>]]</td></tr>
+</tbody></table>
 !! end
 
 # See: T2553
@@ -11625,7 +11650,7 @@ parsoid=wt2html
 |c
 |}
 !!html/parsoid
-<meta typeof="mw:Includes/IncludeOnly" data-parsoid='{"src":"&lt;includeonly>a&lt;/includeonly>"}'/><meta typeof="mw:Includes/IncludeOnly/End" data-parsoid='{"src":""}'/><table about="#mwt2" typeof="mw:ExpandedAttrs" data-parsoid='{"a":{"{{{b}}}":null},"sa":{"{{{b}}}":""}}' data-mw='{"attribs":[[{"txt":"{{{b}}}","html":"&lt;span about=\"#mwt1\" typeof=\"mw:Param\" data-parsoid=&#39;{\"dsr\":[31,38,null,null],\"src\":\"{{{b}}}\"}&#39;>{{{b}}}&lt;/span>"},{"html":""}]]}'>
+<meta typeof="mw:Includes/IncludeOnly" data-parsoid='{"src":"&lt;includeonly>a&lt;/includeonly>"}'/><meta typeof="mw:Includes/IncludeOnly/End" data-parsoid='{"src":""}'/><table about="#mwt2" typeof="mw:ExpandedAttrs" data-parsoid='{"a":{"{{{b}}}":null},"sa":{"{{{b}}}":""}}' data-mw='{"attribs":[[{"txt":"{{{b}}}","html":"&lt;span about=\"#mwt1\" typeof=\"mw:Param\" data-parsoid=&#39;{\"pi\":[[]],\"dsr\":[31,38,null,null]}&#39; data-mw=&#39;{\"parts\":[{\"templatearg\":{\"target\":{\"wt\":\"b\"},\"params\":{},\"i\":0}}]}&#39;>{{{b}}}&lt;/span>"},{"html":""}]]}'>
 <tbody><tr><td>c</td></tr>
 </tbody></table>
 !!end
@@ -12514,11 +12539,16 @@ Templates: Ugly templates: 6. Template encapsulation test: Cyclical nesting of t
 Templates: Parameters substituted at the top-level
 !! wikitext
 {{{foo|''who'' {{echo|me}}? '''never!'''}}}
+
+{{{foo|bar|baz}}}
 !! html/php
 <p><i>who</i> me? <b>never!</b>
+</p><p>bar
 </p>
 !! html/parsoid
-<p about="#mwt2" typeof="mw:Param" data-parsoid="{&quot;src&quot;:&quot;{{{foo|''who'' {{echo|me}}? '''never!'''}}}&quot;}"><i>who</i> me? <b>never!</b></p>
+<p about="#mwt2" typeof="mw:Param" data-mw='{"parts":[{"templatearg":{"target":{"wt":"foo"},"params":{"1":{"wt":"&#39;&#39;who&#39;&#39; {{echo|me}}? &#39;&#39;&#39;never!&#39;&#39;&#39;"}},"i":0}}]}'><i>who</i> me? <b>never!</b></p>
+
+<p about="#mwt3" typeof="mw:Param" data-mw='{"parts":[{"templatearg":{"target":{"wt":"foo"},"params":{"1":{"wt":"bar"},"2":{"wt":"baz"}},"i":0}}]}'>bar</p>
 !! end
 
 !!test
@@ -17689,6 +17719,8 @@ http://===r:::https://b
 # Known to produce bad XML for now
 !! test
 Fuzz testing: Parser24
+!! options
+parsoid=wt2html
 !! wikitext
 {|
 {{{|
@@ -17698,7 +17730,7 @@ Fuzz testing: Parser24
 
 MOVE YOUR MOUSE CURSOR OVER THIS TEXT
 |
-!! html
+!! html/php
 <table>
 {{{|
 <u class="&#124;">}}}} &gt;
@@ -17711,6 +17743,14 @@ MOVE YOUR MOUSE CURSOR OVER THIS TEXT
 </tr>
 </table>
 
+!! html/parsoid
+<p data-parsoid='{"fostered":true,"autoInsertedEnd":true}'>{{{|
+<u class="|" about="#mwt2" typeof="mw:ExpandedAttrs" data-parsoid='{"stx":"html","a":{"{{{{SSSll!!!!!!!VVVV)]]][[Special:*xxxxxxx-->&lt;noinclude>}}}}":null},"sa":{"{{{{SSSll!!!!!!!VVVV)]]][[Special:*xxxxxxx-->&lt;noinclude>}}}}":""},"autoInsertedEnd":true}' data-mw='{"attribs":[[{"txt":"{{{{SSSll!!!!!!!VVVV)]]][[Special:*xxxxxxx-->}}}}","html":"{&lt;span about=\"#mwt1\" typeof=\"mw:Param\" data-parsoid=&#39;{\"pi\":[[]],\"dsr\":[21,79,null,null]}&#39; data-mw=&#39;{\"parts\":[{\"templatearg\":{\"target\":{\"wt\":\"SSSll!!!!!!!VVVV)]]][[Special:*xxxxxxx-->&amp;lt;noinclude>\"},\"params\":{},\"i\":0}}]}&#39;>{{{SSSll!!!!!!!VVVV)]]][[Special:*xxxxxxx-->}}}&lt;/span>}"},{"html":""}]]}'>
+<br style="onmouseover='alert(document.cookie);' " data-parsoid='{"stx":"html","selfClose":true}'/></u></p><p data-parsoid='{"fostered":true,"autoInsertedEnd":true}'><u class="|" about="#mwt2" typeof="mw:ExpandedAttrs" data-parsoid='{"stx":"html","a":{"{{{{SSSll!!!!!!!VVVV)]]][[Special:*xxxxxxx-->&lt;noinclude>}}}}":null},"sa":{"{{{{SSSll!!!!!!!VVVV)]]][[Special:*xxxxxxx-->&lt;noinclude>}}}}":""},"autoInsertedEnd":true,"autoInsertedStart":true}' data-mw='{"attribs":[[{"txt":"{{{{SSSll!!!!!!!VVVV)]]][[Special:*xxxxxxx-->}}}}","html":"{&lt;span about=\"#mwt1\" typeof=\"mw:Param\" data-parsoid=&#39;{\"pi\":[[]],\"dsr\":[21,79,null,null]}&#39; data-mw=&#39;{\"parts\":[{\"templatearg\":{\"target\":{\"wt\":\"SSSll!!!!!!!VVVV)]]][[Special:*xxxxxxx-->&amp;lt;noinclude>\"},\"params\":{},\"i\":0}}]}&#39;>{{{SSSll!!!!!!!VVVV)]]][[Special:*xxxxxxx-->}}}&lt;/span>}"},{"html":""}]]}'>MOVE YOUR MOUSE CURSOR OVER THIS TEXT</u></p><table data-parsoid='{"autoInsertedEnd":true}'>
+
+
+
+<tbody><tr data-parsoid='{"autoInsertedEnd":true,"autoInsertedStart":true}'><td data-parsoid='{"autoInsertedEnd":true}'></td></tr></tbody></table>
 !! end
 
 # Note: the current result listed for this is not what the original one was,
@@ -17729,9 +17769,12 @@ Fuzz testing: Parser25 (bug 6055)
 <LI CLASS=||
  >
 }}}blah" onmouseover="alert('hello world');" align="left"'''MOVE MOUSE CURSOR OVER HERE
-!! html
+!! html/php
 <p>&lt;LI CLASS=blah" onmouseover="alert('hello world');" align="left"<b>MOVE MOUSE CURSOR OVER HERE</b>
 </p>
+!! html/parsoid
+<span about="#mwt1" typeof="mw:Param" data-parsoid='{"pi":[[{"k":"1"},{"k":"2"},{"k":"3"}]]}' data-mw='{"parts":[{"templatearg":{"target":{"wt":"\n"},"params":{"1":{"wt":" \n&lt;LI CLASS="},"2":{"wt":""},"3":{"wt":"\n >\n"}},"i":0}},"blah\" onmouseover=\"alert(&#39;hello world&#39;);\" align=\"left\"&#39;&#39;&#39;MOVE MOUSE CURSOR OVER HERE"]}'> 
+</span><p about="#mwt1">&lt;LI CLASS=blah" onmouseover="alert('hello world');" align="left"<b>MOVE MOUSE CURSOR OVER HERE</b></p>
 !! end
 
 !!test
@@ -20633,10 +20676,12 @@ language=sr variant=sr-ec
 </p>
 !! end
 
+# FIXME: This test is currently broken in the PHP parser T153761
 !! test
 T146304: Don't break template parsing if language converter markup is in the parameter.
 !! options
 language=sr variant=sr-ec
+disabled
 !! wikitext
 {{echo|-{R|foo}-}}
 !! html/php
index 903d7cb..cef03ee 100644 (file)
@@ -167,7 +167,7 @@ return [
         */
        'analyze_signature_compatibility' => true,
 
-       // Emit all issues. They are then supressed via
+       // Emit all issues. They are then suppressed via
        // suppress_issue_types, rather than a minimum
        // severity.
        "minimum_severity" => 0,
index 410d2df..6c93c79 100644 (file)
@@ -113,6 +113,7 @@ class FileBackendDBRepoWrapperTest extends MediaWikiTestCase {
 
        protected function getMocks() {
                $dbMock = $this->getMockBuilder( 'DatabaseMysqli' )
+                       ->disableOriginalClone()
                        ->disableOriginalConstructor()
                        ->getMock();
 
index 7b5120c..1208a20 100644 (file)
  */
 class QueryAllSpecialPagesTest extends MediaWikiTestCase {
 
+       /**
+        * @var SpecialPage[]
+        */
+       private $queryPages;
+
        /** List query pages that can not be tested automatically */
        protected $manualTest = [
                'LinkSearchPage'
index 5d9cda7..94c6b4f 100644 (file)
@@ -726,13 +726,11 @@ class UserTest extends MediaWikiTestCase {
                $this->assertArrayHasKey( 'wm_infinite_blockBlockID', $cookies );
                $expOneDay = wfTimestamp() + ( 24 * 60 * 60 );
                // Check for expiry dates in a 10-second window, to account for slow testing.
-               $this->assertGreaterThan(
-                       $expOneDay - 5,
-                       $cookies['wm_infinite_blockBlockID']['expire']
-               );
-               $this->assertLessThan(
-                       $expOneDay + 5,
-                       $cookies['wm_infinite_blockBlockID']['expire']
+               $this->assertEquals(
+                       $expOneDay,
+                       $cookies['wm_infinite_blockBlockID']['expire'],
+                       'Expiry date',
+                       5.0
                );
 
                // 3. Change the block's expiry (to 2 hours), and the cookie's should be changed also.
@@ -752,4 +750,34 @@ class UserTest extends MediaWikiTestCase {
                // Clean up.
                $block->delete();
        }
+
+       public function testSoftBlockRanges() {
+               global $wgUser;
+
+               $this->setMwGlobals( [
+                       'wgSoftBlockRanges' => [ '10.0.0.0/8' ],
+                       'wgUser' => null,
+               ] );
+
+               // IP isn't in $wgSoftBlockRanges
+               $request = new FauxRequest();
+               $request->setIP( '192.168.0.1' );
+               $wgUser = User::newFromSession( $request );
+               $this->assertNull( $wgUser->getBlock() );
+
+               // IP is in $wgSoftBlockRanges
+               $request = new FauxRequest();
+               $request->setIP( '10.20.30.40' );
+               $wgUser = User::newFromSession( $request );
+               $block = $wgUser->getBlock();
+               $this->assertInstanceOf( Block::class, $block );
+               $this->assertSame( 'wgSoftBlockRanges', $block->getSystemBlockType() );
+
+               // Make sure the block is really soft
+               $request->getSession()->setUser( $this->getTestUser()->getUser() );
+               $wgUser = User::newFromSession( $request );
+               $this->assertFalse( $wgUser->isAnon(), 'sanity check' );
+               $this->assertNull( $wgUser->getBlock() );
+       }
+
 }
index e30088d..f31a646 100644 (file)
@@ -93,6 +93,7 @@ return [
                        'tests/qunit/suites/resources/mediawiki.api/mediawiki.api.watch.test.js',
                        'tests/qunit/suites/resources/mediawiki.api/mediawiki.ForeignApi.test.js',
                        'tests/qunit/suites/resources/mediawiki.special/mediawiki.special.recentchanges.test.js',
+                       'tests/qunit/suites/resources/mediawiki.rcfilters/dm.FiltersViewModel.test.js',
                        'tests/qunit/suites/resources/mediawiki/mediawiki.language.test.js',
                        'tests/qunit/suites/resources/mediawiki/mediawiki.cldr.test.js',
                        'tests/qunit/suites/resources/mediawiki/mediawiki.cookie.test.js',
@@ -136,6 +137,7 @@ return [
                        'mediawiki.util',
                        'mediawiki.viewport',
                        'mediawiki.special.recentchanges',
+                       'mediawiki.rcfilters.filters',
                        'mediawiki.language',
                        'mediawiki.cldr',
                        'mediawiki.cookie',
diff --git a/tests/qunit/suites/resources/mediawiki.rcfilters/dm.FiltersViewModel.test.js b/tests/qunit/suites/resources/mediawiki.rcfilters/dm.FiltersViewModel.test.js
new file mode 100644 (file)
index 0000000..b2857d9
--- /dev/null
@@ -0,0 +1,779 @@
+( function ( mw, $ ) {
+       QUnit.module( 'mediawiki.rcfilters - FiltersViewModel' );
+
+       QUnit.test( 'Setting up filters', function ( assert ) {
+               var definition = {
+                               group1: {
+                                       title: 'Group 1',
+                                       type: 'send_unselected_if_any',
+                                       filters: [
+                                               {
+                                                       name: 'group1filter1',
+                                                       label: 'Group 1: Filter 1',
+                                                       description: 'Description of Filter 1 in Group 1'
+                                               },
+                                               {
+                                                       name: 'group1filter2',
+                                                       label: 'Group 1: Filter 2',
+                                                       description: 'Description of Filter 2 in Group 1'
+                                               }
+                                       ]
+                               },
+                               group2: {
+                                       title: 'Group 2',
+                                       type: 'send_unselected_if_any',
+                                       filters: [
+                                               {
+                                                       name: 'group2filter1',
+                                                       label: 'Group 2: Filter 1',
+                                                       description: 'Description of Filter 1 in Group 2'
+                                               },
+                                               {
+                                                       name: 'group2filter2',
+                                                       label: 'Group 2: Filter 2',
+                                                       description: 'Description of Filter 2 in Group 2'
+                                               }
+                                       ]
+                               },
+                               group3: {
+                                       title: 'Group 3',
+                                       type: 'string_options',
+                                       filters: [
+                                               {
+                                                       name: 'group3filter1',
+                                                       label: 'Group 3: Filter 1',
+                                                       description: 'Description of Filter 1 in Group 3'
+                                               },
+                                               {
+                                                       name: 'group3filter2',
+                                                       label: 'Group 3: Filter 2',
+                                                       description: 'Description of Filter 2 in Group 3'
+                                               }
+                                       ]
+                               }
+                       },
+                       model = new mw.rcfilters.dm.FiltersViewModel();
+
+               model.initializeFilters( definition );
+
+               assert.ok(
+                       model.getItemByName( 'group1filter1' ) instanceof mw.rcfilters.dm.FilterItem &&
+                       model.getItemByName( 'group1filter2' ) instanceof mw.rcfilters.dm.FilterItem &&
+                       model.getItemByName( 'group2filter1' ) instanceof mw.rcfilters.dm.FilterItem &&
+                       model.getItemByName( 'group2filter2' ) instanceof mw.rcfilters.dm.FilterItem &&
+                       model.getItemByName( 'group3filter1' ) instanceof mw.rcfilters.dm.FilterItem &&
+                       model.getItemByName( 'group3filter2' ) instanceof mw.rcfilters.dm.FilterItem,
+                       'Filters instantiated and stored correctly'
+               );
+
+               assert.deepEqual(
+                       model.getState(),
+                       {
+                               group1filter1: false,
+                               group1filter2: false,
+                               group2filter1: false,
+                               group2filter2: false,
+                               group3filter1: false,
+                               group3filter2: false
+                       },
+                       'Initial state of filters'
+               );
+
+               model.updateFilters( {
+                       group1filter1: true,
+                       group2filter2: true,
+                       group3filter1: true
+               } );
+               assert.deepEqual(
+                       model.getState(),
+                       {
+                               group1filter1: true,
+                               group1filter2: false,
+                               group2filter1: false,
+                               group2filter2: true,
+                               group3filter1: true,
+                               group3filter2: false
+                       },
+                       'Updating filter states correctly'
+               );
+       } );
+
+       QUnit.test( 'Finding matching filters', function ( assert ) {
+               var matches,
+                       definition = {
+                               group1: {
+                                       title: 'Group 1',
+                                       type: 'send_unselected_if_any',
+                                       filters: [
+                                               {
+                                                       name: 'group1filter1',
+                                                       label: 'Group 1: Filter 1',
+                                                       description: 'Description of Filter 1 in Group 1'
+                                               },
+                                               {
+                                                       name: 'group1filter2',
+                                                       label: 'Group 1: Filter 2',
+                                                       description: 'Description of Filter 2 in Group 1'
+                                               }
+                                       ]
+                               },
+                               group2: {
+                                       title: 'Group 2',
+                                       type: 'send_unselected_if_any',
+                                       filters: [
+                                               {
+                                                       name: 'group2filter1',
+                                                       label: 'Group 2: Filter 1',
+                                                       description: 'Description of Filter 1 in Group 2'
+                                               },
+                                               {
+                                                       name: 'group2filter2',
+                                                       label: 'Group 2: Filter 2',
+                                                       description: 'Description of Filter 2 in Group 2'
+                                               }
+                                       ]
+                               }
+                       },
+                       model = new mw.rcfilters.dm.FiltersViewModel();
+
+               model.initializeFilters( definition );
+
+               matches = model.findMatches( 'group 1' );
+               assert.equal(
+                       matches.group1.length,
+                       2,
+                       'findMatches finds correct group with correct number of results'
+               );
+
+               assert.deepEqual(
+                       matches.group1.map( function ( item ) { return item.getName(); } ),
+                       [ 'group1filter1', 'group1filter2' ],
+                       'findMatches finds the correct items within a single group'
+               );
+
+               matches = model.findMatches( 'filter 1' );
+               assert.ok(
+                       matches.group1.length === 1 && matches.group2.length === 1,
+                       'findMatches finds correct number of results in multiple groups'
+               );
+
+               assert.deepEqual(
+                       [
+                               matches.group1.map( function ( item ) { return item.getName(); } ),
+                               matches.group2.map( function ( item ) { return item.getName(); } )
+                       ],
+                       [
+                               [ 'group1filter1' ],
+                               [ 'group2filter1' ]
+                       ],
+                       'findMatches finds the correct items within multiple groups'
+               );
+
+               matches = model.findMatches( 'foo' );
+               assert.ok(
+                       $.isEmptyObject( matches ),
+                       'findMatches returns an empty object when no results found'
+               );
+       } );
+
+       QUnit.test( 'getParametersFromFilters', function ( assert ) {
+               var definition = {
+                               group1: {
+                                       title: 'Group 1',
+                                       type: 'send_unselected_if_any',
+                                       filters: [
+                                               {
+                                                       name: 'hidefilter1',
+                                                       label: 'Group 1: Filter 1',
+                                                       description: 'Description of Filter 1 in Group 1'
+                                               },
+                                               {
+                                                       name: 'hidefilter2',
+                                                       label: 'Group 1: Filter 2',
+                                                       description: 'Description of Filter 2 in Group 1'
+                                               },
+                                               {
+                                                       name: 'hidefilter3',
+                                                       label: 'Group 1: Filter 3',
+                                                       description: 'Description of Filter 3 in Group 1'
+                                               }
+                                       ]
+                               },
+                               group2: {
+                                       title: 'Group 2',
+                                       type: 'send_unselected_if_any',
+                                       filters: [
+                                               {
+                                                       name: 'hidefilter4',
+                                                       label: 'Group 2: Filter 1',
+                                                       description: 'Description of Filter 1 in Group 2'
+                                               },
+                                               {
+                                                       name: 'hidefilter5',
+                                                       label: 'Group 2: Filter 2',
+                                                       description: 'Description of Filter 2 in Group 2'
+                                               },
+                                               {
+                                                       name: 'hidefilter6',
+                                                       label: 'Group 2: Filter 3',
+                                                       description: 'Description of Filter 3 in Group 2'
+                                               }
+                                       ]
+                               },
+                               group3: {
+                                       title: 'Group 3',
+                                       type: 'string_options',
+                                       separator: ',',
+                                       filters: [
+                                               {
+                                                       name: 'filter7',
+                                                       label: 'Group 3: Filter 1',
+                                                       description: 'Description of Filter 1 in Group 3'
+                                               },
+                                               {
+                                                       name: 'filter8',
+                                                       label: 'Group 3: Filter 2',
+                                                       description: 'Description of Filter 2 in Group 3'
+                                               },
+                                               {
+                                                       name: 'filter9',
+                                                       label: 'Group 3: Filter 3',
+                                                       description: 'Description of Filter 3 in Group 3'
+                                               }
+                                       ]
+                               }
+                       },
+                       model = new mw.rcfilters.dm.FiltersViewModel();
+
+               model.initializeFilters( definition );
+
+               // Starting with all filters unselected
+               assert.deepEqual(
+                       model.getParametersFromFilters(),
+                       {
+                               hidefilter1: 0,
+                               hidefilter2: 0,
+                               hidefilter3: 0,
+                               hidefilter4: 0,
+                               hidefilter5: 0,
+                               hidefilter6: 0,
+                               group3: 'all',
+                       },
+                       'Unselected filters return all parameters falsey or \'all\'.'
+               );
+
+               // Select 1 filter
+               model.updateFilters( {
+                       hidefilter1: true,
+                       hidefilter2: false,
+                       hidefilter3: false,
+                       hidefilter4: false,
+                       hidefilter5: false,
+                       hidefilter6: false
+               } );
+               // Only one filter in one group
+               assert.deepEqual(
+                       model.getParametersFromFilters(),
+                       {
+                               // Group 1 (one selected, the others are true)
+                               hidefilter1: 0,
+                               hidefilter2: 1,
+                               hidefilter3: 1,
+                               // Group 2 (nothing is selected, all false)
+                               hidefilter4: 0,
+                               hidefilter5: 0,
+                               hidefilter6: 0,
+                               group3: 'all'
+                       },
+                       'One filters in one "send_unselected_if_any" group returns the other parameters truthy.'
+               );
+
+               // Select 2 filters
+               model.updateFilters( {
+                       hidefilter1: true,
+                       hidefilter2: true,
+                       hidefilter3: false,
+                       hidefilter4: false,
+                       hidefilter5: false,
+                       hidefilter6: false
+               } );
+               // Two selected filters in one group
+               assert.deepEqual(
+                       model.getParametersFromFilters(),
+                       {
+                               // Group 1 (two selected, the others are true)
+                               hidefilter1: 0,
+                               hidefilter2: 0,
+                               hidefilter3: 1,
+                               // Group 2 (nothing is selected, all false)
+                               hidefilter4: 0,
+                               hidefilter5: 0,
+                               hidefilter6: 0,
+                               group3: 'all'
+                       },
+                       'One filters in one "send_unselected_if_any" group returns the other parameters truthy.'
+               );
+
+               // Select 3 filters
+               model.updateFilters( {
+                       hidefilter1: true,
+                       hidefilter2: true,
+                       hidefilter3: true,
+                       hidefilter4: false,
+                       hidefilter5: false,
+                       hidefilter6: false
+               } );
+               // All filters of the group are selected == this is the same as not selecting any
+               assert.deepEqual(
+                       model.getParametersFromFilters(),
+                       {
+                               // Group 1 (all selected, all false)
+                               hidefilter1: 0,
+                               hidefilter2: 0,
+                               hidefilter3: 0,
+                               // Group 2 (nothing is selected, all false)
+                               hidefilter4: 0,
+                               hidefilter5: 0,
+                               hidefilter6: 0,
+                               group3: 'all'
+                       },
+                       'All filters selected in one "send_unselected_if_any" group returns all parameters falsy.'
+               );
+
+               // Select 1 filter from string_options
+               model.updateFilters( {
+                       filter7: true,
+                       filter8: false,
+                       filter9: false
+               } );
+               // All filters of the group are selected == this is the same as not selecting any
+               assert.deepEqual(
+                       model.getParametersFromFilters(),
+                       {
+                               // Group 1 (all selected, all)
+                               hidefilter1: 0,
+                               hidefilter2: 0,
+                               hidefilter3: 0,
+                               // Group 2 (nothing is selected, all false)
+                               hidefilter4: 0,
+                               hidefilter5: 0,
+                               hidefilter6: 0,
+                               group3: 'filter7'
+                       },
+                       'One filter selected in "string_option" group returns that filter in the value.'
+               );
+
+               // Select 2 filters from string_options
+               model.updateFilters( {
+                       filter7: true,
+                       filter8: true,
+                       filter9: false
+               } );
+               // All filters of the group are selected == this is the same as not selecting any
+               assert.deepEqual(
+                       model.getParametersFromFilters(),
+                       {
+                               // Group 1 (all selected, all)
+                               hidefilter1: 0,
+                               hidefilter2: 0,
+                               hidefilter3: 0,
+                               // Group 2 (nothing is selected, all false)
+                               hidefilter4: 0,
+                               hidefilter5: 0,
+                               hidefilter6: 0,
+                               group3: 'filter7,filter8'
+                       },
+                       'Two filters selected in "string_option" group returns those filters in the value.'
+               );
+
+               // Select 3 filters from string_options
+               model.updateFilters( {
+                       filter7: true,
+                       filter8: true,
+                       filter9: true
+               } );
+               // All filters of the group are selected == this is the same as not selecting any
+               assert.deepEqual(
+                       model.getParametersFromFilters(),
+                       {
+                               // Group 1 (all selected, all)
+                               hidefilter1: 0,
+                               hidefilter2: 0,
+                               hidefilter3: 0,
+                               // Group 2 (nothing is selected, all false)
+                               hidefilter4: 0,
+                               hidefilter5: 0,
+                               hidefilter6: 0,
+                               group3: 'all'
+                       },
+                       'All filters selected in "string_option" group returns \'all\'.'
+               );
+
+       } );
+
+       QUnit.test( 'getFiltersFromParameters', function ( assert ) {
+               var definition = {
+                               group1: {
+                                       title: 'Group 1',
+                                       type: 'send_unselected_if_any',
+                                       filters: [
+                                               {
+                                                       name: 'hidefilter1',
+                                                       label: 'Show filter 1',
+                                                       description: 'Description of Filter 1 in Group 1'
+                                               },
+                                               {
+                                                       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'
+                                               }
+                                       ]
+                               },
+                               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'
+                                               },
+                                               {
+                                                       name: 'hidefilter6',
+                                                       label: 'Show filter 6',
+                                                       description: 'Description of Filter 3 in Group 2'
+                                               }
+                                       ]
+                               },
+                               group3: {
+                                       title: 'Group 3',
+                                       type: 'string_options',
+                                       separator: ',',
+                                       filters: [
+                                               {
+                                                       name: 'filter7',
+                                                       label: 'Group 3: Filter 1',
+                                                       description: 'Description of Filter 1 in Group 3'
+                                               },
+                                               {
+                                                       name: 'filter8',
+                                                       label: 'Group 3: Filter 2',
+                                                       description: 'Description of Filter 2 in Group 3'
+                                               },
+                                               {
+                                                       name: 'filter9',
+                                                       label: 'Group 3: Filter 3',
+                                                       description: 'Description of Filter 3 in Group 3'
+                                               }
+                                       ]
+                               }
+                       },
+                       model = new mw.rcfilters.dm.FiltersViewModel();
+
+               model.initializeFilters( definition );
+
+               // Empty query = empty filter definition
+               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'
+               );
+
+               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'
+                       } ),
+                       {
+                               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'
+               );
+
+               assert.deepEqual(
+                       model.getFiltersFromParameters( {
+                               hidefilter1: '1',
+                               hidefilter2: '1',
+                               hidefilter3: '1'
+                       } ),
+                       {
+                               // TODO: This will have to be represented as a different state, though.
+                               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
+                       },
+                       '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.
+
+               model.updateFilters(
+                       model.getFiltersFromParameters( {
+                               hidefilter1: '1'
+                       } )
+               );
+
+               model.updateFilters(
+                       model.getFiltersFromParameters( {
+                               hidefilter3: '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).
+               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.'
+               );
+
+               // Reset
+               model = new mw.rcfilters.dm.FiltersViewModel();
+               model.initializeFilters( definition );
+
+               model.updateFilters(
+                       model.getFiltersFromParameters( {
+                               hidefilter1: '1'
+                       } )
+               );
+               model.updateFilters(
+                       model.getFiltersFromParameters( {
+                               hidefilter1: '0'
+                       } )
+               );
+
+               // 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.updateFilters(
+                       model.getFiltersFromParameters( {
+                               group3: 'filter7'
+                       } )
+               );
+               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: true,
+                               filter8: false,
+                               filter9: false
+                       },
+                       'A \'string_options\' parameter containing 1 value, results in the corresponding filter as checked'
+               );
+
+               model.updateFilters(
+                       model.getFiltersFromParameters( {
+                               group3: 'filter7,filter8'
+                       } )
+               );
+               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: true,
+                               filter8: true,
+                               filter9: false
+                       },
+                       'A \'string_options\' parameter containing 2 values, results in both corresponding filters as checked'
+               );
+
+               model.updateFilters(
+                       model.getFiltersFromParameters( {
+                               group3: 'filter7,filter8,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"
+                               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'
+                       } )
+               );
+               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
+                       },
+                       'A \'string_options\' parameter containing the value \'all\', results in all filters of the group as unchecked.'
+               );
+
+               model.updateFilters(
+                       model.getFiltersFromParameters( {
+                               group3: 'filter7,foo,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"
+                               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.'
+               );
+       } );
+
+       QUnit.test( 'sanitizeStringOptionGroup', function ( assert ) {
+               var definition = {
+                               group1: {
+                                       title: 'Group 1',
+                                       type: 'string_options',
+                                       filters: [
+                                               {
+                                                       name: 'filter1',
+                                                       label: 'Show filter 1',
+                                                       description: 'Description of Filter 1 in Group 1'
+                                               },
+                                               {
+                                                       name: 'filter2',
+                                                       label: 'Show filter 2',
+                                                       description: 'Description of Filter 2 in Group 1'
+                                               },
+                                               {
+                                                       name: 'filter3',
+                                                       label: 'Show filter 3',
+                                                       description: 'Description of Filter 3 in Group 1'
+                                               }
+                                       ]
+                               }
+                       },
+                       model = new mw.rcfilters.dm.FiltersViewModel();
+
+               model.initializeFilters( definition );
+
+               assert.deepEqual(
+                       model.sanitizeStringOptionGroup( 'group1', [ 'filter1', 'filter1', 'filter2' ] ),
+                       [ 'filter1', 'filter2' ],
+                       'Remove duplicate values'
+               );
+
+               assert.deepEqual(
+                       model.sanitizeStringOptionGroup( 'group1', [ 'filter1', 'foo', 'filter2' ] ),
+                       [ 'filter1', 'filter2' ],
+                       'Remove invalid values'
+               );
+
+               assert.deepEqual(
+                       model.sanitizeStringOptionGroup( 'group1', [ 'filter1', 'all', 'filter2' ] ),
+                       [ 'all' ],
+                       'If any value is "all", the only value is "all".'
+               );
+       } );
+}( mediaWiki, jQuery ) );