Merge "jquery.confirmable: Add a space between buttons"
authorjenkins-bot <jenkins-bot@gerrit.wikimedia.org>
Sun, 21 Sep 2014 05:10:38 +0000 (05:10 +0000)
committerGerrit Code Review <gerrit@wikimedia.org>
Sun, 21 Sep 2014 05:10:38 +0000 (05:10 +0000)
471 files changed:
RELEASE-NOTES-1.24
RELEASE-NOTES-1.25 [new file with mode: 0644]
assets/file-type-icons/COPYING [deleted file]
assets/file-type-icons/fileicon-c.png [deleted file]
assets/file-type-icons/fileicon-cpp.png [deleted file]
assets/file-type-icons/fileicon-deb.png [deleted file]
assets/file-type-icons/fileicon-djvu.png [deleted file]
assets/file-type-icons/fileicon-djvu.xcf [deleted file]
assets/file-type-icons/fileicon-dvi.png [deleted file]
assets/file-type-icons/fileicon-exe.png [deleted file]
assets/file-type-icons/fileicon-h.png [deleted file]
assets/file-type-icons/fileicon-html.png [deleted file]
assets/file-type-icons/fileicon-iso.png [deleted file]
assets/file-type-icons/fileicon-java.png [deleted file]
assets/file-type-icons/fileicon-mid.png [deleted file]
assets/file-type-icons/fileicon-mov.png [deleted file]
assets/file-type-icons/fileicon-o.png [deleted file]
assets/file-type-icons/fileicon-ogg.png [deleted file]
assets/file-type-icons/fileicon-ogg.xcf [deleted file]
assets/file-type-icons/fileicon-pdf.png [deleted file]
assets/file-type-icons/fileicon-ps.png [deleted file]
assets/file-type-icons/fileicon-psd.png [deleted file]
assets/file-type-icons/fileicon-rm.png [deleted file]
assets/file-type-icons/fileicon-rpm.png [deleted file]
assets/file-type-icons/fileicon-svg.png [deleted file]
assets/file-type-icons/fileicon-tar.png [deleted file]
assets/file-type-icons/fileicon-tex.png [deleted file]
assets/file-type-icons/fileicon-ttf.png [deleted file]
assets/file-type-icons/fileicon-txt.png [deleted file]
assets/file-type-icons/fileicon-xcf.png [deleted file]
assets/file-type-icons/fileicon.png [deleted file]
assets/mediawiki.png [deleted file]
docs/hooks.txt
docs/kss/Makefile
docs/kss/styleguide-template/index.html
docs/kss/styleguide-template/public/kss.less
docs/skin.txt
includes/AutoLoader.php
includes/CategoryViewer.php
includes/DefaultSettings.php
includes/EditPage.php
includes/Export.php
includes/Feed.php
includes/GlobalFunctions.php
includes/HistoryBlob.php
includes/Import.php
includes/Linker.php
includes/MediaWiki.php
includes/MovePage.php [new file with mode: 0644]
includes/OutputPage.php
includes/PHPVersionError.php
includes/Preferences.php
includes/PrefixSearch.php
includes/ProtectionForm.php
includes/Setup.php
includes/Title.php
includes/User.php
includes/UserMailer.php [deleted file]
includes/actions/Action.php
includes/actions/HistoryAction.php
includes/actions/RawAction.php
includes/api/ApiEmailUser.php
includes/api/ApiMain.php
includes/api/ApiQuery.php
includes/api/ApiQueryAllUsers.php
includes/api/ApiQueryBacklinksprop.php [new file with mode: 0644]
includes/api/ApiQueryBase.php
includes/api/ApiQueryCategoryMembers.php
includes/api/ApiQueryImageInfo.php
includes/api/ApiQueryRedirects.php [deleted file]
includes/api/ApiQuerySearch.php
includes/api/ApiQuerySiteinfo.php
includes/api/ApiQueryUserInfo.php
includes/api/ApiQueryUsers.php
includes/cache/HTMLFileCache.php
includes/cache/bloom/BloomCacheRedis.php
includes/config/Config.php
includes/config/GlobalVarConfig.php
includes/config/HashConfig.php [new file with mode: 0644]
includes/config/MultiConfig.php [new file with mode: 0644]
includes/config/MutableConfig.php [new file with mode: 0644]
includes/content/AbstractContent.php
includes/content/CodeContentHandler.php [new file with mode: 0644]
includes/content/CssContent.php
includes/content/CssContentHandler.php
includes/content/JSONContent.php [deleted file]
includes/content/JSONContentHandler.php [deleted file]
includes/content/JavaScriptContent.php
includes/content/JavaScriptContentHandler.php
includes/content/JsonContent.php [new file with mode: 0644]
includes/content/JsonContentHandler.php [new file with mode: 0644]
includes/content/MessageContent.php
includes/content/TextContent.php
includes/content/WikitextContent.php
includes/db/DatabaseError.php
includes/db/DatabaseMssql.php
includes/db/DatabaseMysql.php
includes/db/DatabaseMysqlBase.php
includes/db/DatabaseMysqli.php
includes/db/LoadBalancer.php
includes/externalstore/ExternalStoreDB.php
includes/filebackend/FileBackend.php
includes/filerepo/file/ArchivedFile.php
includes/filerepo/file/File.php
includes/gallery/PackedOverlayImageGallery.php
includes/htmlform/HTMLForm.php
includes/htmlform/HTMLFormField.php
includes/htmlform/HTMLFormFieldCloner.php
includes/installer/CliInstaller.php
includes/installer/Installer.php
includes/installer/WebInstallerPage.php
includes/installer/i18n/be-tarask.json
includes/installer/i18n/be.json
includes/installer/i18n/br.json
includes/installer/i18n/de.json
includes/installer/i18n/en-gb.json
includes/installer/i18n/fi.json
includes/installer/i18n/gl.json
includes/installer/i18n/ms.json
includes/installer/i18n/qqq.json
includes/installer/i18n/zh-hant.json
includes/jobqueue/JobRunner.php
includes/libs/APACHE-LICENSE-2.0.txt [new file with mode: 0644]
includes/libs/CSSJanus.php
includes/mail/EmailNotification.php [new file with mode: 0644]
includes/mail/MailAddress.php [new file with mode: 0644]
includes/mail/UserMailer.php [new file with mode: 0644]
includes/media/Bitmap.php
includes/media/ExifBitmap.php
includes/media/MediaHandler.php
includes/media/TransformationalImageHandler.php [new file with mode: 0644]
includes/media/XCF.php
includes/mime.info
includes/mime.types
includes/objectcache/BagOStuff.php
includes/objectcache/MultiWriteBagOStuff.php
includes/page/Article.php
includes/pager/TablePager.php
includes/parser/Parser.php
includes/parser/ParserOptions.php
includes/profiler/ProfilerSimpleDB.php
includes/rcfeed/MachineReadableRCFeedFormatter.php
includes/resourceloader/ResourceLoader.php
includes/resourceloader/ResourceLoaderEditToolbarModule.php [new file with mode: 0644]
includes/resourceloader/ResourceLoaderFileModule.php
includes/resourceloader/ResourceLoaderLESSFunctions.php [deleted file]
includes/resourceloader/ResourceLoaderStartUpModule.php
includes/resourceloader/ResourceLoaderWikiModule.php
includes/search/SearchMssql.php
includes/search/SearchOracle.php
includes/search/SearchPostgres.php
includes/search/SearchResult.php
includes/search/SearchResultSet.php
includes/site/SiteSQLStore.php
includes/skins/Skin.php
includes/skins/SkinFactory.php
includes/specialpage/QueryPage.php
includes/specialpage/RedirectSpecialPage.php
includes/specialpage/SpecialPage.php
includes/specialpage/SpecialPageFactory.php
includes/specialpage/WantedQueryPage.php
includes/specials/SpecialChangeEmail.php
includes/specials/SpecialEmailuser.php
includes/specials/SpecialListgrouprights.php
includes/specials/SpecialListusers.php
includes/specials/SpecialMIMEsearch.php
includes/specials/SpecialMediaStatistics.php [new file with mode: 0644]
includes/specials/SpecialMergeHistory.php
includes/specials/SpecialPageLanguage.php
includes/specials/SpecialPreferences.php
includes/specials/SpecialRecentchanges.php
includes/specials/SpecialSearch.php
includes/specials/SpecialStatistics.php
includes/specials/SpecialUnblock.php
includes/specials/SpecialUndelete.php
includes/specials/SpecialUpload.php
includes/specials/SpecialVersion.php
includes/specials/SpecialWantedfiles.php
includes/templates/NoLocalSettings.php
languages/Language.php
languages/i18n/ar.json
languages/i18n/as.json
languages/i18n/bcl.json
languages/i18n/be-tarask.json
languages/i18n/be.json
languages/i18n/bg.json
languages/i18n/bn.json
languages/i18n/br.json
languages/i18n/bs.json
languages/i18n/bto.json
languages/i18n/ca.json
languages/i18n/ce.json
languages/i18n/ckb.json
languages/i18n/cs.json
languages/i18n/de.json
languages/i18n/egl.json
languages/i18n/el.json
languages/i18n/en.json
languages/i18n/eo.json
languages/i18n/es.json
languages/i18n/et.json
languages/i18n/fa.json
languages/i18n/fi.json
languages/i18n/fr.json
languages/i18n/frr.json
languages/i18n/gl.json
languages/i18n/hak.json
languages/i18n/he.json
languages/i18n/hi.json
languages/i18n/hr.json
languages/i18n/hsb.json
languages/i18n/hu.json
languages/i18n/hy.json
languages/i18n/ia.json
languages/i18n/id.json
languages/i18n/is.json
languages/i18n/it.json
languages/i18n/ja.json
languages/i18n/ka.json
languages/i18n/kk-cyrl.json
languages/i18n/ko.json
languages/i18n/ku-latn.json
languages/i18n/lb.json
languages/i18n/lrc.json
languages/i18n/lv.json
languages/i18n/lzh.json
languages/i18n/mai.json
languages/i18n/mg.json
languages/i18n/mk.json
languages/i18n/ml.json
languages/i18n/ms.json
languages/i18n/mt.json
languages/i18n/nap.json
languages/i18n/nb.json
languages/i18n/nl.json
languages/i18n/nn.json
languages/i18n/pl.json
languages/i18n/pms.json
languages/i18n/ps.json
languages/i18n/pt-br.json
languages/i18n/pt.json
languages/i18n/qqq.json
languages/i18n/ro.json
languages/i18n/roa-tara.json
languages/i18n/ru.json
languages/i18n/sc.json
languages/i18n/scn.json
languages/i18n/sk.json
languages/i18n/sl.json
languages/i18n/sr-ec.json
languages/i18n/sr-el.json
languages/i18n/su.json
languages/i18n/sv.json
languages/i18n/tg-cyrl.json
languages/i18n/th.json
languages/i18n/tt-cyrl.json
languages/i18n/tyv.json
languages/i18n/uk.json
languages/i18n/vec.json
languages/i18n/vi.json
languages/i18n/wa.json
languages/i18n/yi.json
languages/i18n/zh-hans.json
languages/i18n/zh-hant.json
languages/messages/MessagesEn.php
languages/messages/MessagesKsh.php
languages/messages/MessagesRu.php
maintenance/archives/patch-restructure.sql [deleted file]
maintenance/cssjanus/COPYING [deleted file]
maintenance/cssjanus/LICENSE [deleted file]
maintenance/cssjanus/README [deleted file]
maintenance/cssjanus/cssjanus.py [deleted file]
maintenance/cssjanus/csslex.py [deleted file]
maintenance/dictionary/mediawiki.dic
maintenance/findHooks.php
maintenance/importSiteScripts.php
maintenance/language/generateCollationData.php
maintenance/oracle/tables.sql
resources/Resources.php
resources/assets/file-type-icons/COPYING [new file with mode: 0644]
resources/assets/file-type-icons/fileicon-c.png [new file with mode: 0644]
resources/assets/file-type-icons/fileicon-cpp.png [new file with mode: 0644]
resources/assets/file-type-icons/fileicon-deb.png [new file with mode: 0644]
resources/assets/file-type-icons/fileicon-djvu.png [new file with mode: 0644]
resources/assets/file-type-icons/fileicon-djvu.xcf [new file with mode: 0644]
resources/assets/file-type-icons/fileicon-dvi.png [new file with mode: 0644]
resources/assets/file-type-icons/fileicon-exe.png [new file with mode: 0644]
resources/assets/file-type-icons/fileicon-h.png [new file with mode: 0644]
resources/assets/file-type-icons/fileicon-html.png [new file with mode: 0644]
resources/assets/file-type-icons/fileicon-iso.png [new file with mode: 0644]
resources/assets/file-type-icons/fileicon-java.png [new file with mode: 0644]
resources/assets/file-type-icons/fileicon-mid.png [new file with mode: 0644]
resources/assets/file-type-icons/fileicon-mov.png [new file with mode: 0644]
resources/assets/file-type-icons/fileicon-o.png [new file with mode: 0644]
resources/assets/file-type-icons/fileicon-ogg.png [new file with mode: 0644]
resources/assets/file-type-icons/fileicon-ogg.xcf [new file with mode: 0644]
resources/assets/file-type-icons/fileicon-pdf.png [new file with mode: 0644]
resources/assets/file-type-icons/fileicon-ps.png [new file with mode: 0644]
resources/assets/file-type-icons/fileicon-psd.png [new file with mode: 0644]
resources/assets/file-type-icons/fileicon-rm.png [new file with mode: 0644]
resources/assets/file-type-icons/fileicon-rpm.png [new file with mode: 0644]
resources/assets/file-type-icons/fileicon-svg.png [new file with mode: 0644]
resources/assets/file-type-icons/fileicon-tar.png [new file with mode: 0644]
resources/assets/file-type-icons/fileicon-tex.png [new file with mode: 0644]
resources/assets/file-type-icons/fileicon-ttf.png [new file with mode: 0644]
resources/assets/file-type-icons/fileicon-txt.png [new file with mode: 0644]
resources/assets/file-type-icons/fileicon-xcf.png [new file with mode: 0644]
resources/assets/file-type-icons/fileicon.png [new file with mode: 0644]
resources/assets/licenses/cc-0.png [new file with mode: 0644]
resources/assets/licenses/cc-by-nc-sa.png [new file with mode: 0644]
resources/assets/licenses/cc-by-sa.png [new file with mode: 0644]
resources/assets/licenses/cc-by.png [new file with mode: 0644]
resources/assets/licenses/gnu-fdl.png [new file with mode: 0644]
resources/assets/licenses/public-domain.png [new file with mode: 0644]
resources/assets/mediawiki.png [new file with mode: 0644]
resources/assets/poweredby_mediawiki_88x31.png [new file with mode: 0644]
resources/lib/oojs-ui/i18n/hy.json
resources/lib/oojs-ui/images/icons/help-rtl.png [deleted file]
resources/lib/oojs-ui/oojs-ui-apex.css
resources/lib/oojs-ui/oojs-ui-apex.rtl.css [new file with mode: 0644]
resources/lib/oojs-ui/oojs-ui-minerva.css
resources/lib/oojs-ui/oojs-ui-minerva.rtl.css [new file with mode: 0644]
resources/lib/oojs-ui/oojs-ui.js
resources/lib/oojs-ui/oojs-ui.rtl.css [new file with mode: 0644]
resources/lib/oojs-ui/oojs-ui.svg.css
resources/lib/oojs-ui/oojs-ui.svg.rtl.css [new file with mode: 0644]
resources/lib/oojs/oojs.jquery.js
resources/src/mediawiki.action/mediawiki.action.edit.css [new file with mode: 0644]
resources/src/mediawiki.action/mediawiki.action.edit.js
resources/src/mediawiki.action/mediawiki.action.edit.toolbar/images/ar/button_bold.png [new file with mode: 0644]
resources/src/mediawiki.action/mediawiki.action.edit.toolbar/images/ar/button_headline.png [new file with mode: 0644]
resources/src/mediawiki.action/mediawiki.action.edit.toolbar/images/ar/button_italic.png [new file with mode: 0644]
resources/src/mediawiki.action/mediawiki.action.edit.toolbar/images/ar/button_link.png [new file with mode: 0644]
resources/src/mediawiki.action/mediawiki.action.edit.toolbar/images/ar/button_nowiki.png [new file with mode: 0644]
resources/src/mediawiki.action/mediawiki.action.edit.toolbar/images/be-tarask/button_bold.png [new file with mode: 0644]
resources/src/mediawiki.action/mediawiki.action.edit.toolbar/images/be-tarask/button_italic.png [new file with mode: 0644]
resources/src/mediawiki.action/mediawiki.action.edit.toolbar/images/be-tarask/button_link.png [new file with mode: 0644]
resources/src/mediawiki.action/mediawiki.action.edit.toolbar/images/de/button_bold.png [new file with mode: 0644]
resources/src/mediawiki.action/mediawiki.action.edit.toolbar/images/de/button_italic.png [new file with mode: 0644]
resources/src/mediawiki.action/mediawiki.action.edit.toolbar/images/en/button_bold.png [new file with mode: 0644]
resources/src/mediawiki.action/mediawiki.action.edit.toolbar/images/en/button_extlink.png [new file with mode: 0644]
resources/src/mediawiki.action/mediawiki.action.edit.toolbar/images/en/button_headline.png [new file with mode: 0644]
resources/src/mediawiki.action/mediawiki.action.edit.toolbar/images/en/button_hr.png [new file with mode: 0644]
resources/src/mediawiki.action/mediawiki.action.edit.toolbar/images/en/button_image.png [new file with mode: 0644]
resources/src/mediawiki.action/mediawiki.action.edit.toolbar/images/en/button_italic.png [new file with mode: 0644]
resources/src/mediawiki.action/mediawiki.action.edit.toolbar/images/en/button_link.png [new file with mode: 0644]
resources/src/mediawiki.action/mediawiki.action.edit.toolbar/images/en/button_media.png [new file with mode: 0644]
resources/src/mediawiki.action/mediawiki.action.edit.toolbar/images/en/button_nowiki.png [new file with mode: 0644]
resources/src/mediawiki.action/mediawiki.action.edit.toolbar/images/en/button_sig.png [new file with mode: 0644]
resources/src/mediawiki.action/mediawiki.action.edit.toolbar/images/fa/button_bold.png [new file with mode: 0644]
resources/src/mediawiki.action/mediawiki.action.edit.toolbar/images/fa/button_headline.png [new file with mode: 0644]
resources/src/mediawiki.action/mediawiki.action.edit.toolbar/images/fa/button_italic.png [new file with mode: 0644]
resources/src/mediawiki.action/mediawiki.action.edit.toolbar/images/fa/button_link.png [new file with mode: 0644]
resources/src/mediawiki.action/mediawiki.action.edit.toolbar/images/fa/button_nowiki.png [new file with mode: 0644]
resources/src/mediawiki.action/mediawiki.action.edit.toolbar/images/ksh/LICENSE [new file with mode: 0644]
resources/src/mediawiki.action/mediawiki.action.edit.toolbar/images/ksh/button_italic.png [new file with mode: 0644]
resources/src/mediawiki.action/mediawiki.action.edit.toolbar/images/ru/LICENSE [new file with mode: 0644]
resources/src/mediawiki.action/mediawiki.action.edit.toolbar/images/ru/button_bold.png [new file with mode: 0644]
resources/src/mediawiki.action/mediawiki.action.edit.toolbar/images/ru/button_italic.png [new file with mode: 0644]
resources/src/mediawiki.action/mediawiki.action.edit.toolbar/images/ru/button_link.png [new file with mode: 0644]
resources/src/mediawiki.action/mediawiki.action.edit.toolbar/mediawiki.action.edit.toolbar.less [new file with mode: 0644]
resources/src/mediawiki.action/mediawiki.action.view.redirectPage.css
resources/src/mediawiki.legacy/oldshared.css
resources/src/mediawiki.legacy/protect.js
resources/src/mediawiki.legacy/shared.css
resources/src/mediawiki.legacy/wikibits.js
resources/src/mediawiki.less/mediawiki.mixins.less
resources/src/mediawiki.less/mediawiki.ui/variables.less
resources/src/mediawiki.page/mediawiki.page.ready.js
resources/src/mediawiki.skinning/content.css
resources/src/mediawiki.skinning/content.parsoid.less
resources/src/mediawiki.special/mediawiki.special.preferences.js
resources/src/mediawiki.special/mediawiki.special.userlogin.common.css
resources/src/mediawiki.ui/components/buttons.less
resources/src/mediawiki.ui/components/checkbox.less
resources/src/mediawiki.ui/components/inputs.less
resources/src/mediawiki/mediawiki.js
resources/src/mediawiki/mediawiki.util.js
resources/src/startup.js
skins/common/images/ar/button_bold.png [deleted file]
skins/common/images/ar/button_headline.png [deleted file]
skins/common/images/ar/button_italic.png [deleted file]
skins/common/images/ar/button_link.png [deleted file]
skins/common/images/ar/button_nowiki.png [deleted file]
skins/common/images/be-tarask/button_bold.png [deleted file]
skins/common/images/be-tarask/button_italic.png [deleted file]
skins/common/images/be-tarask/button_link.png [deleted file]
skins/common/images/button_bold.png [deleted file]
skins/common/images/button_extlink.png [deleted file]
skins/common/images/button_headline.png [deleted file]
skins/common/images/button_hr.png [deleted file]
skins/common/images/button_image.png [deleted file]
skins/common/images/button_italic.png [deleted file]
skins/common/images/button_link.png [deleted file]
skins/common/images/button_media.png [deleted file]
skins/common/images/button_nowiki.png [deleted file]
skins/common/images/button_sig.png [deleted file]
skins/common/images/cc-0.png [deleted file]
skins/common/images/cc-by-nc-sa.png [deleted file]
skins/common/images/cc-by-sa.png [deleted file]
skins/common/images/cc-by.png [deleted file]
skins/common/images/cyrl/LICENSE [deleted file]
skins/common/images/cyrl/button_bold.png [deleted file]
skins/common/images/cyrl/button_italic.png [deleted file]
skins/common/images/cyrl/button_link.png [deleted file]
skins/common/images/de/button_bold.png [deleted file]
skins/common/images/de/button_italic.png [deleted file]
skins/common/images/fa/button_bold.png [deleted file]
skins/common/images/fa/button_headline.png [deleted file]
skins/common/images/fa/button_italic.png [deleted file]
skins/common/images/fa/button_link.png [deleted file]
skins/common/images/fa/button_nowiki.png [deleted file]
skins/common/images/gnu-fdl.png [deleted file]
skins/common/images/ksh/LICENSE [deleted file]
skins/common/images/ksh/button_S_italic.png [deleted file]
skins/common/images/poweredby_mediawiki_88x31.png [deleted file]
skins/common/images/public-domain.png [deleted file]
tests/phpunit/LessFileCompilationTest.php
tests/phpunit/MediaWikiTestCase.php
tests/phpunit/ResourceLoaderTestCase.php
tests/phpunit/includes/EditPageTest.php
tests/phpunit/includes/LinkerTest.php
tests/phpunit/includes/MWTimestampTest.php
tests/phpunit/includes/MessageTest.php
tests/phpunit/includes/OutputPageTest.php
tests/phpunit/includes/SampleTest.php
tests/phpunit/includes/TitleArrayFromResultTest.php
tests/phpunit/includes/TitleTest.php
tests/phpunit/includes/UserArrayFromResultTest.php
tests/phpunit/includes/UserMailerTest.php [deleted file]
tests/phpunit/includes/UserTest.php
tests/phpunit/includes/XmlJsTest.php
tests/phpunit/includes/actions/ActionTest.php
tests/phpunit/includes/changes/OldChangesListTest.php
tests/phpunit/includes/changes/TestRecentChangesHelper.php
tests/phpunit/includes/config/GlobalVarConfigTest.php
tests/phpunit/includes/config/HashConfigTest.php [new file with mode: 0644]
tests/phpunit/includes/config/MultiConfigTest.php [new file with mode: 0644]
tests/phpunit/includes/content/JSONContentTest.php [deleted file]
tests/phpunit/includes/content/JsonContentTest.php [new file with mode: 0644]
tests/phpunit/includes/content/WikitextContentTest.php
tests/phpunit/includes/exception/MWExceptionTest.php
tests/phpunit/includes/libs/IPSetTest.php
tests/phpunit/includes/libs/MWMessagePackTest.php
tests/phpunit/includes/mail/MailAddressTest.php [new file with mode: 0644]
tests/phpunit/includes/mail/UserMailerTest.php [new file with mode: 0644]
tests/phpunit/includes/media/ExifRotationTest.php
tests/phpunit/includes/media/GIFTest.php
tests/phpunit/includes/media/PNGTest.php
tests/phpunit/includes/media/SVGTest.php
tests/phpunit/includes/normal/CleanUpTest.php
tests/phpunit/includes/objectcache/BagOStuffTest.php
tests/phpunit/includes/parser/MediaWikiParserTest.php
tests/phpunit/includes/parser/ParserMethodsTest.php
tests/phpunit/includes/parser/TidyTest.php
tests/phpunit/includes/password/BcryptPasswordTest.php
tests/phpunit/includes/password/LayeredParameterizedPasswordTest.php
tests/phpunit/includes/password/PasswordTestCase.php
tests/phpunit/includes/password/Pbkdf2PasswordTest.php
tests/phpunit/includes/resourceloader/ResourceLoaderLESSTest.php [deleted file]
tests/phpunit/includes/resourceloader/ResourceLoaderWikiModuleTest.php
tests/phpunit/includes/resourceloader/fixtures/001-embeddable.css [deleted file]
tests/phpunit/includes/resourceloader/fixtures/001-embeddable.less [deleted file]
tests/phpunit/includes/specialpage/SpecialPageFactoryTest.php [new file with mode: 0644]
tests/phpunit/includes/specials/ImageListPagerTest.php
tests/phpunit/includes/specials/SpecialMIMESearchTest.php
tests/phpunit/includes/specials/SpecialMyLanguageTest.php
tests/phpunit/includes/title/MediaWikiPageLinkRendererTest.php
tests/phpunit/includes/title/MediaWikiTitleCodecTest.php
tests/phpunit/includes/upload/UploadStashTest.php
tests/qunit/suites/resources/startup.test.js

index 01ca4c1..8c584d0 100644 (file)
@@ -47,6 +47,8 @@ production.
 * $wgCompiledFiles has been removed.
 * $wgSortSpecialPages was removed, the listing on Special:SpecialPages is
   now always sorted.
+* $wgSpecialPages may now use callback functions as an alternative to plain class names.
+  This allows more control over constructor parameters.
 * $wgHTCPMulticastAddress, $wgHTCPMulticastRouting and $wgHTCPPort were removed.
 * $wgRC2UDPAddress, $wgRC2UDPInterwikiPrefix, $wgRC2UDPOmitBots, $wgRC2UDPPort
   and $wgRC2UDPPrefix have been removed.
@@ -68,6 +70,7 @@ production.
 * $wgCanonicalLanguageLinks has been removed. Per Google recommendations, we
   will not send a rel=canonical pointing to a variant-neutral page, however
   we will send rel=alternate.
+* $wgResourceLoaderLESSFunctions has been deprecated and will be removed in the future.
 
 === New features in 1.24 ===
 * Added new hook WatchlistEditorBeforeFormRender, allowing subscribers to
@@ -174,7 +177,7 @@ production.
 * (bug 15484) Users will now be redirected to the login page when they need to
   log in, rather than being shown a page asking them to log in and having to click
   another link to actually get to the login page.
-* A JSONContent and JSONContentHandler were added for extensions to extend.
+* A JsonContent and JsonContentHandler were added for extensions to extend.
 * (bug 35045) Redirects to sections will now update the URL in browser's address
   bar using the HTML5 History API. When [[Dog]] redirects to [[Animals#Dog]],
   the user will now see "Animals#Dog" in their browser instead of "Dog#Dog".
@@ -183,6 +186,12 @@ production.
 * Added HTMLAutoCompleteSelectField.
 * Added a new hook, "SkinPreloadExistence", to allow extensions to add titles to
   link existence cache before the page is rendered.
+* Config::set() was moved to its own interface, MutableConfig. GlobalVarConfig::set()
+  is now deprecated, does not implement MutableConfig.
+* A MutableConfig named HashConfig was added, that stores an array of configuration
+  settings.
+* (bug 69418) A MultiConfig implementation was added that supports fallback
+  to multiple Config instances.
 
 === Bug fixes in 1.24 ===
 * (bug 50572) MediaWiki:Blockip should support gender
@@ -216,6 +225,10 @@ production.
 * (bug 69789) Title::getContentModel() now loads from the database when
   necessary instead of incorrectly returning the default content model.
 * (bug 69249) wfBaseConvert() now works around PHP Bug #50175 when using GMP.
+* (bug 57909) URLs in the externallinks table will no longer have certain
+  characters decoded in the query string.
+* (bug 67368) LESS mixins like .background-image() correctly flip image
+  references for RTL stylesheets now.
 
 === Action API changes in 1.24 ===
 * action=parse API now supports prop=modules, which provides the list of
@@ -254,6 +267,15 @@ production.
   parameter for each module is documented in the action=help output and is
   returned from action=paraminfo.
 * New action ClearHasMsg that can be used to clear HasMsg flag.
+* The cmstartsortkey and cmendsortkey parameters to list=categorymembers are
+  deprecated in favor of cmstarthexsortkey and cmendhexsortkey.
+* (bug 63326) Add blockedtimestamp field to output of blockinfo property for
+  the list=allusers and list=users modules.
+* prop=imageinfo no longer requires iiurlwidth to be set when using iiurlparam.
+* Added prop=linkshere, prop=fileusage, and prop=transcludedin, which are
+  roughly equivalent to list=backlinks, list=imageusage, and list=embeddedin
+  but can work on a list of titles (including titles from a generator).
+* prop=redirects can now filter returned redirects by namespace.
 
 === Action API internal changes in 1.24 ===
 * Methods for handling continuation are added to ApiResult, so actions other
@@ -283,6 +305,8 @@ production.
     ApiTokensGetTokenTypes are deprecated, but are still called to support
     backwards-compatible token access.
 * ApiBase::validateLimit and ApiBase::validateTimestamp are now protected.
+* ApiQueryRedirects was removed; prop=redirects is now implemented by
+  ApiQueryBacklinksProp along with the newly-added prop modules.
 * The following methods have been deprecated and may be removed in a future
   release:
   * ApiBase::getResultProperties
@@ -430,10 +454,12 @@ changes to languages because of Bugzilla reports.
   setPreloadedText() from EditPage.php. (deprecated since 1.21)
 * Removed global functions wfArrayLookup(), wfArrayMerge(), wfDebugDieBacktrace()
   and wfTime(). (deprecated since 1.22)
-* Browser support for Internet Explorer 6 lowered from Grade A to Grade C,
-  meaning that JavaScript is no longer executed in this browser.
+* Browser support for Internet Explorer 6 and 7 lowered from Grade A to Grade C,
+  meaning that JavaScript is no longer executed in these browser versions.
 * Browser support for Opera 11 lowered from Grade A to Grade C.
 * Removed IEFixes module which existed purely to provide support for MSIE versions
+* Deprecated SpecialPageFactory::getList() in favor of
+  SpecialPageFactory::getNames()
   below 7 (conditionally loaded only for those browsers).
 * Action::checkCanExecute() no longer has a return value.
 * Removed cleanupForIRC(), loadFromCurRow(), newFromCurRow(), notifyRC2UDP()
@@ -459,6 +485,13 @@ changes to languages because of Bugzilla reports.
 * Some extensions had their ResourceLoader modules depend on the "mediawiki"
   and "jquery" modules. In the past, this behavior was undefined, now it will
   throw an error.
+* Removed BagOStuff::replace(). (deprecated since 1.23)
+* In Linker.php, link(), linkText() and makeBrokenImageLinkObj() now display
+  warnings if their first parameter is not a Title object. Also makeImageLink()
+  now requires a Parser as its first parameter.
+* (bug 67368) LESS functions embed() and embeddable(), added in MediaWiki 1.23
+  and broken by design, have been removed. Use appropriate LESS mixins instead.
+* Removed cssjanus.py from maintenance directory as it was unused.
 
 ==== Renamed classes ====
 * CLDRPluralRuleConverter_Expression to CLDRPluralRuleConverterExpression
@@ -507,10 +540,12 @@ changes to languages because of Bugzilla reports.
 * RawPage - Use RawAction directly
 * StubContLang - Use Language::factory() instead
 * XMLReader2 - Use XMLReader directly
+* ResourceLoaderLESSFunctions - No longer in use, not intended for public usage
 
 == Compatibility ==
 
-MediaWiki 1.24 requires PHP 5.3.2 or later.
+MediaWiki 1.24 requires PHP 5.3.2 or later. There is experimental support for
+HHVM 3.3.0.
 
 MySQL is the recommended DBMS. PostgreSQL or SQLite can also be used, but
 support for them is somewhat less mature. There is experimental support for
diff --git a/RELEASE-NOTES-1.25 b/RELEASE-NOTES-1.25
new file mode 100644 (file)
index 0000000..c935ffe
--- /dev/null
@@ -0,0 +1,95 @@
+Security reminder: If you have PHP's register_globals option set, you must
+turn it off. MediaWiki will not work with it enabled.
+
+== MediaWiki 1.25 ==
+
+THIS IS NOT A RELEASE YET
+
+MediaWiki 1.25 is an alpha-quality branch and is not recommended for use in
+production.
+
+=== Configuration changes in 1.25 ===
+
+=== New features in 1.25 ===
+
+=== Bug fixes in 1.25 ===
+
+=== Web API changes in 1.25 ===
+
+=== Languages updated in 1.25 ===
+
+MediaWiki supports over 350 languages. Many localisations are updated
+regularly. Below only new and removed languages are listed, as well as
+changes to languages because of Bugzilla reports.
+
+=== Other changes in 1.25 ===
+* The skin autodiscovery mechanism, deprecated in MediaWiki 1.23, has been
+  removed. See https://www.mediawiki.org/wiki/Manual:Skin_autodiscovery for
+  migration guide for creators and users of custom skins that relied on it. 
+* Javascript variable 'wgFileCanRotate' now only available on Special:Upload.
+
+== Compatibility ==
+
+MediaWiki 1.25 requires PHP 5.3.2 or later. There is experimental support for
+HHVM 3.3.0.
+
+MySQL is the recommended DBMS. PostgreSQL or SQLite can also be used, but
+support for them is somewhat less mature. There is experimental support for
+Oracle and Microsoft SQL Server.
+
+The supported versions are:
+
+* MySQL 5.0.2 or later
+* PostgreSQL 8.3 or later
+* SQLite 3.3.7 or later
+* Oracle 9.0.1 or later
+* Microsoft SQL Server 2005 (9.00.1399)
+
+== Upgrading ==
+
+1.25 has several database changes since 1.24, and will not work without schema
+updates. Note that due to changes to some very large tables like the revision
+table, the schema update may take quite long (minutes on a medium sized site,
+many hours on a large site).
+
+If upgrading from before 1.11, and you are using a wiki as a commons
+repository, make sure that it is updated as well. Otherwise, errors may arise
+due to database schema changes.
+
+If upgrading from before 1.7, you may want to run refreshLinks.php to ensure
+new database fields are filled with data.
+
+If you are upgrading from MediaWiki 1.4.x or earlier, you should upgrade to
+1.5 first. The upgrade script maintenance/upgrade1_5.php has been removed
+with MediaWiki 1.21.
+
+Don't forget to always back up your database before upgrading!
+
+See the file UPGRADE for more detailed upgrade instructions.
+
+For notes on 1.23.x and older releases, see HISTORY.
+
+== Online documentation ==
+
+Documentation for both end-users and site administrators is available on
+MediaWiki.org, and is covered under the GNU Free Documentation License (except
+for pages that explicitly state that their contents are in the public domain):
+
+       https://www.mediawiki.org/wiki/Documentation
+
+== Mailing list ==
+
+A mailing list is available for MediaWiki user support and discussion:
+
+       https://lists.wikimedia.org/mailman/listinfo/mediawiki-l
+
+A low-traffic announcements-only list is also available:
+
+       https://lists.wikimedia.org/mailman/listinfo/mediawiki-announce
+
+It's highly recommended that you sign up for one of these lists if you're
+going to run a public MediaWiki, so you can be notified of security fixes.
+
+== IRC help ==
+
+There's usually someone online in #mediawiki on irc.freenode.net.
diff --git a/assets/file-type-icons/COPYING b/assets/file-type-icons/COPYING
deleted file mode 100644 (file)
index 136530a..0000000
+++ /dev/null
@@ -1,43 +0,0 @@
-The icons used here are derived from the crystalsvg icons in the the
-pics/crystalsvg/ directory of kdelibs-3.4.0 they were modified on 2005-05-15
-by Ævar Arnfjörð Bjarmason for use in MediaWiki.
-
-What follows is the contents of the LICENSE.crystalsvg file found in the pics/
-subdirectory of kdelibs-3.4.0:
-
-++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-This copyright and license notice covers all CrystalSVG images.
-Note the license notice contains an add-on.
-********************************************************************************
-KDE Crystal theme icons.
-Copyright (C) 2002 and following years KDE Artists
-This library is free software; you can redistribute it and/or
-modify it under the terms of the GNU Lesser General Public
-License as published by the Free Software Foundation,
-version 2.1 of the License.
-This library 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
-Lesser General Public License for more details.
-You should have received a copy of the GNU Lesser General Public
-License along with this library; if not, write to the Free Software
-Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
-    **** NOTE THIS ADD-ON ****
-The GNU Lesser General Public License or LGPL is written for software libraries
-in the first place. We expressly want the LGPL to be valid for this artwork
-library too.
-KDE Crystal theme icons is a special kind of software library, it is an
-artwork library, it's elements can be used in a Graphical User Interface, or
-GUI.
-Source code, for this library means:
- - for vectors svg;
- - for pixels, if applicable, the multi-layered formats xcf or psd, or
-otherwise png.
-The LGPL in some sections obliges you to make the files carry
-notices. With images this is in some cases impossible or hardly useful.
-With this library a notice is placed at a prominent place in the directory
-containing the elements. You may follow this practice.
-The exception in section 6 of the GNU Lesser General Public License covers
-the use of elements of this art library in a GUI.
-kde-artists [at] kde.org
-++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
diff --git a/assets/file-type-icons/fileicon-c.png b/assets/file-type-icons/fileicon-c.png
deleted file mode 100644 (file)
index 0d603b7..0000000
Binary files a/assets/file-type-icons/fileicon-c.png and /dev/null differ
diff --git a/assets/file-type-icons/fileicon-cpp.png b/assets/file-type-icons/fileicon-cpp.png
deleted file mode 100644 (file)
index 123688f..0000000
Binary files a/assets/file-type-icons/fileicon-cpp.png and /dev/null differ
diff --git a/assets/file-type-icons/fileicon-deb.png b/assets/file-type-icons/fileicon-deb.png
deleted file mode 100644 (file)
index 87ca3fa..0000000
Binary files a/assets/file-type-icons/fileicon-deb.png and /dev/null differ
diff --git a/assets/file-type-icons/fileicon-djvu.png b/assets/file-type-icons/fileicon-djvu.png
deleted file mode 100644 (file)
index 1da2276..0000000
Binary files a/assets/file-type-icons/fileicon-djvu.png and /dev/null differ
diff --git a/assets/file-type-icons/fileicon-djvu.xcf b/assets/file-type-icons/fileicon-djvu.xcf
deleted file mode 100644 (file)
index 8043dcd..0000000
Binary files a/assets/file-type-icons/fileicon-djvu.xcf and /dev/null differ
diff --git a/assets/file-type-icons/fileicon-dvi.png b/assets/file-type-icons/fileicon-dvi.png
deleted file mode 100644 (file)
index f37878d..0000000
Binary files a/assets/file-type-icons/fileicon-dvi.png and /dev/null differ
diff --git a/assets/file-type-icons/fileicon-exe.png b/assets/file-type-icons/fileicon-exe.png
deleted file mode 100644 (file)
index dc020eb..0000000
Binary files a/assets/file-type-icons/fileicon-exe.png and /dev/null differ
diff --git a/assets/file-type-icons/fileicon-h.png b/assets/file-type-icons/fileicon-h.png
deleted file mode 100644 (file)
index 339bf02..0000000
Binary files a/assets/file-type-icons/fileicon-h.png and /dev/null differ
diff --git a/assets/file-type-icons/fileicon-html.png b/assets/file-type-icons/fileicon-html.png
deleted file mode 100644 (file)
index f28f8a2..0000000
Binary files a/assets/file-type-icons/fileicon-html.png and /dev/null differ
diff --git a/assets/file-type-icons/fileicon-iso.png b/assets/file-type-icons/fileicon-iso.png
deleted file mode 100644 (file)
index c73d229..0000000
Binary files a/assets/file-type-icons/fileicon-iso.png and /dev/null differ
diff --git a/assets/file-type-icons/fileicon-java.png b/assets/file-type-icons/fileicon-java.png
deleted file mode 100644 (file)
index a1b4f22..0000000
Binary files a/assets/file-type-icons/fileicon-java.png and /dev/null differ
diff --git a/assets/file-type-icons/fileicon-mid.png b/assets/file-type-icons/fileicon-mid.png
deleted file mode 100644 (file)
index ce2bebb..0000000
Binary files a/assets/file-type-icons/fileicon-mid.png and /dev/null differ
diff --git a/assets/file-type-icons/fileicon-mov.png b/assets/file-type-icons/fileicon-mov.png
deleted file mode 100644 (file)
index 952de1f..0000000
Binary files a/assets/file-type-icons/fileicon-mov.png and /dev/null differ
diff --git a/assets/file-type-icons/fileicon-o.png b/assets/file-type-icons/fileicon-o.png
deleted file mode 100644 (file)
index f3523d9..0000000
Binary files a/assets/file-type-icons/fileicon-o.png and /dev/null differ
diff --git a/assets/file-type-icons/fileicon-ogg.png b/assets/file-type-icons/fileicon-ogg.png
deleted file mode 100644 (file)
index ef4d801..0000000
Binary files a/assets/file-type-icons/fileicon-ogg.png and /dev/null differ
diff --git a/assets/file-type-icons/fileicon-ogg.xcf b/assets/file-type-icons/fileicon-ogg.xcf
deleted file mode 100644 (file)
index a91024b..0000000
Binary files a/assets/file-type-icons/fileicon-ogg.xcf and /dev/null differ
diff --git a/assets/file-type-icons/fileicon-pdf.png b/assets/file-type-icons/fileicon-pdf.png
deleted file mode 100644 (file)
index 8c8da92..0000000
Binary files a/assets/file-type-icons/fileicon-pdf.png and /dev/null differ
diff --git a/assets/file-type-icons/fileicon-ps.png b/assets/file-type-icons/fileicon-ps.png
deleted file mode 100644 (file)
index e872833..0000000
Binary files a/assets/file-type-icons/fileicon-ps.png and /dev/null differ
diff --git a/assets/file-type-icons/fileicon-psd.png b/assets/file-type-icons/fileicon-psd.png
deleted file mode 100644 (file)
index 598f190..0000000
Binary files a/assets/file-type-icons/fileicon-psd.png and /dev/null differ
diff --git a/assets/file-type-icons/fileicon-rm.png b/assets/file-type-icons/fileicon-rm.png
deleted file mode 100644 (file)
index 81dbe0b..0000000
Binary files a/assets/file-type-icons/fileicon-rm.png and /dev/null differ
diff --git a/assets/file-type-icons/fileicon-rpm.png b/assets/file-type-icons/fileicon-rpm.png
deleted file mode 100644 (file)
index 1903aac..0000000
Binary files a/assets/file-type-icons/fileicon-rpm.png and /dev/null differ
diff --git a/assets/file-type-icons/fileicon-svg.png b/assets/file-type-icons/fileicon-svg.png
deleted file mode 100644 (file)
index b782113..0000000
Binary files a/assets/file-type-icons/fileicon-svg.png and /dev/null differ
diff --git a/assets/file-type-icons/fileicon-tar.png b/assets/file-type-icons/fileicon-tar.png
deleted file mode 100644 (file)
index e5fd1b7..0000000
Binary files a/assets/file-type-icons/fileicon-tar.png and /dev/null differ
diff --git a/assets/file-type-icons/fileicon-tex.png b/assets/file-type-icons/fileicon-tex.png
deleted file mode 100644 (file)
index a437284..0000000
Binary files a/assets/file-type-icons/fileicon-tex.png and /dev/null differ
diff --git a/assets/file-type-icons/fileicon-ttf.png b/assets/file-type-icons/fileicon-ttf.png
deleted file mode 100644 (file)
index 1ed4e74..0000000
Binary files a/assets/file-type-icons/fileicon-ttf.png and /dev/null differ
diff --git a/assets/file-type-icons/fileicon-txt.png b/assets/file-type-icons/fileicon-txt.png
deleted file mode 100644 (file)
index 9e988e7..0000000
Binary files a/assets/file-type-icons/fileicon-txt.png and /dev/null differ
diff --git a/assets/file-type-icons/fileicon-xcf.png b/assets/file-type-icons/fileicon-xcf.png
deleted file mode 100644 (file)
index 1037b50..0000000
Binary files a/assets/file-type-icons/fileicon-xcf.png and /dev/null differ
diff --git a/assets/file-type-icons/fileicon.png b/assets/file-type-icons/fileicon.png
deleted file mode 100644 (file)
index 59696a3..0000000
Binary files a/assets/file-type-icons/fileicon.png and /dev/null differ
diff --git a/assets/mediawiki.png b/assets/mediawiki.png
deleted file mode 100644 (file)
index 8c42118..0000000
Binary files a/assets/mediawiki.png and /dev/null differ
index 9ac2271..51da2d4 100644 (file)
@@ -1376,6 +1376,10 @@ page history view, i.e. undo, rollback, etc.
 $rev: Revision object
 &$links: Array of HTML links
 
+'HTMLFileCache::useFileCache': Override whether a page should be cached in file
+cache.
+$context: An IContextSource object with information about the request being served.
+
 'ImageBeforeProduceHTML': Called before producing the HTML created by a wiki
 image insertion. You can skip the default logic entirely by returning false, or
 just modify a few things using call-by-reference.
@@ -1550,6 +1554,10 @@ $title: The page's Title.
   Currently unused, but planned to provide support for marking individual
   language links in the UI, e.g. for featured articles.
 
+'LanguageSelector': Hook to change the language selector available on a page.
+$out: The output page.
+$cssClassName: CSS class name of the language selector.
+
 'LinkBegin': Used when generating internal and interwiki links in
 Linker::link(), before processing starts.  Return false to skip default
 processing and return $ret. See documentation for Linker::link() for details on
@@ -2590,6 +2598,10 @@ database result.
 &$titleArray: set this to an object to override the default object returned
 $res: database result used to create the object
 
+'TitleExists': Called when determining whether a page exists at a given title.
+$title: The title being tested.
+&$exists: Whether the title exists.
+
 'TitleQuickPermissions': Called from Title::checkQuickPermissions to add to
 or override the quick permissions check.
 $title: The Title object being accessed
index ff735d5..a7b0c47 100644 (file)
@@ -4,7 +4,9 @@ kss: kssnodecheck
 # Generates CSS of mediawiki.ui and mediawiki.ui.button using ResourceLoader, then applies it to the
 # KSS style guide
        $(eval KSS_RL_TMP := $(shell mktemp /tmp/tmp.XXXXXXXXXX))
-       @curl -sG "${MEDIAWIKI_LOAD_URL}?modules=mediawiki.ui.anchor|mediawiki.ui.checkbox|mediawiki.ui.input|mediawiki.legacy.shared|mediawiki.legacy.commonPrint|mediawiki.ui|mediawiki.ui.button&only=styles" > $(KSS_RL_TMP)
+# Keep module names in strict alphabetical order, so CSS loads in the same order as ResourceLoader's addModuleStyles does; this can affect rendering.
+# See OutputPage::makeResourceLoaderLink.
+       @curl -sG "${MEDIAWIKI_LOAD_URL}?modules=mediawiki.legacy.commonPrint|mediawiki.legacy.shared|mediawiki.ui|mediawiki.ui.anchor|mediawiki.ui.button|mediawiki.ui.checkbox|mediawiki.ui.input&only=styles" > $(KSS_RL_TMP)
        @node_modules/.bin/kss-node ../../resources/src/mediawiki.ui static/ --css $(KSS_RL_TMP) -t styleguide-template
        @rm $(KSS_RL_TMP)
 
index 38f0dd1..933260e 100644 (file)
                        <ul>
                                <li><a href="index.html"><span>0.0</span> Overview</a></li>
                                {{#eachRoot}}
-                                       <li><a href="section-{{reference}}.html"><span>{{reference}}.0</span> {{header}}</a></li>
+                                       <li>
+                                               <a href="section-{{ reference }}.html">
+                                                       <span>{{ reference }}.0</span> {{ header }}
+                                               </a>
+                                               <ul>
+                                               {{#eachSection reference}}
+                                                       {{#whenDepth  2}}
+                                                               <li>
+                                                                       <a href="section-{{../../reference}}.html#section-{{ reference }}">
+                                                                               <span>{{ reference }}</span>
+                                                                               {{ header }}
+                                                                       </a>
+                                                               </li>
+                                                       {{/whenDepth}}
+                                               {{/eachSection}}
+                                               </ul>
+                                       </li>
                                {{/eachRoot}}
                        </ul>
                </nav>
@@ -38,6 +54,7 @@
                                                <h1>{{ reference }}.0 {{ header }}</h1>
                                        {{else}}
                                                {{#whenDepth 2}}
+                                               <a name="section-{{ reference }}"></a>
                                                <h2>{{ reference }} {{ header }}</h2>
                                                {{/whenDepth}}
                                                {{#whenDepth 3}}
index a1d62a3..eeea1a8 100644 (file)
@@ -85,6 +85,17 @@ nav {
                                        width: 35px;
                                }
                        }
+
+                       ul {
+                               li {
+                                       margin: 0;
+                               }
+
+                               li a {
+                                       text-transform: none;
+                                       font-weight: normal;
+                               }
+                       }
                }
        }
 }
@@ -130,6 +141,10 @@ nav {
                        display: block;
                        margin: 0;
                        margin-left: 20px;
+
+                       div {
+                               margin-bottom: 5px;
+                       }
                }
        }
 }
index 58f77cf..e998ebd 100644 (file)
@@ -53,40 +53,30 @@ server-side source files. This is done by editing some pages on the wiki:
 These can also be customised on a per-user basis, by editing
 [[User:<name>/vector.css]], [[User:<name>/vector.js]], etc.
 
-This feature has led to a wide variety of "user styles" becoming available:
 
-https://www.mediawiki.org/wiki/Manual:Gallery_of_user_styles
+== Custom skins ==
 
-If you want a different look for your wiki, that gallery is a good place to start.
+Several custom skins are available as of 2014.
 
-== Drop-in custom skins ==
+https://www.mediawiki.org/wiki/Category:All_skins
 
-If you put a file in MediaWiki's skins directory, ending in .php, the name of 
-the file will automatically be added as a skin name, and the file will be
-expected to contain a class called Skin<name> with the skin class. You can then
-make that skin the default by adding to LocalSettings.php:
+Installing a skin requires adding its files in a subdirectory under skins/ and
+adding an appropriate require_once line to LocalSettings.php, similarly to how
+extensions are installed.
 
-$wgDefaultSkin = '<name>';
+You can then make that skin the default by adding:
+  $wgDefaultSkin = '<name>';
 
-You can also disable dropped-in or core skins using:
+Or disable it entirely by removing the require_once line. (User settings will
+not be lost if it's reenabled later.)
 
-$wgSkipSkins[] = '<name>';
+See https://www.mediawiki.org/wiki/Manual:Skinning for more information on
+writing new skins.
 
-This technique is used by the more ambitious MediaWiki site operators, to 
-create complex custom skins for their wikis. It should be preferred over 
-editing the core Monobook skin directly.
-
-See https://www.mediawiki.org/wiki/Manual:Skinning for more information.
-
-== Extension skins ==
-
-It is now possible (since MediaWiki 1.12) to write a skin as a standard
-MediaWiki extension, enabled via LocalSettings.php. This is done by adding 
-it to $wgValidSkinNames, for example:
-
-$wgValidSkinNames['mycoolskin'] = 'MyCoolSkin';
-
-and then registering a class in $wgAutoloadClasses called SkinMycoolSkin, which 
-derives from Skin. This technique is apparently not yet used (as of 2008) 
-outside the DumpHTML extension.
 
+Until MediaWiki 1.25 it used to be possible to just put a <name>.php file in
+MediaWiki's skins/ directory, which would be loaded and expected to contain the
+Skin<name> class. This way has always been discouraged because of its limitations
+(inability to add localisation messages, ResourceLoader modules, etc.) and
+awkwardness in managing such skins. For information on migrating skins using
+this old method, see <https://www.mediawiki.org/wiki/Manual:Skin_autodiscovery>.
index 87cd5d5..6b0daa1 100644 (file)
@@ -68,7 +68,6 @@ $wgAutoloadLocalClasses = array(
        'DumpOutput' => 'includes/Export.php',
        'DumpPipeOutput' => 'includes/Export.php',
        'EditPage' => 'includes/EditPage.php',
-       'EmailNotification' => 'includes/UserMailer.php',
        'EmptyBloomCache' => 'includes/cache/bloom/BloomCache.php',
        'Fallback' => 'includes/Fallback.php',
        'FauxRequest' => 'includes/WebRequest.php',
@@ -122,12 +121,12 @@ $wgAutoloadLocalClasses = array(
        'LinkFilter' => 'includes/LinkFilter.php',
        'MagicWord' => 'includes/MagicWord.php',
        'MagicWordArray' => 'includes/MagicWord.php',
-       'MailAddress' => 'includes/UserMailer.php',
        'MediaWiki' => 'includes/MediaWiki.php',
        'MediaWikiVersionFetcher' => 'includes/MediaWikiVersionFetcher.php',
        'Message' => 'includes/Message.php',
        'MessageBlobStore' => 'includes/MessageBlobStore.php',
        'MimeMagic' => 'includes/MimeMagic.php',
+       'MovePage' => 'includes/MovePage.php',
        'MWHookException' => 'includes/Hooks.php',
        'MWHttpRequest' => 'includes/HttpFunctions.php',
        'MWNamespace' => 'includes/MWNamespace.php',
@@ -175,7 +174,6 @@ $wgAutoloadLocalClasses = array(
        'User' => 'includes/User.php',
        'UserArray' => 'includes/UserArray.php',
        'UserArrayFromResult' => 'includes/UserArrayFromResult.php',
-       'UserMailer' => 'includes/UserMailer.php',
        'UserRightsProxy' => 'includes/UserRightsProxy.php',
        'WatchedItem' => 'includes/WatchedItem.php',
        'WebRequest' => 'includes/WebRequest.php',
@@ -269,6 +267,7 @@ $wgAutoloadLocalClasses = array(
        'ApiQueryAllPages' => 'includes/api/ApiQueryAllPages.php',
        'ApiQueryAllUsers' => 'includes/api/ApiQueryAllUsers.php',
        'ApiQueryBacklinks' => 'includes/api/ApiQueryBacklinks.php',
+       'ApiQueryBacklinksprop' => 'includes/api/ApiQueryBacklinksprop.php',
        'ApiQueryBase' => 'includes/api/ApiQueryBase.php',
        'ApiQueryBlocks' => 'includes/api/ApiQueryBlocks.php',
        'ApiQueryCategories' => 'includes/api/ApiQueryCategories.php',
@@ -302,7 +301,6 @@ $wgAutoloadLocalClasses = array(
        'ApiQueryRandom' => 'includes/api/ApiQueryRandom.php',
        'ApiQueryRecentChanges' => 'includes/api/ApiQueryRecentChanges.php',
        'ApiQueryFileRepoInfo' => 'includes/api/ApiQueryFileRepoInfo.php',
-       'ApiQueryRedirects' => 'includes/api/ApiQueryRedirects.php',
        'ApiQueryRevisions' => 'includes/api/ApiQueryRevisions.php',
        'ApiQuerySearch' => 'includes/api/ApiQuerySearch.php',
        'ApiQuerySiteinfo' => 'includes/api/ApiQuerySiteinfo.php',
@@ -374,23 +372,27 @@ $wgAutoloadLocalClasses = array(
        'ConfigException' => 'includes/config/ConfigException.php',
        'ConfigFactory' => 'includes/config/ConfigFactory.php',
        'GlobalVarConfig' => 'includes/config/GlobalVarConfig.php',
+       'HashConfig' => 'includes/config/HashConfig.php',
+       'MultiConfig' => 'includes/config/MultiConfig.php',
+       'MutableConfig' => 'includes/config/MutableConfig.php',
 
        # includes/content
        'AbstractContent' => 'includes/content/AbstractContent.php',
-       'ContentHandler' => 'includes/content/ContentHandler.php',
+       'CodeContentHandler' => 'includes/content/CodeContentHandler.php',
        'Content' => 'includes/content/Content.php',
-       'CssContentHandler' => 'includes/content/CssContentHandler.php',
+       'ContentHandler' => 'includes/content/ContentHandler.php',
        'CssContent' => 'includes/content/CssContent.php',
-       'JavaScriptContentHandler' => 'includes/content/JavaScriptContentHandler.php',
+       'CssContentHandler' => 'includes/content/CssContentHandler.php',
        'JavaScriptContent' => 'includes/content/JavaScriptContent.php',
-       'JSONContentHandler' => 'includes/content/JSONContentHandler.php',
-       'JSONContent' => 'includes/content/JSONContent.php',
+       'JavaScriptContentHandler' => 'includes/content/JavaScriptContentHandler.php',
+       'JsonContent' => 'includes/content/JsonContent.php',
+       'JsonContentHandler' => 'includes/content/JsonContentHandler.php',
        'MessageContent' => 'includes/content/MessageContent.php',
        'MWContentSerializationException' => 'includes/content/ContentHandler.php',
-       'TextContentHandler' => 'includes/content/TextContentHandler.php',
        'TextContent' => 'includes/content/TextContent.php',
-       'WikitextContentHandler' => 'includes/content/WikitextContentHandler.php',
+       'TextContentHandler' => 'includes/content/TextContentHandler.php',
        'WikitextContent' => 'includes/content/WikitextContent.php',
+       'WikitextContentHandler' => 'includes/content/WikitextContentHandler.php',
 
        # includes/context
        'ContextSource' => 'includes/context/ContextSource.php',
@@ -724,6 +726,11 @@ $wgAutoloadLocalClasses = array(
        'PackedHoverImageGallery' => 'includes/gallery/PackedOverlayImageGallery.php',
        'PackedOverlayImageGallery' => 'includes/gallery/PackedOverlayImageGallery.php',
 
+       # includes/mail
+       'EmailNotification' => 'includes/mail/EmailNotification.php',
+       'MailAddress' => 'includes/mail/MailAddress.php',
+       'UserMailer' => 'includes/mail/UserMailer.php',
+
        # includes/media
        'BitmapHandler' => 'includes/media/Bitmap.php',
        'BitmapHandler_ClientOnly' => 'includes/media/Bitmap_ClientOnly.php',
@@ -750,6 +757,7 @@ $wgAutoloadLocalClasses = array(
        'SVGReader' => 'includes/media/SVGMetadataExtractor.php',
        'ThumbnailImage' => 'includes/media/MediaTransformOutput.php',
        'TiffHandler' => 'includes/media/Tiff.php',
+       'TransformationalImageHandler' => 'includes/media/TransformationalImageHandler.php',
        'TransformParameterError' => 'includes/media/MediaTransformOutput.php',
        'XCFHandler' => 'includes/media/XCF.php',
        'XMPInfo' => 'includes/media/XMPInfo.php',
@@ -874,10 +882,10 @@ $wgAutoloadLocalClasses = array(
                'includes/resourceloader/DerivativeResourceLoaderContext.php',
        'ResourceLoader' => 'includes/resourceloader/ResourceLoader.php',
        'ResourceLoaderContext' => 'includes/resourceloader/ResourceLoaderContext.php',
+       'ResourceLoaderEditToolbarModule' => 'includes/resourceloader/ResourceLoaderEditToolbarModule.php',
        'ResourceLoaderFileModule' => 'includes/resourceloader/ResourceLoaderFileModule.php',
        'ResourceLoaderFilePageModule' => 'includes/resourceloader/ResourceLoaderFilePageModule.php',
        'ResourceLoaderFilePath' => 'includes/resourceloader/ResourceLoaderFilePath.php',
-       'ResourceLoaderLESSFunctions' => 'includes/resourceloader/ResourceLoaderLESSFunctions.php',
        'ResourceLoaderModule' => 'includes/resourceloader/ResourceLoaderModule.php',
        'ResourceLoaderNoscriptModule' => 'includes/resourceloader/ResourceLoaderNoscriptModule.php',
        'ResourceLoaderSiteModule' => 'includes/resourceloader/ResourceLoaderSiteModule.php',
@@ -988,6 +996,7 @@ $wgAutoloadLocalClasses = array(
        'LoginForm' => 'includes/specials/SpecialUserlogin.php',
        'LonelyPagesPage' => 'includes/specials/SpecialLonelypages.php',
        'LongPagesPage' => 'includes/specials/SpecialLongpages.php',
+       'MediaStatisticsPage' => 'includes/specials/SpecialMediaStatistics.php',
        'MergeHistoryPager' => 'includes/specials/SpecialMergeHistory.php',
        'MIMEsearchPage' => 'includes/specials/SpecialMIMEsearch.php',
        'MostcategoriesPage' => 'includes/specials/SpecialMostcategories.php',
index 60694c9..7581ae4 100644 (file)
@@ -25,10 +25,10 @@ class CategoryViewer extends ContextSource {
        public $limit;
 
        /** @var array */
-       protected $from;
+       public $from;
 
        /** @var array */
-       protected $until;
+       public $until;
 
        /** @var string[] */
        public $articles;
@@ -37,37 +37,37 @@ class CategoryViewer extends ContextSource {
        public $articles_start_char;
 
        /** @var array */
-       protected $children;
+       public $children;
 
        /** @var array */
-       protected $children_start_char;
+       public $children_start_char;
 
        /** @var bool */
-       protected $showGallery;
+       public $showGallery;
 
        /** @var array */
-       protected $imgsNoGallery_start_char;
+       public $imgsNoGallery_start_char;
 
        /** @var array */
-       protected $imgsNoGallery;
+       public $imgsNoGallery;
 
        /** @var array */
-       protected $nextPage;
+       public $nextPage;
 
        /** @var array */
        protected $prevPage;
 
        /** @var array */
-       protected $flip;
+       public $flip;
 
        /** @var Title */
-       protected $title;
+       public $title;
 
        /** @var Collation */
-       protected $collation;
+       public $collation;
 
        /** @var ImageGallery */
-       protected $gallery;
+       public $gallery;
 
        /** @var Category Category object for this page. */
        private $cat;
index 6626ab6..9e57670 100644 (file)
@@ -73,7 +73,7 @@ $wgConfigRegistry = array(
  * MediaWiki version number
  * @since 1.2
  */
-$wgVersion = '1.24alpha';
+$wgVersion = '1.25alpha';
 
 /**
  * Name of the site. It must be changed in LocalSettings.php
@@ -859,7 +859,7 @@ $wgContentHandlers = array(
        // dumb version, no syntax highlighting
        CONTENT_MODEL_JAVASCRIPT => 'JavaScriptContentHandler',
        // simple implementation, for use by extensions, etc.
-       CONTENT_MODEL_JSON => 'JSONContentHandler',
+       CONTENT_MODEL_JSON => 'JsonContentHandler',
        // dumb version, no syntax highlighting
        CONTENT_MODEL_CSS => 'CssContentHandler',
        // plain text, for use by extensions, etc.
@@ -3102,7 +3102,7 @@ $wgFooterIcons = array(
        ),
        "poweredby" => array(
                "mediawiki" => array(
-                       "src" => null, // Defaults to "$wgStylePath/common/images/poweredby_mediawiki_88x31.png"
+                       "src" => null, // Defaults to "$wgResourceBasePath/resources/assets/poweredby_mediawiki_88x31.png"
                        "url" => "//www.mediawiki.org/",
                        "alt" => "Powered by MediaWiki",
                )
@@ -3488,11 +3488,10 @@ $wgResourceLoaderLESSVars = array();
  * Changes to LESS functions do not trigger cache invalidation.
  *
  * @since 1.22
+ * @deprecated since 1.24 Questionable usefulness and problematic to support,
+ *     will be removed in the future.
  */
-$wgResourceLoaderLESSFunctions = array(
-       'embeddable' => 'ResourceLoaderLESSFunctions::embeddable',
-       'embed' => 'ResourceLoaderLESSFunctions::embed',
-);
+$wgResourceLoaderLESSFunctions = array();
 
 /**
  * Default import paths for LESS modules. LESS files referenced in @import
@@ -6189,8 +6188,10 @@ $wgEnableParserLimitReporting = true;
 $wgValidSkinNames = array();
 
 /**
- * Special page list.
- * See the top of SpecialPage.php for documentation.
+ * Special page list. This is an associative array mapping the (canonical) names of
+ * special pages to either a class name to be instantiated, or a callback to use for
+ * creating the special page object. In both cases, the result must be an instance of
+ * SpecialPage.
  */
 $wgSpecialPages = array();
 
index a14191a..a9925ff 100644 (file)
@@ -185,7 +185,7 @@ class EditPage {
        private $mContextTitle = null;
 
        /** @var string */
-       protected $action = 'submit';
+       public $action = 'submit';
 
        /** @var bool */
        public $isConflict = false;
@@ -200,13 +200,13 @@ class EditPage {
        public $isJsSubpage = false;
 
        /** @var bool */
-       protected $isWrongCaseCssJsPage = false;
+       public $isWrongCaseCssJsPage = false;
 
        /** @var bool New page or new section */
-       protected $isNew = false;
+       public $isNew = false;
 
        /** @var bool */
-       protected $deletedSinceEdit;
+       public $deletedSinceEdit;
 
        /** @var string */
        public $formtype;
@@ -215,39 +215,34 @@ class EditPage {
        public $firsttime;
 
        /** @var bool|stdClass */
-       protected $lastDelete;
+       public $lastDelete;
 
-       /** @var bool
-        * This is public because SemanticForms uses it (bug 67522).
-        * However, please consider using this property publicly
-        * to be deprecated.
-        * @protected
-        */
+       /** @var bool */
        public $mTokenOk = false;
 
        /** @var bool */
-       protected $mTokenOkExceptSuffix = false;
+       public $mTokenOkExceptSuffix = false;
 
        /** @var bool */
-       protected $mTriedSave = false;
+       public $mTriedSave = false;
 
        /** @var bool */
-       protected $incompleteForm = false;
+       public $incompleteForm = false;
 
        /** @var bool */
-       protected $tooBig = false;
+       public $tooBig = false;
 
        /** @var bool */
-       protected $kblength = false;
+       public $kblength = false;
 
        /** @var bool */
-       protected $missingComment = false;
+       public $missingComment = false;
 
        /** @var bool */
-       protected $missingSummary = false;
+       public $missingSummary = false;
 
        /** @var bool */
-       protected $allowBlankSummary = false;
+       public $allowBlankSummary = false;
 
        /** @var bool */
        protected $blankArticle = false;
@@ -256,19 +251,19 @@ class EditPage {
        protected $allowBlankArticle = false;
 
        /** @var string */
-       protected $autoSumm = '';
+       public $autoSumm = '';
 
        /** @var string */
        public $hookError = '';
 
        /** @var ParserOutput */
-       protected $mParserOutput;
+       public $mParserOutput;
 
        /** @var bool Has a summary been preset using GET parameter &summary= ? */
-       protected $hasPresetSummary = false;
+       public $hasPresetSummary = false;
 
        /** @var bool */
-       protected $mBaseRevision = false;
+       public $mBaseRevision = false;
 
        /** @var bool */
        public $mShowSummaryField = true;
@@ -282,16 +277,16 @@ class EditPage {
        public $preview = false;
 
        /** @var bool */
-       protected $diff = false;
+       public $diff = false;
 
        /** @var bool */
        public $minoredit = false;
 
        /** @var bool */
-       protected $watchthis = false;
+       public $watchthis = false;
 
        /** @var bool */
-       protected $recreate = false;
+       public $recreate = false;
 
        /** @var string */
        public $textbox1 = '';
@@ -303,7 +298,7 @@ class EditPage {
        public $summary = '';
 
        /** @var bool */
-       protected $nosummary = false;
+       public $nosummary = false;
 
        /** @var string */
        public $edittime = '';
@@ -315,13 +310,13 @@ class EditPage {
        public $sectiontitle = '';
 
        /** @var string */
-       protected $starttime = '';
+       public $starttime = '';
 
        /** @var int */
        public $oldid = 0;
 
        /** @var string */
-       protected $editintro = '';
+       public $editintro = '';
 
        /** @var null */
        public $scrolltop = null;
@@ -1897,8 +1892,14 @@ class EditPage {
                        ( ( $this->minoredit && !$this->isNew ) ? EDIT_MINOR : 0 ) |
                        ( $bot ? EDIT_FORCE_BOT : 0 );
 
-               $doEditStatus = $this->mArticle->doEditContent( $content, $this->summary, $flags,
-                                                                                                               false, null, $this->contentFormat );
+               $doEditStatus = $this->mArticle->doEditContent(
+                       $content,
+                       $this->summary,
+                       $flags,
+                       false,
+                       null,
+                       $content->getDefaultFormat()
+               );
 
                if ( !$doEditStatus->isOK() ) {
                        // Failure from doEdit()
@@ -1943,9 +1944,7 @@ class EditPage {
                        // Do this in its own transaction to reduce contention...
                        $dbw = wfGetDB( DB_MASTER );
                        $dbw->onTransactionIdle( function () use ( $dbw, $title, $watch, $wgUser, $fname ) {
-                               $dbw->begin( $fname );
                                WatchAction::doWatchOrUnwatch( $watch, $title, $wgUser );
-                               $dbw->commit( $fname );
                        } );
                }
        }
@@ -3231,6 +3230,7 @@ HTML
                        $attrs['class'] = 'mw-ui-button mw-ui-quiet';
                }
                $edithelp = Html::element( 'a', $attrs, wfMessage( 'edithelp' )->text() ) .
+                       wfMessage( 'word-separator' )->escaped() .
                        wfMessage( 'newwindow' )->parse();
 
                $wgOut->addHTML( "      <span class='cancelLink'>{$cancel}</span>\n" );
@@ -3553,22 +3553,22 @@ HTML
         * @return string
         */
        static function getEditToolbar() {
-               global $wgStylePath, $wgContLang, $wgLang, $wgOut;
+               global $wgContLang, $wgOut;
                global $wgEnableUploads, $wgForeignFileRepos;
 
                $imagesAvailable = $wgEnableUploads || count( $wgForeignFileRepos );
 
                /**
                 * $toolarray is an array of arrays each of which includes the
-                * filename of the button image (without path), the opening
-                * tag, the closing tag, optionally a sample text that is
+                * opening tag, the closing tag, optionally a sample text that is
                 * inserted between the two when no selection is highlighted
                 * and.  The tip text is shown when the user moves the mouse
                 * over the button.
+                *
+                * Images are defined in ResourceLoaderEditToolbarModule.
                 */
                $toolarray = array(
                        array(
-                               'image'  => $wgLang->getImageFile( 'button-bold' ),
                                'id'     => 'mw-editbutton-bold',
                                'open'   => '\'\'\'',
                                'close'  => '\'\'\'',
@@ -3576,7 +3576,6 @@ HTML
                                'tip'    => wfMessage( 'bold_tip' )->text(),
                        ),
                        array(
-                               'image'  => $wgLang->getImageFile( 'button-italic' ),
                                'id'     => 'mw-editbutton-italic',
                                'open'   => '\'\'',
                                'close'  => '\'\'',
@@ -3584,7 +3583,6 @@ HTML
                                'tip'    => wfMessage( 'italic_tip' )->text(),
                        ),
                        array(
-                               'image'  => $wgLang->getImageFile( 'button-link' ),
                                'id'     => 'mw-editbutton-link',
                                'open'   => '[[',
                                'close'  => ']]',
@@ -3592,7 +3590,6 @@ HTML
                                'tip'    => wfMessage( 'link_tip' )->text(),
                        ),
                        array(
-                               'image'  => $wgLang->getImageFile( 'button-extlink' ),
                                'id'     => 'mw-editbutton-extlink',
                                'open'   => '[',
                                'close'  => ']',
@@ -3600,7 +3597,6 @@ HTML
                                'tip'    => wfMessage( 'extlink_tip' )->text(),
                        ),
                        array(
-                               'image'  => $wgLang->getImageFile( 'button-headline' ),
                                'id'     => 'mw-editbutton-headline',
                                'open'   => "\n== ",
                                'close'  => " ==\n",
@@ -3608,7 +3604,6 @@ HTML
                                'tip'    => wfMessage( 'headline_tip' )->text(),
                        ),
                        $imagesAvailable ? array(
-                               'image'  => $wgLang->getImageFile( 'button-image' ),
                                'id'     => 'mw-editbutton-image',
                                'open'   => '[[' . $wgContLang->getNsText( NS_FILE ) . ':',
                                'close'  => ']]',
@@ -3616,7 +3611,6 @@ HTML
                                'tip'    => wfMessage( 'image_tip' )->text(),
                        ) : false,
                        $imagesAvailable ? array(
-                               'image'  => $wgLang->getImageFile( 'button-media' ),
                                'id'     => 'mw-editbutton-media',
                                'open'   => '[[' . $wgContLang->getNsText( NS_MEDIA ) . ':',
                                'close'  => ']]',
@@ -3624,7 +3618,6 @@ HTML
                                'tip'    => wfMessage( 'media_tip' )->text(),
                        ) : false,
                        array(
-                               'image'  => $wgLang->getImageFile( 'button-nowiki' ),
                                'id'     => 'mw-editbutton-nowiki',
                                'open'   => "<nowiki>",
                                'close'  => "</nowiki>",
@@ -3632,7 +3625,6 @@ HTML
                                'tip'    => wfMessage( 'nowiki_tip' )->text(),
                        ),
                        array(
-                               'image'  => $wgLang->getImageFile( 'button-sig' ),
                                'id'     => 'mw-editbutton-signature',
                                'open'   => '--~~~~',
                                'close'  => '',
@@ -3640,7 +3632,6 @@ HTML
                                'tip'    => wfMessage( 'sig_tip' )->text(),
                        ),
                        array(
-                               'image'  => $wgLang->getImageFile( 'button-hr' ),
                                'id'     => 'mw-editbutton-hr',
                                'open'   => "\n----\n",
                                'close'  => '',
@@ -3656,7 +3647,8 @@ HTML
                        }
 
                        $params = array(
-                               $wgStylePath . '/common/images/' . $tool['image'],
+                               // Images are defined in ResourceLoaderEditToolbarModule
+                               false,
                                // Note that we use the tip both for the ALT tag and the TITLE tag of the image.
                                // Older browsers show a "speedtip" type message only for ALT.
                                // Ideally these should be different, realistically they
index 43dfd17..84f5c60 100644 (file)
@@ -41,7 +41,7 @@ class WikiExporter {
        public $dumpUploadFileContents = false;
 
        /** @var string */
-       protected $author_list = "";
+       public $author_list = "";
 
        const FULL = 1;
        const CURRENT = 2;
@@ -56,13 +56,13 @@ class WikiExporter {
        const STUB = 1;
 
        /** @var int */
-       protected $buffer;
+       public $buffer;
 
        /** @var int */
-       protected $text;
+       public $text;
 
        /** @var DumpOutput */
-       protected $sink;
+       public $sink;
 
        /**
         * Returns the export schema version.
@@ -267,7 +267,7 @@ class WikiExporter {
                        if ( $this->buffer == WikiExporter::STREAM ) {
                                $prev = $this->db->bufferResults( false );
                        }
-                       $wrapper = null; // Assuring $wrapper is not undefined, if exception occurs early
+                       $result = null; // Assuring $result is not undefined, if exception occurs early
                        try {
                                $result = $this->db->select( array( 'logging', 'user' ),
                                        array( "{$logging}.*", 'user_name' ), // grab the user name
@@ -275,8 +275,7 @@ class WikiExporter {
                                        __METHOD__,
                                        array( 'ORDER BY' => 'log_id', 'USE INDEX' => array( 'logging' => 'PRIMARY' ) )
                                );
-                               $wrapper = $this->db->resultObject( $result );
-                               $this->outputLogStream( $wrapper );
+                               $this->outputLogStream( $result );
                                if ( $this->buffer == WikiExporter::STREAM ) {
                                        $this->db->bufferResults( $prev );
                                }
@@ -286,8 +285,8 @@ class WikiExporter {
 
                                // Freeing result
                                try {
-                                       if ( $wrapper ) {
-                                               $wrapper->free();
+                                       if ( $result ) {
+                                               $result->free();
                                        }
                                } catch ( Exception $e2 ) {
                                        // Already in panic mode -> ignoring $e2 as $e has
@@ -377,16 +376,15 @@ class WikiExporter {
                                $prev = $this->db->bufferResults( false );
                        }
 
-                       $wrapper = null; // Assuring $wrapper is not undefined, if exception occurs early
+                       $result = null; // Assuring $result is not undefined, if exception occurs early
                        try {
                                wfRunHooks( 'ModifyExportQuery',
                                                array( $this->db, &$tables, &$cond, &$opts, &$join ) );
 
                                # Do the query!
                                $result = $this->db->select( $tables, '*', $cond, __METHOD__, $opts, $join );
-                               $wrapper = $this->db->resultObject( $result );
                                # Output dump results
-                               $this->outputPageStream( $wrapper );
+                               $this->outputPageStream( $result );
 
                                if ( $this->buffer == WikiExporter::STREAM ) {
                                        $this->db->bufferResults( $prev );
@@ -397,8 +395,8 @@ class WikiExporter {
 
                                // Freeing result
                                try {
-                                       if ( $wrapper ) {
-                                               $wrapper->free();
+                                       if ( $result ) {
+                                               $result->free();
                                        }
                                } catch ( Exception $e2 ) {
                                        // Already in panic mode -> ignoring $e2 as $e has
@@ -467,7 +465,7 @@ class WikiExporter {
        }
 
        /**
-        * @param array $resultset
+        * @param ResultWrapper $resultset
         */
        protected function outputLogStream( $resultset ) {
                foreach ( $resultset as $row ) {
@@ -1370,10 +1368,10 @@ class DumpNotalkFilter extends DumpFilter {
  */
 class DumpNamespaceFilter extends DumpFilter {
        /** @var bool */
-       protected $invert = false;
+       public $invert = false;
 
        /** @var array */
-       protected $namespaces = array();
+       public $namespaces = array();
 
        /**
         * @param DumpOutput $sink
@@ -1437,13 +1435,13 @@ class DumpNamespaceFilter extends DumpFilter {
  * @ingroup Dump
  */
 class DumpLatestFilter extends DumpFilter {
-       protected $page;
+       public $page;
 
-       protected $pageString;
+       public $pageString;
 
-       protected $rev;
+       public $rev;
 
-       protected $revString;
+       public $revString;
 
        /**
         * @param object $page
index 03dd7f5..2fdfa42 100644 (file)
  */
 class FeedItem {
        /** @var Title */
-       protected $title;
+       public $title;
 
-       protected $description;
+       public $description;
 
-       protected $url;
+       public $url;
 
-       protected $date;
+       public $date;
 
-       protected $author;
+       public $author;
 
-       protected $uniqueId;
+       public $uniqueId;
 
-       protected $comments;
+       public $comments;
 
        public $rssIsPermalink = false;
 
index cfe9a87..490df24 100644 (file)
@@ -1407,7 +1407,7 @@ function wfGetLangObj( $langcode = false ) {
  *
  * This function replaces all old wfMsg* functions.
  *
- * @param string $key Message key
+ * @param string|string[] $key Message key, or array of keys
  * @param mixed $params,... Normal message parameters
  * @return Message
  *
@@ -3179,10 +3179,10 @@ function wfDiff( $before, $after, $params = '-u' ) {
 
        // Kill the --- and +++ lines. They're not useful.
        $diff_lines = explode( "\n", $diff );
-       if ( strpos( $diff_lines[0], '---' ) === 0 ) {
+       if ( isset( $diff_lines[0] ) && strpos( $diff_lines[0], '---' ) === 0 ) {
                unset( $diff_lines[0] );
        }
-       if ( strpos( $diff_lines[1], '+++' ) === 0 ) {
+       if ( isset( $diff_lines[1] ) && strpos( $diff_lines[1], '+++' ) === 0 ) {
                unset( $diff_lines[1] );
        }
 
index d2be9e9..69f1120 100644 (file)
@@ -351,10 +351,10 @@ class HistoryBlobCurStub {
  */
 class DiffHistoryBlob implements HistoryBlob {
        /** @var array Uncompressed item cache */
-       protected $mItems = array();
+       public $mItems = array();
 
        /** @var int Total uncompressed size */
-       protected $mSize = 0;
+       public $mSize = 0;
 
        /**
         * @var array Array of diffs. If a diff D from A to B is notated D = B - A,
@@ -364,20 +364,20 @@ class DiffHistoryBlob implements HistoryBlob {
         *    diff[i] = {
         *              { item[map[i]] - Z                where i = 0
         */
-       protected $mDiffs;
+       public $mDiffs;
 
        /** @var array The diff map, see above */
-       protected $mDiffMap;
+       public $mDiffMap;
 
        /** @var int The key for getText()
         */
-       protected $mDefaultKey;
+       public $mDefaultKey;
 
        /** @var string Compressed storage */
        public $mCompressed;
 
        /** @var bool True if the object is locked against further writes */
-       protected $mFrozen = false;
+       public $mFrozen = false;
 
        /**
         * @var int The maximum uncompressed size before the object becomes sad
index b3ca041..5319076 100644 (file)
@@ -891,7 +891,7 @@ class WikiImporter {
 /** This is a horrible hack used to keep source compatibility */
 class UploadSourceAdapter {
        /** @var array */
-       private static $sourceRegistrations = array();
+       public static $sourceRegistrations = array();
 
        /** @var string */
        private $mSource;
@@ -1015,13 +1015,13 @@ class UploadSourceAdapter {
  */
 class WikiRevision {
        /** @todo Unused? */
-       private $importer = null;
+       public $importer = null;
 
        /** @var Title */
        public $title = null;
 
        /** @var int */
-       private $id = 0;
+       public $id = 0;
 
        /** @var string */
        public $timestamp = "20010115000000";
@@ -1035,10 +1035,10 @@ class WikiRevision {
        public $user_text = "";
 
        /** @var string */
-       protected $model = null;
+       public $model = null;
 
        /** @var string */
-       protected $format = null;
+       public $format = null;
 
        /** @var string */
        public $text = "";
@@ -1047,7 +1047,7 @@ class WikiRevision {
        protected $size;
 
        /** @var Content */
-       protected $content = null;
+       public $content = null;
 
        /** @var ContentHandler */
        protected $contentHandler = null;
@@ -1056,31 +1056,31 @@ class WikiRevision {
        public $comment = "";
 
        /** @var bool */
-       protected $minor = false;
+       public $minor = false;
 
        /** @var string */
-       protected $type = "";
+       public $type = "";
 
        /** @var string */
-       protected $action = "";
+       public $action = "";
 
        /** @var string */
-       protected $params = "";
+       public $params = "";
 
        /** @var string */
-       protected $fileSrc = '';
+       public $fileSrc = '';
 
        /** @var bool|string */
-       protected $sha1base36 = false;
+       public $sha1base36 = false;
 
        /**
         * @var bool
         * @todo Unused?
         */
-       private $isTemp = false;
+       public $isTemp = false;
 
        /** @var string */
-       protected $archiveName = '';
+       public $archiveName = '';
 
        protected $filename;
 
@@ -1088,7 +1088,7 @@ class WikiRevision {
        protected $src;
 
        /** @todo Unused? */
-       private $fileIsTemp;
+       public $fileIsTemp;
 
        /** @var bool */
        private $mNoUpdates = false;
index f0b16ab..be850d0 100644 (file)
@@ -192,11 +192,11 @@ class Linker {
        public static function link(
                $target, $html = null, $customAttribs = array(), $query = array(), $options = array()
        ) {
-               wfProfileIn( __METHOD__ );
                if ( !$target instanceof Title ) {
-                       wfProfileOut( __METHOD__ );
+                       wfWarn( __METHOD__ . ': Requires $target to be a Title object.' );
                        return "<!-- ERROR -->$html";
                }
+               wfProfileIn( __METHOD__ );
 
                if ( is_string( $query ) ) {
                        // some functions withing core using this still hand over query strings
@@ -380,11 +380,10 @@ class Linker {
         * @return string
         */
        private static function linkText( $target ) {
-               // We might be passed a non-Title by make*LinkObj().  Fail gracefully.
                if ( !$target instanceof Title ) {
+                       wfWarn( __METHOD__ . ': Requires $target to be a Title object.' );
                        return '';
                }
-
                // If the target is just a fragment, with no title, we return the fragment
                // text.  Otherwise, we return the title text itself.
                if ( $target->getPrefixedText() === '' && $target->hasFragment() ) {
@@ -544,7 +543,7 @@ class Linker {
         * @since 1.20
         * @return string HTML for an image, with links, wrappers, etc.
         */
-       public static function makeImageLink( /*Parser*/ $parser, Title $title,
+       public static function makeImageLink( Parser $parser, Title $title,
                $file, $frameParams = array(), $handlerParams = array(), $time = false,
                $query = "", $widthOption = null
        ) {
@@ -637,13 +636,7 @@ class Linker {
                        # If a thumbnail width has not been provided, it is set
                        # to the default user option as specified in Language*.php
                        if ( $fp['align'] == '' ) {
-                               if ( $parser instanceof Parser ) {
-                                       $fp['align'] = $parser->getTargetLanguage()->alignEnd();
-                               } else {
-                                       # backwards compatibility, remove with makeImageLink2()
-                                       global $wgContLang;
-                                       $fp['align'] = $wgContLang->alignEnd();
-                               }
+                               $fp['align'] = $parser->getTargetLanguage()->alignEnd();
                        }
                        return $prefix . self::makeThumbLink2( $title, $file, $fp, $hp, $time, $query ) . $postfix;
                }
@@ -897,7 +890,7 @@ class Linker {
         */
        public static function processResponsiveImages( $file, $thumb, $hp ) {
                global $wgResponsiveImages;
-               if ( $wgResponsiveImages ) {
+               if ( $wgResponsiveImages && $thumb && !$thumb->isError() ) {
                        $hp15 = $hp;
                        $hp15['width'] = round( $hp['width'] * 1.5 );
                        $hp20 = $hp;
@@ -932,10 +925,12 @@ class Linker {
        public static function makeBrokenImageLinkObj( $title, $label = '',
                $query = '', $unused1 = '', $unused2 = '', $time = false
        ) {
-               global $wgEnableUploads, $wgUploadMissingFileUrl, $wgUploadNavigationUrl;
                if ( !$title instanceof Title ) {
+                       wfWarn( __METHOD__ . ': Requires $title to be a Title object.' );
                        return "<!-- ERROR -->" . htmlspecialchars( $label );
                }
+
+               global $wgEnableUploads, $wgUploadMissingFileUrl, $wgUploadNavigationUrl;
                wfProfileIn( __METHOD__ );
                if ( $label == '' ) {
                        $label = $title->getPrefixedText();
@@ -2151,7 +2146,7 @@ class Linker {
                return $tooltip;
        }
 
-       private static $accesskeycache;
+       public static $accesskeycache;
 
        /**
         * Given the id of an interface element, constructs the appropriate
index 9213c02..545a46f 100644 (file)
@@ -560,7 +560,7 @@ class MediaWiki {
                        wfProfileIn( 'main-try-filecache' );
                        if ( HTMLFileCache::useFileCache( $this->context ) ) {
                                // Try low-level file cache hit
-                               $cache = HTMLFileCache::newFromTitle( $title, $action );
+                               $cache = new HTMLFileCache( $title, $action );
                                if ( $cache->isCacheGood( /* Assume up to date */ ) ) {
                                        // Check incoming headers to see if client has this cached
                                        $timestamp = $cache->cacheTimestamp();
diff --git a/includes/MovePage.php b/includes/MovePage.php
new file mode 100644 (file)
index 0000000..fdece8d
--- /dev/null
@@ -0,0 +1,343 @@
+<?php
+
+/**
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * @file
+ */
+
+/**
+ * Handles the backend logic of moving a page from one title
+ * to another.
+ *
+ * @since 1.24
+ */
+class MovePage {
+
+       /**
+        * @var Title
+        */
+       protected $oldTitle;
+
+       /**
+        * @var Title
+        */
+       protected $newTitle;
+
+       public function __construct( Title $oldTitle, Title $newTitle ) {
+               $this->oldTitle = $oldTitle;
+               $this->newTitle = $newTitle;
+       }
+
+       /**
+        * @param User $user
+        * @param string $reason
+        * @param bool $createRedirect
+        * @return Status
+        */
+       public function move( User $user, $reason, $createRedirect ) {
+               global $wgCategoryCollation;
+
+               // If it is a file, move it first.
+               // It is done before all other moving stuff is done because it's hard to revert.
+               $dbw = wfGetDB( DB_MASTER );
+               if ( $this->oldTitle->getNamespace() == NS_FILE ) {
+                       $file = wfLocalFile( $this->oldTitle );
+                       if ( $file->exists() ) {
+                               $status = $file->move( $this->newTitle );
+                               if ( !$status->isOk() ) {
+                                       return $status;
+                               }
+                       }
+                       // Clear RepoGroup process cache
+                       RepoGroup::singleton()->clearCache( $this->oldTitle );
+                       RepoGroup::singleton()->clearCache( $this->newTitle ); # clear false negative cache
+               }
+
+               $dbw->begin( __METHOD__ ); # If $file was a LocalFile, its transaction would have closed our own.
+               $pageid = $this->oldTitle->getArticleID( Title::GAID_FOR_UPDATE );
+               $protected = $this->oldTitle->isProtected();
+
+               // Do the actual move
+               $this->moveToInternal( $user, $this->newTitle, $reason, $createRedirect );
+
+               // Refresh the sortkey for this row.  Be careful to avoid resetting
+               // cl_timestamp, which may disturb time-based lists on some sites.
+               // @todo This block should be killed, it's duplicating code
+               // from LinksUpdate::getCategoryInsertions() and friends.
+               $prefixes = $dbw->select(
+                       'categorylinks',
+                       array( 'cl_sortkey_prefix', 'cl_to' ),
+                       array( 'cl_from' => $pageid ),
+                       __METHOD__
+               );
+               if ( $this->newTitle->getNamespace() == NS_CATEGORY ) {
+                       $type = 'subcat';
+               } elseif ( $this->newTitle->getNamespace() == NS_FILE ) {
+                       $type = 'file';
+               } else {
+                       $type = 'page';
+               }
+               foreach ( $prefixes as $prefixRow ) {
+                       $prefix = $prefixRow->cl_sortkey_prefix;
+                       $catTo = $prefixRow->cl_to;
+                       $dbw->update( 'categorylinks',
+                               array(
+                                       'cl_sortkey' => Collation::singleton()->getSortKey(
+                                                       $this->newTitle->getCategorySortkey( $prefix ) ),
+                                       'cl_collation' => $wgCategoryCollation,
+                                       'cl_type' => $type,
+                                       'cl_timestamp=cl_timestamp' ),
+                               array(
+                                       'cl_from' => $pageid,
+                                       'cl_to' => $catTo ),
+                               __METHOD__
+                       );
+               }
+
+               $redirid = $this->oldTitle->getArticleID();
+
+               if ( $protected ) {
+                       # Protect the redirect title as the title used to be...
+                       $dbw->insertSelect( 'page_restrictions', 'page_restrictions',
+                               array(
+                                       'pr_page' => $redirid,
+                                       'pr_type' => 'pr_type',
+                                       'pr_level' => 'pr_level',
+                                       'pr_cascade' => 'pr_cascade',
+                                       'pr_user' => 'pr_user',
+                                       'pr_expiry' => 'pr_expiry'
+                               ),
+                               array( 'pr_page' => $pageid ),
+                               __METHOD__,
+                               array( 'IGNORE' )
+                       );
+                       # Update the protection log
+                       $log = new LogPage( 'protect' );
+                       $comment = wfMessage(
+                               'prot_1movedto2',
+                               $this->oldTitle->getPrefixedText(),
+                               $this->newTitle->getPrefixedText()
+                       )->inContentLanguage()->text();
+                       if ( $reason ) {
+                               $comment .= wfMessage( 'colon-separator' )->inContentLanguage()->text() . $reason;
+                       }
+                       // @todo FIXME: $params?
+                       $logId = $log->addEntry(
+                               'move_prot',
+                               $this->newTitle,
+                               $comment,
+                               array( $this->oldTitle->getPrefixedText() ),
+                               $user
+                       );
+
+                       // reread inserted pr_ids for log relation
+                       $insertedPrIds = $dbw->select(
+                               'page_restrictions',
+                               'pr_id',
+                               array( 'pr_page' => $redirid ),
+                               __METHOD__
+                       );
+                       $logRelationsValues = array();
+                       foreach ( $insertedPrIds as $prid ) {
+                               $logRelationsValues[] = $prid->pr_id;
+                       }
+                       $log->addRelations( 'pr_id', $logRelationsValues, $logId );
+               }
+
+               // Update *_from_namespace fields as needed
+               if ( $this->oldTitle->getNamespace() != $this->newTitle->getNamespace() ) {
+                       $dbw->update( 'pagelinks',
+                               array( 'pl_from_namespace' => $this->newTitle->getNamespace() ),
+                               array( 'pl_from' => $pageid ),
+                               __METHOD__
+                       );
+                       $dbw->update( 'templatelinks',
+                               array( 'tl_from_namespace' => $this->newTitle->getNamespace() ),
+                               array( 'tl_from' => $pageid ),
+                               __METHOD__
+                       );
+                       $dbw->update( 'imagelinks',
+                               array( 'il_from_namespace' => $this->newTitle->getNamespace() ),
+                               array( 'il_from' => $pageid ),
+                               __METHOD__
+                       );
+               }
+
+               # Update watchlists
+               $oldtitle = $this->oldTitle->getDBkey();
+               $newtitle = $this->newTitle->getDBkey();
+               $oldsnamespace = MWNamespace::getSubject( $this->oldTitle->getNamespace() );
+               $newsnamespace = MWNamespace::getSubject( $this->newTitle->getNamespace() );
+               if ( $oldsnamespace != $newsnamespace || $oldtitle != $newtitle ) {
+                       WatchedItem::duplicateEntries( $this->oldTitle, $this->newTitle );
+               }
+
+               $dbw->commit( __METHOD__ );
+
+               wfRunHooks( 'TitleMoveComplete', array( &$this->oldTitle, &$this->newTitle, &$user, $pageid, $redirid, $reason ) );
+               return Status::newGood();
+
+       }
+
+       /**
+        * Move page to a title which is either a redirect to the
+        * source page or nonexistent
+        *
+        * @fixme This was basically directly moved from Title, it should be split into smaller functions
+        * @param User $user the User doing the move
+        * @param Title $nt The page to move to, which should be a redirect or nonexistent
+        * @param string $reason The reason for the move
+        * @param bool $createRedirect Whether to leave a redirect at the old title. Does not check
+        *   if the user has the suppressredirect right
+        * @throws MWException
+        */
+       private function moveToInternal( User $user, &$nt, $reason = '', $createRedirect = true ) {
+               global $wgContLang;
+
+               if ( $nt->exists() ) {
+                       $moveOverRedirect = true;
+                       $logType = 'move_redir';
+               } else {
+                       $moveOverRedirect = false;
+                       $logType = 'move';
+               }
+
+               if ( $createRedirect ) {
+                       if ( $this->oldTitle->getNamespace() == NS_CATEGORY
+                               && !wfMessage( 'category-move-redirect-override' )->inContentLanguage()->isDisabled()
+                       ) {
+                               $redirectContent = new WikitextContent(
+                                       wfMessage( 'category-move-redirect-override' )
+                                               ->params( $nt->getPrefixedText() )->inContentLanguage()->plain() );
+                       } else {
+                               $contentHandler = ContentHandler::getForTitle( $this->oldTitle );
+                               $redirectContent = $contentHandler->makeRedirectContent( $nt,
+                                       wfMessage( 'move-redirect-text' )->inContentLanguage()->plain() );
+                       }
+
+                       // NOTE: If this page's content model does not support redirects, $redirectContent will be null.
+               } else {
+                       $redirectContent = null;
+               }
+
+               // bug 57084: log_page should be the ID of the *moved* page
+               $oldid = $this->oldTitle->getArticleID();
+               $logTitle = clone $this->oldTitle;
+
+               $logEntry = new ManualLogEntry( 'move', $logType );
+               $logEntry->setPerformer( $user );
+               $logEntry->setTarget( $logTitle );
+               $logEntry->setComment( $reason );
+               $logEntry->setParameters( array(
+                       '4::target' => $nt->getPrefixedText(),
+                       '5::noredir' => $redirectContent ? '0': '1',
+               ) );
+
+               $formatter = LogFormatter::newFromEntry( $logEntry );
+               $formatter->setContext( RequestContext::newExtraneousContext( $this->oldTitle ) );
+               $comment = $formatter->getPlainActionText();
+               if ( $reason ) {
+                       $comment .= wfMessage( 'colon-separator' )->inContentLanguage()->text() . $reason;
+               }
+               # Truncate for whole multibyte characters.
+               $comment = $wgContLang->truncate( $comment, 255 );
+
+               $dbw = wfGetDB( DB_MASTER );
+
+               $newpage = WikiPage::factory( $nt );
+
+               if ( $moveOverRedirect ) {
+                       $newid = $nt->getArticleID();
+                       $newcontent = $newpage->getContent();
+
+                       # Delete the old redirect. We don't save it to history since
+                       # by definition if we've got here it's rather uninteresting.
+                       # We have to remove it so that the next step doesn't trigger
+                       # a conflict on the unique namespace+title index...
+                       $dbw->delete( 'page', array( 'page_id' => $newid ), __METHOD__ );
+
+                       $newpage->doDeleteUpdates( $newid, $newcontent );
+               }
+
+               # Save a null revision in the page's history notifying of the move
+               $nullRevision = Revision::newNullRevision( $dbw, $oldid, $comment, true, $user );
+               if ( !is_object( $nullRevision ) ) {
+                       throw new MWException( 'No valid null revision produced in ' . __METHOD__ );
+               }
+
+               $nullRevision->insertOn( $dbw );
+
+               # Change the name of the target page:
+               $dbw->update( 'page',
+                       /* SET */ array(
+                               'page_namespace' => $nt->getNamespace(),
+                               'page_title' => $nt->getDBkey(),
+                       ),
+                       /* WHERE */ array( 'page_id' => $oldid ),
+                       __METHOD__
+               );
+
+               // clean up the old title before reset article id - bug 45348
+               if ( !$redirectContent ) {
+                       WikiPage::onArticleDelete( $this->oldTitle );
+               }
+
+               $this->oldTitle->resetArticleID( 0 ); // 0 == non existing
+               $nt->resetArticleID( $oldid );
+               $newpage->loadPageData( WikiPage::READ_LOCKING ); // bug 46397
+
+               $newpage->updateRevisionOn( $dbw, $nullRevision );
+
+               wfRunHooks( 'NewRevisionFromEditComplete',
+                       array( $newpage, $nullRevision, $nullRevision->getParentId(), $user ) );
+
+               $newpage->doEditUpdates( $nullRevision, $user, array( 'changed' => false ) );
+
+               if ( !$moveOverRedirect ) {
+                       WikiPage::onArticleCreate( $nt );
+               }
+
+               # Recreate the redirect, this time in the other direction.
+               if ( $redirectContent ) {
+                       $redirectArticle = WikiPage::factory( $this->oldTitle );
+                       $redirectArticle->loadFromRow( false, WikiPage::READ_LOCKING ); // bug 46397
+                       $newid = $redirectArticle->insertOn( $dbw );
+                       if ( $newid ) { // sanity
+                               $this->oldTitle->resetArticleID( $newid );
+                               $redirectRevision = new Revision( array(
+                                       'title' => $this->oldTitle, // for determining the default content model
+                                       'page' => $newid,
+                                       'user_text' => $user->getName(),
+                                       'user' => $user->getId(),
+                                       'comment' => $comment,
+                                       'content' => $redirectContent ) );
+                               $redirectRevision->insertOn( $dbw );
+                               $redirectArticle->updateRevisionOn( $dbw, $redirectRevision, 0 );
+
+                               wfRunHooks( 'NewRevisionFromEditComplete',
+                                       array( $redirectArticle, $redirectRevision, false, $user ) );
+
+                               $redirectArticle->doEditUpdates( $redirectRevision, $user, array( 'created' => true ) );
+                       }
+               }
+
+               # Log the move
+               $logid = $logEntry->insert();
+               $logEntry->publish( $logid );
+       }
+
+}
\ No newline at end of file
index af90ca6..22a6012 100644 (file)
@@ -2769,7 +2769,10 @@ $templates
                                );
                                $context = new ResourceLoaderContext( $resourceLoader, new FauxRequest( $query ) );
 
-                               // Extract modules that know they're empty
+
+                               // Extract modules that know they're empty and see if we have one or more
+                               // raw modules
+                               $isRaw = false;
                                foreach ( $grpModules as $key => $module ) {
                                        // Inline empty modules: since they're empty, just mark them as 'ready' (bug 46857)
                                        // If we're only getting the styles, we don't need to do anything for empty modules.
@@ -2779,6 +2782,8 @@ $templates
                                                        $links['states'][$key] = 'ready';
                                                }
                                        }
+
+                                       $isRaw |= $module->isRaw();
                                }
 
                                // If there are no non-empty modules, skip this group
@@ -2845,6 +2850,17 @@ $templates
                                                );
                                        } else {
                                                $link = Html::linkedScript( $url );
+                                               if ( $context->getOnly() === 'scripts' && !$context->getRaw() && !$isRaw ) {
+                                                       // Wrap only=script requests in a conditional as browsers not supported
+                                                       // by the startup module would unconditionally execute this module.
+                                                       // Otherwise users will get "ReferenceError: mw is undefined" or
+                                                       // "jQuery is undefined" from e.g. a "site" module.
+                                                       $link = Html::inlineScript(
+                                                               ResourceLoader::makeLoaderConditionalScript(
+                                                                       Xml::encodeJsCall( 'document.write', array( $link ) )
+                                                               )
+                                                       );
+                                               }
 
                                                // For modules requested directly in the html via <link> or <script>,
                                                // tell mw.loader they are being loading to prevent duplicate requests.
index 44038a5..5af818f 100644 (file)
@@ -39,7 +39,7 @@
  * version are hardcoded here
  */
 function wfPHPVersionError( $type ) {
-       $mwVersion = '1.24';
+       $mwVersion = '1.25';
        $minimumVersionPHP = '5.3.2';
 
        $phpVersion = PHP_VERSION;
@@ -60,7 +60,7 @@ function wfPHPVersionError( $type ) {
                }
                $encLogo = htmlspecialchars(
                        str_replace( '//', '/', $dirname . '/' ) .
-                       'assets/mediawiki.png'
+                       'resources/assets/mediawiki.png'
                );
 
                header( "$protocol 500 MediaWiki configuration Error" );
index eb29e41..84cf5af 100644 (file)
@@ -113,8 +113,7 @@ class Preferences {
         */
        static function loadPreferenceValues( $user, $context, &$defaultPreferences ) {
                ## Remove preferences that wikis don't want to use
-               global $wgHiddenPrefs;
-               foreach ( $wgHiddenPrefs as $pref ) {
+               foreach ( $context->getConfig()->get( 'HiddenPrefs' ) as $pref ) {
                        if ( isset( $defaultPreferences[$pref] ) ) {
                                unset( $defaultPreferences[$pref] );
                        }
@@ -207,12 +206,9 @@ class Preferences {
         * @return void
         */
        static function profilePreferences( $user, IContextSource $context, &$defaultPreferences ) {
-               global $wgAuth, $wgContLang, $wgParser, $wgLanguageCode,
-                       $wgDisableLangConversion, $wgMaxSigChars,
-                       $wgEnableEmail, $wgEmailConfirmToEdit, $wgEnableUserEmail, $wgEmailAuthentication,
-                       $wgEnotifWatchlist, $wgEnotifUserTalk, $wgEnotifRevealEditorAddress,
-                       $wgSecureLogin;
+               global $wgAuth, $wgContLang, $wgParser;
 
+               $config = $context->getConfig();
                // retrieving user name for GENDER and misc.
                $userName = $user->getName();
 
@@ -310,7 +306,7 @@ class Preferences {
                        );
                }
                // Only show prefershttps if secure login is turned on
-               if ( $wgSecureLogin && wfCanIPUseHTTPS( $context->getRequest()->getIP() ) ) {
+               if ( $config->get( 'SecureLogin' ) && wfCanIPUseHTTPS( $context->getRequest()->getIP() ) ) {
                        $defaultPreferences['prefershttps'] = array(
                                'type' => 'toggle',
                                'label-message' => 'tog-prefershttps',
@@ -321,8 +317,9 @@ class Preferences {
 
                // Language
                $languages = Language::fetchLanguageNames( null, 'mw' );
-               if ( !array_key_exists( $wgLanguageCode, $languages ) ) {
-                       $languages[$wgLanguageCode] = $wgLanguageCode;
+               $languageCode = $config->get( 'LanguageCode' );
+               if ( !array_key_exists( $languageCode, $languages ) ) {
+                       $languages[$languageCode] = $languageCode;
                }
                ksort( $languages );
 
@@ -353,7 +350,7 @@ class Preferences {
                );
 
                // see if there are multiple language variants to choose from
-               if ( !$wgDisableLangConversion ) {
+               if ( !$config->get( 'DisableLangConversion' ) ) {
                        foreach ( LanguageConverter::$languagesWithVariants as $langCode ) {
                                if ( $langCode == $wgContLang->getCode() ) {
                                        $variants = $wgContLang->getVariants();
@@ -418,7 +415,7 @@ class Preferences {
                );
                $defaultPreferences['nickname'] = array(
                        'type' => $wgAuth->allowPropChange( 'nickname' ) ? 'text' : 'info',
-                       'maxlength' => $wgMaxSigChars,
+                       'maxlength' => $config->get( 'MaxSigChars' ),
                        'label-message' => 'yournick',
                        'validation-callback' => array( 'Preferences', 'validateSignature' ),
                        'section' => 'personal/signature',
@@ -434,13 +431,13 @@ class Preferences {
 
                ## Email stuff
 
-               if ( $wgEnableEmail ) {
+               if ( $config->get( 'EnableEmail' ) ) {
                        if ( $canViewPrivateInfo ) {
-                               $helpMessages[] = $wgEmailConfirmToEdit
+                               $helpMessages[] = $config->get( 'EmailConfirmToEdit' )
                                                ? 'prefs-help-email-required'
                                                : 'prefs-help-email';
 
-                               if ( $wgEnableUserEmail ) {
+                               if ( $config->get( 'EnableUserEmail' ) ) {
                                        // additional messages when users can send email to each other
                                        $helpMessages[] = 'prefs-help-email-others';
                                }
@@ -472,7 +469,7 @@ class Preferences {
 
                        $disableEmailPrefs = false;
 
-                       if ( $wgEmailAuthentication ) {
+                       if ( $config->get( 'EmailAuthentication' ) ) {
                                $emailauthenticationclass = 'mw-email-not-authenticated';
                                if ( $user->getEmail() ) {
                                        if ( $user->getEmailAuthenticationTimestamp() ) {
@@ -517,7 +514,7 @@ class Preferences {
                                }
                        }
 
-                       if ( $wgEnableUserEmail && $user->isAllowed( 'sendemail' ) ) {
+                       if ( $config->get( 'EnableUserEmail' ) && $user->isAllowed( 'sendemail' ) ) {
                                $defaultPreferences['disablemail'] = array(
                                        'type' => 'toggle',
                                        'invert' => true,
@@ -533,7 +530,7 @@ class Preferences {
                                );
                        }
 
-                       if ( $wgEnotifWatchlist ) {
+                       if ( $config->get( 'EnotifWatchlist' ) ) {
                                $defaultPreferences['enotifwatchlistpages'] = array(
                                        'type' => 'toggle',
                                        'section' => 'personal/email',
@@ -541,7 +538,7 @@ class Preferences {
                                        'disabled' => $disableEmailPrefs,
                                );
                        }
-                       if ( $wgEnotifUserTalk ) {
+                       if ( $config->get( 'EnotifUserTalk' ) ) {
                                $defaultPreferences['enotifusertalkpages'] = array(
                                        'type' => 'toggle',
                                        'section' => 'personal/email',
@@ -549,7 +546,7 @@ class Preferences {
                                        'disabled' => $disableEmailPrefs,
                                );
                        }
-                       if ( $wgEnotifUserTalk || $wgEnotifWatchlist ) {
+                       if ( $config->get( 'EnotifUserTalk' ) || $config->get( 'EnotifWatchlist' ) ) {
                                $defaultPreferences['enotifminoredits'] = array(
                                        'type' => 'toggle',
                                        'section' => 'personal/email',
@@ -557,7 +554,7 @@ class Preferences {
                                        'disabled' => $disableEmailPrefs,
                                );
 
-                               if ( $wgEnotifRevealEditorAddress ) {
+                               if ( $config->get( 'EnotifRevealEditorAddress' ) ) {
                                        $defaultPreferences['enotifrevealaddr'] = array(
                                                'type' => 'toggle',
                                                'section' => 'personal/email',
@@ -577,7 +574,6 @@ class Preferences {
         */
        static function skinPreferences( $user, IContextSource $context, &$defaultPreferences ) {
                ## Skin #####################################
-               global $wgAllowUserCss, $wgAllowUserJs;
 
                // Skin selector, if there is at least one valid skin
                $skinOptions = self::generateSkinOptions( $user, $context );
@@ -590,19 +586,22 @@ class Preferences {
                        );
                }
 
+               $config = $context->getConfig();
+               $allowUserCss = $config->get( 'AllowUserCss' );
+               $allowUserJs = $config->get( 'AllowUserJs' );
                # Create links to user CSS/JS pages for all skins
                # This code is basically copied from generateSkinOptions().  It'd
                # be nice to somehow merge this back in there to avoid redundancy.
-               if ( $wgAllowUserCss || $wgAllowUserJs ) {
+               if ( $allowUserCss || $allowUserJs ) {
                        $linkTools = array();
                        $userName = $user->getName();
 
-                       if ( $wgAllowUserCss ) {
+                       if ( $allowUserCss ) {
                                $cssPage = Title::makeTitleSafe( NS_USER, $userName . '/common.css' );
                                $linkTools[] = Linker::link( $cssPage, $context->msg( 'prefs-custom-css' )->escaped() );
                        }
 
-                       if ( $wgAllowUserJs ) {
+                       if ( $allowUserJs ) {
                                $jsPage = Title::makeTitleSafe( NS_USER, $userName . '/common.js' );
                                $linkTools[] = Linker::link( $jsPage, $context->msg( 'prefs-custom-js' )->escaped() );
                        }
@@ -730,8 +729,7 @@ class Preferences {
                );
 
                ## Page Rendering ##############################
-               global $wgAllowUserCssPrefs;
-               if ( $wgAllowUserCssPrefs ) {
+               if ( $context->getConfig()->get( 'AllowUserCssPrefs' ) ) {
                        $defaultPreferences['underline'] = array(
                                'type' => 'select',
                                'options' => array(
@@ -776,8 +774,6 @@ class Preferences {
         * @param array $defaultPreferences
         */
        static function editingPreferences( $user, IContextSource $context, &$defaultPreferences ) {
-               global $wgAllowUserCssPrefs;
-
                ## Editing #####################################
                $defaultPreferences['editsectiononrightclick'] = array(
                        'type' => 'toggle',
@@ -790,7 +786,7 @@ class Preferences {
                        'label-message' => 'tog-editondblclick',
                );
 
-               if ( $wgAllowUserCssPrefs ) {
+               if ( $context->getConfig()->get( 'AllowUserCssPrefs' ) ) {
                        $defaultPreferences['editfont'] = array(
                                'type' => 'select',
                                'section' => 'editing/editor',
@@ -864,17 +860,17 @@ class Preferences {
         * @param array $defaultPreferences
         */
        static function rcPreferences( $user, IContextSource $context, &$defaultPreferences ) {
-               global $wgRCMaxAge, $wgRCShowWatchingUsers;
-
+               $config = $context->getConfig();
+               $rcMaxAge = $config->get( 'RCMaxAge' );
                ## RecentChanges #####################################
                $defaultPreferences['rcdays'] = array(
                        'type' => 'float',
                        'label-message' => 'recentchangesdays',
                        'section' => 'rc/displayrc',
                        'min' => 1,
-                       'max' => ceil( $wgRCMaxAge / ( 3600 * 24 ) ),
+                       'max' => ceil( $rcMaxAge / ( 3600 * 24 ) ),
                        'help' => $context->msg( 'recentchangesdays-max' )->numParams(
-                               ceil( $wgRCMaxAge / ( 3600 * 24 ) ) )->text()
+                               ceil( $rcMaxAge / ( 3600 * 24 ) ) )->text()
                );
                $defaultPreferences['rclimit'] = array(
                        'type' => 'int',
@@ -906,7 +902,7 @@ class Preferences {
                        );
                }
 
-               if ( $wgRCShowWatchingUsers ) {
+               if ( $config->get( 'RCShowWatchingUsers' ) ) {
                        $defaultPreferences['shownumberswatching'] = array(
                                'type' => 'toggle',
                                'section' => 'rc/advancedrc',
@@ -921,9 +917,8 @@ class Preferences {
         * @param array $defaultPreferences
         */
        static function watchlistPreferences( $user, IContextSource $context, &$defaultPreferences ) {
-               global $wgUseRCPatrol, $wgEnableAPI, $wgRCMaxAge;
-
-               $watchlistdaysMax = ceil( $wgRCMaxAge / ( 3600 * 24 ) );
+               $config = $context->getConfig();
+               $watchlistdaysMax = ceil( $config->get( 'RCMaxAge' ) / ( 3600 * 24 ) );
 
                ## Watchlist #####################################
                $defaultPreferences['watchlistdays'] = array(
@@ -974,7 +969,7 @@ class Preferences {
                        'label-message' => 'tog-watchlisthideliu',
                );
 
-               if ( $wgUseRCPatrol ) {
+               if ( $context->getConfig()->get( 'UseRCPatrol' ) ) {
                        $defaultPreferences['watchlisthidepatrolled'] = array(
                                'type' => 'toggle',
                                'section' => 'watchlist/advancedwatchlist',
@@ -1010,7 +1005,7 @@ class Preferences {
                        }
                }
 
-               if ( $wgEnableAPI ) {
+               if ( $config->get( 'EnableAPI' ) ) {
                        $defaultPreferences['watchlisttoken'] = array(
                                'type' => 'api',
                        );
@@ -1049,7 +1044,6 @@ class Preferences {
         * @return array Text/links to display as key; $skinkey as value
         */
        static function generateSkinOptions( $user, IContextSource $context ) {
-               global $wgDefaultSkin, $wgAllowUserCss, $wgAllowUserJs;
                $ret = array();
 
                $mptitle = Title::newMainPage();
@@ -1068,12 +1062,17 @@ class Preferences {
                }
                asort( $validSkinNames );
 
+               $config = $context->getConfig();
+               $defaultSkin = $config->get( 'DefaultSkin' );
+               $allowUserCss = $config->get( 'AllowUserCss' );
+               $allowUserJs = $config->get( 'AllowUserJs' );
+
                $foundDefault = false;
                foreach ( $validSkinNames as $skinkey => $sn ) {
                        $linkTools = array();
 
                        # Mark the default skin
-                       if ( $skinkey == $wgDefaultSkin ) {
+                       if ( $skinkey == $defaultSkin ) {
                                $linkTools[] = $context->msg( 'default' )->escaped();
                                $foundDefault = true;
                        }
@@ -1083,12 +1082,12 @@ class Preferences {
                        $linkTools[] = "<a target='_blank' href=\"$mplink\">$previewtext</a>";
 
                        # Create links to user CSS/JS pages
-                       if ( $wgAllowUserCss ) {
+                       if ( $allowUserCss ) {
                                $cssPage = Title::makeTitleSafe( NS_USER, $user->getName() . '/' . $skinkey . '.css' );
                                $linkTools[] = Linker::link( $cssPage, $context->msg( 'prefs-custom-css' )->escaped() );
                        }
 
-                       if ( $wgAllowUserJs ) {
+                       if ( $allowUserJs ) {
                                $jsPage = Title::makeTitleSafe( NS_USER, $user->getName() . '/' . $skinkey . '.js' );
                                $linkTools[] = Linker::link( $jsPage, $context->msg( 'prefs-custom-js' )->escaped() );
                        }
@@ -1125,7 +1124,7 @@ class Preferences {
                                                                                // Bug 19237
                        }
 
-                       // KLUGE: site default might not be valid for user language
+                       // FIXME KLUGE: site default might not be valid for user language
                        global $wgDefaultUserOptions;
                        if ( !in_array( $wgDefaultUserOptions['date'], $dateopts ) ) {
                                $wgDefaultUserOptions['date'] = 'default';
@@ -1149,12 +1148,10 @@ class Preferences {
         * @return array
         */
        static function getImageSizes( IContextSource $context ) {
-               global $wgImageLimits;
-
                $ret = array();
                $pixels = $context->msg( 'unit-pixel' )->text();
 
-               foreach ( $wgImageLimits as $index => $limits ) {
+               foreach ( $context->getConfig()->get( 'ImageLimits' ) as $index => $limits ) {
                        $display = "{$limits[0]}×{$limits[1]}" . $pixels;
                        $ret[$display] = $index;
                }
@@ -1167,12 +1164,10 @@ class Preferences {
         * @return array
         */
        static function getThumbSizes( IContextSource $context ) {
-               global $wgThumbLimits;
-
                $ret = array();
                $pixels = $context->msg( 'unit-pixel' )->text();
 
-               foreach ( $wgThumbLimits as $index => $size ) {
+               foreach ( $context->getConfig()->get( 'ThumbLimits' ) as $index => $size ) {
                        $display = $size . $pixels;
                        $ret[$display] = $index;
                }
@@ -1187,10 +1182,11 @@ class Preferences {
         * @return bool|string
         */
        static function validateSignature( $signature, $alldata, $form ) {
-               global $wgParser, $wgMaxSigChars;
-               if ( mb_strlen( $signature ) > $wgMaxSigChars ) {
+               global $wgParser;
+               $maxSigChars = $form->getConfig()->get( 'MaxSigChars' );
+               if ( mb_strlen( $signature ) > $maxSigChars ) {
                        return Xml::element( 'span', array( 'class' => 'error' ),
-                               $form->msg( 'badsiglength' )->numParams( $wgMaxSigChars )->text() );
+                               $form->msg( 'badsiglength' )->numParams( $maxSigChars )->text() );
                } elseif ( isset( $alldata['fancysig'] ) &&
                                $alldata['fancysig'] &&
                                $wgParser->validateSig( $signature ) === false
@@ -1272,10 +1268,10 @@ class Preferences {
        static function getTimezoneOptions( IContextSource $context ) {
                $opt = array();
 
-               global $wgLocalTZoffset;
+               $localTZoffset = $context->getConfig()->get( 'LocalTZoffset' );
                $timestamp = MWTimestamp::getLocalInstance();
-               // Check that $wgLocalTZoffset is the same as the local time zone offset
-               if ( $wgLocalTZoffset == $timestamp->format( 'Z' ) / 60 ) {
+               // Check that the LocalTZoffset is the same as the local time zone offset
+               if ( $localTZoffset == $timestamp->format( 'Z' ) / 60 ) {
                        $server_tz_msg = $context->msg(
                                'timezoneuseserverdefault',
                                $timestamp->getTimezone()->getName()
@@ -1283,12 +1279,12 @@ class Preferences {
                } else {
                        $tzstring = sprintf(
                                '%+03d:%02d',
-                               floor( $wgLocalTZoffset / 60 ),
-                               abs( $wgLocalTZoffset ) % 60
+                               floor( $localTZoffset / 60 ),
+                               abs( $localTZoffset ) % 60
                        );
                        $server_tz_msg = $context->msg( 'timezoneuseserverdefault', $tzstring )->text();
                }
-               $opt[$server_tz_msg] = "System|$wgLocalTZoffset";
+               $opt[$server_tz_msg] = "System|$localTZoffset";
                $opt[$context->msg( 'timezoneuseoffset' )->text()] = 'other';
                $opt[$context->msg( 'guesstimezone' )->text()] = 'guess';
 
@@ -1388,9 +1384,10 @@ class Preferences {
         * @return bool|Status|string
         */
        static function tryFormSubmit( $formData, $form ) {
-               global $wgHiddenPrefs, $wgAuth;
+               global $wgAuth;
 
                $user = $form->getModifiedUser();
+               $hiddenPrefs = $form->getConfig()->get( 'HiddenPrefs' );
                $result = true;
 
                if ( !$user->isAllowedAny( 'editmyprivateinfo', 'editmyoptions' ) ) {
@@ -1407,7 +1404,7 @@ class Preferences {
 
                // Fortunately, the realname field is MUCH simpler
                // (not really "private", but still shouldn't be edited without permission)
-               if ( !in_array( 'realname', $wgHiddenPrefs )
+               if ( !in_array( 'realname', $hiddenPrefs )
                        && $user->isAllowed( 'editmyprivateinfo' )
                        && array_key_exists( 'realname', $formData )
                ) {
@@ -1423,7 +1420,7 @@ class Preferences {
                        # If users have saved a value for a preference which has subsequently been disabled
                        # via $wgHiddenPrefs, we don't want to destroy that setting in case the preference
                        # is subsequently re-enabled
-                       foreach ( $wgHiddenPrefs as $pref ) {
+                       foreach ( $hiddenPrefs as $pref ) {
                                # If the user has not set a non-default value here, the default will be returned
                                # and subsequently discarded
                                $formData[$pref] = $user->getOption( $pref, null, true );
@@ -1542,6 +1539,13 @@ class PreferencesForm extends HTMLForm {
         * @return string
         */
        function getButtons() {
+               global $wgUseMediaWikiUIEverywhere;
+
+               $attrs = array( 'id' => 'mw-prefs-restoreprefs' );
+               if ( $wgUseMediaWikiUIEverywhere ) {
+                       $attrs['class'] = 'mw-ui-button mw-ui-quiet';
+               }
+
                if ( !$this->getModifiedUser()->isAllowedAny( 'editmyprivateinfo', 'editmyoptions' ) ) {
                        return '';
                }
@@ -1551,7 +1555,8 @@ class PreferencesForm extends HTMLForm {
                if ( $this->getModifiedUser()->isAllowed( 'editmyoptions' ) ) {
                        $t = SpecialPage::getTitleFor( 'Preferences', 'reset' );
 
-                       $html .= "\n" . Linker::link( $t, $this->msg( 'restoreprefs' )->escaped() );
+                       $html .= "\n" . Linker::link( $t, $this->msg( 'restoreprefs' )->escaped(),
+                               $attrs );
 
                        $html = Xml::tags( 'div', array( 'class' => 'mw-prefs-buttons' ), $html );
                }
index 295183c..718750f 100644 (file)
@@ -195,12 +195,12 @@ abstract class PrefixSearch {
                // Unlike SpecialPage itself, we want the canonical forms of both
                // canonical and alias title forms...
                $keys = array();
-               foreach ( SpecialPageFactory::getList() as $page => $class ) {
+               foreach ( SpecialPageFactory::getNames() as $page  ) {
                        $keys[$wgContLang->caseFold( $page )] = $page;
                }
 
                foreach ( $wgContLang->getSpecialPageAliases() as $page => $aliases ) {
-                       if ( !array_key_exists( $page, SpecialPageFactory::getList() ) ) {# bug 20885
+                       if ( !in_array( $page, SpecialPageFactory::getNames() ) ) {# bug 20885
                                continue;
                        }
 
index 4aa65d9..7bad8b5 100644 (file)
@@ -352,7 +352,7 @@ class ProtectionForm {
                        $output->addJsConfigVars( 'wgCascadeableLevels', $cascadingRestrictionLevels );
                        $out .= Xml::openElement( 'form', array( 'method' => 'post',
                                'action' => $this->mTitle->getLocalURL( 'action=protect' ),
-                               'id' => 'mw-Protect-Form', 'onsubmit' => 'ProtectionForm.enableUnchainedInputs(true)' ) );
+                               'id' => 'mw-Protect-Form' ) );
                }
 
                $out .= Xml::openElement( 'fieldset' ) .
@@ -384,13 +384,18 @@ class ProtectionForm {
                        );
 
                        $expiryFormOptions = '';
-                       if ( $this->mExistingExpiry[$action] && $this->mExistingExpiry[$action] != 'infinity' ) {
-                               $timestamp = $lang->timeanddate( $this->mExistingExpiry[$action], true );
-                               $d = $lang->date( $this->mExistingExpiry[$action], true );
-                               $t = $lang->time( $this->mExistingExpiry[$action], true );
+                       if ( $this->mExistingExpiry[$action] ) {
+                               if ( $this->mExistingExpiry[$action] == 'infinity' ) {
+                                       $existingExpiryMessage = wfMessage( 'protect-existing-expiry-infinity' );
+                               } else {
+                                       $timestamp = $lang->timeanddate( $this->mExistingExpiry[$action], true );
+                                       $d = $lang->date( $this->mExistingExpiry[$action], true );
+                                       $t = $lang->time( $this->mExistingExpiry[$action], true );
+                                       $existingExpiryMessage = wfMessage( 'protect-existing-expiry', $timestamp, $d, $t );
+                               }
                                $expiryFormOptions .=
                                        Xml::option(
-                                               wfMessage( 'protect-existing-expiry', $timestamp, $d, $t )->text(),
+                                               $existingExpiryMessage->text(),
                                                'existing',
                                                $this->mExpirySelection[$action] == 'existing'
                                        ) . "\n";
@@ -426,16 +431,13 @@ class ProtectionForm {
                                                                array(
                                                                        'id' => "mwProtectExpirySelection-$action",
                                                                        'name' => "wpProtectExpirySelection-$action",
-                                                                       'onchange' => "ProtectionForm.updateExpiryList(this)",
                                                                        'tabindex' => '2' ) + $this->disabledAttrib,
                                                                $expiryFormOptions ) .
                                                "</td>
                                        </tr></table>";
                        }
                        # Add custom expiry field
-                       $attribs = array( 'id' => "mwProtect-$action-expires",
-                               'onkeyup' => 'ProtectionForm.updateExpiry(this)',
-                               'onchange' => 'ProtectionForm.updateExpiry(this)' ) + $this->disabledAttrib;
+                       $attribs = array( 'id' => "mwProtect-$action-expires" ) + $this->disabledAttrib;
                        $out .= "<table><tr>
                                        <td class='mw-label'>" .
                                                $mProtectother .
@@ -556,7 +558,6 @@ class ProtectionForm {
                                $user->getEditToken( array( 'protect', $this->mTitle->getPrefixedDBkey() ) )
                        );
                        $out .= Xml::closeElement( 'form' );
-                       $output->addScript( $this->buildCleanupScript() );
                }
 
                return $out;
@@ -581,8 +582,7 @@ class ProtectionForm {
                        'id' => $id,
                        'name' => $id,
                        'size' => count( $levels ),
-                       'onchange' => 'ProtectionForm.updateLevels(this)',
-                       ) + $this->disabledAttrib;
+               ) + $this->disabledAttrib;
 
                $out = Xml::openElement( 'select', $attribs );
                foreach ( $levels as $key ) {
@@ -611,19 +611,6 @@ class ProtectionForm {
                }
        }
 
-       function buildCleanupScript() {
-               $options = array(
-                       'tableId' => 'mwProtectSet',
-                       'labelText' => wfMessage( 'protect-unchain-permissions' )->plain(),
-                       'numTypes' => count( $this->mApplicableTypes ),
-                       'existingMatch' => count( array_unique( $this->mExistingExpiry ) ) === 1,
-               );
-
-               $script = Xml::encodeJsCall( 'ProtectionForm.init', array( $options ) );
-
-               return Html::inlineScript( ResourceLoader::makeLoaderConditionalScript( $script ) );
-       }
-
        /**
         * Show protection long extracts for this page
         *
index cddb30b..253d25b 100644 (file)
@@ -77,6 +77,9 @@ if ( $wgStyleDirectory === false ) {
 if ( $wgExtensionAssetsPath === false ) {
        $wgExtensionAssetsPath = "$wgScriptPath/extensions";
 }
+if ( $wgResourceBasePath === null ) {
+       $wgResourceBasePath = $wgScriptPath;
+}
 
 if ( $wgLogo === false ) {
        $wgLogo = "$wgStylePath/common/images/wiki.png";
@@ -102,6 +105,15 @@ if ( $wgGitInfoCacheDirectory === false && $wgCacheDirectory !== false ) {
        $wgGitInfoCacheDirectory = "{$wgCacheDirectory}/gitinfo";
 }
 
+// Fix path to icon images after they were moved in 1.24
+if ( $wgRightsIcon ) {
+       $wgRightsIcon = str_replace(
+               "{$wgStylePath}/common/images/",
+               "{$wgResourceBasePath}/resources/assets/licenses/",
+               $wgRightsIcon
+       );
+}
+
 if ( isset( $wgFooterIcons['copyright'] )
        && isset( $wgFooterIcons['copyright']['copyright'] )
        && $wgFooterIcons['copyright']['copyright'] === array()
@@ -124,7 +136,7 @@ if ( isset( $wgFooterIcons['poweredby'] )
        && $wgFooterIcons['poweredby']['mediawiki']['src'] === null
 ) {
        $wgFooterIcons['poweredby']['mediawiki']['src'] =
-               "$wgStylePath/common/images/poweredby_mediawiki_88x31.png";
+               "$wgResourceBasePath/resources/assets/poweredby_mediawiki_88x31.png";
 }
 
 /**
@@ -302,7 +314,33 @@ if ( !$wgCookiePrefix ) {
 }
 $wgCookiePrefix = strtr( $wgCookiePrefix, '=,; +."\'\\[', '__________' );
 
-$wgUseEnotif = $wgEnotifUserTalk || $wgEnotifWatchlist;
+if ( $wgEnableEmail ) {
+       $wgUseEnotif = $wgEnotifUserTalk || $wgEnotifWatchlist;
+} else {
+       // Disable all other email settings automatically if $wgEnableEmail
+       // is set to false. - bug 63678
+       $wgAllowHTMLEmail = false;
+       $wgEmailAuthentication = false; // do not require auth if you're not sending email anyway
+       $wgEnableUserEmail = false;
+       $wgEnotifFromEditor = false;
+       $wgEnotifImpersonal = false;
+       $wgEnotifMaxRecips = 0;
+       $wgEnotifMinorEdits = false;
+       $wgEnotifRevealEditorAddress = false;
+       $wgEnotifUseJobQ = false;
+       $wgEnotifUseRealName = false;
+       $wgEnotifUserTalk = false;
+       $wgEnotifWatchlist = false;
+       unset( $wgGroupPermissions['user']['sendemail'] );
+       $wgUseEnotif = false;
+       $wgUserEmailUseReplyTo = false;
+       $wgUsersNotifiedOnAllChanges = array();
+}
+
+// Doesn't make sense to have if disabled.
+if ( !$wgEnotifMinorEdits ) {
+       $wgHiddenPrefs[] = 'enotifminoredits';
+}
 
 if ( $wgMetaNamespace === false ) {
        $wgMetaNamespace = str_replace( ' ', '_', $wgSitename );
@@ -355,11 +393,6 @@ if ( $wgUseFileCache || $wgUseSquid ) {
        $wgDebugToolbar = false;
 }
 
-// Doesn't make sense to have if disabled.
-if ( !$wgEnotifMinorEdits ) {
-       $wgHiddenPrefs[] = 'enotifminoredits';
-}
-
 // We always output HTML5 since 1.22, overriding these is no longer supported
 // we set them here for extensions that depend on its value.
 $wgHtml5 = true;
@@ -601,26 +634,6 @@ $wgTitle = null;
  */
 $wgDeferredUpdateList = array();
 
-// Disable all other email settings automatically if $wgEnableEmail
-// is set to false. - bug 63678
-if ( !$wgEnableEmail ) {
-       $wgAllowHTMLEmail = false;
-       $wgEmailAuthentication = false; // do not require auth if you're not sending email anyway
-       $wgEnableUserEmail = false;
-       $wgEnotifFromEditor = false;
-       $wgEnotifImpersonal = false;
-       $wgEnotifMaxRecips = 0;
-       $wgEnotifMinorEdits = false;
-       $wgEnotifRevealEditorAddress = false;
-       $wgEnotifUseJobQ = false;
-       $wgEnotifUseRealName = false;
-       $wgEnotifUserTalk = false;
-       $wgEnotifWatchlist = false;
-       unset( $wgGroupPermissions['user']['sendemail'] );
-       $wgUserEmailUseReplyTo = false;
-       $wgUsersNotifiedOnAllChanges = array();
-}
-
 wfProfileOut( $fname . '-globals' );
 wfProfileIn( $fname . '-extensions' );
 
index ca292ee..74d78ba 100644 (file)
@@ -3589,6 +3589,7 @@ class Title {
         * Check whether a given move operation would be valid.
         * Returns true if ok, or a getUserPermissionsErrors()-like array otherwise
         *
+        * @todo move this into MovePage
         * @param Title $nt The new title
         * @param bool $auth Indicates whether $wgUser's permissions
         *  should be checked
@@ -3739,6 +3740,7 @@ class Title {
        /**
         * Move a title to a new location
         *
+        * @todo Deprecate this in favor of MovePage
         * @param Title $nt The new title
         * @param bool $auth Indicates whether $wgUser's permissions
         *  should be checked
@@ -3762,279 +3764,13 @@ class Title {
 
                wfRunHooks( 'TitleMove', array( $this, $nt, $wgUser ) );
 
-               // If it is a file, move it first.
-               // It is done before all other moving stuff is done because it's hard to revert.
-               $dbw = wfGetDB( DB_MASTER );
-               if ( $this->getNamespace() == NS_FILE ) {
-                       $file = wfLocalFile( $this );
-                       if ( $file->exists() ) {
-                               $status = $file->move( $nt );
-                               if ( !$status->isOk() ) {
-                                       return $status->getErrorsArray();
-                               }
-                       }
-                       // Clear RepoGroup process cache
-                       RepoGroup::singleton()->clearCache( $this );
-                       RepoGroup::singleton()->clearCache( $nt ); # clear false negative cache
-               }
-
-               $dbw->begin( __METHOD__ ); # If $file was a LocalFile, its transaction would have closed our own.
-               $pageid = $this->getArticleID( self::GAID_FOR_UPDATE );
-               $protected = $this->isProtected();
-
-               // Do the actual move
-               $this->moveToInternal( $nt, $reason, $createRedirect );
-
-               // Refresh the sortkey for this row.  Be careful to avoid resetting
-               // cl_timestamp, which may disturb time-based lists on some sites.
-               $prefixes = $dbw->select(
-                       'categorylinks',
-                       array( 'cl_sortkey_prefix', 'cl_to' ),
-                       array( 'cl_from' => $pageid ),
-                       __METHOD__
-               );
-               foreach ( $prefixes as $prefixRow ) {
-                       $prefix = $prefixRow->cl_sortkey_prefix;
-                       $catTo = $prefixRow->cl_to;
-                       $dbw->update( 'categorylinks',
-                               array(
-                                       'cl_sortkey' => Collation::singleton()->getSortKey(
-                                               $nt->getCategorySortkey( $prefix ) ),
-                                       'cl_timestamp=cl_timestamp' ),
-                               array(
-                                       'cl_from' => $pageid,
-                                       'cl_to' => $catTo ),
-                               __METHOD__
-                       );
-               }
-
-               $redirid = $this->getArticleID();
-
-               if ( $protected ) {
-                       # Protect the redirect title as the title used to be...
-                       $dbw->insertSelect( 'page_restrictions', 'page_restrictions',
-                               array(
-                                       'pr_page' => $redirid,
-                                       'pr_type' => 'pr_type',
-                                       'pr_level' => 'pr_level',
-                                       'pr_cascade' => 'pr_cascade',
-                                       'pr_user' => 'pr_user',
-                                       'pr_expiry' => 'pr_expiry'
-                               ),
-                               array( 'pr_page' => $pageid ),
-                               __METHOD__,
-                               array( 'IGNORE' )
-                       );
-                       # Update the protection log
-                       $log = new LogPage( 'protect' );
-                       $comment = wfMessage(
-                               'prot_1movedto2',
-                               $this->getPrefixedText(),
-                               $nt->getPrefixedText()
-                       )->inContentLanguage()->text();
-                       if ( $reason ) {
-                               $comment .= wfMessage( 'colon-separator' )->inContentLanguage()->text() . $reason;
-                       }
-                       // @todo FIXME: $params?
-                       $logId = $log->addEntry(
-                               'move_prot',
-                               $nt,
-                               $comment,
-                               array( $this->getPrefixedText() ),
-                               $wgUser
-                       );
-
-                       // reread inserted pr_ids for log relation
-                       $insertedPrIds = $dbw->select(
-                               'page_restrictions',
-                               'pr_id',
-                               array( 'pr_page' => $redirid ),
-                               __METHOD__
-                       );
-                       $logRelationsValues = array();
-                       foreach ( $insertedPrIds as $prid ) {
-                               $logRelationsValues[] = $prid->pr_id;
-                       }
-                       $log->addRelations( 'pr_id', $logRelationsValues, $logId );
-               }
-
-               // Update *_from_namespace fields as needed
-               if ( $this->getNamespace() != $nt->getNamespace() ) {
-                       $dbw->update( 'pagelinks',
-                               array( 'pl_from_namespace' => $nt->getNamespace() ),
-                               array( 'pl_from' => $pageid ),
-                               __METHOD__
-                       );
-                       $dbw->update( 'templatelinks',
-                               array( 'tl_from_namespace' => $nt->getNamespace() ),
-                               array( 'tl_from' => $pageid ),
-                               __METHOD__
-                       );
-                       $dbw->update( 'imagelinks',
-                               array( 'il_from_namespace' => $nt->getNamespace() ),
-                               array( 'il_from' => $pageid ),
-                               __METHOD__
-                       );
-               }
-
-               # Update watchlists
-               $oldtitle = $this->getDBkey();
-               $newtitle = $nt->getDBkey();
-               $oldsnamespace = MWNamespace::getSubject( $this->getNamespace() );
-               $newsnamespace = MWNamespace::getSubject( $nt->getNamespace() );
-               if ( $oldsnamespace != $newsnamespace || $oldtitle != $newtitle ) {
-                       WatchedItem::duplicateEntries( $this, $nt );
-               }
-
-               $dbw->commit( __METHOD__ );
-
-               wfRunHooks( 'TitleMoveComplete', array( &$this, &$nt, &$wgUser, $pageid, $redirid, $reason ) );
-               return true;
-       }
-
-       /**
-        * Move page to a title which is either a redirect to the
-        * source page or nonexistent
-        *
-        * @param Title $nt The page to move to, which should be a redirect or nonexistent
-        * @param string $reason The reason for the move
-        * @param bool $createRedirect Whether to leave a redirect at the old title. Does not check
-        *   if the user has the suppressredirect right
-        * @throws MWException
-        */
-       private function moveToInternal( &$nt, $reason = '', $createRedirect = true ) {
-               global $wgUser, $wgContLang;
-
-               if ( $nt->exists() ) {
-                       $moveOverRedirect = true;
-                       $logType = 'move_redir';
-               } else {
-                       $moveOverRedirect = false;
-                       $logType = 'move';
-               }
-
-               if ( $createRedirect ) {
-                       if ( $this->getNamespace() == NS_CATEGORY
-                               && !wfMessage( 'category-move-redirect-override' )->inContentLanguage()->isDisabled()
-                       ) {
-                               $redirectContent = new WikitextContent(
-                                       wfMessage( 'category-move-redirect-override' )
-                                               ->params( $nt->getPrefixedText() )->inContentLanguage()->plain() );
-                       } else {
-                               $contentHandler = ContentHandler::getForTitle( $this );
-                               $redirectContent = $contentHandler->makeRedirectContent( $nt,
-                                       wfMessage( 'move-redirect-text' )->inContentLanguage()->plain() );
-                       }
-
-                       // NOTE: If this page's content model does not support redirects, $redirectContent will be null.
+               $mp = new MovePage( $this, $nt );
+               $status = $mp->move( $wgUser, $reason, $createRedirect );
+               if ( $status->isOK() ) {
+                       return true;
                } else {
-                       $redirectContent = null;
-               }
-
-               // bug 57084: log_page should be the ID of the *moved* page
-               $oldid = $this->getArticleID();
-               $logTitle = clone $this;
-
-               $logEntry = new ManualLogEntry( 'move', $logType );
-               $logEntry->setPerformer( $wgUser );
-               $logEntry->setTarget( $logTitle );
-               $logEntry->setComment( $reason );
-               $logEntry->setParameters( array(
-                       '4::target' => $nt->getPrefixedText(),
-                       '5::noredir' => $redirectContent ? '0': '1',
-               ) );
-
-               $formatter = LogFormatter::newFromEntry( $logEntry );
-               $formatter->setContext( RequestContext::newExtraneousContext( $this ) );
-               $comment = $formatter->getPlainActionText();
-               if ( $reason ) {
-                       $comment .= wfMessage( 'colon-separator' )->inContentLanguage()->text() . $reason;
-               }
-               # Truncate for whole multibyte characters.
-               $comment = $wgContLang->truncate( $comment, 255 );
-
-               $dbw = wfGetDB( DB_MASTER );
-
-               $newpage = WikiPage::factory( $nt );
-
-               if ( $moveOverRedirect ) {
-                       $newid = $nt->getArticleID();
-                       $newcontent = $newpage->getContent();
-
-                       # Delete the old redirect. We don't save it to history since
-                       # by definition if we've got here it's rather uninteresting.
-                       # We have to remove it so that the next step doesn't trigger
-                       # a conflict on the unique namespace+title index...
-                       $dbw->delete( 'page', array( 'page_id' => $newid ), __METHOD__ );
-
-                       $newpage->doDeleteUpdates( $newid, $newcontent );
+                       return $status->getErrorsArray();
                }
-
-               # Save a null revision in the page's history notifying of the move
-               $nullRevision = Revision::newNullRevision( $dbw, $oldid, $comment, true, $wgUser );
-               if ( !is_object( $nullRevision ) ) {
-                       throw new MWException( 'No valid null revision produced in ' . __METHOD__ );
-               }
-
-               $nullRevision->insertOn( $dbw );
-
-               # Change the name of the target page:
-               $dbw->update( 'page',
-                       /* SET */ array(
-                               'page_namespace' => $nt->getNamespace(),
-                               'page_title' => $nt->getDBkey(),
-                       ),
-                       /* WHERE */ array( 'page_id' => $oldid ),
-                       __METHOD__
-               );
-
-               // clean up the old title before reset article id - bug 45348
-               if ( !$redirectContent ) {
-                       WikiPage::onArticleDelete( $this );
-               }
-
-               $this->resetArticleID( 0 ); // 0 == non existing
-               $nt->resetArticleID( $oldid );
-               $newpage->loadPageData( WikiPage::READ_LOCKING ); // bug 46397
-
-               $newpage->updateRevisionOn( $dbw, $nullRevision );
-
-               wfRunHooks( 'NewRevisionFromEditComplete',
-                       array( $newpage, $nullRevision, $nullRevision->getParentId(), $wgUser ) );
-
-               $newpage->doEditUpdates( $nullRevision, $wgUser, array( 'changed' => false ) );
-
-               if ( !$moveOverRedirect ) {
-                       WikiPage::onArticleCreate( $nt );
-               }
-
-               # Recreate the redirect, this time in the other direction.
-               if ( $redirectContent ) {
-                       $redirectArticle = WikiPage::factory( $this );
-                       $redirectArticle->loadFromRow( false, WikiPage::READ_LOCKING ); // bug 46397
-                       $newid = $redirectArticle->insertOn( $dbw );
-                       if ( $newid ) { // sanity
-                               $this->resetArticleID( $newid );
-                               $redirectRevision = new Revision( array(
-                                       'title' => $this, // for determining the default content model
-                                       'page' => $newid,
-                                       'user_text' => $wgUser->getName(),
-                                       'user' => $wgUser->getId(),
-                                       'comment' => $comment,
-                                       'content' => $redirectContent ) );
-                               $redirectRevision->insertOn( $dbw );
-                               $redirectArticle->updateRevisionOn( $dbw, $redirectRevision, 0 );
-
-                               wfRunHooks( 'NewRevisionFromEditComplete',
-                                       array( $redirectArticle, $redirectRevision, false, $wgUser ) );
-
-                               $redirectArticle->doEditUpdates( $redirectRevision, $wgUser, array( 'created' => true ) );
-                       }
-               }
-
-               # Log the move
-               $logid = $logEntry->insert();
-               $logEntry->publish( $logid );
        }
 
        /**
@@ -4597,7 +4333,9 @@ class Title {
         * @return bool
         */
        public function exists() {
-               return $this->getArticleID() != 0;
+               $exists = $this->getArticleID() != 0;
+               wfRunHooks( 'TitleExists', array( $this, &$exists ) );
+               return $exists;
        }
 
        /**
index 4557096..635b1e9 100644 (file)
@@ -3992,10 +3992,10 @@ class User implements IDBAccessObject {
                        $sender = new MailAddress( $wgPasswordSender,
                                wfMessage( 'emailsender' )->inContentLanguage()->text() );
                } else {
-                       $sender = new MailAddress( $from );
+                       $sender = MailAddress::newFromUser( $from );
                }
 
-               $to = new MailAddress( $this );
+               $to = MailAddress::newFromUser( $this );
                return UserMailer::send( $to, $sender, $subject, $body, $replyto );
        }
 
diff --git a/includes/UserMailer.php b/includes/UserMailer.php
deleted file mode 100644 (file)
index 0ce9b5a..0000000
+++ /dev/null
@@ -1,949 +0,0 @@
-<?php
-/**
- * Classes used to send e-mails
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- * http://www.gnu.org/copyleft/gpl.html
- *
- * @file
- * @author <brion@pobox.com>
- * @author <mail@tgries.de>
- * @author Tim Starling
- * @author Luke Welling lwelling@wikimedia.org
- */
-
-/**
- * Stores a single person's name and email address.
- * These are passed in via the constructor, and will be returned in SMTP
- * header format when requested.
- */
-class MailAddress {
-       /**
-        * @param string|User $address String with an email address, or a User object
-        * @param string $name Human-readable name if a string address is given
-        * @param string $realName Human-readable real name if a string address is given
-        */
-       function __construct( $address, $name = null, $realName = null ) {
-               if ( is_object( $address ) && $address instanceof User ) {
-                       $this->address = $address->getEmail();
-                       $this->name = $address->getName();
-                       $this->realName = $address->getRealName();
-               } else {
-                       $this->address = strval( $address );
-                       $this->name = strval( $name );
-                       $this->realName = strval( $realName );
-               }
-       }
-
-       /**
-        * Return formatted and quoted address to insert into SMTP headers
-        * @return string
-        */
-       function toString() {
-               # PHP's mail() implementation under Windows is somewhat shite, and
-               # can't handle "Joe Bloggs <joe@bloggs.com>" format email addresses,
-               # so don't bother generating them
-               if ( $this->address ) {
-                       if ( $this->name != '' && !wfIsWindows() ) {
-                               global $wgEnotifUseRealName;
-                               $name = ( $wgEnotifUseRealName && $this->realName !== '' ) ? $this->realName : $this->name;
-                               $quoted = UserMailer::quotedPrintable( $name );
-                               if ( strpos( $quoted, '.' ) !== false || strpos( $quoted, ',' ) !== false ) {
-                                       $quoted = '"' . $quoted . '"';
-                               }
-                               return "$quoted <{$this->address}>";
-                       } else {
-                               return $this->address;
-                       }
-               } else {
-                       return "";
-               }
-       }
-
-       function __toString() {
-               return $this->toString();
-       }
-}
-
-/**
- * Collection of static functions for sending mail
- */
-class UserMailer {
-       private static $mErrorString;
-
-       /**
-        * Send mail using a PEAR mailer
-        *
-        * @param UserMailer $mailer
-        * @param string $dest
-        * @param string $headers
-        * @param string $body
-        *
-        * @return Status
-        */
-       protected static function sendWithPear( $mailer, $dest, $headers, $body ) {
-               $mailResult = $mailer->send( $dest, $headers, $body );
-
-               # Based on the result return an error string,
-               if ( PEAR::isError( $mailResult ) ) {
-                       wfDebug( "PEAR::Mail failed: " . $mailResult->getMessage() . "\n" );
-                       return Status::newFatal( 'pear-mail-error', $mailResult->getMessage() );
-               } else {
-                       return Status::newGood();
-               }
-       }
-
-       /**
-        * Creates a single string from an associative array
-        *
-        * @param array $headers Associative Array: keys are header field names,
-        *                 values are ... values.
-        * @param string $endl The end of line character.  Defaults to "\n"
-        *
-        * Note RFC2822 says newlines must be CRLF (\r\n)
-        * but php mail naively "corrects" it and requires \n for the "correction" to work
-        *
-        * @return string
-        */
-       static function arrayToHeaderString( $headers, $endl = "\n" ) {
-               $strings = array();
-               foreach ( $headers as $name => $value ) {
-                       // Prevent header injection by stripping newlines from value
-                       $value = self::sanitizeHeaderValue( $value );
-                       $strings[] = "$name: $value";
-               }
-               return implode( $endl, $strings );
-       }
-
-       /**
-        * Create a value suitable for the MessageId Header
-        *
-        * @return string
-        */
-       static function makeMsgId() {
-               global $wgSMTP, $wgServer;
-
-               $msgid = uniqid( wfWikiID() . ".", true ); /* true required for cygwin */
-               if ( is_array( $wgSMTP ) && isset( $wgSMTP['IDHost'] ) && $wgSMTP['IDHost'] ) {
-                       $domain = $wgSMTP['IDHost'];
-               } else {
-                       $url = wfParseUrl( $wgServer );
-                       $domain = $url['host'];
-               }
-               return "<$msgid@$domain>";
-       }
-
-       /**
-        * This function will perform a direct (authenticated) login to
-        * a SMTP Server to use for mail relaying if 'wgSMTP' specifies an
-        * array of parameters. It requires PEAR:Mail to do that.
-        * Otherwise it just uses the standard PHP 'mail' function.
-        *
-        * @param MailAddress|MailAddress[] $to Recipient's email (or an array of them)
-        * @param MailAddress $from Sender's email
-        * @param string $subject Email's subject.
-        * @param string $body Email's text or Array of two strings to be the text and html bodies
-        * @param MailAddress $replyto Optional reply-to email (default: null).
-        * @param string $contentType Optional custom Content-Type (default: text/plain; charset=UTF-8)
-        * @throws MWException
-        * @throws Exception
-        * @return Status
-        */
-       public static function send( $to, $from, $subject, $body, $replyto = null,
-               $contentType = 'text/plain; charset=UTF-8'
-       ) {
-               global $wgSMTP, $wgEnotifMaxRecips, $wgAdditionalMailParams, $wgAllowHTMLEmail;
-               $mime = null;
-               if ( !is_array( $to ) ) {
-                       $to = array( $to );
-               }
-
-               // mail body must have some content
-               $minBodyLen = 10;
-               // arbitrary but longer than Array or Object to detect casting error
-
-               // body must either be a string or an array with text and body
-               if (
-                       !(
-                               !is_array( $body ) &&
-                               strlen( $body ) >= $minBodyLen
-                       )
-                       &&
-                       !(
-                               is_array( $body ) &&
-                               isset( $body['text'] ) &&
-                               isset( $body['html'] ) &&
-                               strlen( $body['text'] ) >= $minBodyLen &&
-                               strlen( $body['html'] ) >= $minBodyLen
-                       )
-               ) {
-                       // if it is neither we have a problem
-                       return Status::newFatal( 'user-mail-no-body' );
-               }
-
-               if ( !$wgAllowHTMLEmail && is_array( $body ) ) {
-                       // HTML not wanted.  Dump it.
-                       $body = $body['text'];
-               }
-
-               wfDebug( __METHOD__ . ': sending mail to ' . implode( ', ', $to ) . "\n" );
-
-               # Make sure we have at least one address
-               $has_address = false;
-               foreach ( $to as $u ) {
-                       if ( $u->address ) {
-                               $has_address = true;
-                               break;
-                       }
-               }
-               if ( !$has_address ) {
-                       return Status::newFatal( 'user-mail-no-addy' );
-               }
-
-               # Forge email headers
-               # -------------------
-               #
-               # WARNING
-               #
-               # DO NOT add To: or Subject: headers at this step. They need to be
-               # handled differently depending upon the mailer we are going to use.
-               #
-               # To:
-               #  PHP mail() first argument is the mail receiver. The argument is
-               #  used as a recipient destination and as a To header.
-               #
-               #  PEAR mailer has a recipient argument which is only used to
-               #  send the mail. If no To header is given, PEAR will set it to
-               #  to 'undisclosed-recipients:'.
-               #
-               #  NOTE: To: is for presentation, the actual recipient is specified
-               #  by the mailer using the Rcpt-To: header.
-               #
-               # Subject:
-               #  PHP mail() second argument to pass the subject, passing a Subject
-               #  as an additional header will result in a duplicate header.
-               #
-               #  PEAR mailer should be passed a Subject header.
-               #
-               # -- hashar 20120218
-
-               $headers['From'] = $from->toString();
-               $returnPath = $from->address;
-               $extraParams = $wgAdditionalMailParams;
-
-               // Hook to generate custom VERP address for 'Return-Path'
-               wfRunHooks( 'UserMailerChangeReturnPath', array( $to, &$returnPath ) );
-               # Add the envelope sender address using the -f command line option when PHP mail() is used.
-               # Will default to the $from->address when the UserMailerChangeReturnPath hook fails and the
-               # generated VERP address when the hook runs effectively.
-               $extraParams .= ' -f ' . $returnPath;
-
-               $headers['Return-Path'] = $returnPath;
-
-               if ( $replyto ) {
-                       $headers['Reply-To'] = $replyto->toString();
-               }
-
-               $headers['Date'] = MWTimestamp::getLocalInstance()->format( 'r' );
-               $headers['Message-ID'] = self::makeMsgId();
-               $headers['X-Mailer'] = 'MediaWiki mailer';
-
-               # Line endings need to be different on Unix and Windows due to
-               # the bug described at http://trac.wordpress.org/ticket/2603
-               if ( wfIsWindows() ) {
-                       $endl = "\r\n";
-               } else {
-                       $endl = "\n";
-               }
-
-               if ( is_array( $body ) ) {
-                       // we are sending a multipart message
-                       wfDebug( "Assembling multipart mime email\n" );
-                       if ( !stream_resolve_include_path( 'Mail/mime.php' ) ) {
-                               wfDebug( "PEAR Mail_Mime package is not installed. Falling back to text email.\n" );
-                               // remove the html body for text email fall back
-                               $body = $body['text'];
-                       } else {
-                               require_once 'Mail/mime.php';
-                               if ( wfIsWindows() ) {
-                                       $body['text'] = str_replace( "\n", "\r\n", $body['text'] );
-                                       $body['html'] = str_replace( "\n", "\r\n", $body['html'] );
-                               }
-                               $mime = new Mail_mime( array(
-                                       'eol' => $endl,
-                                       'text_charset' => 'UTF-8',
-                                       'html_charset' => 'UTF-8'
-                               ) );
-                               $mime->setTXTBody( $body['text'] );
-                               $mime->setHTMLBody( $body['html'] );
-                               $body = $mime->get(); // must call get() before headers()
-                               $headers = $mime->headers( $headers );
-                       }
-               }
-               if ( $mime === null ) {
-                       // sending text only, either deliberately or as a fallback
-                       if ( wfIsWindows() ) {
-                               $body = str_replace( "\n", "\r\n", $body );
-                       }
-                       $headers['MIME-Version'] = '1.0';
-                       $headers['Content-type'] = ( is_null( $contentType ) ?
-                               'text/plain; charset=UTF-8' : $contentType );
-                       $headers['Content-transfer-encoding'] = '8bit';
-               }
-
-               $ret = wfRunHooks( 'AlternateUserMailer', array( $headers, $to, $from, $subject, $body ) );
-               if ( $ret === false ) {
-                       // the hook implementation will return false to skip regular mail sending
-                       return Status::newGood();
-               } elseif ( $ret !== true ) {
-                       // the hook implementation will return a string to pass an error message
-                       return Status::newFatal( 'php-mail-error', $ret );
-               }
-
-               if ( is_array( $wgSMTP ) ) {
-                       #
-                       # PEAR MAILER
-                       #
-
-                       if ( !stream_resolve_include_path( 'Mail.php' ) ) {
-                               throw new MWException( 'PEAR mail package is not installed' );
-                       }
-                       require_once 'Mail.php';
-
-                       wfSuppressWarnings();
-
-                       // Create the mail object using the Mail::factory method
-                       $mail_object =& Mail::factory( 'smtp', $wgSMTP );
-                       if ( PEAR::isError( $mail_object ) ) {
-                               wfDebug( "PEAR::Mail factory failed: " . $mail_object->getMessage() . "\n" );
-                               wfRestoreWarnings();
-                               return Status::newFatal( 'pear-mail-error', $mail_object->getMessage() );
-                       }
-
-                       wfDebug( "Sending mail via PEAR::Mail\n" );
-
-                       $headers['Subject'] = self::quotedPrintable( $subject );
-
-                       # When sending only to one recipient, shows it its email using To:
-                       if ( count( $to ) == 1 ) {
-                               $headers['To'] = $to[0]->toString();
-                       }
-
-                       # Split jobs since SMTP servers tends to limit the maximum
-                       # number of possible recipients.
-                       $chunks = array_chunk( $to, $wgEnotifMaxRecips );
-                       foreach ( $chunks as $chunk ) {
-                               $status = self::sendWithPear( $mail_object, $chunk, $headers, $body );
-                               # FIXME : some chunks might be sent while others are not!
-                               if ( !$status->isOK() ) {
-                                       wfRestoreWarnings();
-                                       return $status;
-                               }
-                       }
-                       wfRestoreWarnings();
-                       return Status::newGood();
-               } else {
-                       #
-                       # PHP mail()
-                       #
-                       if ( count( $to ) > 1 ) {
-                               $headers['To'] = 'undisclosed-recipients:;';
-                       }
-                       $headers = self::arrayToHeaderString( $headers, $endl );
-
-                       wfDebug( "Sending mail via internal mail() function\n" );
-
-                       self::$mErrorString = '';
-                       $html_errors = ini_get( 'html_errors' );
-                       ini_set( 'html_errors', '0' );
-                       set_error_handler( 'UserMailer::errorHandler' );
-
-                       try {
-                               $safeMode = wfIniGetBool( 'safe_mode' );
-
-                               foreach ( $to as $recip ) {
-                                       if ( $safeMode ) {
-                                               $sent = mail( $recip, self::quotedPrintable( $subject ), $body, $headers );
-                                       } else {
-                                               $sent = mail(
-                                                       $recip,
-                                                       self::quotedPrintable( $subject ),
-                                                       $body,
-                                                       $headers,
-                                                       $extraParams
-                                               );
-                                       }
-                               }
-                       } catch ( Exception $e ) {
-                               restore_error_handler();
-                               throw $e;
-                       }
-
-                       restore_error_handler();
-                       ini_set( 'html_errors', $html_errors );
-
-                       if ( self::$mErrorString ) {
-                               wfDebug( "Error sending mail: " . self::$mErrorString . "\n" );
-                               return Status::newFatal( 'php-mail-error', self::$mErrorString );
-                       } elseif ( !$sent ) {
-                               // mail function only tells if there's an error
-                               wfDebug( "Unknown error sending mail\n" );
-                               return Status::newFatal( 'php-mail-error-unknown' );
-                       } else {
-                               return Status::newGood();
-                       }
-               }
-       }
-
-       /**
-        * Set the mail error message in self::$mErrorString
-        *
-        * @param int $code Error number
-        * @param string $string Error message
-        */
-       static function errorHandler( $code, $string ) {
-               self::$mErrorString = preg_replace( '/^mail\(\)(\s*\[.*?\])?: /', '', $string );
-       }
-
-       /**
-        * Strips bad characters from a header value to prevent PHP mail header injection attacks
-        * @param string $val String to be santizied
-        * @return string
-        */
-       public static function sanitizeHeaderValue( $val ) {
-               return strtr( $val, array( "\r" => '', "\n" => '' ) );
-       }
-
-       /**
-        * Converts a string into a valid RFC 822 "phrase", such as is used for the sender name
-        * @param string $phrase
-        * @return string
-        */
-       public static function rfc822Phrase( $phrase ) {
-               // Remove line breaks
-               $phrase = self::sanitizeHeaderValue( $phrase );
-               // Remove quotes
-               $phrase = str_replace( '"', '', $phrase );
-               return '"' . $phrase . '"';
-       }
-
-       /**
-        * Converts a string into quoted-printable format
-        * @since 1.17
-        *
-        * From PHP5.3 there is a built in function quoted_printable_encode()
-        * This method does not duplicate that.
-        * This method is doing Q encoding inside encoded-words as defined by RFC 2047
-        * This is for email headers.
-        * The built in quoted_printable_encode() is for email bodies
-        * @param string $string
-        * @param string $charset
-        * @return string
-        */
-       public static function quotedPrintable( $string, $charset = '' ) {
-               # Probably incomplete; see RFC 2045
-               if ( empty( $charset ) ) {
-                       $charset = 'UTF-8';
-               }
-               $charset = strtoupper( $charset );
-               $charset = str_replace( 'ISO-8859', 'ISO8859', $charset ); // ?
-
-               $illegal = '\x00-\x08\x0b\x0c\x0e-\x1f\x7f-\xff=';
-               $replace = $illegal . '\t ?_';
-               if ( !preg_match( "/[$illegal]/", $string ) ) {
-                       return $string;
-               }
-               $out = "=?$charset?Q?";
-               $out .= preg_replace_callback( "/([$replace])/",
-                       array( __CLASS__, 'quotedPrintableCallback' ), $string );
-               $out .= '?=';
-               return $out;
-       }
-
-       protected static function quotedPrintableCallback( $matches ) {
-               return sprintf( "=%02X", ord( $matches[1] ) );
-       }
-}
-
-/**
- * This module processes the email notifications when the current page is
- * changed. It looks up the table watchlist to find out which users are watching
- * that page.
- *
- * The current implementation sends independent emails to each watching user for
- * the following reason:
- *
- * - Each watching user will be notified about the page edit time expressed in
- * his/her local time (UTC is shown additionally). To achieve this, we need to
- * find the individual timeoffset of each watching user from the preferences..
- *
- * Suggested improvement to slack down the number of sent emails: We could think
- * of sending out bulk mails (bcc:user1,user2...) for all these users having the
- * same timeoffset in their preferences.
- *
- * Visit the documentation pages under http://meta.wikipedia.com/Enotif
- *
- *
- */
-class EmailNotification {
-       protected $subject, $body, $replyto, $from;
-       protected $timestamp, $summary, $minorEdit, $oldid, $composed_common, $pageStatus;
-       protected $mailTargets = array();
-
-       /**
-        * @var Title
-        */
-       protected $title;
-
-       /**
-        * @var User
-        */
-       protected $editor;
-
-       /**
-        * Send emails corresponding to the user $editor editing the page $title.
-        * Also updates wl_notificationtimestamp.
-        *
-        * May be deferred via the job queue.
-        *
-        * @param User $editor
-        * @param Title $title
-        * @param string $timestamp
-        * @param string $summary
-        * @param bool $minorEdit
-        * @param bool $oldid (default: false)
-        * @param string $pageStatus (default: 'changed')
-        */
-       public function notifyOnPageChange( $editor, $title, $timestamp, $summary,
-               $minorEdit, $oldid = false, $pageStatus = 'changed'
-       ) {
-               global $wgEnotifUseJobQ, $wgEnotifWatchlist, $wgShowUpdatedMarker, $wgEnotifMinorEdits,
-                       $wgUsersNotifiedOnAllChanges, $wgEnotifUserTalk;
-
-               if ( $title->getNamespace() < 0 ) {
-                       return;
-               }
-
-               // Build a list of users to notify
-               $watchers = array();
-               if ( $wgEnotifWatchlist || $wgShowUpdatedMarker ) {
-                       $dbw = wfGetDB( DB_MASTER );
-                       $res = $dbw->select( array( 'watchlist' ),
-                               array( 'wl_user' ),
-                               array(
-                                       'wl_user != ' . intval( $editor->getID() ),
-                                       'wl_namespace' => $title->getNamespace(),
-                                       'wl_title' => $title->getDBkey(),
-                                       'wl_notificationtimestamp IS NULL',
-                               ), __METHOD__
-                       );
-                       foreach ( $res as $row ) {
-                               $watchers[] = intval( $row->wl_user );
-                       }
-                       if ( $watchers ) {
-                               // Update wl_notificationtimestamp for all watching users except the editor
-                               $fname = __METHOD__;
-                               $dbw->onTransactionIdle(
-                                       function () use ( $dbw, $timestamp, $watchers, $title, $fname ) {
-                                               $dbw->update( 'watchlist',
-                                                       array( /* SET */
-                                                               'wl_notificationtimestamp' => $dbw->timestamp( $timestamp )
-                                                       ), array( /* WHERE */
-                                                               'wl_user' => $watchers,
-                                                               'wl_namespace' => $title->getNamespace(),
-                                                               'wl_title' => $title->getDBkey(),
-                                                       ), $fname
-                                               );
-                                       }
-                               );
-                       }
-               }
-
-               $sendEmail = true;
-               // If nobody is watching the page, and there are no users notified on all changes
-               // don't bother creating a job/trying to send emails
-               // $watchers deals with $wgEnotifWatchlist
-               if ( !count( $watchers ) && !count( $wgUsersNotifiedOnAllChanges ) ) {
-                       $sendEmail = false;
-                       // Only send notification for non minor edits, unless $wgEnotifMinorEdits
-                       if ( !$minorEdit || ( $wgEnotifMinorEdits && !$editor->isAllowed( 'nominornewtalk' ) ) ) {
-                               $isUserTalkPage = ( $title->getNamespace() == NS_USER_TALK );
-                               if ( $wgEnotifUserTalk
-                                       && $isUserTalkPage
-                                       && $this->canSendUserTalkEmail( $editor, $title, $minorEdit )
-                               ) {
-                                       $sendEmail = true;
-                               }
-                       }
-               }
-
-               if ( !$sendEmail ) {
-                       return;
-               }
-
-               if ( $wgEnotifUseJobQ ) {
-                       $params = array(
-                               'editor' => $editor->getName(),
-                               'editorID' => $editor->getID(),
-                               'timestamp' => $timestamp,
-                               'summary' => $summary,
-                               'minorEdit' => $minorEdit,
-                               'oldid' => $oldid,
-                               'watchers' => $watchers,
-                               'pageStatus' => $pageStatus
-                       );
-                       $job = new EnotifNotifyJob( $title, $params );
-                       JobQueueGroup::singleton()->push( $job );
-               } else {
-                       $this->actuallyNotifyOnPageChange(
-                               $editor,
-                               $title,
-                               $timestamp,
-                               $summary,
-                               $minorEdit,
-                               $oldid,
-                               $watchers,
-                               $pageStatus
-                       );
-               }
-       }
-
-       /**
-        * Immediate version of notifyOnPageChange().
-        *
-        * Send emails corresponding to the user $editor editing the page $title.
-        * Also updates wl_notificationtimestamp.
-        *
-        * @param User $editor
-        * @param Title $title
-        * @param string $timestamp Edit timestamp
-        * @param string $summary Edit summary
-        * @param bool $minorEdit
-        * @param int $oldid Revision ID
-        * @param array $watchers Array of user IDs
-        * @param string $pageStatus
-        * @throws MWException
-        */
-       public function actuallyNotifyOnPageChange( $editor, $title, $timestamp, $summary, $minorEdit,
-               $oldid, $watchers, $pageStatus = 'changed' ) {
-               # we use $wgPasswordSender as sender's address
-               global $wgEnotifWatchlist;
-               global $wgEnotifMinorEdits, $wgEnotifUserTalk;
-
-               wfProfileIn( __METHOD__ );
-
-               # The following code is only run, if several conditions are met:
-               # 1. EmailNotification for pages (other than user_talk pages) must be enabled
-               # 2. minor edits (changes) are only regarded if the global flag indicates so
-
-               $isUserTalkPage = ( $title->getNamespace() == NS_USER_TALK );
-
-               $this->title = $title;
-               $this->timestamp = $timestamp;
-               $this->summary = $summary;
-               $this->minorEdit = $minorEdit;
-               $this->oldid = $oldid;
-               $this->editor = $editor;
-               $this->composed_common = false;
-               $this->pageStatus = $pageStatus;
-
-               $formattedPageStatus = array( 'deleted', 'created', 'moved', 'restored', 'changed' );
-
-               wfRunHooks( 'UpdateUserMailerFormattedPageStatus', array( &$formattedPageStatus ) );
-               if ( !in_array( $this->pageStatus, $formattedPageStatus ) ) {
-                       wfProfileOut( __METHOD__ );
-                       throw new MWException( 'Not a valid page status!' );
-               }
-
-               $userTalkId = false;
-
-               if ( !$minorEdit || ( $wgEnotifMinorEdits && !$editor->isAllowed( 'nominornewtalk' ) ) ) {
-                       if ( $wgEnotifUserTalk
-                               && $isUserTalkPage
-                               && $this->canSendUserTalkEmail( $editor, $title, $minorEdit )
-                       ) {
-                               $targetUser = User::newFromName( $title->getText() );
-                               $this->compose( $targetUser );
-                               $userTalkId = $targetUser->getId();
-                       }
-
-                       if ( $wgEnotifWatchlist ) {
-                               // Send updates to watchers other than the current editor
-                               $userArray = UserArray::newFromIDs( $watchers );
-                               foreach ( $userArray as $watchingUser ) {
-                                       if ( $watchingUser->getOption( 'enotifwatchlistpages' )
-                                               && ( !$minorEdit || $watchingUser->getOption( 'enotifminoredits' ) )
-                                               && $watchingUser->isEmailConfirmed()
-                                               && $watchingUser->getID() != $userTalkId
-                                       ) {
-                                               if ( wfRunHooks( 'SendWatchlistEmailNotification', array( $watchingUser, $title, $this ) ) ) {
-                                                       $this->compose( $watchingUser );
-                                               }
-                                       }
-                               }
-                       }
-               }
-
-               global $wgUsersNotifiedOnAllChanges;
-               foreach ( $wgUsersNotifiedOnAllChanges as $name ) {
-                       if ( $editor->getName() == $name ) {
-                               // No point notifying the user that actually made the change!
-                               continue;
-                       }
-                       $user = User::newFromName( $name );
-                       $this->compose( $user );
-               }
-
-               $this->sendMails();
-               wfProfileOut( __METHOD__ );
-       }
-
-       /**
-        * @param User $editor
-        * @param Title $title
-        * @param bool $minorEdit
-        * @return bool
-        */
-       private function canSendUserTalkEmail( $editor, $title, $minorEdit ) {
-               global $wgEnotifUserTalk;
-               $isUserTalkPage = ( $title->getNamespace() == NS_USER_TALK );
-
-               if ( $wgEnotifUserTalk && $isUserTalkPage ) {
-                       $targetUser = User::newFromName( $title->getText() );
-
-                       if ( !$targetUser || $targetUser->isAnon() ) {
-                               wfDebug( __METHOD__ . ": user talk page edited, but user does not exist\n" );
-                       } elseif ( $targetUser->getId() == $editor->getId() ) {
-                               wfDebug( __METHOD__ . ": user edited their own talk page, no notification sent\n" );
-                       } elseif ( $targetUser->getOption( 'enotifusertalkpages' )
-                               && ( !$minorEdit || $targetUser->getOption( 'enotifminoredits' ) )
-                       ) {
-                               if ( !$targetUser->isEmailConfirmed() ) {
-                                       wfDebug( __METHOD__ . ": talk page owner doesn't have validated email\n" );
-                               } elseif ( !wfRunHooks( 'AbortTalkPageEmailNotification', array( $targetUser, $title ) ) ) {
-                                       wfDebug( __METHOD__ . ": talk page update notification is aborted for this user\n" );
-                               } else {
-                                       wfDebug( __METHOD__ . ": sending talk page update notification\n" );
-                                       return true;
-                               }
-                       } else {
-                               wfDebug( __METHOD__ . ": talk page owner doesn't want notifications\n" );
-                       }
-               }
-               return false;
-       }
-
-       /**
-        * Generate the generic "this page has been changed" e-mail text.
-        */
-       private function composeCommonMailtext() {
-               global $wgPasswordSender, $wgNoReplyAddress;
-               global $wgEnotifFromEditor, $wgEnotifRevealEditorAddress;
-               global $wgEnotifImpersonal, $wgEnotifUseRealName;
-
-               $this->composed_common = true;
-
-               # You as the WikiAdmin and Sysops can make use of plenty of
-               # named variables when composing your notification emails while
-               # simply editing the Meta pages
-
-               $keys = array();
-               $postTransformKeys = array();
-               $pageTitleUrl = $this->title->getCanonicalURL();
-               $pageTitle = $this->title->getPrefixedText();
-
-               if ( $this->oldid ) {
-                       // Always show a link to the diff which triggered the mail. See bug 32210.
-                       $keys['$NEWPAGE'] = "\n\n" . wfMessage( 'enotif_lastdiff',
-                               $this->title->getCanonicalURL( array( 'diff' => 'next', 'oldid' => $this->oldid ) ) )
-                               ->inContentLanguage()->text();
-
-                       if ( !$wgEnotifImpersonal ) {
-                               // For personal mail, also show a link to the diff of all changes
-                               // since last visited.
-                               $keys['$NEWPAGE'] .= "\n\n" . wfMessage( 'enotif_lastvisited',
-                                       $this->title->getCanonicalURL( array( 'diff' => '0', 'oldid' => $this->oldid ) ) )
-                                       ->inContentLanguage()->text();
-                       }
-                       $keys['$OLDID'] = $this->oldid;
-                       // Deprecated since MediaWiki 1.21, not used by default. Kept for backwards-compatibility.
-                       $keys['$CHANGEDORCREATED'] = wfMessage( 'changed' )->inContentLanguage()->text();
-               } else {
-                       # clear $OLDID placeholder in the message template
-                       $keys['$OLDID'] = '';
-                       $keys['$NEWPAGE'] = '';
-                       // Deprecated since MediaWiki 1.21, not used by default. Kept for backwards-compatibility.
-                       $keys['$CHANGEDORCREATED'] = wfMessage( 'created' )->inContentLanguage()->text();
-               }
-
-               $keys['$PAGETITLE'] = $this->title->getPrefixedText();
-               $keys['$PAGETITLE_URL'] = $this->title->getCanonicalURL();
-               $keys['$PAGEMINOREDIT'] = $this->minorEdit ?
-                       wfMessage( 'minoredit' )->inContentLanguage()->text() : '';
-               $keys['$UNWATCHURL'] = $this->title->getCanonicalURL( 'action=unwatch' );
-
-               if ( $this->editor->isAnon() ) {
-                       # real anon (user:xxx.xxx.xxx.xxx)
-                       $keys['$PAGEEDITOR'] = wfMessage( 'enotif_anon_editor', $this->editor->getName() )
-                               ->inContentLanguage()->text();
-                       $keys['$PAGEEDITOR_EMAIL'] = wfMessage( 'noemailtitle' )->inContentLanguage()->text();
-
-               } else {
-                       $keys['$PAGEEDITOR'] = $wgEnotifUseRealName && $this->editor->getRealName() !== ''
-                               ? $this->editor->getRealName() : $this->editor->getName();
-                       $emailPage = SpecialPage::getSafeTitleFor( 'Emailuser', $this->editor->getName() );
-                       $keys['$PAGEEDITOR_EMAIL'] = $emailPage->getCanonicalURL();
-               }
-
-               $keys['$PAGEEDITOR_WIKI'] = $this->editor->getUserPage()->getCanonicalURL();
-               $keys['$HELPPAGE'] = wfExpandUrl(
-                       Skin::makeInternalOrExternalUrl( wfMessage( 'helppage' )->inContentLanguage()->text() )
-               );
-
-               # Replace this after transforming the message, bug 35019
-               $postTransformKeys['$PAGESUMMARY'] = $this->summary == '' ? ' - ' : $this->summary;
-
-               // Now build message's subject and body
-
-               // Messages:
-               // enotif_subject_deleted, enotif_subject_created, enotif_subject_moved,
-               // enotif_subject_restored, enotif_subject_changed
-               $this->subject = wfMessage( 'enotif_subject_' . $this->pageStatus )->inContentLanguage()
-                       ->params( $pageTitle, $keys['$PAGEEDITOR'] )->text();
-
-               // Messages:
-               // enotif_body_intro_deleted, enotif_body_intro_created, enotif_body_intro_moved,
-               // enotif_body_intro_restored, enotif_body_intro_changed
-               $keys['$PAGEINTRO'] = wfMessage( 'enotif_body_intro_' . $this->pageStatus )
-                       ->inContentLanguage()->params( $pageTitle, $keys['$PAGEEDITOR'], $pageTitleUrl )
-                       ->text();
-
-               $body = wfMessage( 'enotif_body' )->inContentLanguage()->plain();
-               $body = strtr( $body, $keys );
-               $body = MessageCache::singleton()->transform( $body, false, null, $this->title );
-               $this->body = wordwrap( strtr( $body, $postTransformKeys ), 72 );
-
-               # Reveal the page editor's address as REPLY-TO address only if
-               # the user has not opted-out and the option is enabled at the
-               # global configuration level.
-               $adminAddress = new MailAddress( $wgPasswordSender,
-                       wfMessage( 'emailsender' )->inContentLanguage()->text() );
-               if ( $wgEnotifRevealEditorAddress
-                       && ( $this->editor->getEmail() != '' )
-                       && $this->editor->getOption( 'enotifrevealaddr' )
-               ) {
-                       $editorAddress = new MailAddress( $this->editor );
-                       if ( $wgEnotifFromEditor ) {
-                               $this->from = $editorAddress;
-                       } else {
-                               $this->from = $adminAddress;
-                               $this->replyto = $editorAddress;
-                       }
-               } else {
-                       $this->from = $adminAddress;
-                       $this->replyto = new MailAddress( $wgNoReplyAddress );
-               }
-       }
-
-       /**
-        * Compose a mail to a given user and either queue it for sending, or send it now,
-        * depending on settings.
-        *
-        * Call sendMails() to send any mails that were queued.
-        * @param User $user
-        */
-       function compose( $user ) {
-               global $wgEnotifImpersonal;
-
-               if ( !$this->composed_common ) {
-                       $this->composeCommonMailtext();
-               }
-
-               if ( $wgEnotifImpersonal ) {
-                       $this->mailTargets[] = new MailAddress( $user );
-               } else {
-                       $this->sendPersonalised( $user );
-               }
-       }
-
-       /**
-        * Send any queued mails
-        */
-       function sendMails() {
-               global $wgEnotifImpersonal;
-               if ( $wgEnotifImpersonal ) {
-                       $this->sendImpersonal( $this->mailTargets );
-               }
-       }
-
-       /**
-        * Does the per-user customizations to a notification e-mail (name,
-        * timestamp in proper timezone, etc) and sends it out.
-        * Returns true if the mail was sent successfully.
-        *
-        * @param User $watchingUser
-        * @return bool
-        * @private
-        */
-       function sendPersonalised( $watchingUser ) {
-               global $wgContLang, $wgEnotifUseRealName;
-               // From the PHP manual:
-               //   Note: The to parameter cannot be an address in the form of
-               //   "Something <someone@example.com>". The mail command will not parse
-               //   this properly while talking with the MTA.
-               $to = new MailAddress( $watchingUser );
-
-               # $PAGEEDITDATE is the time and date of the page change
-               # expressed in terms of individual local time of the notification
-               # recipient, i.e. watching user
-               $body = str_replace(
-                       array( '$WATCHINGUSERNAME',
-                               '$PAGEEDITDATE',
-                               '$PAGEEDITTIME' ),
-                       array( $wgEnotifUseRealName && $watchingUser->getRealName() !== ''
-                                       ? $watchingUser->getRealName() : $watchingUser->getName(),
-                               $wgContLang->userDate( $this->timestamp, $watchingUser ),
-                               $wgContLang->userTime( $this->timestamp, $watchingUser ) ),
-                       $this->body );
-
-               return UserMailer::send( $to, $this->from, $this->subject, $body, $this->replyto );
-       }
-
-       /**
-        * Same as sendPersonalised but does impersonal mail suitable for bulk
-        * mailing.  Takes an array of MailAddress objects.
-        * @param MailAddress[] $addresses
-        * @return Status|null
-        */
-       function sendImpersonal( $addresses ) {
-               global $wgContLang;
-
-               if ( empty( $addresses ) ) {
-                       return null;
-               }
-
-               $body = str_replace(
-                               array( '$WATCHINGUSERNAME',
-                                       '$PAGEEDITDATE',
-                                       '$PAGEEDITTIME' ),
-                               array( wfMessage( 'enotif_impersonal_salutation' )->inContentLanguage()->text(),
-                                       $wgContLang->date( $this->timestamp, false, false ),
-                                       $wgContLang->time( $this->timestamp, false, false ) ),
-                               $this->body );
-
-               return UserMailer::send( $addresses, $this->from, $this->subject, $body, $this->replyto );
-       }
-
-} # end of class EmailNotification
index ffdf516..8d11d90 100644 (file)
@@ -351,7 +351,7 @@ abstract class Action {
                $out = $this->getOutput();
                $out->setRobotPolicy( "noindex,nofollow" );
                $out->setPageTitle( $this->getPageTitle() );
-               $this->getOutput()->setSubtitle( $this->getDescription() );
+               $out->setSubtitle( $this->getDescription() );
                $out->setArticleRelated( true );
        }
 
index 523da68..8522e56 100644 (file)
@@ -110,7 +110,7 @@ class HistoryAction extends FormlessAction {
                # Fill in the file cache if not set already
                $useFileCache = $config->get( 'UseFileCache' );
                if ( $useFileCache && HTMLFileCache::useFileCache( $this->getContext() ) ) {
-                       $cache = HTMLFileCache::newFromTitle( $this->getTitle(), 'history' );
+                       $cache = new HTMLFileCache( $this->getTitle(), 'history' );
                        if ( !$cache->isCacheGood( /* Assume up to date */ ) ) {
                                ob_start( array( &$cache, 'saveToFileCache' ) );
                        }
index cd4e4ba..d0d956e 100644 (file)
  * @ingroup Actions
  */
 class RawAction extends FormlessAction {
-       private $mGen;
+       /**
+        * @var bool Does the request include a gen=css|javascript parameter
+        * @deprecated This used to be a string for "css" or "javascript" but
+        * it is no longer used. Setting this parameter results in empty content
+        * being served
+        */
+       private $gen = false;
 
        public function getName() {
                return 'raw';
@@ -66,12 +72,10 @@ class RawAction extends FormlessAction {
                $smaxage = $request->getIntOrNull( 'smaxage' );
 
                if ( $gen == 'css' || $gen == 'js' ) {
-                       $this->mGen = $gen;
+                       $this->gen = true;
                        if ( $smaxage === null ) {
                                $smaxage = $config->get( 'SquidMaxage' );
                        }
-               } else {
-                       $this->mGen = false;
                }
 
                $contentType = $this->getContentType();
@@ -130,7 +134,7 @@ class RawAction extends FormlessAction {
                global $wgParser;
 
                # No longer used
-               if ( $this->mGen ) {
+               if ( $this->gen ) {
                        return '';
                }
 
index d35b848..9870b2d 100644 (file)
@@ -40,7 +40,11 @@ class ApiEmailUser extends ApiBase {
                }
 
                // Check permissions and errors
-               $error = SpecialEmailUser::getPermissionsError( $this->getUser(), $params['token'] );
+               $error = SpecialEmailUser::getPermissionsError(
+                       $this->getUser(),
+                       $params['token'],
+                       $this->getConfig()
+               );
                if ( $error ) {
                        $this->dieUsageMsg( array( $error ) );
                }
index 3497c8e..bd20b14 100644 (file)
@@ -783,12 +783,14 @@ class ApiMain extends ApiBase {
                                $this->dieUsageMsg( array( 'missingparam', 'token' ) );
                        }
 
-                       if ( array_key_exists(
-                               $module->encodeParamName( 'token' ),
-                               $this->getRequest()->getQueryValues()
-                       ) ) {
+                       if ( !$this->getConfig()->get( 'DebugAPI' ) &&
+                               array_key_exists(
+                                       $module->encodeParamName( 'token' ),
+                                       $this->getRequest()->getQueryValues()
+                               )
+                       ) {
                                $this->dieUsage(
-                                       "The '{$module->encodeParamName( 'token' )}' parameter must be POSTed",
+                                       "The '{$module->encodeParamName( 'token' )}' parameter was found in the query string, but must be in the POST body",
                                        'mustposttoken'
                                );
                        }
index 3d6372c..7c750e4 100644 (file)
@@ -47,17 +47,20 @@ class ApiQuery extends ApiBase {
                'contributors' => 'ApiQueryContributors',
                'duplicatefiles' => 'ApiQueryDuplicateFiles',
                'extlinks' => 'ApiQueryExternalLinks',
+               'fileusage' => 'ApiQueryBacklinksprop',
                'images' => 'ApiQueryImages',
                'imageinfo' => 'ApiQueryImageInfo',
                'info' => 'ApiQueryInfo',
                'links' => 'ApiQueryLinks',
+               'linkshere' => 'ApiQueryBacklinksprop',
                'iwlinks' => 'ApiQueryIWLinks',
                'langlinks' => 'ApiQueryLangLinks',
                'pageprops' => 'ApiQueryPageProps',
-               'redirects' => 'ApiQueryRedirects',
+               'redirects' => 'ApiQueryBacklinksprop',
                'revisions' => 'ApiQueryRevisions',
                'stashimageinfo' => 'ApiQueryStashImageInfo',
                'templates' => 'ApiQueryLinks',
+               'transcludedin' => 'ApiQueryBacklinksprop',
        );
 
        /**
@@ -526,6 +529,7 @@ class ApiQuery extends ApiBase {
                        'exportnowrap' => false,
                        'iwurl' => false,
                        'continue' => null,
+                       'rawcontinue' => false,
                );
                if ( $flags ) {
                        $result += $this->getPageSet()->getFinalParams( $flags );
@@ -608,6 +612,8 @@ class ApiQuery extends ApiBase {
                                'This parameter is recommended for all new development, and ' .
                                        'will be made default in the next API version.'
                        ),
+                       'rawcontinue' => 'Currently ignored. In the future, \'continue=\' will become the ' .
+                               'default and this will be needed to receive the raw query-continue data.',
                );
        }
 
index dfef286..d241311 100644 (file)
@@ -111,35 +111,18 @@ class ApiQueryAllUsers extends ApiQueryBase {
                        }
                }
 
-               if ( !is_null( $params['group'] ) && !is_null( $params['excludegroup'] ) ) {
-                       $this->dieUsage( 'group and excludegroup cannot be used together', 'group-excludegroup' );
-               }
-
                if ( !is_null( $params['group'] ) && count( $params['group'] ) ) {
-                       $useIndex = false;
                        // Filter only users that belong to a given group
-                       $this->addTables( 'user_groups', 'ug1' );
-                       $this->addJoinConds( array( 'ug1' => array( 'INNER JOIN', array( 'ug1.ug_user=user_id',
-                               'ug1.ug_group' => $params['group'] ) ) ) );
+                       $this->addWhere( 'EXISTS (' . $db->selectSQLText(
+                               'user_groups', '1', array( 'ug_user=user_id', 'ug_group' => $params['group'] )
+                       ) . ')' );
                }
 
                if ( !is_null( $params['excludegroup'] ) && count( $params['excludegroup'] ) ) {
-                       $useIndex = false;
                        // Filter only users don't belong to a given group
-                       $this->addTables( 'user_groups', 'ug1' );
-
-                       if ( count( $params['excludegroup'] ) == 1 ) {
-                               $exclude = array( 'ug1.ug_group' => $params['excludegroup'][0] );
-                       } else {
-                               $exclude = array( $db->makeList(
-                                       array( 'ug1.ug_group' => $params['excludegroup'] ),
-                                       LIST_OR
-                               ) );
-                       }
-                       $this->addJoinConds( array( 'ug1' => array( 'LEFT OUTER JOIN',
-                               array_merge( array( 'ug1.ug_user=user_id' ), $exclude )
-                       ) ) );
-                       $this->addWhere( 'ug1.ug_user IS NULL' );
+                       $this->addWhere( 'NOT EXISTS (' . $db->selectSQLText(
+                               'user_groups', '1', array( 'ug_user=user_id', 'ug_group' => $params['excludegroup'] )
+                       ) . ')' );
                }
 
                if ( $params['witheditsonly'] ) {
@@ -156,7 +139,7 @@ class ApiQueryAllUsers extends ApiQueryBase {
 
                        $this->addTables( 'user_groups', 'ug2' );
                        $this->addJoinConds( array( 'ug2' => array( 'LEFT JOIN', 'ug2.ug_user=user_id' ) ) );
-                       $this->addFields( 'ug2.ug_group ug_group2' );
+                       $this->addFields( array( 'ug_group2' => 'ug2.ug_group' ) );
                } else {
                        $sqlLimit = $limit + 1;
                }
@@ -256,6 +239,7 @@ class ApiQueryAllUsers extends ApiQueryBase {
                                        $lastUserData['blockid'] = $row->ipb_id;
                                        $lastUserData['blockedby'] = $row->ipb_by_text;
                                        $lastUserData['blockedbyid'] = $row->ipb_by;
+                                       $lastUserData['blockedtimestamp'] = wfTimestamp( TS_ISO_8601, $row->ipb_timestamp );
                                        $lastUserData['blockreason'] = $row->ipb_reason;
                                        $lastUserData['blockexpiry'] = $row->ipb_expiry;
                                }
diff --git a/includes/api/ApiQueryBacklinksprop.php b/includes/api/ApiQueryBacklinksprop.php
new file mode 100644 (file)
index 0000000..cd68261
--- /dev/null
@@ -0,0 +1,472 @@
+<?php
+/**
+ * API module to handle links table back-queries
+ *
+ * Created on Aug 19, 2014
+ *
+ * Copyright © 2014 Brad Jorsch <bjorsch@wikimedia.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * @file
+ * @since 1.24
+ */
+
+/**
+ * This implements prop=redirects, prop=linkshere, prop=catmembers,
+ * prop=transcludedin, and prop=fileusage
+ *
+ * @ingroup API
+ * @since 1.24
+ */
+class ApiQueryBacklinksprop extends ApiQueryGeneratorBase {
+
+       // Data for the various modules implemented by this class
+       private static $settings = array(
+               'redirects' => array(
+                       'code' => 'rd',
+                       'prefix' => 'rd',
+                       'linktable' => 'redirect',
+                       'what' => 'redirects to',
+                       'description' => 'Returns all redirects to the given pages.',
+                       'props' => array(
+                               'fragment' => 'Fragment of each redirect, if any',
+                       ),
+                       'showredirects' => false,
+                       'show' => array(
+                               'fragment' => 'Only show redirects with a fragment',
+                               '!fragment' => 'Only show redirects without a fragment',
+                       ),
+               ),
+               'linkshere' => array(
+                       'code' => 'lh',
+                       'prefix' => 'pl',
+                       'linktable' => 'pagelinks',
+                       'from_namespace' => true,
+                       'what' => 'pages linking to',
+                       'description' => 'Find all pages that link to the given pages.',
+                       'showredirects' => true,
+               ),
+               'transcludedin' => array(
+                       'code' => 'ti',
+                       'prefix' => 'tl',
+                       'linktable' => 'templatelinks',
+                       'from_namespace' => true,
+                       'what' => 'pages transcluding',
+                       'description' => 'Find all pages that transclude the given pages.',
+                       'showredirects' => true,
+               ),
+               'fileusage' => array(
+                       'code' => 'fu',
+                       'prefix' => 'il',
+                       'linktable' => 'imagelinks',
+                       'from_namespace' => true,
+                       'to_namespace' => NS_FILE,
+                       'what' => 'pages using',
+                       'exampletitle' => 'File:Example.jpg',
+                       'description' => 'Find all pages that use the given files.',
+                       'showredirects' => true,
+               ),
+       );
+
+       public function __construct( ApiQuery $query, $moduleName ) {
+               parent::__construct( $query, $moduleName, self::$settings[$moduleName]['code'] );
+       }
+
+       public function execute() {
+               $this->run();
+       }
+
+       public function executeGenerator( $resultPageSet ) {
+               $this->run( $resultPageSet );
+       }
+
+       /**
+        * @param ApiPageSet $resultPageSet
+        */
+       private function run( ApiPageSet $resultPageSet = null ) {
+               $settings = self::$settings[$this->getModuleName()];
+
+               $db = $this->getDB();
+               $params = $this->extractRequestParams();
+               $prop = array_flip( $params['prop'] );
+               $emptyString = $db->addQuotes( '' );
+
+               $pageSet = $this->getPageSet();
+               $titles = $pageSet->getGoodTitles() + $pageSet->getMissingTitles();
+               $map = $pageSet->getAllTitlesByNamespace();
+
+               // Determine our fields to query on
+               $p = $settings['prefix'];
+               $hasNS = !isset( $settings['to_namespace'] );
+               if ( $hasNS ) {
+                       $bl_namespace = "{$p}_namespace";
+                       $bl_title = "{$p}_title";
+               } else {
+                       $bl_namespace = $settings['to_namespace'];
+                       $bl_title = "{$p}_to";
+
+                       $titles = array_filter( $titles, function ( $t ) use ( $bl_namespace ) {
+                               return $t->getNamespace() === $bl_namespace;
+                       } );
+                       $map = array_intersect_key( $map, array( $bl_namespace => true ) );
+               }
+               $bl_from = "{$p}_from";
+
+               if ( !$titles ) {
+                       return; // nothing to do
+               }
+
+               // Figure out what we're sorting by, and add associated WHERE clauses.
+               // MySQL's query planner screws up if we include a field in ORDER BY
+               // when it's constant in WHERE, so we have to test that for each field.
+               $sortby = array();
+               if ( $hasNS && count( $map ) > 1 ) {
+                       $sortby[$bl_namespace] = 'ns';
+               }
+               $theTitle = null;
+               foreach ( $map as $nsTitles ) {
+                       reset( $nsTitles );
+                       $key = key( $nsTitles );
+                       if ( $theTitle === null ) {
+                               $theTitle = $key;
+                       }
+                       if ( count( $nsTitles ) > 1 || $key !== $theTitle ) {
+                               $sortby[$bl_title] = 'title';
+                               break;
+                       }
+               }
+               $miser_ns = null;
+               if ( $params['namespace'] !== null ) {
+                       if ( empty( $settings['from_namespace'] ) && $this->getConfig()->get( 'MiserMode' ) ) {
+                               $miser_ns = $params['namespace'];
+                       } else {
+                               $this->addWhereFld( "{$p}_from_namespace", $params['namespace'] );
+                               if ( !empty( $settings['from_namespace'] ) && count( $params['namespace'] ) > 1 ) {
+                                       $sortby["{$p}_from_namespace"] = 'int';
+                               }
+                       }
+               }
+               $sortby[$bl_from] = 'int';
+
+               // Now use the $sortby to figure out the continuation
+               if ( !is_null( $params['continue'] ) ) {
+                       $cont = explode( '|', $params['continue'] );
+                       $this->dieContinueUsageIf( count( $cont ) != count( $sortby ) );
+                       $where = '';
+                       $i = count( $sortby ) - 1;
+                       $cont_ns = 0;
+                       $cont_title = '';
+                       foreach ( array_reverse( $sortby, true ) as $field => $type ) {
+                               $v = $cont[$i];
+                               switch ( $type ) {
+                                       case 'ns':
+                                               $cont_ns = (int)$v;
+                                               /* fall through */
+                                       case 'int':
+                                               $v = (int)$v;
+                                               $this->dieContinueUsageIf( $v != $cont[$i] );
+                                               break;
+
+                                       case 'title':
+                                               $cont_title = $v;
+                                               /* fall through */
+                                       default:
+                                               $v = $db->addQuotes( $v );
+                                               break;
+                               }
+
+                               if ( $where === '' ) {
+                                       $where = "$field >= $v";
+                               } else {
+                                       $where = "$field > $v OR ($field = $v AND ($where))";
+                               }
+
+                               $i--;
+                       }
+                       $this->addWhere( $where );
+               }
+
+               // Populate the rest of the query
+               $this->addTables( array( $settings['linktable'], 'page' ) );
+               $this->addWhere( "$bl_from = page_id" );
+
+               if ( $this->getModuleName() === 'redirects' ) {
+                       $this->addWhere( "rd_interwiki = $emptyString OR rd_interwiki IS NULL" );
+               }
+
+               $this->addFields( array_keys( $sortby ) );
+               $this->addFields( array( 'bl_namespace' => $bl_namespace, 'bl_title' => $bl_title ) );
+               if ( is_null( $resultPageSet ) ) {
+                       $fld_pageid = isset( $prop['pageid'] );
+                       $fld_title = isset( $prop['title'] );
+                       $fld_redirect = isset( $prop['redirect'] );
+
+                       $this->addFieldsIf( 'page_id', $fld_pageid );
+                       $this->addFieldsIf( array( 'page_title', 'page_namespace' ), $fld_title );
+                       $this->addFieldsIf( 'page_is_redirect', $fld_redirect );
+
+                       // prop=redirects
+                       $fld_fragment = isset( $prop['fragment'] );
+                       $this->addFieldsIf( 'rd_fragment', $fld_fragment );
+               } else {
+                       $this->addFields( $resultPageSet->getPageTableFields() );
+               }
+
+               $this->addFieldsIf( 'page_namespace', $miser_ns !== null );
+
+               if ( $hasNS ) {
+                       $lb = new LinkBatch( $titles );
+                       $this->addWhere( $lb->constructSet( $p, $db ) );
+               } else {
+                       $where = array();
+                       foreach ( $titles as $t ) {
+                               if ( $t->getNamespace() == $bl_namespace ) {
+                                       $where[] = "$bl_title = " . $db->addQuotes( $t->getDBkey() );
+                               }
+                       }
+                       $this->addWhere( $db->makeList( $where, LIST_OR ) );
+               }
+
+               if ( $params['show'] !== null ) {
+                       // prop=redirects only
+                       $show = array_flip( $params['show'] );
+                       if ( isset( $show['fragment'] ) && isset( $show['!fragment'] ) ||
+                               isset( $show['redirect'] ) && isset( $show['!redirect'] )
+                       ) {
+                               $this->dieUsageMsg( 'show' );
+                       }
+                       $this->addWhereIf( "rd_fragment != $emptyString", isset( $show['fragment'] ) );
+                       $this->addWhereIf(
+                               "rd_fragment = $emptyString OR rd_fragment IS NULL",
+                               isset( $show['!fragment'] )
+                       );
+                       $this->addWhereIf( array( 'page_is_redirect' => 1 ), isset( $show['redirect'] ) );
+                       $this->addWhereIf( array( 'page_is_redirect' => 0 ), isset( $show['!redirect'] ) );
+               }
+
+               // Override any ORDER BY from above with what we calculated earlier.
+               $this->addOption( 'ORDER BY', array_keys( $sortby ) );
+
+               $this->addOption( 'LIMIT', $params['limit'] + 1 );
+
+               $res = $this->select( __METHOD__ );
+
+               if ( is_null( $resultPageSet ) ) {
+                       $count = 0;
+                       foreach ( $res as $row ) {
+                               if ( ++$count > $params['limit'] ) {
+                                       // We've reached the one extra which shows that
+                                       // there are additional pages to be had. Stop here...
+                                       $this->setContinue( $row, $sortby );
+                                       break;
+                               }
+
+                               if ( $miser_ns !== null && !in_array( $row->page_namespace, $miser_ns ) ) {
+                                       // Miser mode namespace check
+                                       continue;
+                               }
+
+                               // Get the ID of the current page
+                               $id = $map[$row->bl_namespace][$row->bl_title];
+
+                               $vals = array();
+                               if ( $fld_pageid ) {
+                                       $vals['pageid'] = $row->page_id;
+                               }
+                               if ( $fld_title ) {
+                                       ApiQueryBase::addTitleInfo( $vals,
+                                               Title::makeTitle( $row->page_namespace, $row->page_title )
+                                       );
+                               }
+                               if ( $fld_fragment && $row->rd_fragment !== null && $row->rd_fragment !== '' ) {
+                                       $vals['fragment'] = $row->rd_fragment;
+                               }
+                               if ( $fld_redirect && $row->page_is_redirect ) {
+                                       $vals['redirect'] = '';
+                               }
+                               $fit = $this->addPageSubItem( $id, $vals );
+                               if ( !$fit ) {
+                                       $this->setContinue( $row, $sortby );
+                                       break;
+                               }
+                       }
+               } else {
+                       $titles = array();
+                       $count = 0;
+                       foreach ( $res as $row ) {
+                               if ( ++$count > $params['limit'] ) {
+                                       // We've reached the one extra which shows that
+                                       // there are additional pages to be had. Stop here...
+                                       $this->setContinue( $row, $sortby );
+                                       break;
+                               }
+                               $titles[] = Title::makeTitle( $row->page_namespace, $row->page_title );
+                       }
+                       $resultPageSet->populateFromTitles( $titles );
+               }
+       }
+
+       private function setContinue( $row, $sortby ) {
+               $cont = array();
+               foreach ( $sortby as $field => $v ) {
+                       $cont[] = $row->$field;
+               }
+               $this->setContinueEnumParameter( 'continue', join( '|', $cont ) );
+       }
+
+       public function getCacheMode( $params ) {
+               return 'public';
+       }
+
+       public function getAllowedParams() {
+               $settings = self::$settings[$this->getModuleName()];
+
+               $ret = array(
+                       'prop' => array(
+                               ApiBase::PARAM_TYPE => array(
+                                       'pageid',
+                                       'title',
+                               ),
+                               ApiBase::PARAM_ISMULTI => true,
+                               ApiBase::PARAM_DFLT => 'pageid|title',
+                       ),
+                       'namespace' => array(
+                               ApiBase::PARAM_ISMULTI => true,
+                               ApiBase::PARAM_TYPE => 'namespace',
+                       ),
+                       'limit' => array(
+                               ApiBase::PARAM_DFLT => 10,
+                               ApiBase::PARAM_TYPE => 'limit',
+                               ApiBase::PARAM_MIN => 1,
+                               ApiBase::PARAM_MAX => ApiBase::LIMIT_BIG1,
+                               ApiBase::PARAM_MAX2 => ApiBase::LIMIT_BIG2
+                       ),
+                       'continue' => null,
+               );
+
+               if ( !empty( $settings['showredirects'] ) ) {
+                       $ret['prop'][ApiBase::PARAM_TYPE][] = 'redirect';
+                       $ret['prop'][ApiBase::PARAM_DFLT] .= '|redirect';
+               }
+               if ( isset( $settings['props'] ) ) {
+                       $ret['prop'][ApiBase::PARAM_TYPE] = array_merge(
+                               $ret['prop'][ApiBase::PARAM_TYPE], array_keys( $settings['props'] )
+                       );
+               }
+
+               $show = array();
+               if ( !empty( $settings['showredirects'] ) ) {
+                       $show[] = 'redirect';
+                       $show[] = '!redirect';
+               }
+               if ( isset( $settings['show'] ) ) {
+                       $show = array_merge( $show, array_keys( $settings['show'] ) );
+               }
+               if ( $show ) {
+                       $ret['show'] = array(
+                               ApiBase::PARAM_TYPE => $show,
+                               ApiBase::PARAM_ISMULTI => true,
+                       );
+               }
+
+               return $ret;
+       }
+
+       public function getParamDescription() {
+               $settings = self::$settings[$this->getModuleName()];
+               $p = $this->getModulePrefix();
+
+               $ret = array(
+                       'prop' => array(
+                               'Which properties to get:',
+                       ),
+                       'show' => array(
+                               'Show only items that meet this criteria.',
+                       ),
+                       'namespace' => 'Only include pages in these namespaces',
+                       'limit' => 'How many to return',
+                       'continue' => 'When more results are available, use this to continue',
+               );
+
+               if ( empty( $settings['from_namespace'] ) && $this->getConfig()->get( 'MiserMode' ) ) {
+                       $ret['namespace'] = array(
+                               $ret['namespace'],
+                               "NOTE: Due to \$wgMiserMode, using this may result in fewer than \"{$p}limit\" results",
+                               'returned before continuing; in extreme cases, zero results may be returned.',
+                       );
+                       if ( isset( $ret['type'] ) ) {
+                               $ret['namespace'][] = "Note that you can use {$p}type=subcat or {$p}type=file " .
+                                       "instead of {$p}namespace=14 or 6.";
+                       }
+               }
+
+               $props = array(
+                       'pageid' => 'Adds the ID of page',
+                       'title' => 'Adds the title and namespace ID of the page',
+               );
+               if ( !empty( $settings['showredirects'] ) ) {
+                       $props['redirect'] = 'Indicate if the page is a redirect';
+               }
+               if ( isset( $settings['props'] ) ) {
+                       $props += $settings['props'];
+               }
+               foreach ( $props as $k => $v ) {
+                       $ret['props'][] = sprintf( "%-9s - %s", $k, $v );
+               }
+
+               $show = array();
+               if ( !empty( $settings['showredirects'] ) ) {
+                       $show += array(
+                               'redirect' => 'Only show redirects',
+                               '!redirect' => 'Only show non-redirects',
+                       );
+               }
+               if ( isset( $settings['show'] ) ) {
+                       $show += $settings['show'];
+               }
+               foreach ( $show as $k => $v ) {
+                       $ret['show'][] = sprintf( "%-9s - %s", $k, $v );
+               }
+
+               return $ret;
+       }
+
+       public function getDescription() {
+               return self::$settings[$this->getModuleName()]['description'];
+       }
+
+       public function getExamples() {
+               $settings = self::$settings[$this->getModuleName()];
+               $name = $this->getModuleName();
+               $what = $settings['what'];
+               $title = isset( $settings['exampletitle'] ) ? $settings['exampletitle'] : 'Main Page';
+               $etitle = rawurlencode( $title );
+
+               return array(
+                       "api.php?action=query&prop={$name}&titles={$etitle}"
+                               => "Get a list of $what [[$title]]",
+                       "api.php?action=query&generator={$name}&titles={$etitle}&prop=info"
+                               => "Get information about $what [[$title]]",
+               );
+       }
+
+       public function getHelpUrls() {
+               $name = $this->getModuleName();
+               $prefix = $this->getModulePrefix();
+               return "https://www.mediawiki.org/wiki/API:Properties#{$name}_.2F_{$prefix}";
+       }
+}
index 6b08fc5..65e10ab 100644 (file)
@@ -414,7 +414,7 @@ abstract class ApiQueryBase extends ApiBase {
                $this->addFields( 'ipb_deleted' );
 
                if ( $showBlockInfo ) {
-                       $this->addFields( array( 'ipb_id', 'ipb_by', 'ipb_by_text', 'ipb_reason', 'ipb_expiry' ) );
+                       $this->addFields( array( 'ipb_id', 'ipb_by', 'ipb_by_text', 'ipb_reason', 'ipb_expiry', 'ipb_timestamp' ) );
                }
 
                // Don't show hidden names
index 17badb1..a88a9cb 100644 (file)
@@ -140,12 +140,22 @@ class ApiQueryCategoryMembers extends ApiQueryGeneratorBase {
                                $this->addWhereRange( 'cl_sortkey', $dir, null, null );
                                $this->addWhereRange( 'cl_from', $dir, null, null );
                        } else {
-                               $startsortkey = $params['startsortkeyprefix'] !== null ?
-                                       Collation::singleton()->getSortkey( $params['startsortkeyprefix'] ) :
-                                       $params['startsortkey'];
-                               $endsortkey = $params['endsortkeyprefix'] !== null ?
-                                       Collation::singleton()->getSortkey( $params['endsortkeyprefix'] ) :
-                                       $params['endsortkey'];
+                               if ( $params['startsortkeyprefix'] !== null ) {
+                                       $startsortkey = Collation::singleton()->getSortkey( $params['startsortkeyprefix'] );
+                               } elseif ( $params['starthexsortkey'] !== null ) {
+                                       $startsortkey = pack( 'H*', $params['starthexsortkey'] );
+                               } else {
+                                       $this->logFeatureUsage( 'list=categorymembers&cmstartsortkey' );
+                                       $startsortkey = $params['startsortkey'];
+                               }
+                               if ( $params['endsortkeyprefix'] !== null ) {
+                                       $endsortkey = Collation::singleton()->getSortkey( $params['endsortkeyprefix'] );
+                               } elseif ( $params['endhexsortkey'] !== null ) {
+                                       $endsortkey = pack( 'H*', $params['endhexsortkey'] );
+                               } else {
+                                       $this->logFeatureUsage( 'list=categorymembers&cmendsortkey' );
+                                       $endsortkey = $params['endsortkey'];
+                               }
 
                                // The below produces ORDER BY cl_sortkey, cl_from, possibly with DESC added to each of them
                                $this->addWhereRange( 'cl_sortkey',
@@ -330,10 +340,16 @@ class ApiQueryCategoryMembers extends ApiQueryGeneratorBase {
                        'end' => array(
                                ApiBase::PARAM_TYPE => 'timestamp'
                        ),
-                       'startsortkey' => null,
-                       'endsortkey' => null,
+                       'starthexsortkey' => null,
+                       'endhexsortkey' => null,
                        'startsortkeyprefix' => null,
                        'endsortkeyprefix' => null,
+                       'startsortkey' => array(
+                               ApiBase::PARAM_DEPRECATED => true,
+                       ),
+                       'endsortkey' => array(
+                               ApiBase::PARAM_DEPRECATED => true,
+                       ),
                );
        }
 
@@ -359,15 +375,17 @@ class ApiQueryCategoryMembers extends ApiQueryGeneratorBase {
                        'dir' => 'In which direction to sort',
                        'start' => "Timestamp to start listing from. Can only be used with {$p}sort=timestamp",
                        'end' => "Timestamp to end listing at. Can only be used with {$p}sort=timestamp",
-                       'startsortkey' => "Sortkey to start listing from. Must be given in " .
-                               "binary format. Can only be used with {$p}sort=sortkey",
-                       'endsortkey' => "Sortkey to end listing at. Must be given in binary " .
-                               "format. Can only be used with {$p}sort=sortkey",
+                       'starthexsortkey' => "Sortkey to start listing from, as returned by prop=sortkey. " .
+                               "Can only be used with {$p}sort=sortkey",
+                       'endhexsortkey' => "Sortkey to end listing from, as returned by prop=sortkey. " .
+                               "Can only be used with {$p}sort=sortkey",
                        'startsortkeyprefix' => "Sortkey prefix to start listing from. Can " .
-                               "only be used with {$p}sort=sortkey. Overrides {$p}startsortkey",
+                               "only be used with {$p}sort=sortkey. Overrides {$p}starthexsortkey",
                        'endsortkeyprefix' => "Sortkey prefix to end listing BEFORE (not at, " .
                                "if this value occurs it will not be included!). Can only be used with " .
-                               "{$p}sort=sortkey. Overrides {$p}endsortkey",
+                               "{$p}sort=sortkey. Overrides {$p}endhexsortkey",
+                       'startsortkey' => "Use starthexsortkey instead",
+                       'endsortkey' => "Use endhexsortkey instead",
                        'continue' => 'For large categories, give the value returned from previous query',
                        'limit' => 'The maximum number of pages to return.',
                );
index 5cc1454..945374b 100644 (file)
@@ -237,9 +237,11 @@ class ApiQueryImageInfo extends ApiQueryBase {
                        $scale = array();
                        $scale['height'] = $params['urlheight'];
                } else {
-                       $scale = null;
                        if ( $params['urlparam'] ) {
-                               $this->dieUsage( "{$p}urlparam requires {$p}urlwidth", "urlparam_no_width" );
+                               // Audio files might not have a width/height.
+                               $scale = array();
+                       } else {
+                               $scale = null;
                        }
                }
 
@@ -256,6 +258,10 @@ class ApiQueryImageInfo extends ApiQueryBase {
         * @return array Array of parameters for transform.
         */
        protected function mergeThumbParams( $image, $thumbParams, $otherParams ) {
+               if ( $thumbParams === null ) {
+                       // No scaling requested
+                       return null;
+               }
                if ( !isset( $thumbParams['width'] ) && isset( $thumbParams['height'] ) ) {
                        // We want to limit only by height in this situation, so pass the
                        // image's full width as the limiting width. But some file types
@@ -269,6 +275,7 @@ class ApiQueryImageInfo extends ApiQueryBase {
                }
 
                if ( !$otherParams ) {
+                       $this->checkParameterNormalise( $image, $thumbParams );
                        return $thumbParams;
                }
                $p = $this->getModulePrefix();
@@ -289,11 +296,11 @@ class ApiQueryImageInfo extends ApiQueryBase {
                        // handlers.
                        $this->setWarning( "Could not parse {$p}urlparam for " . $image->getName()
                                . '. Using only width and height' );
-
+                       $this->checkParameterNormalise( $image, $thumbParams );
                        return $thumbParams;
                }
 
-               if ( isset( $paramList['width'] ) ) {
+               if ( isset( $paramList['width'] ) && isset( $thumbParams['width'] ) ) {
                        if ( intval( $paramList['width'] ) != intval( $thumbParams['width'] ) ) {
                                $this->setWarning( "Ignoring width value set in {$p}urlparam ({$paramList['width']}) "
                                        . "in favor of width value derived from {$p}urlwidth/{$p}urlheight "
@@ -307,7 +314,33 @@ class ApiQueryImageInfo extends ApiQueryBase {
                        }
                }
 
-               return $thumbParams + $paramList;
+               $finalParams = $thumbParams + $paramList;
+               $this->checkParameterNormalise( $image, $finalParams );
+               return $finalParams;
+       }
+
+       /**
+        * Verify that the final image parameters can be normalised.
+        *
+        * This doesn't use the normalised parameters, since $file->transform
+        * expects the pre-normalised parameters, but doing the normalisation
+        * allows us to catch certain error conditions early (such as missing
+        * required parameter).
+        *
+        * @param $image File
+        * @param $finalParams array List of parameters to transform image with
+        */
+       protected function checkParameterNormalise( $image, $finalParams ) {
+               $h = $image->getHandler();
+               if ( !$h ) {
+                       return;
+               }
+               // Note: normaliseParams modifies the array in place, but we aren't interested
+               // in the actual normalised version, only if we can actually normalise them,
+               // so we use the functions scope to throw away the normalisations.
+               if ( !$h->normaliseParams( $image, $finalParams ) ) {
+                       $this->dieUsage( "Could not normalise image parameters for " . $image->getName(), "urlparamnormal" );
+               }
        }
 
        /**
@@ -391,6 +424,13 @@ class ApiQueryImageInfo extends ApiQueryBase {
                        if ( $pageCount !== false ) {
                                $vals['pagecount'] = $pageCount;
                        }
+
+                       // length as in how many seconds long a video is.
+                       $length = $file->getLength();
+                       if ( $length ) {
+                               // Call it duration, because "length" can be ambiguous.
+                               $vals['duration'] = (float)$length;
+                       }
                }
 
                $pcomment = isset( $prop['parsedcomment'] );
@@ -666,8 +706,8 @@ class ApiQueryImageInfo extends ApiQueryBase {
                        'parsedcomment' =>  ' parsedcomment - Parse the comment on the version',
                        'canonicaltitle' => ' canonicaltitle - Adds the canonical title of the image file',
                        'url' =>            ' url           - Gives URL to the image and the description page',
-                       'size' =>           ' size          - Adds the size of the image in bytes ' .
-                               'and the height, width and page count (if applicable)',
+                       'size' =>           ' size          - Adds the size of the image in bytes, ' .
+                               'its height and its width. Page count and duration are added if applicable',
                        'dimensions' =>     ' dimensions    - Alias for size', // B/C with Allimages
                        'sha1' =>           ' sha1          - Adds SHA-1 hash for the image',
                        'mime' =>           ' mime          - Adds MIME type of the image',
@@ -716,8 +756,10 @@ class ApiQueryImageInfo extends ApiQueryBase {
                                        'no more than ' . self::TRANSFORM_LIMIT . ' scaled images will be returned.'
                        ),
                        'urlheight' => "Similar to {$p}urlwidth.",
-                       'urlparam' => array( "A handler specific parameter string. For example, pdf's ",
-                               "might use 'page15-100px'. {$p}urlwidth must be used and be consistent with {$p}urlparam" ),
+                       'urlparam' => array(
+                               "A handler specific parameter string. For example, pdf's ",
+                               "might use 'page15-100px'."
+                       ),
                        'limit' => 'How many image revisions to return per image',
                        'start' => 'Timestamp to start listing from',
                        'end' => 'Timestamp to stop listing at',
diff --git a/includes/api/ApiQueryRedirects.php b/includes/api/ApiQueryRedirects.php
deleted file mode 100644 (file)
index afb2c56..0000000
+++ /dev/null
@@ -1,270 +0,0 @@
-<?php
-/**
- * API module to return redirects to a page
- *
- * Created on Dec 30, 2013
- *
- * Copyright © 2013 Brad Jorsch <bjorsch@wikimedia.org>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- * http://www.gnu.org/copyleft/gpl.html
- *
- * @file
- * @since 1.23
- */
-
-/**
- * This query lists redirects to the given pages.
- *
- * @ingroup API
- */
-class ApiQueryRedirects extends ApiQueryGeneratorBase {
-
-       public function __construct( ApiQuery $query, $moduleName ) {
-               parent::__construct( $query, $moduleName, 'rd' );
-       }
-
-       public function execute() {
-               $this->run();
-       }
-
-       public function executeGenerator( $resultPageSet ) {
-               $this->run( $resultPageSet );
-       }
-
-       /**
-        * @param ApiPageSet $resultPageSet
-        */
-       private function run( ApiPageSet $resultPageSet = null ) {
-               $db = $this->getDB();
-               $params = $this->extractRequestParams();
-               $emptyString = $db->addQuotes( '' );
-
-               $pageSet = $this->getPageSet();
-               $titles = $pageSet->getGoodTitles() + $pageSet->getMissingTitles();
-
-               if ( !is_null( $params['continue'] ) ) {
-                       $cont = explode( '|', $params['continue'] );
-                       $this->dieContinueUsageIf( count( $cont ) != 3 );
-                       $rd_namespace = (int)$cont[0];
-                       $this->dieContinueUsageIf( $rd_namespace != $cont[0] );
-                       $rd_title = $db->addQuotes( $cont[1] );
-                       $rd_from = (int)$cont[2];
-                       $this->dieContinueUsageIf( $rd_from != $cont[2] );
-                       $this->addWhere(
-                               "rd_namespace > $rd_namespace OR " .
-                               "(rd_namespace = $rd_namespace AND " .
-                               "(rd_title > $rd_title OR " .
-                               "(rd_title = $rd_title AND " .
-                               "rd_from >= $rd_from)))"
-                       );
-
-                       // Remove titles that we're past already
-                       $titles = array_filter( $titles, function ( $t ) use ( $rd_namespace, $rd_title ) {
-                               $ns = $t->getNamespace();
-                               return ( $ns > $rd_namespace ||
-                                       $ns == $rd_namespace && $t->getDBKey() >= $rd_title
-                               );
-                       } );
-               }
-
-               if ( !$titles ) {
-                       return; // nothing to do
-               }
-
-               $this->addTables( array( 'redirect', 'page' ) );
-               $this->addFields( array(
-                       'rd_from',
-                       'rd_namespace',
-                       'rd_title',
-               ) );
-
-               if ( is_null( $resultPageSet ) ) {
-                       $prop = array_flip( $params['prop'] );
-                       $fld_pageid = isset( $prop['pageid'] );
-                       $fld_title = isset( $prop['title'] );
-                       $fld_fragment = isset( $prop['fragment'] );
-
-                       $this->addFieldsIf( 'rd_fragment', $fld_fragment );
-                       $this->addFieldsIf( array( 'page_namespace', 'page_title' ), $fld_title );
-               } else {
-                       $this->addFields( array( 'page_namespace', 'page_title' ) );
-               }
-
-               $lb = new LinkBatch( $titles );
-               $this->addWhere( array(
-                       'rd_from = page_id',
-                       "rd_interwiki = $emptyString OR rd_interwiki IS NULL",
-                       $lb->constructSet( 'rd', $db ),
-               ) );
-
-               if ( $params['show'] !== null ) {
-                       $show = array_flip( $params['show'] );
-                       if ( isset( $show['fragment'] ) && isset( $show['!fragment'] ) ) {
-                               $this->dieUsageMsg( 'show' );
-                       }
-                       $this->addWhereIf( "rd_fragment != $emptyString", isset( $show['fragment'] ) );
-                       $this->addWhereIf(
-                               "rd_fragment = $emptyString OR rd_fragment IS NULL",
-                               isset( $show['!fragment'] )
-                       );
-               }
-
-               $map = $pageSet->getAllTitlesByNamespace();
-
-               // Why, MySQL? Why do you do this to us?
-               $sortby = array();
-               if ( count( $map ) > 1 ) {
-                       $sortby[] = 'rd_namespace';
-               }
-               $theTitle = null;
-               foreach ( $map as $nsTitles ) {
-                       reset( $nsTitles );
-                       $key = key( $nsTitles );
-                       if ( $theTitle === null ) {
-                               $theTitle = $key;
-                       }
-                       if ( count( $nsTitles ) > 1 || $key !== $theTitle ) {
-                               $sortby[] = 'rd_title';
-                               break;
-                       }
-               }
-               $sortby[] = 'rd_from';
-               $this->addOption( 'ORDER BY', $sortby );
-
-               $this->addOption( 'LIMIT', $params['limit'] + 1 );
-
-               $res = $this->select( __METHOD__ );
-
-               if ( is_null( $resultPageSet ) ) {
-                       $count = 0;
-                       foreach ( $res as $row ) {
-                               if ( ++$count > $params['limit'] ) {
-                                       // We've reached the one extra which shows that
-                                       // there are additional pages to be had. Stop here...
-                                       $this->setContinueEnumParameter( 'continue',
-                                               "$row->rd_namespace|$row->rd_title|$row->rd_from"
-                                       );
-                                       break;
-                               }
-
-                               # Get the ID of the current page
-                               $id = $map[$row->rd_namespace][$row->rd_title];
-
-                               $vals = array();
-                               if ( $fld_pageid ) {
-                                       $vals['pageid'] = $row->rd_from;
-                               }
-                               if ( $fld_title ) {
-                                       ApiQueryBase::addTitleInfo( $vals,
-                                               Title::makeTitle( $row->page_namespace, $row->page_title )
-                                       );
-                               }
-                               if ( $fld_fragment && $row->rd_fragment !== null && $row->rd_fragment !== '' ) {
-                                       $vals['fragment'] = $row->rd_fragment;
-                               }
-                               $fit = $this->addPageSubItem( $id, $vals );
-                               if ( !$fit ) {
-                                       $this->setContinueEnumParameter( 'continue',
-                                               "$row->rd_namespace|$row->rd_title|$row->rd_from"
-                                       );
-                                       break;
-                               }
-                       }
-               } else {
-                       $titles = array();
-                       $count = 0;
-                       foreach ( $res as $row ) {
-                               if ( ++$count > $params['limit'] ) {
-                                       // We've reached the one extra which shows that
-                                       // there are additional pages to be had. Stop here...
-                                       $this->setContinueEnumParameter( 'continue',
-                                               "$row->rd_namespace|$row->rd_title|$row->rd_from"
-                                       );
-                                       break;
-                               }
-                               $titles[] = Title::makeTitle( $row->page_namespace, $row->page_title );
-                       }
-                       $resultPageSet->populateFromTitles( $titles );
-               }
-       }
-
-       public function getCacheMode( $params ) {
-               return 'public';
-       }
-
-       public function getAllowedParams() {
-               return array(
-                       'prop' => array(
-                               ApiBase::PARAM_TYPE => array(
-                                       'pageid',
-                                       'title',
-                                       'fragment',
-                               ),
-                               ApiBase::PARAM_ISMULTI => true,
-                               ApiBase::PARAM_DFLT => 'pageid|title',
-                       ),
-                       'show' => array(
-                               ApiBase::PARAM_TYPE => array(
-                                       'fragment', '!fragment',
-                               ),
-                               ApiBase::PARAM_ISMULTI => true,
-                       ),
-                       'limit' => array(
-                               ApiBase::PARAM_DFLT => 10,
-                               ApiBase::PARAM_TYPE => 'limit',
-                               ApiBase::PARAM_MIN => 1,
-                               ApiBase::PARAM_MAX => ApiBase::LIMIT_BIG1,
-                               ApiBase::PARAM_MAX2 => ApiBase::LIMIT_BIG2
-                       ),
-                       'continue' => null,
-               );
-       }
-
-       public function getParamDescription() {
-               return array(
-                       'prop' => array(
-                               'Which properties to get:',
-                               ' pageid   - Page id of each redirect',
-                               ' title    - Title of each redirect',
-                               ' fragment - Fragment of each redirect, if any',
-                       ),
-                       'show' => array(
-                               'Show only items that meet this criteria.',
-                               ' fragment  - Only show redirects with a fragment',
-                               ' !fragment - Only show redirects without a fragment',
-                       ),
-                       'limit' => 'How many redirects to return',
-                       'continue' => 'When more results are available, use this to continue',
-               );
-       }
-
-       public function getDescription() {
-               return 'Returns all redirects to the given page(s).';
-       }
-
-       public function getExamples() {
-               return array(
-                       'api.php?action=query&prop=redirects&titles=Main%20Page'
-                               => 'Get a list of redirects to the [[Main Page]]',
-                       'api.php?action=query&generator=redirects&titles=Main%20Page&prop=info'
-                               => 'Get information about all redirects to the [[Main Page]]',
-               );
-       }
-
-       public function getHelpUrls() {
-               return 'https://www.mediawiki.org/wiki/API:Properties#redirects_.2F_rd';
-       }
-}
index be6bc68..b7dcd0e 100644 (file)
@@ -67,6 +67,16 @@ class ApiQuerySearch extends ApiQueryGeneratorBase {
                $searchInfo = array_flip( $params['info'] );
                $prop = array_flip( $params['prop'] );
 
+               // Deprecated parameters
+               if ( isset( $prop['hasrelated'] ) ) {
+                       $this->logFeatureUsage( 'action=search&srprop=hasrelated' );
+                       $this->setWarning( 'srprop=hasrelated has been deprecated' );
+               }
+               if ( isset( $prop['score'] ) ) {
+                       $this->logFeatureUsage( 'action=search&srprop=score' );
+                       $this->setWarning( 'srprop=score has been deprecated' );
+               }
+
                // Create search engine instance and set options
                $search = isset( $params['backend'] ) && $params['backend'] != self::BACKEND_NULL_PARAM ?
                        SearchEngine::create( $params['backend'] ) : SearchEngine::create();
@@ -176,9 +186,6 @@ class ApiQuerySearch extends ApiQueryGeneratorBase {
                                                $vals['sectionsnippet'] = $result->getSectionSnippet();
                                        }
                                }
-                               if ( isset( $prop['hasrelated'] ) && $result->hasRelated() ) {
-                                       $vals['hasrelated'] = '';
-                               }
 
                                // Add item to results and see whether it fits
                                $fit = $apiResult->addValue( array( 'query', $this->getModuleName() ),
@@ -332,14 +339,14 @@ class ApiQuerySearch extends ApiQueryGeneratorBase {
                                ' size             - Adds the size of the page in bytes',
                                ' wordcount        - Adds the word count of the page',
                                ' timestamp        - Adds the timestamp of when the page was last edited',
-                               ' score            - Adds the score (if any) from the search engine',
+                               ' score            - DEPRECATED and IGNORED',
                                ' snippet          - Adds a parsed snippet of the page',
                                ' titlesnippet     - Adds a parsed snippet of the page title',
                                ' redirectsnippet  - Adds a parsed snippet of the redirect title',
                                ' redirecttitle    - Adds the title of the matching redirect',
                                ' sectionsnippet   - Adds a parsed snippet of the matching section title',
                                ' sectiontitle     - Adds the title of the matching section',
-                               ' hasrelated       - Indicates whether a related search is available',
+                               ' hasrelated       - DEPRECATED and IGNORED',
                        ),
                        'offset' => 'Use this value to continue paging (return by query)',
                        'limit' => 'How many total pages to return',
index 522c7c0..311438f 100644 (file)
@@ -344,7 +344,7 @@ class ApiQuerySiteinfo extends ApiQueryBase {
                global $wgContLang;
                $data = array();
                $aliases = $wgContLang->getSpecialPageAliases();
-               foreach ( SpecialPageFactory::getList() as $specialpage => $stuff ) {
+               foreach ( SpecialPageFactory::getNames() as $specialpage ) {
                        if ( isset( $aliases[$specialpage] ) ) {
                                $arr = array( 'realname' => $specialpage, 'aliases' => $aliases[$specialpage] );
                                $this->getResult()->setIndexedTagName( $arr['aliases'], 'alias' );
@@ -399,7 +399,7 @@ class ApiQuerySiteinfo extends ApiQueryBase {
                        if ( isset( $row['iw_local'] ) && $row['iw_local'] == '1' ) {
                                $val['local'] = '';
                        }
-                       if ( $row['iw_trans'] == '1' ) {
+                       if ( isset( $row['iw_trans'] ) && $row['iw_trans'] == '1' ) {
                                $val['trans'] = '';
                        }
 
@@ -501,6 +501,7 @@ class ApiQuerySiteinfo extends ApiQueryBase {
 
                $data = array();
                $result = $this->getResult();
+               $allGroups = User::getAllGroups();
                foreach ( $config->get( 'GroupPermissions' ) as $group => $permissions ) {
                        $arr = array(
                                'name' => $group,
@@ -527,8 +528,11 @@ class ApiQuerySiteinfo extends ApiQueryBase {
 
                        foreach ( $groupArr as $type => $rights ) {
                                if ( isset( $rights[$group] ) ) {
-                                       $arr[$type] = $rights[$group];
-                                       $result->setIndexedTagName( $arr[$type], 'group' );
+                                       $groups = array_intersect( $rights[$group], $allGroups );
+                                       if ( $groups ) {
+                                               $arr[$type] = $groups;
+                                               $result->setIndexedTagName( $arr[$type], 'group' );
+                                       }
                                }
                        }
 
@@ -692,6 +696,16 @@ class ApiQuerySiteinfo extends ApiQueryBase {
                $allowed = Skin::getAllowedSkins();
                $default = Skin::normalizeKey( 'default' );
                foreach ( Skin::getSkinNames() as $name => $displayName ) {
+                       $msg = $this->msg( "skinname-{$name}" );
+                       $code = $this->getParameter( 'inlanguagecode' );
+                       if ( $code && Language::isValidCode( $code ) ) {
+                               $msg->inLanguage( $code );
+                       } else {
+                               $msg->inContentLanguage();
+                       }
+                       if ( $msg->exists() ) {
+                               $displayName = $msg->text();
+                       }
                        $skin = array( 'code' => $name );
                        ApiResult::setContent( $skin, $displayName );
                        if ( !isset( $allowed[$name] ) ) {
@@ -845,7 +859,8 @@ class ApiQuerySiteinfo extends ApiQueryBase {
                                ' restrictions          - Returns information on available restriction (protection) types',
                                ' languages             - Returns a list of languages MediaWiki supports ' .
                                        "(optionally localised by using {$p}inlanguagecode)",
-                               ' skins                 - Returns a list of all enabled skins',
+                               ' skins                 - Returns a list of all enabled skins ' .
+                                       "(optionally localised by using {$p}inlanguagecode, otherwise in content language)",
                                ' extensiontags         - Returns a list of parser extension tags',
                                ' functionhooks         - Returns a list of parser function hooks',
                                ' showhooks             - Returns a list of all subscribed hooks (contents of $wgHooks)',
@@ -857,7 +872,7 @@ class ApiQuerySiteinfo extends ApiQueryBase {
                        'showalldb' => 'List all database servers, not just the one lagging the most',
                        'numberingroup' => 'Lists the number of users in user groups',
                        'inlanguagecode' => 'Language code for localised language names ' .
-                               '(best effort, use CLDR extension)',
+                               '(best effort, use CLDR extension) and skin names',
                );
        }
 
index 8b7831c..fd5f47b 100644 (file)
@@ -69,6 +69,10 @@ class ApiQueryUserInfo extends ApiQueryBase {
                                $vals['blockedby'] = $block->getByName();
                                $vals['blockedbyid'] = $block->getBy();
                                $vals['blockreason'] = $user->blockedFor();
+                               $vals['blockedtimestamp'] = wfTimestamp( TS_ISO_8601, $block->mTimestamp );
+                               $vals['blockexpiry'] = $block->getExpiry() === 'infinity'
+                                       ? 'infinite'
+                                       : wfTimestamp( TS_ISO_8601, $block->getExpiry() );
                        }
                }
 
index b62d6a8..2f5e4b4 100644 (file)
@@ -195,6 +195,7 @@ class ApiQueryUsers extends ApiQueryBase {
                                        $data[$name]['blockid'] = $row->ipb_id;
                                        $data[$name]['blockedby'] = $row->ipb_by_text;
                                        $data[$name]['blockedbyid'] = $row->ipb_by;
+                                       $data[$name]['blockedtimestamp'] = wfTimestamp( TS_ISO_8601, $row->ipb_timestamp );
                                        $data[$name]['blockreason'] = $row->ipb_reason;
                                        $data[$name]['blockexpiry'] = $row->ipb_expiry;
                                }
index 91580f9..58ca2dc 100644 (file)
@@ -35,21 +35,28 @@ class HTMLFileCache extends FileCacheBase {
         * @param string $action
         * @throws MWException
         * @return HTMLFileCache
+        *
+        * @deprecated Since 1.24, instantiate this class directly
         */
        public static function newFromTitle( $title, $action ) {
-               $cache = new self();
+               return new self( $title, $action );
+       }
 
+       /**
+        * @param Title|string $title Title object or prefixed DB key string
+        * @param string $action
+        * @throws MWException
+        */
+       public function __construct( $title, $action ) {
                $allowedTypes = self::cacheablePageActions();
                if ( !in_array( $action, $allowedTypes ) ) {
-                       throw new MWException( "Invalid filecache type given." );
+                       throw new MWException( 'Invalid file cache type given.' );
                }
-               $cache->mKey = ( $title instanceof Title )
+               $this->mKey = ( $title instanceof Title )
                        ? $title->getPrefixedDBkey()
                        : (string)$title;
-               $cache->mType = (string)$action;
-               $cache->mExt = 'html';
-
-               return $cache;
+               $this->mType = (string)$action;
+               $this->mExt = 'html';
        }
 
        /**
@@ -120,7 +127,11 @@ class HTMLFileCache extends FileCacheBase {
                $clang = $wgContLang->getCode();
 
                // Check that there are no other sources of variation
-               return !$user->getId() && !$user->getNewtalk() && $ulang == $clang;
+               if ( $user->getId() || $user->getNewtalk() || $ulang != $clang ) {
+                       return false;
+               }
+               // Allow extensions to disable caching
+               return wfRunHooks( 'HTMLFileCache::useFileCache', array( $context ) );
        }
 
        /**
@@ -211,7 +222,7 @@ class HTMLFileCache extends FileCacheBase {
                }
 
                foreach ( self::cacheablePageActions() as $type ) {
-                       $fc = self::newFromTitle( $title, $type );
+                       $fc = new self( $title, $type );
                        $fc->clearCache();
                }
 
index 7bafc99..212e5e8 100644 (file)
  */
 
 /**
- * Bloom filter implented using Redis
+ * Bloom filter implemented using Redis
  *
  * The Redis server must be >= 2.6 and should have volatile-lru or volatile-ttl
  * if there is any eviction policy. It should not be allkeys-* in any case. Also,
- * this can be used in a simple master/slave setup or with Redis Sentinal preferably.
+ * this can be used in a simple master/slave setup or with Redis Sentinel preferably.
  *
  * Some bits are based on https://github.com/ErikDubbelboer/redis-lua-scaling-bloom-filter
  * but are simplified to use a single filter instead of up to 32 filters.
index 68e90b4..38f589d 100644 (file)
@@ -37,11 +37,11 @@ interface Config {
        public function get( $name );
 
        /**
-        * Set a configuration variable such a "Sitename" to something like "My Wiki"
+        * Check whether a configuration option is set for the given name
         *
         * @param string $name Name of configuration option
-        * @param mixed $value Value to set
-        * @throws ConfigException
+        * @return bool
+        * @since 1.24
         */
-       public function set( $name, $value );
+       public function has( $name );
 }
index 0841a00..39d6e8e 100644 (file)
@@ -49,13 +49,25 @@ class GlobalVarConfig implements Config {
         * @see Config::get
         */
        public function get( $name ) {
+               if ( !$this->has( $name ) ) {
+                       throw new ConfigException( __METHOD__ . ": undefined option: '$name'" );
+               }
                return $this->getWithPrefix( $this->prefix, $name );
        }
 
        /**
-        * @see Config::set
+        * @see Config::has
+        */
+       public function has( $name ) {
+               return $this->hasWithPrefix( $this->prefix, $name );
+       }
+
+       /**
+        * @see MutableConfig::set
+        * @deprecated since 1.24
         */
        public function set( $name, $value ) {
+               wfDeprecated( __METHOD__, '1.24' );
                $this->setWithPrefix( $this->prefix, $name, $value );
        }
 
@@ -64,15 +76,22 @@ class GlobalVarConfig implements Config {
         *
         * @param string $prefix Prefix to use on the variable, if one.
         * @param string $name Variable name without prefix
-        * @throws ConfigException
         * @return mixed
         */
        protected function getWithPrefix( $prefix, $name ) {
+               return $GLOBALS[$prefix . $name];
+       }
+
+       /**
+        * Check if a variable with a given prefix is set
+        *
+        * @param string $prefix Prefix to use on the variable
+        * @param string $name Variable name without prefix
+        * @return bool
+        */
+       protected function hasWithPrefix( $prefix, $name ) {
                $var = $prefix . $name;
-               if ( !array_key_exists( $var, $GLOBALS ) ) {
-                       throw new ConfigException( __METHOD__ . ": undefined variable: '$var'" );
-               }
-               return $GLOBALS[$var];
+               return array_key_exists( $var, $GLOBALS );
        }
 
        /**
@@ -81,6 +100,7 @@ class GlobalVarConfig implements Config {
         * @param string $prefix Prefix to use on the variable
         * @param string $name Variable name without prefix
         * @param mixed $value Value to set
+        * @deprecated since 1.24
         */
        protected function setWithPrefix( $prefix, $name, $value ) {
                $GLOBALS[$prefix . $name] = $value;
diff --git a/includes/config/HashConfig.php b/includes/config/HashConfig.php
new file mode 100644 (file)
index 0000000..a09a0a4
--- /dev/null
@@ -0,0 +1,75 @@
+<?php
+/**
+ * Copyright 2014
+ *
+ * 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
+ */
+
+/**
+ * A Config instance which stores all settings as a member variable
+ *
+ * @since 1.24
+ */
+class HashConfig implements Config, MutableConfig {
+
+       /**
+        * Array of config settings
+        *
+        * @var array
+        */
+       private $settings;
+
+       /**
+        * @return HashConfig
+        */
+       public static function newInstance() {
+               return new HashConfig;
+       }
+
+       /**
+        * @param array $settings Any current settings to pre-load
+        */
+       public function __construct( array $settings = array() ) {
+               $this->settings = $settings;
+       }
+
+       /**
+        * @see Config::get
+        */
+       public function get( $name ) {
+               if ( !$this->has( $name ) ) {
+                       throw new ConfigException( __METHOD__ . ": undefined option: '$name'" );
+               }
+
+               return $this->settings[$name];
+       }
+
+       /**
+        * @see Config::has
+        */
+       public function has( $name ) {
+               return array_key_exists( $name, $this->settings );
+       }
+
+       /**
+        * @see Config::set
+        */
+       public function set( $name, $value ) {
+               $this->settings[$name] = $value;
+       }
+}
diff --git a/includes/config/MultiConfig.php b/includes/config/MultiConfig.php
new file mode 100644 (file)
index 0000000..cbb65aa
--- /dev/null
@@ -0,0 +1,72 @@
+<?php
+/**
+ * Copyright 2014
+ *
+ * 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
+ */
+
+/**
+ * Provides a fallback sequence for Config objects
+ *
+ * @since 1.24
+ */
+class MultiConfig implements Config {
+
+       /**
+        * Array of Config objects to use
+        * Order matters, the Config objects
+        * will be checked in order to see
+        * whether they have the requested setting
+        *
+        * @var Config[]
+        */
+       private $configs;
+
+       /**
+        * @param Config[] $configs
+        */
+       public function __construct( array $configs ) {
+               $this->configs = $configs;
+       }
+
+       /**
+        * @see Config::get
+        */
+       public function get( $name ) {
+               foreach ( $this->configs as $config ) {
+                       if ( $config->has( $name ) ) {
+                               return $config->get( $name );
+                       }
+               }
+
+               throw new ConfigException( __METHOD__ . ": undefined option: '$name'" );
+       }
+
+       /**
+        * @see Config::has
+        */
+       public function has( $name ) {
+               foreach ( $this->configs as $config ) {
+                       if ( $config->has( $name ) ) {
+                               return true;
+                       }
+               }
+
+               return false;
+       }
+}
diff --git a/includes/config/MutableConfig.php b/includes/config/MutableConfig.php
new file mode 100644 (file)
index 0000000..e765e3b
--- /dev/null
@@ -0,0 +1,38 @@
+<?php
+/**
+ * Copyright 2014
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * @file
+ */
+
+/**
+ * Interface for mutable configuration instances
+ *
+ * @since 1.24
+ */
+interface MutableConfig {
+
+       /**
+        * Set a configuration variable such a "Sitename" to something like "My Wiki"
+        *
+        * @param string $name Name of configuration option
+        * @param mixed $value Value to set
+        * @throws ConfigException
+        */
+       public function set( $name, $value );
+}
index 683c959..9d257a6 100644 (file)
@@ -483,7 +483,12 @@ abstract class AbstractContent implements Content {
                if ( wfRunHooks( 'ContentGetParserOutput',
                        array( $this, $title, $revId, $options, $generateHtml, &$po ) ) ) {
 
+                       // Save and restore the old value, just in case something is reusing
+                       // the ParserOptions object in some weird way.
+                       $oldRedir = $options->getRedirectTarget();
+                       $options->setRedirectTarget( $this->getRedirectTarget() );
                        $this->fillParserOutput( $title, $revId, $options, $generateHtml, $po );
+                       $options->setRedirectTarget( $oldRedir );
                }
 
                return $po;
diff --git a/includes/content/CodeContentHandler.php b/includes/content/CodeContentHandler.php
new file mode 100644 (file)
index 0000000..447a2a7
--- /dev/null
@@ -0,0 +1,65 @@
+<?php
+/**
+ * Content handler for the pages with code, such as CSS, JavaScript, JSON.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * @file
+ * @ingroup Content
+ */
+
+/**
+ * Content handler for code content such as CSS, JavaScript, JSON, etc
+ * @since 1.24
+ * @ingroup Content
+ */
+abstract class CodeContentHandler extends TextContentHandler {
+
+       /**
+        * Returns the english language, because code is english, and should be handled as such.
+        *
+        * @param Title $title
+        * @param Content $content
+        *
+        * @return Language Return of wfGetLangObj( 'en' )
+        *
+        * @see ContentHandler::getPageLanguage()
+        */
+       public function getPageLanguage( Title $title, Content $content = null ) {
+               return wfGetLangObj( 'en' );
+       }
+
+       /**
+        * Returns the english language, because code is english, and should be handled as such.
+        *
+        * @param Title $title
+        * @param Content $content
+        *
+        * @return Language Return of wfGetLangObj( 'en' )
+        *
+        * @see ContentHandler::getPageViewLanguage()
+        */
+       public function getPageViewLanguage( Title $title, Content $content = null ) {
+               return wfGetLangObj( 'en' );
+       }
+
+       /**
+        * @return string
+        */
+       protected function getContentClass() {
+               throw new MWException( 'Subclass must override' );
+       }
+}
index 7241458..8290603 100644 (file)
@@ -34,9 +34,10 @@ class CssContent extends TextContent {
 
        /**
         * @param string $text CSS code.
+        * @param string $modelId the content content model
         */
-       public function __construct( $text ) {
-               parent::__construct( $text, CONTENT_MODEL_CSS );
+       public function __construct( $text, $modelId = CONTENT_MODEL_CSS ) {
+               parent::__construct( $text, $modelId );
        }
 
        /**
index 1ab4ee2..b2a8676 100644 (file)
@@ -27,7 +27,7 @@
  * @since 1.21
  * @ingroup Content
  */
-class CssContentHandler extends TextContentHandler {
+class CssContentHandler extends CodeContentHandler {
 
        /**
         * @param string $modelId
@@ -39,33 +39,4 @@ class CssContentHandler extends TextContentHandler {
        protected function getContentClass() {
                return 'CssContent';
        }
-
-       /**
-        * Returns the english language, because CSS is english, and should be handled as such.
-        *
-        * @param Title $title
-        * @param Content $content
-        *
-        * @return Language Return of wfGetLangObj( 'en' )
-        *
-        * @see ContentHandler::getPageLanguage()
-        */
-       public function getPageLanguage( Title $title, Content $content = null ) {
-               return wfGetLangObj( 'en' );
-       }
-
-       /**
-        * Returns the english language, because CSS is english, and should be handled as such.
-        *
-        * @param Title $title
-        * @param Content $content
-        *
-        * @return Language Return of wfGetLangObj( 'en' )
-        *
-        * @see ContentHandler::getPageViewLanguage()
-        */
-       public function getPageViewLanguage( Title $title, Content $content = null ) {
-               return wfGetLangObj( 'en' );
-       }
-
 }
diff --git a/includes/content/JSONContent.php b/includes/content/JSONContent.php
deleted file mode 100644 (file)
index e563780..0000000
+++ /dev/null
@@ -1,120 +0,0 @@
-<?php
-/**
- * JSON Content Model
- *
- * @file
- *
- * @author Ori Livneh <ori@wikimedia.org>
- * @author Kunal Mehta <legoktm@gmail.com>
- */
-
-/**
- * Represents the content of a JSON content.
- * @since 1.24
- */
-class JSONContent extends TextContent {
-
-       public function __construct( $text, $modelId = CONTENT_MODEL_JSON ) {
-               parent::__construct( $text, $modelId );
-       }
-
-       /**
-        * Decodes the JSON into a PHP associative array.
-        * @return array
-        */
-       public function getJsonData() {
-               return FormatJson::decode( $this->getNativeData(), true );
-       }
-
-       /**
-        * @return bool Whether content is valid JSON.
-        */
-       public function isValid() {
-               return $this->getJsonData() !== null;
-       }
-
-       /**
-        * Pretty-print JSON
-        *
-        * @return bool|null|string
-        */
-       public function beautifyJSON() {
-               $decoded = FormatJson::decode( $this->getNativeData(), true );
-               if ( !is_array( $decoded ) ) {
-                       return null;
-               }
-               return FormatJson::encode( $decoded, true );
-
-       }
-
-       /**
-        * Beautifies JSON prior to save.
-        * @param Title $title Title
-        * @param User $user User
-        * @param ParserOptions $popts
-        * @return JSONContent
-        */
-       public function preSaveTransform( Title $title, User $user, ParserOptions $popts ) {
-               return new static( $this->beautifyJSON() );
-       }
-
-       /**
-        * Set the HTML and add the appropriate styles
-        *
-        *
-        * @param Title $title
-        * @param int $revId
-        * @param ParserOptions $options
-        * @param bool $generateHtml
-        * @param ParserOutput $output
-        */
-       protected function fillParserOutput( Title $title, $revId,
-               ParserOptions $options, $generateHtml, ParserOutput &$output
-       ) {
-               if ( $generateHtml ) {
-                       $output->setText( $this->objectTable( $this->getJsonData() ) );
-                       $output->addModuleStyles( 'mediawiki.content.json' );
-               } else {
-                       $output->setText( '' );
-               }
-       }
-       /**
-        * Constructs an HTML representation of a JSON object.
-        * @param array $mapping
-        * @return string HTML
-        */
-       protected function objectTable( $mapping ) {
-               $rows = array();
-
-               foreach ( $mapping as $key => $val ) {
-                       $rows[] = $this->objectRow( $key, $val );
-               }
-               return Xml::tags( 'table', array( 'class' => 'mw-json' ),
-                       Xml::tags( 'tbody', array(), join( "\n", $rows ) )
-               );
-       }
-
-       /**
-        * Constructs HTML representation of a single key-value pair.
-        * @param string $key
-        * @param mixed $val
-        * @return string HTML.
-        */
-       protected function objectRow( $key, $val ) {
-               $th = Xml::elementClean( 'th', array(), $key );
-               if ( is_array( $val ) ) {
-                       $td = Xml::tags( 'td', array(), self::objectTable( $val ) );
-               } else {
-                       if ( is_string( $val ) ) {
-                               $val = '"' . $val . '"';
-                       } else {
-                               $val = FormatJson::encode( $val );
-                       }
-
-                       $td = Xml::elementClean( 'td', array( 'class' => 'value' ), $val );
-               }
-
-               return Xml::tags( 'tr', array(), $th . $td );
-       }
-
-}
diff --git a/includes/content/JSONContentHandler.php b/includes/content/JSONContentHandler.php
deleted file mode 100644 (file)
index b0b7aae..0000000
+++ /dev/null
@@ -1,54 +0,0 @@
-<?php
-/**
- * JSON Schema Content Handler
- *
- * @file
- *
- * @author Ori Livneh <ori@wikimedia.org>
- * @author Kunal Mehta <legoktm@gmail.com>
- */
-
-/**
- * @since 1.24
- */
-class JSONContentHandler extends TextContentHandler {
-
-       public function __construct( $modelId = CONTENT_MODEL_JSON ) {
-               parent::__construct( $modelId, array( CONTENT_FORMAT_JSON ) );
-       }
-
-       /**
-        * @return string
-        */
-       protected function getContentClass() {
-               return 'JSONContent';
-       }
-
-       /**
-        * Returns the english language, because JSON is english, and should be handled as such.
-        *
-        * @param Title $title
-        * @param Content|null $content
-        *
-        * @return Language Return of wfGetLangObj( 'en' )
-        *
-        * @see ContentHandler::getPageLanguage()
-        */
-       public function getPageLanguage( Title $title, Content $content = null ) {
-               return wfGetLangObj( 'en' );
-       }
-
-       /**
-        * Returns the english language, because JSON is english, and should be handled as such.
-        *
-        * @param Title $title
-        * @param Content|null $content
-        *
-        * @return Language Return of wfGetLangObj( 'en' )
-        *
-        * @see ContentHandler::getPageLanguage()
-        */
-       public function getPageViewLanguage( Title $title, Content $content = null ) {
-               return wfGetLangObj( 'en' );
-       }
-}
index 0991f07..c0194c2 100644 (file)
@@ -34,9 +34,10 @@ class JavaScriptContent extends TextContent {
 
        /**
         * @param string $text JavaScript code.
+        * @param string $modelId the content model name
         */
-       public function __construct( $text ) {
-               parent::__construct( $text, CONTENT_MODEL_JAVASCRIPT );
+       public function __construct( $text, $modelId = CONTENT_MODEL_JAVASCRIPT ) {
+               parent::__construct( $text, $modelId );
        }
 
        /**
index 8d62e2a..457b83d 100644 (file)
@@ -27,7 +27,7 @@
  * @ingroup Content
  * @todo make ScriptContentHandler base class, do highlighting stuff there?
  */
-class JavaScriptContentHandler extends TextContentHandler {
+class JavaScriptContentHandler extends CodeContentHandler {
 
        /**
         * @param string $modelId
@@ -39,33 +39,4 @@ class JavaScriptContentHandler extends TextContentHandler {
        protected function getContentClass() {
                return 'JavaScriptContent';
        }
-
-       /**
-        * Returns the english language, because JS is english, and should be handled as such.
-        *
-        * @param Title $title
-        * @param Content $content
-        *
-        * @return Language Return of wfGetLangObj( 'en' )
-        *
-        * @see ContentHandler::getPageLanguage()
-        */
-       public function getPageLanguage( Title $title, Content $content = null ) {
-               return wfGetLangObj( 'en' );
-       }
-
-       /**
-        * Returns the english language, because JS is english, and should be handled as such.
-        *
-        * @param Title $title
-        * @param Content $content
-        *
-        * @return Language Return of wfGetLangObj( 'en' )
-        *
-        * @see ContentHandler::getPageViewLanguage()
-        */
-       public function getPageViewLanguage( Title $title, Content $content = null ) {
-               return wfGetLangObj( 'en' );
-       }
-
 }
diff --git a/includes/content/JsonContent.php b/includes/content/JsonContent.php
new file mode 100644 (file)
index 0000000..b36827c
--- /dev/null
@@ -0,0 +1,120 @@
+<?php
+/**
+ * JSON Content Model
+ *
+ * @file
+ *
+ * @author Ori Livneh <ori@wikimedia.org>
+ * @author Kunal Mehta <legoktm@gmail.com>
+ */
+
+/**
+ * Represents the content of a JSON content.
+ * @since 1.24
+ */
+class JsonContent extends TextContent {
+
+       public function __construct( $text, $modelId = CONTENT_MODEL_JSON ) {
+               parent::__construct( $text, $modelId );
+       }
+
+       /**
+        * Decodes the JSON into a PHP associative array.
+        * @return array
+        */
+       public function getJsonData() {
+               return FormatJson::decode( $this->getNativeData(), true );
+       }
+
+       /**
+        * @return bool Whether content is valid JSON.
+        */
+       public function isValid() {
+               return $this->getJsonData() !== null;
+       }
+
+       /**
+        * Pretty-print JSON
+        *
+        * @return bool|null|string
+        */
+       public function beautifyJSON() {
+               $decoded = FormatJson::decode( $this->getNativeData(), true );
+               if ( !is_array( $decoded ) ) {
+                       return null;
+               }
+               return FormatJson::encode( $decoded, true );
+
+       }
+
+       /**
+        * Beautifies JSON prior to save.
+        * @param Title $title Title
+        * @param User $user User
+        * @param ParserOptions $popts
+        * @return JsonContent
+        */
+       public function preSaveTransform( Title $title, User $user, ParserOptions $popts ) {
+               return new static( $this->beautifyJSON() );
+       }
+
+       /**
+        * Set the HTML and add the appropriate styles
+        *
+        *
+        * @param Title $title
+        * @param int $revId
+        * @param ParserOptions $options
+        * @param bool $generateHtml
+        * @param ParserOutput $output
+        */
+       protected function fillParserOutput( Title $title, $revId,
+               ParserOptions $options, $generateHtml, ParserOutput &$output
+       ) {
+               if ( $generateHtml ) {
+                       $output->setText( $this->objectTable( $this->getJsonData() ) );
+                       $output->addModuleStyles( 'mediawiki.content.json' );
+               } else {
+                       $output->setText( '' );
+               }
+       }
+       /**
+        * Constructs an HTML representation of a JSON object.
+        * @param array $mapping
+        * @return string HTML
+        */
+       protected function objectTable( $mapping ) {
+               $rows = array();
+
+               foreach ( $mapping as $key => $val ) {
+                       $rows[] = $this->objectRow( $key, $val );
+               }
+               return Xml::tags( 'table', array( 'class' => 'mw-json' ),
+                       Xml::tags( 'tbody', array(), join( "\n", $rows ) )
+               );
+       }
+
+       /**
+        * Constructs HTML representation of a single key-value pair.
+        * @param string $key
+        * @param mixed $val
+        * @return string HTML.
+        */
+       protected function objectRow( $key, $val ) {
+               $th = Xml::elementClean( 'th', array(), $key );
+               if ( is_array( $val ) ) {
+                       $td = Xml::tags( 'td', array(), self::objectTable( $val ) );
+               } else {
+                       if ( is_string( $val ) ) {
+                               $val = '"' . $val . '"';
+                       } else {
+                               $val = FormatJson::encode( $val );
+                       }
+
+                       $td = Xml::elementClean( 'td', array( 'class' => 'value' ), $val );
+               }
+
+               return Xml::tags( 'tr', array(), $th . $td );
+       }
+
+}
diff --git a/includes/content/JsonContentHandler.php b/includes/content/JsonContentHandler.php
new file mode 100644 (file)
index 0000000..392ce37
--- /dev/null
@@ -0,0 +1,26 @@
+<?php
+/**
+ * JSON Schema Content Handler
+ *
+ * @file
+ *
+ * @author Ori Livneh <ori@wikimedia.org>
+ * @author Kunal Mehta <legoktm@gmail.com>
+ */
+
+/**
+ * @since 1.24
+ */
+class JsonContentHandler extends CodeContentHandler {
+
+       public function __construct( $modelId = CONTENT_MODEL_JSON ) {
+               parent::__construct( $modelId, array( CONTENT_FORMAT_JSON ) );
+       }
+
+       /**
+        * @return string
+        */
+       protected function getContentClass() {
+               return 'JsonContent';
+       }
+}
index edbd075..5b84657 100644 (file)
@@ -29,7 +29,7 @@
  * Wrapper allowing us to handle a system message as a Content object.
  * Note that this is generally *not* used to represent content from the
  * MediaWiki namespace, and that there is no MessageContentHandler.
- * MessageContent is just intended as glue for wrapping a message programatically.
+ * MessageContent is just intended as glue for wrapping a message programmatically.
  *
  * @ingroup Content
  */
@@ -165,6 +165,8 @@ class MessageContent extends AbstractContent {
                }
 
                $po = new ParserOutput( $html );
+               // Message objects are in the user language.
+               $po->recordOption( 'userlang' );
 
                return $po;
        }
index d292880..c479f20 100644 (file)
@@ -160,7 +160,7 @@ class TextContent extends AbstractContent {
                $text = $this->getNativeData();
                $pst = rtrim( $text );
 
-               return ( $text === $pst ) ? $this : new static( $pst );
+               return ( $text === $pst ) ? $this : new static( $pst, $this->getModel() );
        }
 
        /**
index 3ab6a6d..9a8ab3a 100644 (file)
@@ -31,6 +31,7 @@
  * @ingroup Content
  */
 class WikitextContent extends TextContent {
+       private $redirectTargetAndText = null;
 
        public function __construct( $text ) {
                parent::__construct( $text, CONTENT_MODEL_WIKITEXT );
@@ -178,10 +179,17 @@ class WikitextContent extends TextContent {
         */
        protected function getRedirectTargetAndText() {
                global $wgMaxRedirects;
+
+               if ( $this->redirectTargetAndText !== null ) {
+                       return $this->redirectTargetAndText;
+               }
+
                if ( $wgMaxRedirects < 1 ) {
                        // redirects are disabled, so quit early
-                       return array( null, $this->getNativeData() );
+                       $this->redirectTargetAndText = array( null, $this->getNativeData() );
+                       return $this->redirectTargetAndText;
                }
+
                $redir = MagicWord::get( 'redirect' );
                $text = ltrim( $this->getNativeData() );
                if ( $redir->matchStartAndRemove( $text ) ) {
@@ -199,14 +207,17 @@ class WikitextContent extends TextContent {
                                $title = Title::newFromText( $m[1] );
                                // If the title is a redirect to bad special pages or is invalid, return null
                                if ( !$title instanceof Title || !$title->isValidRedirectTarget() ) {
-                                       return array( null, $this->getNativeData() );
+                                       $this->redirectTargetAndText = array( null, $this->getNativeData() );
+                                       return $this->redirectTargetAndText;
                                }
 
-                               return array( $title, substr( $text, strlen( $m[0] ) ) );
+                               $this->redirectTargetAndText = array( $title, substr( $text, strlen( $m[0] ) ) );
+                               return $this->redirectTargetAndText;
                        }
                }
 
-               return array( null, $this->getNativeData() );
+               $this->redirectTargetAndText = array( null, $this->getNativeData() );
+               return $this->redirectTargetAndText;
        }
 
        /**
index 8229c99..2dfec41 100644 (file)
@@ -306,7 +306,7 @@ EOT;
                        }
                }
 
-               $cache = HTMLFileCache::newFromTitle( $t, 'view' );
+               $cache = new HTMLFileCache( $t, 'view' );
                if ( $cache->isCached() ) {
                        return $cache->fetchText();
                } else {
index 3a4bb27..af3cc72 100644 (file)
@@ -228,7 +228,7 @@ class DatabaseMssql extends DatabaseBase {
 
                                if ( $success ) {
                                        $this->mAffectedRows = 0;
-                                       return true;
+                                       return $stmt;
                                }
                        }
                }
@@ -415,10 +415,8 @@ class DatabaseMssql extends DatabaseBase {
                        }
                        $this->mScrollableCursor = true;
                        $this->mPrepareStatements = true;
-
                        return $ret;
                }
-
                return $this->query( $sql, $fname );
        }
 
@@ -614,6 +612,13 @@ class DatabaseMssql extends DatabaseBase {
                // Determine binary/varbinary fields so we can encode data as a hex string like 0xABCDEF
                $binaryColumns = $this->getBinaryColumns( $table );
 
+               // INSERT IGNORE is not supported by SQL Server
+               // remove IGNORE from options list and set ignore flag to true
+               if ( in_array( 'IGNORE', $options ) ) {
+                       $options = array_diff( $options, array( 'IGNORE' ) );
+                       $this->mIgnoreDupKeyErrors = true;
+               }
+
                foreach ( $arrToInsert as $a ) {
                        // start out with empty identity column, this is so we can return
                        // it as a result of the insert logic
@@ -645,14 +650,6 @@ class DatabaseMssql extends DatabaseBase {
 
                        $keys = array_keys( $a );
 
-                       // INSERT IGNORE is not supported by SQL Server
-                       // remove IGNORE from options list and set ignore flag to true
-                       $ignoreClause = false;
-                       if ( in_array( 'IGNORE', $options ) ) {
-                               $options = array_diff( $options, array( 'IGNORE' ) );
-                               $this->mIgnoreDupKeyErrors = true;
-                       }
-
                        // Build the actual query
                        $sql = $sqlPre . 'INSERT ' . implode( ' ', $options ) .
                                " INTO $table (" . implode( ',', $keys ) . ") $identityClause VALUES (";
@@ -691,15 +688,16 @@ class DatabaseMssql extends DatabaseBase {
                                throw $e;
                        }
                        $this->mScrollableCursor = true;
-                       $this->mIgnoreDupKeyErrors = false;
 
                        if ( !is_null( $identity ) ) {
                                // then we want to get the identity column value we were assigned and save it off
                                $row = $ret->fetchObject();
-                               $this->mInsertId = $row->$identity;
+                               if( is_object( $row ) ){
+                                       $this->mInsertId = $row->$identity;
+                               }
                        }
                }
-
+               $this->mIgnoreDupKeyErrors = false;
                return $ret;
        }
 
@@ -921,7 +919,7 @@ class DatabaseMssql extends DatabaseBase {
                        }
                        if ( !$s2 ) {
                                // no ORDER BY
-                               $overOrder = 'ORDER BY 1';
+                               $overOrder = 'ORDER BY (SELECT 1)';
                        } else {
                                if ( !isset( $orderby[2] ) || !$orderby[2] ) {
                                        // don't need to strip it out if we're using a FOR XML clause
index dc4a67d..823d9b6 100644 (file)
@@ -142,13 +142,6 @@ class DatabaseMysql extends DatabaseMysqlBase {
                return mysql_select_db( $db, $this->mConn );
        }
 
-       /**
-        * @return string
-        */
-       function getServerVersion() {
-               return mysql_get_server_info( $this->mConn );
-       }
-
        protected function mysqlFreeResult( $res ) {
                return mysql_free_result( $res );
        }
index ba0f39f..2008f4d 100644 (file)
@@ -38,6 +38,9 @@ abstract class DatabaseMysqlBase extends DatabaseBase {
 
        protected $mFakeMaster = false;
 
+       /** @var string|null */
+       private $serverVersion = null;
+
        /**
         * @return string
         */
@@ -763,9 +766,9 @@ abstract class DatabaseMysqlBase extends DatabaseBase {
         * @return string
         */
        public function getSoftwareLink() {
-               // MariaDB includes its name in its version string (sent when the connection is opened),
-               // and this is how MariaDB's version of the mysql command-line client identifies MariaDB
-               // servers (see the mariadb_connection() function in libmysql/libmysql.c).
+               // MariaDB includes its name in its version string; this is how MariaDB's version of
+               // the mysql command-line client identifies MariaDB servers (see mariadb_connection()
+               // in libmysql/libmysql.c).
                $version = $this->getServerVersion();
                if ( strpos( $version, 'MariaDB' ) !== false || strpos( $version, '-maria-' ) !== false ) {
                        return '[{{int:version-db-mariadb-url}} MariaDB]';
@@ -777,6 +780,19 @@ abstract class DatabaseMysqlBase extends DatabaseBase {
                return '[{{int:version-db-mysql-url}} MySQL]';
        }
 
+       /**
+        * @return string
+        */
+       public function getServerVersion() {
+               // Not using mysql_get_server_info() or similar for consistency: in the handshake,
+               // MariaDB 10 adds the prefix "5.5.5-", and only some newer client libraries strip
+               // it off (see RPL_VERSION_HACK in include/mysql_com.h).
+               if ( $this->serverVersion === null ) {
+                       $this->serverVersion = $this->selectField( '', 'VERSION()', '', __METHOD__ );
+               }
+               return $this->serverVersion;
+       }
+
        /**
         * @param array $options
         */
index 2ce6307..e9c4b39 100644 (file)
@@ -58,14 +58,22 @@ class DatabaseMysqli extends DatabaseMysqlBase {
                }
 
                // Other than mysql_connect, mysqli_real_connect expects an explicit port
-               // parameter. So we need to parse the port out of $realServer
+               // and socket parameters. So we need to parse the port and socket out of
+               // $realServer
                $port = null;
+               $socket = null;
                $hostAndPort = IP::splitHostAndPort( $realServer );
                if ( $hostAndPort ) {
                        $realServer = $hostAndPort[0];
                        if ( $hostAndPort[1] ) {
                                $port = $hostAndPort[1];
                        }
+               } elseif ( substr_count( $realServer, ':' ) == 1 ) {
+                       // If we have a colon and something that's not a port number
+                       // inside the hostname, assume it's the socket location
+                       $hostAndSocket = explode( ':', $realServer );
+                       $realServer = $hostAndSocket[0];
+                       $socket = $hostAndSocket[1];
                }
 
                $connFlags = 0;
@@ -90,7 +98,7 @@ class DatabaseMysqli extends DatabaseMysqlBase {
                $mysqli->options( MYSQLI_OPT_CONNECT_TIMEOUT, 3 );
 
                if ( $mysqli->real_connect( $realServer, $this->mUser,
-                       $this->mPassword, $this->mDBname, $port, null, $connFlags )
+                       $this->mPassword, $this->mDBname, $port, $socket, $connFlags )
                ) {
                        return $mysqli;
                }
@@ -157,13 +165,6 @@ class DatabaseMysqli extends DatabaseMysqlBase {
                return $this->mConn->select_db( $db );
        }
 
-       /**
-        * @return string
-        */
-       function getServerVersion() {
-               return $this->mConn->server_info;
-       }
-
        /**
         * @param mysqli $res
         * @return bool
index db4ed60..e517a02 100644 (file)
  * @ingroup Database
  */
 class LoadBalancer {
-       private $mServers, $mConns, $mLoads, $mGroupLoads;
+       /** @var array Map of (server index => server config array) */
+       private $mServers;
+       /** @var array Map of (local/foreignUsed/foreignFree => server index => DatabaseBase array) */
+       private $mConns;
+       /** @var array Map of (server index => weight) */
+       private $mLoads;
+       /** @var array Map of (group => server index => weight) */
+       private $mGroupLoads;
+       /** @var bool Whether to disregard slave lag as a factor in slave selection */
+       private $mAllowLagged;
+       /** @var integer Seconds to spend waiting on slave lag to resolve */
+       private $mWaitTimeout;
+
+       /** @var array LBFactory information */
+       private $mParentInfo;
+       /** @var string The LoadMonitor subclass name */
+       private $mLoadMonitorClass;
+       /** @var LoadMonitor */
+       private $mLoadMonitor;
 
        /** @var bool|DatabaseBase Database connection that caused a problem */
        private $mErrorConnection;
-       private $mReadIndex, $mAllowLagged;
-
+       /** @var integer The generic (not query grouped) slave index (of $mServers) */
+       private $mReadIndex;
        /** @var bool|DBMasterPos False if not set */
        private $mWaitForPos;
-
-       private $mWaitTimeout;
-       private $mLaggedSlaveMode, $mLastError = 'Unknown error';
-       private $mParentInfo, $mLagTimes;
-       private $mLoadMonitorClass, $mLoadMonitor;
+       /** @var bool Whether the generic reader fell back to a lagged slave */
+       private $mLaggedSlaveMode;
+       /** @var string The last DB selection or connection error */
+       private $mLastError = 'Unknown error';
+       /** @var array Process cache of LoadMonitor::getLagTimes() */
+       private $mLagTimes;
 
        /**
         * @param array $params Array with keys:
index 5774a24..952bf63 100644 (file)
@@ -96,9 +96,6 @@ class ExternalStoreDB extends ExternalStoreMedium {
                if ( !$id ) {
                        throw new MWException( __METHOD__ . ': no insert ID' );
                }
-               if ( $dbw->getFlag( DBO_TRX ) ) {
-                       $dbw->commit( __METHOD__ );
-               }
 
                return "DB://$cluster/$id";
        }
@@ -134,7 +131,10 @@ class ExternalStoreDB extends ExternalStoreMedium {
                        wfDebug( "writable external store\n" );
                }
 
-               return $lb->getConnection( DB_SLAVE, array(), $wiki );
+               $db = $lb->getConnection( DB_SLAVE, array(), $wiki );
+               $db->clearFlag( DBO_TRX ); // sanity
+
+               return $db;
        }
 
        /**
@@ -147,7 +147,10 @@ class ExternalStoreDB extends ExternalStoreMedium {
                $wiki = isset( $this->params['wiki'] ) ? $this->params['wiki'] : false;
                $lb = $this->getLoadBalancer( $cluster );
 
-               return $lb->getConnection( DB_MASTER, array(), $wiki );
+               $db = $lb->getConnection( DB_MASTER, array(), $wiki );
+               $db->clearFlag( DBO_TRX ); // sanity
+
+               return $db;
        }
 
        /**
@@ -282,6 +285,10 @@ class ExternalStoreDB extends ExternalStoreMedium {
                }
        }
 
+       /**
+        * @param string $url
+        * @return array
+        */
        protected function parseURL( $url ) {
                $path = explode( '/', $url );
 
index 78810eb..8c0a61a 100644 (file)
@@ -135,19 +135,12 @@ abstract class FileBackend {
         */
        public function __construct( array $config ) {
                $this->name = $config['name'];
+               $this->wikiId = $config['wikiId']; // e.g. "my_wiki-en_"
                if ( !preg_match( '!^[a-zA-Z0-9-_]{1,255}$!', $this->name ) ) {
-                       throw new FileBackendException( "Backend name `{$this->name}` is invalid." );
-               }
-               if ( !isset( $config['wikiId'] ) ) {
-                       $config['wikiId'] = wfWikiID();
-                       wfDeprecated( __METHOD__ . ' called without "wikiID".', '1.23' );
+                       throw new FileBackendException( "Backend name '{$this->name}' is invalid." );
+               } elseif ( !is_string( $this->wikiId ) ) {
+                       throw new FileBackendException( "Backend wiki ID not provided for '{$this->name}'." );
                }
-               if ( isset( $config['lockManager'] ) && !is_object( $config['lockManager'] ) ) {
-                       $config['lockManager'] =
-                               LockManagerGroup::singleton( $config['wikiId'] )->get( $config['lockManager'] );
-                       wfDeprecated( __METHOD__ . ' called with non-object "lockManager".', '1.23' );
-               }
-               $this->wikiId = $config['wikiId']; // e.g. "my_wiki-en_"
                $this->lockManager = isset( $config['lockManager'] )
                        ? $config['lockManager']
                        : new NullLockManager( array() );
index 8bf9040..5b0d8e2 100644 (file)
@@ -264,6 +264,9 @@ class ArchivedFile {
                        // old row, populate from key
                        $this->sha1 = LocalRepo::getHashFromKey( $this->key );
                }
+               if ( !$this->title ) {
+                       $this->title = Title::makeTitleSafe( NS_FILE, $row->fa_name );
+               }
        }
 
        /**
@@ -272,6 +275,9 @@ class ArchivedFile {
         * @return Title
         */
        public function getTitle() {
+               if ( !$this->title ) {
+                       $this->load();
+               }
                return $this->title;
        }
 
@@ -572,6 +578,7 @@ class ArchivedFile {
        public function userCan( $field, User $user = null ) {
                $this->load();
 
-               return Revision::userCanBitfield( $this->deleted, $field, $user );
+               $title = $this->getTitle();
+               return Revision::userCanBitfield( $this->deleted, $field, $user, $title ? : null );
        }
 }
index f9e0a2d..b574c5e 100644 (file)
@@ -1231,9 +1231,25 @@ abstract class File {
                        }
                }
 
+               // Thumbnailing a very large file could result in network saturation if
+               // everyone does it at once.
+               if ( $this->getSize() >= 1e7 ) { // 10MB
+                       $that = $this;
+                       $work = new PoolCounterWorkViaCallback( 'GetLocalFileCopy', sha1( $this->getName() ),
+                               array(
+                                       'doWork' => function() use ( $that ) {
+                                               return $that->getLocalRefPath();
+                                       }
+                               )
+                       );
+                       $srcPath = $work->execute();
+               } else {
+                       $srcPath = $this->getLocalRefPath();
+               }
+
                // Original file
                return array(
-                       'path' => $this->getLocalRefPath(),
+                       'path' => $srcPath,
                        'width' => $this->getWidth(),
                        'height' => $this->getHeight()
                );
@@ -1312,9 +1328,9 @@ abstract class File {
         * @return ThumbnailImage
         */
        function iconThumb() {
-               global $wgScriptPath, $IP;
-               $assetsPath = "$wgScriptPath/assets/file-type-icons/";
-               $assetsDirectory = "$IP/assets/file-type-icons/";
+               global $wgResourceBasePath, $IP;
+               $assetsPath = "$wgResourceBasePath/resources/assets/file-type-icons/";
+               $assetsDirectory = "$IP/resources/assets/file-type-icons/";
 
                $try = array( 'fileicon-' . $this->getExtension() . '.png', 'fileicon.png' );
                foreach ( $try as $icon ) {
index f9c131f..01360d0 100644 (file)
@@ -50,7 +50,7 @@ class PackedOverlayImageGallery extends PackedImageGallery {
 
                return "\n\t\t\t" . $outerWrapper . '<div class="gallerytext">' . "\n"
                        . $galleryText
-                       . "\n\t\t\t</div>";
+                       . "\n\t\t\t</div></div>";
        }
 }
 
index c810f68..d582da3 100644 (file)
@@ -139,6 +139,7 @@ class HTMLForm extends ContextSource {
        protected $mFieldTree;
        protected $mShowReset = false;
        protected $mShowSubmit = true;
+       protected $mSubmitModifierClass = 'mw-ui-constructive';
 
        protected $mSubmitCallback;
        protected $mValidationErrorMessage;
@@ -473,6 +474,9 @@ class HTMLForm extends ContextSource {
                        if ( !empty( $field->mParams['nodata'] ) ) {
                                continue;
                        }
+                       if ( $field->isHidden( $this->mFieldData ) ) {
+                               continue;
+                       }
                        if ( $field->validate(
                                        $this->mFieldData[$fieldname],
                                        $this->mFieldData )
@@ -894,7 +898,7 @@ class HTMLForm extends ContextSource {
                        $attribs['class'] = array( 'mw-htmlform-submit' );
 
                        if ( $this->isVForm() || $useMediaWikiUIEverywhere ) {
-                               array_push( $attribs['class'], 'mw-ui-button', 'mw-ui-constructive' );
+                               array_push( $attribs['class'], 'mw-ui-button', $this->mSubmitModifierClass );
                        }
 
                        if ( $this->isVForm() ) {
@@ -1039,6 +1043,14 @@ class HTMLForm extends ContextSource {
                return $this;
        }
 
+       /**
+        * Identify that the submit button in the form has a destructive action
+        *
+        */
+       public function setSubmitDestructive() {
+               $this->mSubmitModifierClass = 'mw-ui-destructive';
+       }
+
        /**
         * Set the text for the submit button to a message
         * @since 1.19
index 70b1535..4cf2394 100644 (file)
@@ -113,7 +113,7 @@ abstract class HTMLFormField {
                                }
                                $data = $data[$key];
                        }
-                       $testValue = $data;
+                       $testValue = (string)$data;
                        break;
                }
 
index 597a03f..029911c 100644 (file)
@@ -80,7 +80,7 @@ class HTMLFormFieldCloner extends HTMLFormField {
         * specified key.
         *
         * @param string $key Array key under which these fields should be named
-        * @return HTMLFormFields[]
+        * @return HTMLFormField[]
         */
        protected function createFieldsForKey( $key ) {
                $fields = array();
@@ -303,6 +303,7 @@ class HTMLFormFieldCloner extends HTMLFormField {
                                'cssclass' => 'mw-htmlform-cloner-delete-button',
                                'default' => $this->msg( $label )->text(),
                        ) );
+                       $field->mParent = $this->mParent;
                        $v = $field->getDefault();
 
                        if ( $displayFormat === 'table' ) {
@@ -373,6 +374,7 @@ class HTMLFormFieldCloner extends HTMLFormField {
                        'cssclass' => 'mw-htmlform-cloner-create-button',
                        'default' => $this->msg( $label )->text(),
                ) );
+               $field->mParent = $this->mParent;
                $html .= $field->getInputHTML( $field->getDefault() );
 
                return $html;
index 1c7762b..7290740 100644 (file)
@@ -107,6 +107,15 @@ class CliInstaller extends Installer {
                if ( isset( $option['pass'] ) ) {
                        $this->setVar( '_AdminPassword', $option['pass'] );
                }
+
+               // Set up the default skins
+               $skins = $this->findExtensions( 'skins' );
+               $this->setVar( '_Skins', $skins );
+
+               if ( $skins ) {
+                       $skinNames = array_map( 'strtolower', $skins );
+                       $this->setVar( 'wgDefaultSkin', $this->getDefaultSkin( $skinNames ) );
+               }
        }
 
        /**
index 987925c..8160e3d 100644 (file)
@@ -286,27 +286,27 @@ abstract class Installer {
        public $licenses = array(
                'cc-by' => array(
                        'url' => 'http://creativecommons.org/licenses/by/3.0/',
-                       'icon' => '{$wgStylePath}/common/images/cc-by.png',
+                       'icon' => '{$wgResourceBasePath}/resources/assets/licenses/cc-by.png',
                ),
                'cc-by-sa' => array(
                        'url' => 'http://creativecommons.org/licenses/by-sa/3.0/',
-                       'icon' => '{$wgStylePath}/common/images/cc-by-sa.png',
+                       'icon' => '{$wgResourceBasePath}/resources/assets/licenses/cc-by-sa.png',
                ),
                'cc-by-nc-sa' => array(
                        'url' => 'http://creativecommons.org/licenses/by-nc-sa/3.0/',
-                       'icon' => '{$wgStylePath}/common/images/cc-by-nc-sa.png',
+                       'icon' => '{$wgResourceBasePath}/resources/assets/licenses/cc-by-nc-sa.png',
                ),
                'cc-0' => array(
                        'url' => 'https://creativecommons.org/publicdomain/zero/1.0/',
-                       'icon' => '{$wgStylePath}/common/images/cc-0.png',
+                       'icon' => '{$wgResourceBasePath}/resources/assets/licenses/cc-0.png',
                ),
                'pd' => array(
                        'url' => '',
-                       'icon' => '{$wgStylePath}/common/images/public-domain.png',
+                       'icon' => '{$wgResourceBasePath}/resources/assets/licenses/public-domain.png',
                ),
                'gfdl' => array(
                        'url' => 'http://www.gnu.org/copyleft/fdl.html',
-                       'icon' => '{$wgStylePath}/common/images/gnu-fdl.png',
+                       'icon' => '{$wgResourceBasePath}/resources/assets/licenses/gnu-fdl.png',
                ),
                'none' => array(
                        'url' => '',
@@ -1468,6 +1468,22 @@ abstract class Installer {
                return $exts;
        }
 
+       /**
+        * Returns a default value to be used for $wgDefaultSkin: the preferred skin, if available among
+        * the installed skins, or any other one otherwise.
+        *
+        * @param string[] $skinNames Names of installed skins.
+        * @return string
+        */
+       public function getDefaultSkin( array $skinNames ) {
+               $defaultSkin = $GLOBALS['wgDefaultSkin'];
+               if ( in_array( $defaultSkin, $skinNames ) ) {
+                       return $defaultSkin;
+               } else {
+                       return $skinNames[0];
+               }
+       }
+
        /**
         * Installs the auto-detected extensions.
         *
@@ -1772,11 +1788,6 @@ abstract class Installer {
 
                // Some of the environment checks make shell requests, remove limits
                $GLOBALS['wgMaxShellMemory'] = 0;
-
-               // Don't bother embedding images into generated CSS, which is not cached
-               $GLOBALS['wgResourceLoaderLESSFunctions']['embeddable'] = function ( $frame, $less ) {
-                       return $less->toBool( false );
-               };
        }
 
        /**
index 2a9c54c..2e31e41 100644 (file)
@@ -1037,7 +1037,7 @@ class WebInstallerOptions extends WebInstallerPage {
                                'var' => 'wgDefaultSkin',
                                'itemLabels' => array_fill_keys( $skinNames, 'config-skins-use-as-default' ),
                                'values' => $skinNames,
-                               'value' => $this->getVar( 'wgDefaultSkin', $this->getDefaultSkin( $skinNames ) ),
+                               'value' => $this->getVar( 'wgDefaultSkin', $this->parent->getDefaultSkin( $skinNames ) ),
                        ) );
 
                        foreach ( $skins as $skin ) {
@@ -1254,22 +1254,6 @@ class WebInstallerOptions extends WebInstallerPage {
                $this->addHTML( $this->getCCDoneBox() );
        }
 
-       /**
-        * Returns a default value to be used for $wgDefaultSkin: the preferred skin, if available among
-        * the installed skins, or any other one otherwise.
-        *
-        * @param string[] $skinNames Names of installed skins.
-        * @return string
-        */
-       public function getDefaultSkin( array $skinNames ) {
-               $defaultSkin = $GLOBALS['wgDefaultSkin'];
-               if ( in_array( $defaultSkin, $skinNames ) ) {
-                       return $defaultSkin;
-               } else {
-                       return $skinNames[0];
-               }
-       }
-
        /**
         * If the user skips this installer page, we still need to set up the default skins, but ignore
         * everything else.
@@ -1282,7 +1266,7 @@ class WebInstallerOptions extends WebInstallerPage {
 
                if ( $skins ) {
                        $skinNames = array_map( 'strtolower', $skins );
-                       $this->parent->setVar( 'wgDefaultSkin', $this->getDefaultSkin( $skinNames ) );
+                       $this->parent->setVar( 'wgDefaultSkin', $this->parent->getDefaultSkin( $skinNames ) );
                }
 
                return true;
index a834df8..0aeae7f 100644 (file)
        "config-skins-use-as-default": "Выкарыстоўваць па змоўчаньні гэтую тэму афармленьня",
        "config-skins-missing": "Тэмы афармленьня ня знойдзеныя; MediaWiki будзе ўжываць рэзэрвовую тэму афармленьня, пакуль вы не ўсталюеце нешта адпаведнае.",
        "config-skins-must-enable-some": "Вы павінны ўключыць як мінімум адну тэму афармленьня.",
+       "config-skins-must-enable-default": "Тэма афармленьня, абраная па змоўчаньні, мусіць быць уключаная.",
        "config-install-alreadydone": "'''Папярэджаньне:''' здаецца, што Вы ўжо ўсталёўвалі MediaWiki і спрабуеце зрабіць гэтай зноў.\nКалі ласка, перайдзіце на наступную старонку.",
        "config-install-begin": "Пасьля націску кнопкі «{{int:config-continue}}» пачнецца ўсталяваньне MediaWiki.\nКалі Вы жадаеце што-небудзь зьмяніць, націсьніце кнопку «{{int:config-back}}».",
        "config-install-step-done": "зроблена",
        "config-install-stats": "Ініцыялізацыі статыстыкі",
        "config-install-keys": "Стварэньне сакрэтных ключоў",
        "config-insecure-keys": "<strong>Папярэджаньне:</strong> {{PLURAL:$2|1=Ключ бясьпекі $1 створаны|Ключы бясьпекі $1 створаныя}} падчас усталяваньня, {{PLURAL:$2|1=не зьяўляецца паўнасьцю бясьпечным|не зьяўляюцца поўнасьцю бясьпечнымі}}. Рэкамэндуецца зьмяніць {{PLURAL:$2|1=яго ўручную|іх уручную}}.",
+       "config-install-updates": "Прадухіленьне запуску непатрэбных абнаўленьняў",
+       "config-install-updates-failed": "<strong>Памылка</strong>: устаўка ключоў абнаўленьня ў табліцы завершылася наступнай памылкай: $1",
        "config-install-sysop": "Стварэньне рахунку адміністратара",
        "config-install-subscribe-fail": "Немагчыма падпісацца на «mediawiki-announce»: $1",
        "config-install-subscribe-notpossible": "cURL не ўсталяваны, <code>allow_url_fopen</code> недаступны.",
index 7f353ec..028ef62 100644 (file)
@@ -1,5 +1,20 @@
 {
-       "@metadata": [],
+       "@metadata": {
+               "authors": [
+                       "Чаховіч Уладзіслаў"
+               ]
+       },
+       "config-desc": "Інсталятар MediaWiki",
+       "config-information": "Інфармацыя",
+       "config-localsettings-key": "Ключ абнаўлення:",
+       "config-your-language": "Ваша мова:",
+       "config-wiki-language": "Мова Вікі:",
+       "config-back": "← Назад",
+       "config-page-language": "Мова",
+       "config-page-welcome": "Сардэчна запрашаем у MediaWiki!",
+       "config-page-name": "Назва",
+       "config-page-options": "Настройкі",
+       "config-upload-settings": "Загрузка выяў і файлаў",
        "mainpagetext": "'''MediaWiki паспяхова ўсталяваная.'''",
        "mainpagedocfooter": "Гл. [//meta.wikimedia.org/wiki/Help:Contents Дапаможнік карыстальніка (англ.)] па далейшыя звесткі аб карыстанні вікі-праграмамі.\n\n== З чаго пачаць ==\n\n* [//www.mediawiki.org/wiki/Special:MyLanguage/Manual:Configuration_settings Пералік параметраў канфігурацыі (англ.)]\n* [//www.mediawiki.org/wiki/Special:MyLanguage/Manual:FAQ ЧАПЫ MediaWiki (англ.)]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-announce Ліставанне аб выпусках MediaWiki (англ.)]"
 }
index 1108f7f..78381be 100644 (file)
        "config-header-oracle": "Arventennoù Oracle",
        "config-header-mssql": "Arventennoù Microsoft SQL Server",
        "config-invalid-db-type": "Direizh eo ar seurt diaz roadennoù",
-       "config-missing-db-name": "Ret eo deoc'h merkañ un dalvoudenn evit \"Anv an diaz titouroù\"",
-       "config-missing-db-host": "Ret eo deoc'h merkañ un dalvoudenn evit \"Ostiz an diaz titouroù\"",
-       "config-missing-db-server-oracle": "Ret eo deoc'h merkañ un dalvoudenn evit \"Anv TNS an diaz titouroù\"",
+       "config-missing-db-name": "Ret eo deoc'h merkañ un dalvoudenn evit \"{{int:config-db-name}}\".",
+       "config-missing-db-host": "Ret eo deoc'h merkañ un dalvoudenn evit \"{{int:config-db-host}}\"",
+       "config-missing-db-server-oracle": "Ret eo deoc'h merkañ un dalvoudenn evit \"{{int:config-db-host-oracle}}\".",
        "config-invalid-db-server-oracle": "Direizh eo anv TNS an diaz titouroù \"$1\".\nOber hepken gant lizherennoù ASCII (a-z, A-Z), sifroù (0-9), arouezennoù islinennañ (_) ha pikoù (.).",
        "config-invalid-db-name": "Direizh eo anv an diaz titouroù \"$1\".\nOber hepken gant lizherennoù ASCII (a-z, A-Z), sifroù (0-9), arouezennoù islinennañ (_) ha tiredoù (-).",
        "config-invalid-db-prefix": "Direizh eo rakger an diaz titouroù \"$1\".\nOber hepken gant lizherennoù ASCII (a-z, A-Z), sifroù (0-9), arouezennoù islinennañ (_) ha tiredoù (-).",
index 284a356..f329db9 100644 (file)
        "config-advanced-settings": "Erweiterte Konfiguration",
        "config-cache-options": "Einstellungen für die Zwischenspeicherung von Objekten:",
        "config-cache-help": "Das Objektcaching wird dazu genutzt, die Geschwindigkeit von MediaWiki zu verbessern, indem häufig genutzte Daten zwischengespeichert werden.\nEs wird sehr empfohlen, es für mittelgroße bis große Wikis zu nutzen, aber auch für kleine Wikis ergeben sich erkennbare Geschwindigkeitsverbesserungen.",
-       "config-cache-none": "Kein Objektcaching (es wird keine Funktion entfernt, allerdings kann dies die Geschwindigkeit größerer Wikis negativ beeinflussen)",
+       "config-cache-none": "Kein Objektcaching (es wird keine Funktion entfernt, allerdings kann dies die Leistungsfähigkeit größerer Wikis negativ beeinflussen)",
        "config-cache-accel": "Objektcaching von PHP (APC, XCache oder WinCache)",
-       "config-cache-memcached": "Memcached Cacheserver nutzen (erfordert einen zusätzlichen Installationsvorgang mitsamt Konfiguration)",
+       "config-cache-memcached": "Memcached Cacheserver (erfordert einen zusätzlichen Installationsvorgang mitsamt Konfiguration)",
        "config-memcached-servers": "Memcached Cacheserver",
        "config-memcached-help": "Liste der für Memcached nutzbaren IP-Adressen.\nEs sollte eine je Zeile mitsamt des vorgesehenen Ports angegeben werden. Beispiele:\n127.0.0.1:11211 oder\n192.168.1.25:1234 usw.",
        "config-memcache-needservers": "Memcached wurde als Cacheserver ausgewählt. Dabei wurde allerdings kein Server angegeben.",
index 7d782d5..6b9f590 100644 (file)
@@ -15,7 +15,7 @@
        "config-license-none": "No licence footer",
        "config-license-gfdl": "GNU Free Documentation Licence 1.3 or later",
        "config-license-cc-choose": "Select a custom Creative Commons licence",
-       "config-license-help": "Many public wikis put all contributions under a [http://freedomdefined.org/Definition free licence].\nThis helps to create a sense of community ownership and encourages long-term contribution.\nIt is not generally necessary for a private or corporate wiki.\n\nIf you want to be able to use text from Wikipedia, and you want Wikipedia to be able to accept text copied from your wiki, you should choose '''Creative Commons Attribution Share Alike'''.\n\nWikipedia previously used the GNU Free Documentation Licence.\nThe GFDL is a valid licence, but it is difficult to understand.\nIt is also difficult to reuse content licenced under the GFDL.",
+       "config-license-help": "Many public wikis put all contributions under a [http://freedomdefined.org/Definition free licence].\nThis helps to create a sense of community ownership and encourages long-term contribution.\nIt is not generally necessary for a private or corporate wiki.\n\nIf you want to be able to use text from Wikipedia, and you want Wikipedia to be able to accept text copied from your wiki, you should choose <strong>{{int:config-license-cc-by-sa}}</strong>.\n\nWikipedia previously used the GNU Free Documentation Licence.\nThe GFDL is a valid licence, but it is difficult to understand.\nIt is also difficult to reuse content licenced under the GFDL.",
        "config-cc-error": "The Creative Commons licence chooser gave no result.\nEnter the licence name manually.",
        "config-cc-not-chosen": "Choose which Creative Commons licence you want and click \"proceed\".",
        "config-install-stats": "Initialising statistics"
index 0835f41..c40544d 100644 (file)
@@ -12,7 +12,8 @@
                        "아라",
                        "Elseweyr",
                        "Lliehu",
-                       "Syreeni"
+                       "Syreeni",
+                       "Stryn"
                ]
        },
        "config-desc": "MediaWiki-asennin",
@@ -56,6 +57,7 @@
        "config-env-good": "Asennusympäristö on tarkastettu.\nVoit asentaa MediaWikin.",
        "config-env-bad": "Asennusympäristö on tarkastettu.\nEt voi asentaa MediaWikiä.",
        "config-env-php": "PHP $1 on asennettu.",
+       "config-env-hhvm": "HHVM $1 on asennettu.",
        "config-no-db": "Sopivaa tietokanta-ajuria ei löytynyt! Sinun täytyy asentaa tietokanta-ajurit PHP:lle.\nSeuraavat tietokantatyypit ovat tuettuja: $1.",
        "config-outdated-sqlite": "<strong>Varoitus:</strong> sinulla on käytössä SQLite $1, joke on vanhempi kuin vähintään vaadittava versio $2. SQLite ei ole saatavilla.",
        "config-safe-mode": "'''Varoitus:''' PHP:n [http://www.php.net/features.safe-mode safe mode] -tila on aktiivinen.\nSe voi aiheuttaa ongelmia erityisesti tiedostojen tallentamisen ja matemaattisten kaavojen kanssa.",
index cd209c5..a42cb17 100644 (file)
@@ -49,6 +49,7 @@
        "config-env-good": "Rematou a comprobación da contorna.\nPode instalar MediaWiki.",
        "config-env-bad": "Rematou a comprobación da contorna.\nNon pode instalar MediaWiki.",
        "config-env-php": "Está instalado o PHP $1.",
+       "config-env-hhvm": "Está instalado o HHVM $1.",
        "config-unicode-using-utf8": "Usando utf8_normalize.so de Brion Vibber para a normalización Unicode.",
        "config-unicode-using-intl": "Usando a [http://pecl.php.net/intl extensión intl PECL] para a normalización Unicode.",
        "config-unicode-pure-php-warning": "<strong>Atención:</strong> A [http://pecl.php.net/intl extensión intl PECL] non está dispoñible para manexar a normalización Unicode; volvendo á implementación lenta de PHP puro.\nSe o seu sitio posúe un alto tráfico de visitantes, debería ler un chisco sobre a [//www.mediawiki.org/wiki/Special:MyLanguage/Unicode_normalization_considerations normalización Unicode].",
        "config-install-stats": "Iniciando as estatísticas",
        "config-install-keys": "Xerando as claves secretas",
        "config-insecure-keys": "<strong>Atención:</strong> {{PLURAL:$2|A clave de seguridade|As claves de seguridade}} ($1) {{PLURAL:$2|xerada|xeradas}} durante a instalación non {{PLURAL:$2|é|son}} completamente {{PLURAL:$2|segura|seguras}}. Considere a posibilidade de {{PLURAL:$2|cambiala|cambialas}} manualmente.",
+       "config-install-updates": "Evitar executar actualizacións innecesarias",
+       "config-install-updates-failed": "<strong>Error:</strong> a inserción de claves de actualización nas táboas fallou co seguinte erro: $1",
        "config-install-sysop": "Creando a conta de usuario de administrador",
        "config-install-subscribe-fail": "Non se puido subscribir á lista mediawiki-announce: $1",
        "config-install-subscribe-notpossible": "cURL non está instalado e <code>allow_url_fopen</code> non está dispoñible.",
index f9bcb91..879a330 100644 (file)
@@ -53,6 +53,7 @@
        "config-unicode-using-utf8": "utf8_normalize.so oleh Brion Vibber digunakan untuk penormalan Unicode.",
        "config-unicode-using-intl": "[http://pecl.php.net/intl Sambungan intl PECL] digunakan untuk penormalan Unicode.",
        "config-unicode-update-warning": "<strong>Amaran:</strong> Versi pembalut penormalan Unicode yang terpasang menggunakan perpustakaan [http://site.icu-project.org/ projek ICU] dalam versi yang lampau.\nAnda harus [//www.mediawiki.org/wiki/Special:MyLanguage/Unicode_normalization_considerations menaik taraf] jika Unicode penting bagi anda.",
+       "config-outdated-sqlite": "<strong>Amaran:</strong> anda mempunyai SQLite $1, yang lebih rendah daripada versi keperluan minimum $1. SQLite tidak akan disediakan.",
        "config-no-fts3": "<strong>Amaran:</strong> SQLite disusun tanpa [//sqlite.org/fts3.html modil FTS3], maka ciri-ciri pencarian tidak akan disediakan pada backend ini.",
        "config-mbstring": "<strong>Amaran keras: [http://www.php.net/manual/en/ref.mbstring.php#mbstring.overload mbstring.func_overload] sedang aktif!</strong>\nOpsyen ini menyebabkan ralat dan mungkin mencemari data secara tanpa diduga.\nAnda tidak boleh memasang atau menggunakan MediaWiki melainkan opsyen ini dinyahdayakan.",
        "config-pcre-old": "<strong>Amaran keras:</strong> PCRE $1 ke atas diperlukan.\nBinari PHP anda berpaut dengan PCRE $2.\n[https://www.mediawiki.org/wiki/Manual:Errors_and_symptoms/PCRE Keterangan lanjut].",
index dc65dd6..772ce96 100644 (file)
        "config-cache-help": "Explanation for what object caching is, next to {{msg|config-cache-options}}.",
        "config-cache-none": "Label for the object caching disabled option.",
        "config-cache-accel": "Label for the object caching via PHP option.",
-       "config-cache-memcached": "Label for the object caching via memcached option.",
+       "config-cache-memcached": "{{doc-important|Do not translate \"memcached\".}}\nLabel for the object caching via memcached option.",
        "config-memcached-servers": "{{doc-important|Do not translate \"memcached\".}}\n{{Identical|Memcached server}}",
        "config-memcached-help": "Prompt for the object caching via Memcached option for the user to define server(s) to be used.",
-       "config-memcache-needservers": "Error message for the object caching via Memcached option when the user has failed to define servers at the above prompt.",
+       "config-memcache-needservers": "Error message for the object caching via Memcached option when the user has failed to define servers at the above prompt.\n{{doc-important|Do not translate \"memcached\".}}",
        "config-memcache-badip": "Used as error message. Parameters:\n* $1 - IP address for Memcached\nSee also:\n* {{msg-mw|Config-memcache-noport}}\n* {{msg-mw|Config-memcache-badport}}",
-       "config-memcache-noport": "Used as error message. Parameters:\n* $1 - Memcached server name\nSee also:\n* {{msg-mw|Config-memcache-badip}}\n* {{msg-mw|Config-memcache-badport}}",
-       "config-memcache-badport": "Used as error message. Parameters:\n* $1 - 1 (hard-coded)\n* $2 - 65535 (hard-coded)\nSee also:\n* {{msg-mw|Config-memcache-badip}}\n* {{msg-mw|Config-memcache-noport}}",
+       "config-memcache-noport": "Used as error message. Parameters:\n* $1 - Memcached server name\nSee also:\n* {{msg-mw|Config-memcache-badip}}\n* {{msg-mw|Config-memcache-badport}}\n{{doc-important|Do not translate \"memcached\".}}",
+       "config-memcache-badport": "Used as error message. Parameters:\n* $1 - 1 (hard-coded)\n* $2 - 65535 (hard-coded)\nSee also:\n* {{msg-mw|Config-memcache-badip}}\n* {{msg-mw|Config-memcache-noport}}\n{{doc-important|Do not translate \"memcached\".}}",
        "config-extensions": "{{Identical|Extension}}",
        "config-extensions-help": "{{doc-important|Do not translate <code>./extensions</code>.}}\nUsed in help box.",
        "config-skins": "{{Identical|Skin}}",
index b860dc6..ce1b260 100644 (file)
        "config-install-stats": "初始化統計資訊",
        "config-install-keys": "產生秘密金鑰中",
        "config-insecure-keys": "<strong>警告:</strong>在安裝過程中所產生的 $2 組安全金鑰($1)並不完全安全。請考慮手動更改。",
+       "config-install-updates": "略過執行不需要的更新",
+       "config-install-updates-failed": "<strong>錯誤:</strong> 插入更新鍵值至資料表失敗,並出現以下錯誤:$1",
        "config-install-sysop": "正在建立管理員使用者帳號",
        "config-install-subscribe-fail": "無法訂閱 mediawiki-announce:$1",
        "config-install-subscribe-notpossible": "未安裝 cURL,因此無法使用 <code>allow_url_fopen</code> 設定項目。",
index 8a708f1..8ccceda 100644 (file)
@@ -84,10 +84,10 @@ class JobRunner {
                $backoffDeltas = array(); // map of (type => seconds)
                $wait = 'wait'; // block to read backoffs the first time
 
-               $jobsRun = 0; // counter
+               $jobsRun = 0;
                $timeMsTotal = 0;
                $flags = JobQueueGroup::USE_CACHE;
-               $sTime = microtime( true ); // time since jobs started running
+               $startTime = microtime( true ); // time since jobs started running
                $lastTime = microtime( true ); // time since last slave check
                do {
                        // Sync the persistent backoffs with concurrent runners
@@ -121,7 +121,7 @@ class JobRunner {
 
                                // Run the job...
                                wfProfileIn( __METHOD__ . '-' . get_class( $job ) );
-                               $sTime = microtime( true );
+                               $jobStartTime = microtime( true );
                                try {
                                        ++$jobsRun;
                                        $status = $job->run();
@@ -133,7 +133,7 @@ class JobRunner {
                                        $error = get_class( $e ) . ': ' . $e->getMessage();
                                        MWExceptionHandler::logException( $e );
                                }
-                               $timeMs = intval( ( microtime( true ) - $sTime ) * 1000 );
+                               $timeMs = intval( ( microtime( true ) - $jobStartTime ) * 1000 );
                                wfProfileOut( __METHOD__ . '-' . get_class( $job ) );
                                $timeMsTotal += $timeMs;
 
@@ -167,7 +167,7 @@ class JobRunner {
                                if ( $maxJobs && $jobsRun >= $maxJobs ) {
                                        $response['reached'] = 'job-limit';
                                        break;
-                               } elseif ( $maxTime && ( microtime( true ) - $sTime ) > $maxTime ) {
+                               } elseif ( $maxTime && ( microtime( true ) - $startTime ) > $maxTime ) {
                                        $response['reached'] = 'time-limit';
                                        break;
                                }
diff --git a/includes/libs/APACHE-LICENSE-2.0.txt b/includes/libs/APACHE-LICENSE-2.0.txt
new file mode 100644 (file)
index 0000000..d645695
--- /dev/null
@@ -0,0 +1,202 @@
+
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
+   APPENDIX: How to apply the Apache License to your work.
+
+      To apply the Apache License to your work, attach the following
+      boilerplate notice, with the fields enclosed by brackets "[]"
+      replaced with your own identifying information. (Don't include
+      the brackets!)  The text should be enclosed in the appropriate
+      comment syntax for the file format. We also recommend that a
+      file or class name and description of purpose be included on the
+      same "printed page" as the copyright notice for easier
+      identification within third-party archives.
+
+   Copyright [yyyy] [name of copyright owner]
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
index ae28163..7b7b407 100644 (file)
@@ -2,20 +2,20 @@
 /**
  * PHP port of CSSJanus.
  *
- * 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.
+ * Copyright 2008 Google Inc.
+ * Copyright 2010 Roan Kattouw
  *
- * 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.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
  *
- * 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
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
  *
  * @file
  */
  * This is a PHP port of CSSJanus, a utility that transforms CSS style sheets
  * written for LTR to RTL.
  *
- * The original Python version of CSSJanus is Copyright 2008 by Google Inc. and
- * is distributed under the Apache license. This PHP port is Copyright 2010 by
- * Roan Kattouw and is dual-licensed under the GPL (as in the comment above) and
- * the Apache (as in the original code) licenses.
- *
  * Original code: http://code.google.com/p/cssjanus/source/browse/trunk/cssjanus.py
- * License of original code: http://code.google.com/p/cssjanus/source/browse/trunk/LICENSE
- * @author Roan Kattouw
  *
+ * @author Lindsey Simon <elsigh@google.com>
+ * @author Roan Kattouw
  */
 class CSSJanus {
        // Patterns defined as null are built dynamically by buildPatterns()
diff --git a/includes/mail/EmailNotification.php b/includes/mail/EmailNotification.php
new file mode 100644 (file)
index 0000000..8215403
--- /dev/null
@@ -0,0 +1,512 @@
+<?php
+/**
+ * Classes used to send e-mails
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * @file
+ * @author <brion@pobox.com>
+ * @author <mail@tgries.de>
+ * @author Tim Starling
+ * @author Luke Welling lwelling@wikimedia.org
+ */
+
+/**
+ * This module processes the email notifications when the current page is
+ * changed. It looks up the table watchlist to find out which users are watching
+ * that page.
+ *
+ * The current implementation sends independent emails to each watching user for
+ * the following reason:
+ *
+ * - Each watching user will be notified about the page edit time expressed in
+ * his/her local time (UTC is shown additionally). To achieve this, we need to
+ * find the individual timeoffset of each watching user from the preferences..
+ *
+ * Suggested improvement to slack down the number of sent emails: We could think
+ * of sending out bulk mails (bcc:user1,user2...) for all these users having the
+ * same timeoffset in their preferences.
+ *
+ * Visit the documentation pages under http://meta.wikipedia.com/Enotif
+ */
+class EmailNotification {
+       protected $subject, $body, $replyto, $from;
+       protected $timestamp, $summary, $minorEdit, $oldid, $composed_common, $pageStatus;
+       protected $mailTargets = array();
+
+       /**
+        * @var Title
+        */
+       protected $title;
+
+       /**
+        * @var User
+        */
+       protected $editor;
+
+       /**
+        * @param User $editor The editor that triggered the update.  Their notification
+        *  timestamp will not be updated(they have already seen it)
+        * @param Title $title The title to update timestamps for
+        * @param string $timestamp Set the upate timestamp to this value
+        * @return int[]
+        */
+       public static function updateWatchlistTimestamp( User $editor, Title $title, $timestamp ) {
+               global $wgEnotifWatchlist, $wgShowUpdatedMarker;
+
+               if ( !$wgEnotifWatchlist && !$wgShowUpdatedMarker ) {
+                       return array();
+               }
+
+               $dbw = wfGetDB( DB_MASTER );
+               $res = $dbw->select( array( 'watchlist' ),
+                       array( 'wl_user' ),
+                       array(
+                               'wl_user != ' . intval( $editor->getID() ),
+                               'wl_namespace' => $title->getNamespace(),
+                               'wl_title' => $title->getDBkey(),
+                               'wl_notificationtimestamp IS NULL',
+                       ), __METHOD__
+               );
+
+               $watchers = array();
+               foreach ( $res as $row ) {
+                       $watchers[] = intval( $row->wl_user );
+               }
+
+               if ( $watchers ) {
+                       // Update wl_notificationtimestamp for all watching users except the editor
+                       $fname = __METHOD__;
+                       $dbw->onTransactionIdle(
+                               function () use ( $dbw, $timestamp, $watchers, $title, $fname ) {
+                                       $dbw->update( 'watchlist',
+                                               array( /* SET */
+                                                       'wl_notificationtimestamp' => $dbw->timestamp( $timestamp )
+                                               ), array( /* WHERE */
+                                                       'wl_user' => $watchers,
+                                                       'wl_namespace' => $title->getNamespace(),
+                                                       'wl_title' => $title->getDBkey(),
+                                               ), $fname
+                                       );
+                               }
+                       );
+               }
+
+               return $watchers;
+       }
+
+       /**
+        * Send emails corresponding to the user $editor editing the page $title.
+        * Also updates wl_notificationtimestamp.
+        *
+        * May be deferred via the job queue.
+        *
+        * @param User $editor
+        * @param Title $title
+        * @param string $timestamp
+        * @param string $summary
+        * @param bool $minorEdit
+        * @param bool $oldid (default: false)
+        * @param string $pageStatus (default: 'changed')
+        */
+       public function notifyOnPageChange( $editor, $title, $timestamp, $summary,
+               $minorEdit, $oldid = false, $pageStatus = 'changed'
+       ) {
+               global $wgEnotifUseJobQ, $wgEnotifMinorEdits, $wgUsersNotifiedOnAllChanges, $wgEnotifUserTalk;
+
+               if ( $title->getNamespace() < 0 ) {
+                       return;
+               }
+
+               // update wl_notificationtimestamp for watchers
+               $watchers = self::updateWatchlistTimestamp( $editor, $title, $timestamp );
+
+               $sendEmail = true;
+               // If nobody is watching the page, and there are no users notified on all changes
+               // don't bother creating a job/trying to send emails
+               // $watchers deals with $wgEnotifWatchlist
+               if ( !count( $watchers ) && !count( $wgUsersNotifiedOnAllChanges ) ) {
+                       $sendEmail = false;
+                       // Only send notification for non minor edits, unless $wgEnotifMinorEdits
+                       if ( !$minorEdit || ( $wgEnotifMinorEdits && !$editor->isAllowed( 'nominornewtalk' ) ) ) {
+                               $isUserTalkPage = ( $title->getNamespace() == NS_USER_TALK );
+                               if ( $wgEnotifUserTalk
+                                       && $isUserTalkPage
+                                       && $this->canSendUserTalkEmail( $editor, $title, $minorEdit )
+                               ) {
+                                       $sendEmail = true;
+                               }
+                       }
+               }
+
+               if ( !$sendEmail ) {
+                       return;
+               }
+
+               if ( $wgEnotifUseJobQ ) {
+                       $params = array(
+                               'editor' => $editor->getName(),
+                               'editorID' => $editor->getID(),
+                               'timestamp' => $timestamp,
+                               'summary' => $summary,
+                               'minorEdit' => $minorEdit,
+                               'oldid' => $oldid,
+                               'watchers' => $watchers,
+                               'pageStatus' => $pageStatus
+                       );
+                       $job = new EnotifNotifyJob( $title, $params );
+                       JobQueueGroup::singleton()->push( $job );
+               } else {
+                       $this->actuallyNotifyOnPageChange(
+                               $editor,
+                               $title,
+                               $timestamp,
+                               $summary,
+                               $minorEdit,
+                               $oldid,
+                               $watchers,
+                               $pageStatus
+                       );
+               }
+       }
+
+       /**
+        * Immediate version of notifyOnPageChange().
+        *
+        * Send emails corresponding to the user $editor editing the page $title.
+        * Also updates wl_notificationtimestamp.
+        *
+        * @param User $editor
+        * @param Title $title
+        * @param string $timestamp Edit timestamp
+        * @param string $summary Edit summary
+        * @param bool $minorEdit
+        * @param int $oldid Revision ID
+        * @param array $watchers Array of user IDs
+        * @param string $pageStatus
+        * @throws MWException
+        */
+       public function actuallyNotifyOnPageChange( $editor, $title, $timestamp, $summary, $minorEdit,
+               $oldid, $watchers, $pageStatus = 'changed' ) {
+               # we use $wgPasswordSender as sender's address
+               global $wgEnotifWatchlist;
+               global $wgEnotifMinorEdits, $wgEnotifUserTalk;
+
+               wfProfileIn( __METHOD__ );
+
+               # The following code is only run, if several conditions are met:
+               # 1. EmailNotification for pages (other than user_talk pages) must be enabled
+               # 2. minor edits (changes) are only regarded if the global flag indicates so
+
+               $isUserTalkPage = ( $title->getNamespace() == NS_USER_TALK );
+
+               $this->title = $title;
+               $this->timestamp = $timestamp;
+               $this->summary = $summary;
+               $this->minorEdit = $minorEdit;
+               $this->oldid = $oldid;
+               $this->editor = $editor;
+               $this->composed_common = false;
+               $this->pageStatus = $pageStatus;
+
+               $formattedPageStatus = array( 'deleted', 'created', 'moved', 'restored', 'changed' );
+
+               wfRunHooks( 'UpdateUserMailerFormattedPageStatus', array( &$formattedPageStatus ) );
+               if ( !in_array( $this->pageStatus, $formattedPageStatus ) ) {
+                       wfProfileOut( __METHOD__ );
+                       throw new MWException( 'Not a valid page status!' );
+               }
+
+               $userTalkId = false;
+
+               if ( !$minorEdit || ( $wgEnotifMinorEdits && !$editor->isAllowed( 'nominornewtalk' ) ) ) {
+                       if ( $wgEnotifUserTalk
+                               && $isUserTalkPage
+                               && $this->canSendUserTalkEmail( $editor, $title, $minorEdit )
+                       ) {
+                               $targetUser = User::newFromName( $title->getText() );
+                               $this->compose( $targetUser );
+                               $userTalkId = $targetUser->getId();
+                       }
+
+                       if ( $wgEnotifWatchlist ) {
+                               // Send updates to watchers other than the current editor
+                               $userArray = UserArray::newFromIDs( $watchers );
+                               foreach ( $userArray as $watchingUser ) {
+                                       if ( $watchingUser->getOption( 'enotifwatchlistpages' )
+                                               && ( !$minorEdit || $watchingUser->getOption( 'enotifminoredits' ) )
+                                               && $watchingUser->isEmailConfirmed()
+                                               && $watchingUser->getID() != $userTalkId
+                                       ) {
+                                               if ( wfRunHooks( 'SendWatchlistEmailNotification', array( $watchingUser, $title, $this ) ) ) {
+                                                       $this->compose( $watchingUser );
+                                               }
+                                       }
+                               }
+                       }
+               }
+
+               global $wgUsersNotifiedOnAllChanges;
+               foreach ( $wgUsersNotifiedOnAllChanges as $name ) {
+                       if ( $editor->getName() == $name ) {
+                               // No point notifying the user that actually made the change!
+                               continue;
+                       }
+                       $user = User::newFromName( $name );
+                       $this->compose( $user );
+               }
+
+               $this->sendMails();
+               wfProfileOut( __METHOD__ );
+       }
+
+       /**
+        * @param User $editor
+        * @param Title $title
+        * @param bool $minorEdit
+        * @return bool
+        */
+       private function canSendUserTalkEmail( $editor, $title, $minorEdit ) {
+               global $wgEnotifUserTalk;
+               $isUserTalkPage = ( $title->getNamespace() == NS_USER_TALK );
+
+               if ( $wgEnotifUserTalk && $isUserTalkPage ) {
+                       $targetUser = User::newFromName( $title->getText() );
+
+                       if ( !$targetUser || $targetUser->isAnon() ) {
+                               wfDebug( __METHOD__ . ": user talk page edited, but user does not exist\n" );
+                       } elseif ( $targetUser->getId() == $editor->getId() ) {
+                               wfDebug( __METHOD__ . ": user edited their own talk page, no notification sent\n" );
+                       } elseif ( $targetUser->getOption( 'enotifusertalkpages' )
+                               && ( !$minorEdit || $targetUser->getOption( 'enotifminoredits' ) )
+                       ) {
+                               if ( !$targetUser->isEmailConfirmed() ) {
+                                       wfDebug( __METHOD__ . ": talk page owner doesn't have validated email\n" );
+                               } elseif ( !wfRunHooks( 'AbortTalkPageEmailNotification', array( $targetUser, $title ) ) ) {
+                                       wfDebug( __METHOD__ . ": talk page update notification is aborted for this user\n" );
+                               } else {
+                                       wfDebug( __METHOD__ . ": sending talk page update notification\n" );
+                                       return true;
+                               }
+                       } else {
+                               wfDebug( __METHOD__ . ": talk page owner doesn't want notifications\n" );
+                       }
+               }
+               return false;
+       }
+
+       /**
+        * Generate the generic "this page has been changed" e-mail text.
+        */
+       private function composeCommonMailtext() {
+               global $wgPasswordSender, $wgNoReplyAddress;
+               global $wgEnotifFromEditor, $wgEnotifRevealEditorAddress;
+               global $wgEnotifImpersonal, $wgEnotifUseRealName;
+
+               $this->composed_common = true;
+
+               # You as the WikiAdmin and Sysops can make use of plenty of
+               # named variables when composing your notification emails while
+               # simply editing the Meta pages
+
+               $keys = array();
+               $postTransformKeys = array();
+               $pageTitleUrl = $this->title->getCanonicalURL();
+               $pageTitle = $this->title->getPrefixedText();
+
+               if ( $this->oldid ) {
+                       // Always show a link to the diff which triggered the mail. See bug 32210.
+                       $keys['$NEWPAGE'] = "\n\n" . wfMessage( 'enotif_lastdiff',
+                                       $this->title->getCanonicalURL( array( 'diff' => 'next', 'oldid' => $this->oldid ) ) )
+                                       ->inContentLanguage()->text();
+
+                       if ( !$wgEnotifImpersonal ) {
+                               // For personal mail, also show a link to the diff of all changes
+                               // since last visited.
+                               $keys['$NEWPAGE'] .= "\n\n" . wfMessage( 'enotif_lastvisited',
+                                               $this->title->getCanonicalURL( array( 'diff' => '0', 'oldid' => $this->oldid ) ) )
+                                               ->inContentLanguage()->text();
+                       }
+                       $keys['$OLDID'] = $this->oldid;
+                       // Deprecated since MediaWiki 1.21, not used by default. Kept for backwards-compatibility.
+                       $keys['$CHANGEDORCREATED'] = wfMessage( 'changed' )->inContentLanguage()->text();
+               } else {
+                       # clear $OLDID placeholder in the message template
+                       $keys['$OLDID'] = '';
+                       $keys['$NEWPAGE'] = '';
+                       // Deprecated since MediaWiki 1.21, not used by default. Kept for backwards-compatibility.
+                       $keys['$CHANGEDORCREATED'] = wfMessage( 'created' )->inContentLanguage()->text();
+               }
+
+               $keys['$PAGETITLE'] = $this->title->getPrefixedText();
+               $keys['$PAGETITLE_URL'] = $this->title->getCanonicalURL();
+               $keys['$PAGEMINOREDIT'] = $this->minorEdit ?
+                       wfMessage( 'minoredit' )->inContentLanguage()->text() : '';
+               $keys['$UNWATCHURL'] = $this->title->getCanonicalURL( 'action=unwatch' );
+
+               if ( $this->editor->isAnon() ) {
+                       # real anon (user:xxx.xxx.xxx.xxx)
+                       $keys['$PAGEEDITOR'] = wfMessage( 'enotif_anon_editor', $this->editor->getName() )
+                               ->inContentLanguage()->text();
+                       $keys['$PAGEEDITOR_EMAIL'] = wfMessage( 'noemailtitle' )->inContentLanguage()->text();
+
+               } else {
+                       $keys['$PAGEEDITOR'] = $wgEnotifUseRealName && $this->editor->getRealName() !== ''
+                               ? $this->editor->getRealName() : $this->editor->getName();
+                       $emailPage = SpecialPage::getSafeTitleFor( 'Emailuser', $this->editor->getName() );
+                       $keys['$PAGEEDITOR_EMAIL'] = $emailPage->getCanonicalURL();
+               }
+
+               $keys['$PAGEEDITOR_WIKI'] = $this->editor->getUserPage()->getCanonicalURL();
+               $keys['$HELPPAGE'] = wfExpandUrl(
+                       Skin::makeInternalOrExternalUrl( wfMessage( 'helppage' )->inContentLanguage()->text() )
+               );
+
+               # Replace this after transforming the message, bug 35019
+               $postTransformKeys['$PAGESUMMARY'] = $this->summary == '' ? ' - ' : $this->summary;
+
+               // Now build message's subject and body
+
+               // Messages:
+               // enotif_subject_deleted, enotif_subject_created, enotif_subject_moved,
+               // enotif_subject_restored, enotif_subject_changed
+               $this->subject = wfMessage( 'enotif_subject_' . $this->pageStatus )->inContentLanguage()
+                       ->params( $pageTitle, $keys['$PAGEEDITOR'] )->text();
+
+               // Messages:
+               // enotif_body_intro_deleted, enotif_body_intro_created, enotif_body_intro_moved,
+               // enotif_body_intro_restored, enotif_body_intro_changed
+               $keys['$PAGEINTRO'] = wfMessage( 'enotif_body_intro_' . $this->pageStatus )
+                       ->inContentLanguage()->params( $pageTitle, $keys['$PAGEEDITOR'], $pageTitleUrl )
+                       ->text();
+
+               $body = wfMessage( 'enotif_body' )->inContentLanguage()->plain();
+               $body = strtr( $body, $keys );
+               $body = MessageCache::singleton()->transform( $body, false, null, $this->title );
+               $this->body = wordwrap( strtr( $body, $postTransformKeys ), 72 );
+
+               # Reveal the page editor's address as REPLY-TO address only if
+               # the user has not opted-out and the option is enabled at the
+               # global configuration level.
+               $adminAddress = new MailAddress( $wgPasswordSender,
+                       wfMessage( 'emailsender' )->inContentLanguage()->text() );
+               if ( $wgEnotifRevealEditorAddress
+                       && ( $this->editor->getEmail() != '' )
+                       && $this->editor->getOption( 'enotifrevealaddr' )
+               ) {
+                       $editorAddress = MailAddress::newFromUser( $this->editor );
+                       if ( $wgEnotifFromEditor ) {
+                               $this->from = $editorAddress;
+                       } else {
+                               $this->from = $adminAddress;
+                               $this->replyto = $editorAddress;
+                       }
+               } else {
+                       $this->from = $adminAddress;
+                       $this->replyto = new MailAddress( $wgNoReplyAddress );
+               }
+       }
+
+       /**
+        * Compose a mail to a given user and either queue it for sending, or send it now,
+        * depending on settings.
+        *
+        * Call sendMails() to send any mails that were queued.
+        * @param User $user
+        */
+       function compose( $user ) {
+               global $wgEnotifImpersonal;
+
+               if ( !$this->composed_common ) {
+                       $this->composeCommonMailtext();
+               }
+
+               if ( $wgEnotifImpersonal ) {
+                       $this->mailTargets[] = MailAddress::newFromUser( $user );
+               } else {
+                       $this->sendPersonalised( $user );
+               }
+       }
+
+       /**
+        * Send any queued mails
+        */
+       function sendMails() {
+               global $wgEnotifImpersonal;
+               if ( $wgEnotifImpersonal ) {
+                       $this->sendImpersonal( $this->mailTargets );
+               }
+       }
+
+       /**
+        * Does the per-user customizations to a notification e-mail (name,
+        * timestamp in proper timezone, etc) and sends it out.
+        * Returns true if the mail was sent successfully.
+        *
+        * @param User $watchingUser
+        * @return bool
+        * @private
+        */
+       function sendPersonalised( $watchingUser ) {
+               global $wgContLang, $wgEnotifUseRealName;
+               // From the PHP manual:
+               //   Note: The to parameter cannot be an address in the form of
+               //   "Something <someone@example.com>". The mail command will not parse
+               //   this properly while talking with the MTA.
+               $to = MailAddress::newFromUser( $watchingUser );
+
+               # $PAGEEDITDATE is the time and date of the page change
+               # expressed in terms of individual local time of the notification
+               # recipient, i.e. watching user
+               $body = str_replace(
+                       array( '$WATCHINGUSERNAME',
+                               '$PAGEEDITDATE',
+                               '$PAGEEDITTIME' ),
+                       array( $wgEnotifUseRealName && $watchingUser->getRealName() !== ''
+                               ? $watchingUser->getRealName() : $watchingUser->getName(),
+                               $wgContLang->userDate( $this->timestamp, $watchingUser ),
+                               $wgContLang->userTime( $this->timestamp, $watchingUser ) ),
+                       $this->body );
+
+               return UserMailer::send( $to, $this->from, $this->subject, $body, $this->replyto );
+       }
+
+       /**
+        * Same as sendPersonalised but does impersonal mail suitable for bulk
+        * mailing.  Takes an array of MailAddress objects.
+        * @param MailAddress[] $addresses
+        * @return Status|null
+        */
+       function sendImpersonal( $addresses ) {
+               global $wgContLang;
+
+               if ( empty( $addresses ) ) {
+                       return null;
+               }
+
+               $body = str_replace(
+                       array( '$WATCHINGUSERNAME',
+                               '$PAGEEDITDATE',
+                               '$PAGEEDITTIME' ),
+                       array( wfMessage( 'enotif_impersonal_salutation' )->inContentLanguage()->text(),
+                               $wgContLang->date( $this->timestamp, false, false ),
+                               $wgContLang->time( $this->timestamp, false, false ) ),
+                       $this->body );
+
+               return UserMailer::send( $addresses, $this->from, $this->subject, $body, $this->replyto );
+       }
+
+}
diff --git a/includes/mail/MailAddress.php b/includes/mail/MailAddress.php
new file mode 100644 (file)
index 0000000..6817908
--- /dev/null
@@ -0,0 +1,91 @@
+<?php
+/**
+ * Classes used to send e-mails
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * @file
+ * @author <brion@pobox.com>
+ * @author <mail@tgries.de>
+ * @author Tim Starling
+ * @author Luke Welling lwelling@wikimedia.org
+ */
+
+/**
+ * Stores a single person's name and email address.
+ * These are passed in via the constructor, and will be returned in SMTP
+ * header format when requested.
+ */
+class MailAddress {
+       /**
+        * @param string $address String with an email address, or a User object
+        * @param string $name Human-readable name if a string address is given
+        * @param string $realName Human-readable real name if a string address is given
+        */
+       function __construct( $address, $name = null, $realName = null ) {
+               if ( is_object( $address ) && $address instanceof User ) {
+                       // Old calling format, now deprecated
+                       wfDeprecated( __METHOD__ . ' with a User object' , '1.24' );
+                       $this->address = $address->getEmail();
+                       $this->name = $address->getName();
+                       $this->realName = $address->getRealName();
+               } else {
+                       $this->address = strval( $address );
+                       $this->name = strval( $name );
+                       $this->realName = strval( $realName );
+               }
+       }
+
+       /**
+        * Create a new MailAddress object for the given user
+        *
+        * @since 1.24
+        * @param User $user
+        * @return MailAddress
+        */
+       public static function newFromUser( User $user ) {
+               return new MailAddress( $user->getEmail(), $user->getName(), $user->getRealName() );
+       }
+
+       /**
+        * Return formatted and quoted address to insert into SMTP headers
+        * @return string
+        */
+       function toString() {
+               # PHP's mail() implementation under Windows is somewhat shite, and
+               # can't handle "Joe Bloggs <joe@bloggs.com>" format email addresses,
+               # so don't bother generating them
+               if ( $this->address ) {
+                       if ( $this->name != '' && !wfIsWindows() ) {
+                               global $wgEnotifUseRealName;
+                               $name = ( $wgEnotifUseRealName && $this->realName !== '' ) ? $this->realName : $this->name;
+                               $quoted = UserMailer::quotedPrintable( $name );
+                               if ( strpos( $quoted, '.' ) !== false || strpos( $quoted, ',' ) !== false ) {
+                                       $quoted = '"' . $quoted . '"';
+                               }
+                               return "$quoted <{$this->address}>";
+                       } else {
+                               return $this->address;
+                       }
+               } else {
+                       return "";
+               }
+       }
+
+       function __toString() {
+               return $this->toString();
+       }
+}
diff --git a/includes/mail/UserMailer.php b/includes/mail/UserMailer.php
new file mode 100644 (file)
index 0000000..b5a57a8
--- /dev/null
@@ -0,0 +1,425 @@
+<?php
+/**
+ * Classes used to send e-mails
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * @file
+ * @author <brion@pobox.com>
+ * @author <mail@tgries.de>
+ * @author Tim Starling
+ * @author Luke Welling lwelling@wikimedia.org
+ */
+
+/**
+ * Collection of static functions for sending mail
+ */
+class UserMailer {
+       private static $mErrorString;
+
+       /**
+        * Send mail using a PEAR mailer
+        *
+        * @param UserMailer $mailer
+        * @param string $dest
+        * @param string $headers
+        * @param string $body
+        *
+        * @return Status
+        */
+       protected static function sendWithPear( $mailer, $dest, $headers, $body ) {
+               $mailResult = $mailer->send( $dest, $headers, $body );
+
+               # Based on the result return an error string,
+               if ( PEAR::isError( $mailResult ) ) {
+                       wfDebug( "PEAR::Mail failed: " . $mailResult->getMessage() . "\n" );
+                       return Status::newFatal( 'pear-mail-error', $mailResult->getMessage() );
+               } else {
+                       return Status::newGood();
+               }
+       }
+
+       /**
+        * Creates a single string from an associative array
+        *
+        * @param array $headers Associative Array: keys are header field names,
+        *                 values are ... values.
+        * @param string $endl The end of line character.  Defaults to "\n"
+        *
+        * Note RFC2822 says newlines must be CRLF (\r\n)
+        * but php mail naively "corrects" it and requires \n for the "correction" to work
+        *
+        * @return string
+        */
+       static function arrayToHeaderString( $headers, $endl = "\n" ) {
+               $strings = array();
+               foreach ( $headers as $name => $value ) {
+                       // Prevent header injection by stripping newlines from value
+                       $value = self::sanitizeHeaderValue( $value );
+                       $strings[] = "$name: $value";
+               }
+               return implode( $endl, $strings );
+       }
+
+       /**
+        * Create a value suitable for the MessageId Header
+        *
+        * @return string
+        */
+       static function makeMsgId() {
+               global $wgSMTP, $wgServer;
+
+               $msgid = uniqid( wfWikiID() . ".", true ); /* true required for cygwin */
+               if ( is_array( $wgSMTP ) && isset( $wgSMTP['IDHost'] ) && $wgSMTP['IDHost'] ) {
+                       $domain = $wgSMTP['IDHost'];
+               } else {
+                       $url = wfParseUrl( $wgServer );
+                       $domain = $url['host'];
+               }
+               return "<$msgid@$domain>";
+       }
+
+       /**
+        * This function will perform a direct (authenticated) login to
+        * a SMTP Server to use for mail relaying if 'wgSMTP' specifies an
+        * array of parameters. It requires PEAR:Mail to do that.
+        * Otherwise it just uses the standard PHP 'mail' function.
+        *
+        * @param MailAddress|MailAddress[] $to Recipient's email (or an array of them)
+        * @param MailAddress $from Sender's email
+        * @param string $subject Email's subject.
+        * @param string $body Email's text or Array of two strings to be the text and html bodies
+        * @param MailAddress $replyto Optional reply-to email (default: null).
+        * @param string $contentType Optional custom Content-Type (default: text/plain; charset=UTF-8)
+        * @throws MWException
+        * @throws Exception
+        * @return Status
+        */
+       public static function send( $to, $from, $subject, $body, $replyto = null,
+               $contentType = 'text/plain; charset=UTF-8'
+       ) {
+               global $wgSMTP, $wgEnotifMaxRecips, $wgAdditionalMailParams, $wgAllowHTMLEmail;
+               $mime = null;
+               if ( !is_array( $to ) ) {
+                       $to = array( $to );
+               }
+
+               // mail body must have some content
+               $minBodyLen = 10;
+               // arbitrary but longer than Array or Object to detect casting error
+
+               // body must either be a string or an array with text and body
+               if (
+                       !(
+                               !is_array( $body ) &&
+                               strlen( $body ) >= $minBodyLen
+                       )
+                       &&
+                       !(
+                               is_array( $body ) &&
+                               isset( $body['text'] ) &&
+                               isset( $body['html'] ) &&
+                               strlen( $body['text'] ) >= $minBodyLen &&
+                               strlen( $body['html'] ) >= $minBodyLen
+                       )
+               ) {
+                       // if it is neither we have a problem
+                       return Status::newFatal( 'user-mail-no-body' );
+               }
+
+               if ( !$wgAllowHTMLEmail && is_array( $body ) ) {
+                       // HTML not wanted.  Dump it.
+                       $body = $body['text'];
+               }
+
+               wfDebug( __METHOD__ . ': sending mail to ' . implode( ', ', $to ) . "\n" );
+
+               # Make sure we have at least one address
+               $has_address = false;
+               foreach ( $to as $u ) {
+                       if ( $u->address ) {
+                               $has_address = true;
+                               break;
+                       }
+               }
+               if ( !$has_address ) {
+                       return Status::newFatal( 'user-mail-no-addy' );
+               }
+
+               # Forge email headers
+               # -------------------
+               #
+               # WARNING
+               #
+               # DO NOT add To: or Subject: headers at this step. They need to be
+               # handled differently depending upon the mailer we are going to use.
+               #
+               # To:
+               #  PHP mail() first argument is the mail receiver. The argument is
+               #  used as a recipient destination and as a To header.
+               #
+               #  PEAR mailer has a recipient argument which is only used to
+               #  send the mail. If no To header is given, PEAR will set it to
+               #  to 'undisclosed-recipients:'.
+               #
+               #  NOTE: To: is for presentation, the actual recipient is specified
+               #  by the mailer using the Rcpt-To: header.
+               #
+               # Subject:
+               #  PHP mail() second argument to pass the subject, passing a Subject
+               #  as an additional header will result in a duplicate header.
+               #
+               #  PEAR mailer should be passed a Subject header.
+               #
+               # -- hashar 20120218
+
+               $headers['From'] = $from->toString();
+               $returnPath = $from->address;
+               $extraParams = $wgAdditionalMailParams;
+
+               // Hook to generate custom VERP address for 'Return-Path'
+               wfRunHooks( 'UserMailerChangeReturnPath', array( $to, &$returnPath ) );
+               # Add the envelope sender address using the -f command line option when PHP mail() is used.
+               # Will default to the $from->address when the UserMailerChangeReturnPath hook fails and the
+               # generated VERP address when the hook runs effectively.
+               $extraParams .= ' -f ' . $returnPath;
+
+               $headers['Return-Path'] = $returnPath;
+
+               if ( $replyto ) {
+                       $headers['Reply-To'] = $replyto->toString();
+               }
+
+               $headers['Date'] = MWTimestamp::getLocalInstance()->format( 'r' );
+               $headers['Message-ID'] = self::makeMsgId();
+               $headers['X-Mailer'] = 'MediaWiki mailer';
+
+               # Line endings need to be different on Unix and Windows due to
+               # the bug described at http://trac.wordpress.org/ticket/2603
+               if ( wfIsWindows() ) {
+                       $endl = "\r\n";
+               } else {
+                       $endl = "\n";
+               }
+
+               if ( is_array( $body ) ) {
+                       // we are sending a multipart message
+                       wfDebug( "Assembling multipart mime email\n" );
+                       if ( !stream_resolve_include_path( 'Mail/mime.php' ) ) {
+                               wfDebug( "PEAR Mail_Mime package is not installed. Falling back to text email.\n" );
+                               // remove the html body for text email fall back
+                               $body = $body['text'];
+                       } else {
+                               require_once 'Mail/mime.php';
+                               if ( wfIsWindows() ) {
+                                       $body['text'] = str_replace( "\n", "\r\n", $body['text'] );
+                                       $body['html'] = str_replace( "\n", "\r\n", $body['html'] );
+                               }
+                               $mime = new Mail_mime( array(
+                                       'eol' => $endl,
+                                       'text_charset' => 'UTF-8',
+                                       'html_charset' => 'UTF-8'
+                               ) );
+                               $mime->setTXTBody( $body['text'] );
+                               $mime->setHTMLBody( $body['html'] );
+                               $body = $mime->get(); // must call get() before headers()
+                               $headers = $mime->headers( $headers );
+                       }
+               }
+               if ( $mime === null ) {
+                       // sending text only, either deliberately or as a fallback
+                       if ( wfIsWindows() ) {
+                               $body = str_replace( "\n", "\r\n", $body );
+                       }
+                       $headers['MIME-Version'] = '1.0';
+                       $headers['Content-type'] = ( is_null( $contentType ) ?
+                               'text/plain; charset=UTF-8' : $contentType );
+                       $headers['Content-transfer-encoding'] = '8bit';
+               }
+
+               $ret = wfRunHooks( 'AlternateUserMailer', array( $headers, $to, $from, $subject, $body ) );
+               if ( $ret === false ) {
+                       // the hook implementation will return false to skip regular mail sending
+                       return Status::newGood();
+               } elseif ( $ret !== true ) {
+                       // the hook implementation will return a string to pass an error message
+                       return Status::newFatal( 'php-mail-error', $ret );
+               }
+
+               if ( is_array( $wgSMTP ) ) {
+                       #
+                       # PEAR MAILER
+                       #
+
+                       if ( !stream_resolve_include_path( 'Mail.php' ) ) {
+                               throw new MWException( 'PEAR mail package is not installed' );
+                       }
+                       require_once 'Mail.php';
+
+                       wfSuppressWarnings();
+
+                       // Create the mail object using the Mail::factory method
+                       $mail_object =& Mail::factory( 'smtp', $wgSMTP );
+                       if ( PEAR::isError( $mail_object ) ) {
+                               wfDebug( "PEAR::Mail factory failed: " . $mail_object->getMessage() . "\n" );
+                               wfRestoreWarnings();
+                               return Status::newFatal( 'pear-mail-error', $mail_object->getMessage() );
+                       }
+
+                       wfDebug( "Sending mail via PEAR::Mail\n" );
+
+                       $headers['Subject'] = self::quotedPrintable( $subject );
+
+                       # When sending only to one recipient, shows it its email using To:
+                       if ( count( $to ) == 1 ) {
+                               $headers['To'] = $to[0]->toString();
+                       }
+
+                       # Split jobs since SMTP servers tends to limit the maximum
+                       # number of possible recipients.
+                       $chunks = array_chunk( $to, $wgEnotifMaxRecips );
+                       foreach ( $chunks as $chunk ) {
+                               $status = self::sendWithPear( $mail_object, $chunk, $headers, $body );
+                               # FIXME : some chunks might be sent while others are not!
+                               if ( !$status->isOK() ) {
+                                       wfRestoreWarnings();
+                                       return $status;
+                               }
+                       }
+                       wfRestoreWarnings();
+                       return Status::newGood();
+               } else {
+                       #
+                       # PHP mail()
+                       #
+                       if ( count( $to ) > 1 ) {
+                               $headers['To'] = 'undisclosed-recipients:;';
+                       }
+                       $headers = self::arrayToHeaderString( $headers, $endl );
+
+                       wfDebug( "Sending mail via internal mail() function\n" );
+
+                       self::$mErrorString = '';
+                       $html_errors = ini_get( 'html_errors' );
+                       ini_set( 'html_errors', '0' );
+                       set_error_handler( 'UserMailer::errorHandler' );
+
+                       try {
+                               $safeMode = wfIniGetBool( 'safe_mode' );
+
+                               foreach ( $to as $recip ) {
+                                       if ( $safeMode ) {
+                                               $sent = mail( $recip, self::quotedPrintable( $subject ), $body, $headers );
+                                       } else {
+                                               $sent = mail(
+                                                       $recip,
+                                                       self::quotedPrintable( $subject ),
+                                                       $body,
+                                                       $headers,
+                                                       $extraParams
+                                               );
+                                       }
+                               }
+                       } catch ( Exception $e ) {
+                               restore_error_handler();
+                               throw $e;
+                       }
+
+                       restore_error_handler();
+                       ini_set( 'html_errors', $html_errors );
+
+                       if ( self::$mErrorString ) {
+                               wfDebug( "Error sending mail: " . self::$mErrorString . "\n" );
+                               return Status::newFatal( 'php-mail-error', self::$mErrorString );
+                       } elseif ( !$sent ) {
+                               // mail function only tells if there's an error
+                               wfDebug( "Unknown error sending mail\n" );
+                               return Status::newFatal( 'php-mail-error-unknown' );
+                       } else {
+                               return Status::newGood();
+                       }
+               }
+       }
+
+       /**
+        * Set the mail error message in self::$mErrorString
+        *
+        * @param int $code Error number
+        * @param string $string Error message
+        */
+       static function errorHandler( $code, $string ) {
+               self::$mErrorString = preg_replace( '/^mail\(\)(\s*\[.*?\])?: /', '', $string );
+       }
+
+       /**
+        * Strips bad characters from a header value to prevent PHP mail header injection attacks
+        * @param string $val String to be santizied
+        * @return string
+        */
+       public static function sanitizeHeaderValue( $val ) {
+               return strtr( $val, array( "\r" => '', "\n" => '' ) );
+       }
+
+       /**
+        * Converts a string into a valid RFC 822 "phrase", such as is used for the sender name
+        * @param string $phrase
+        * @return string
+        */
+       public static function rfc822Phrase( $phrase ) {
+               // Remove line breaks
+               $phrase = self::sanitizeHeaderValue( $phrase );
+               // Remove quotes
+               $phrase = str_replace( '"', '', $phrase );
+               return '"' . $phrase . '"';
+       }
+
+       /**
+        * Converts a string into quoted-printable format
+        * @since 1.17
+        *
+        * From PHP5.3 there is a built in function quoted_printable_encode()
+        * This method does not duplicate that.
+        * This method is doing Q encoding inside encoded-words as defined by RFC 2047
+        * This is for email headers.
+        * The built in quoted_printable_encode() is for email bodies
+        * @param string $string
+        * @param string $charset
+        * @return string
+        */
+       public static function quotedPrintable( $string, $charset = '' ) {
+               # Probably incomplete; see RFC 2045
+               if ( empty( $charset ) ) {
+                       $charset = 'UTF-8';
+               }
+               $charset = strtoupper( $charset );
+               $charset = str_replace( 'ISO-8859', 'ISO8859', $charset ); // ?
+
+               $illegal = '\x00-\x08\x0b\x0c\x0e-\x1f\x7f-\xff=';
+               $replace = $illegal . '\t ?_';
+               if ( !preg_match( "/[$illegal]/", $string ) ) {
+                       return $string;
+               }
+               $out = "=?$charset?Q?";
+               $out .= preg_replace_callback( "/([$replace])/",
+                       array( __CLASS__, 'quotedPrintableCallback' ), $string );
+               $out .= '?=';
+               return $out;
+       }
+
+       protected static function quotedPrintableCallback( $matches ) {
+               return sprintf( "=%02X", ord( $matches[1] ) );
+       }
+}
index b2802dd..e81b37d 100644 (file)
  *
  * @ingroup Media
  */
-class BitmapHandler extends ImageHandler {
-       /**
-        * @param File $image
-        * @param array $params Transform parameters. Entries with the keys 'width'
-        * and 'height' are the respective screen width and height, while the keys
-        * 'physicalWidth' and 'physicalHeight' indicate the thumbnail dimensions.
-        * @return bool
-        */
-       function normaliseParams( $image, &$params ) {
-               if ( !parent::normaliseParams( $image, $params ) ) {
-                       return false;
-               }
-
-               # Obtain the source, pre-rotation dimensions
-               $srcWidth = $image->getWidth( $params['page'] );
-               $srcHeight = $image->getHeight( $params['page'] );
-
-               # Don't make an image bigger than the source
-               if ( $params['physicalWidth'] >= $srcWidth ) {
-                       $params['physicalWidth'] = $srcWidth;
-                       $params['physicalHeight'] = $srcHeight;
-
-                       # Skip scaling limit checks if no scaling is required
-                       # due to requested size being bigger than source.
-                       if ( !$image->mustRender() ) {
-                               return true;
-                       }
-               }
-
-               # Check if the file is smaller than the maximum image area for thumbnailing
-               $checkImageAreaHookResult = null;
-               wfRunHooks(
-                       'BitmapHandlerCheckImageArea',
-                       array( $image, &$params, &$checkImageAreaHookResult )
-               );
-
-               if ( is_null( $checkImageAreaHookResult ) ) {
-                       global $wgMaxImageArea;
-
-                       if ( $srcWidth * $srcHeight > $wgMaxImageArea
-                               && !( $image->getMimeType() == 'image/jpeg'
-                                       && self::getScalerType( false, false ) == 'im' )
-                       ) {
-                               # Only ImageMagick can efficiently downsize jpg images without loading
-                               # the entire file in memory
-                               return false;
-                       }
-               } else {
-                       return $checkImageAreaHookResult;
-               }
-
-               return true;
-       }
-
-       /**
-        * Extracts the width/height if the image will be scaled before rotating
-        *
-        * This will match the physical size/aspect ratio of the original image
-        * prior to application of the rotation -- so for a portrait image that's
-        * stored as raw landscape with 90-degress rotation, the resulting size
-        * will be wider than it is tall.
-        *
-        * @param array $params Parameters as returned by normaliseParams
-        * @param int $rotation The rotation angle that will be applied
-        * @return array ($width, $height) array
-        */
-       public function extractPreRotationDimensions( $params, $rotation ) {
-               if ( $rotation == 90 || $rotation == 270 ) {
-                       # We'll resize before rotation, so swap the dimensions again
-                       $width = $params['physicalHeight'];
-                       $height = $params['physicalWidth'];
-               } else {
-                       $width = $params['physicalWidth'];
-                       $height = $params['physicalHeight'];
-               }
-
-               return array( $width, $height );
-       }
-
-       /**
-        * @param File $image
-        * @param string $dstPath
-        * @param string $dstUrl
-        * @param array $params
-        * @param int $flags
-        * @return MediaTransformError|ThumbnailImage|TransformParameterError
-        */
-       function doTransform( $image, $dstPath, $dstUrl, $params, $flags = 0 ) {
-               if ( !$this->normaliseParams( $image, $params ) ) {
-                       return new TransformParameterError( $params );
-               }
-
-               # Create a parameter array to pass to the scaler
-               $scalerParams = array(
-                       # The size to which the image will be resized
-                       'physicalWidth' => $params['physicalWidth'],
-                       'physicalHeight' => $params['physicalHeight'],
-                       'physicalDimensions' => "{$params['physicalWidth']}x{$params['physicalHeight']}",
-                       # The size of the image on the page
-                       'clientWidth' => $params['width'],
-                       'clientHeight' => $params['height'],
-                       # Comment as will be added to the Exif of the thumbnail
-                       'comment' => isset( $params['descriptionUrl'] )
-                               ? "File source: {$params['descriptionUrl']}"
-                               : '',
-                       # Properties of the original image
-                       'srcWidth' => $image->getWidth(),
-                       'srcHeight' => $image->getHeight(),
-                       'mimeType' => $image->getMimeType(),
-                       'dstPath' => $dstPath,
-                       'dstUrl' => $dstUrl,
-               );
-
-               if ( isset( $params['quality'] ) && $params['quality'] === 'low' ) {
-                       $scalerParams['quality'] = 30;
-               }
-
-               # Determine scaler type
-               $scaler = self::getScalerType( $dstPath );
-
-               wfDebug( __METHOD__ . ": creating {$scalerParams['physicalDimensions']} " .
-                       "thumbnail at $dstPath using scaler $scaler\n" );
-
-               if ( !$image->mustRender() &&
-                       $scalerParams['physicalWidth'] == $scalerParams['srcWidth']
-                       && $scalerParams['physicalHeight'] == $scalerParams['srcHeight']
-                       && !isset( $scalerParams['quality'] )
-               ) {
-
-                       # normaliseParams (or the user) wants us to return the unscaled image
-                       wfDebug( __METHOD__ . ": returning unscaled image\n" );
-
-                       return $this->getClientScalingThumbnailImage( $image, $scalerParams );
-               }
-
-               if ( $scaler == 'client' ) {
-                       # Client-side image scaling, use the source URL
-                       # Using the destination URL in a TRANSFORM_LATER request would be incorrect
-                       return $this->getClientScalingThumbnailImage( $image, $scalerParams );
-               }
-
-               if ( $flags & self::TRANSFORM_LATER ) {
-                       wfDebug( __METHOD__ . ": Transforming later per flags.\n" );
-                       $newParams = array(
-                               'width' => $scalerParams['clientWidth'],
-                               'height' => $scalerParams['clientHeight']
-                       );
-                       if ( isset( $params['quality'] ) ) {
-                               $newParams['quality'] = $params['quality'];
-                       }
-                       return new ThumbnailImage( $image, $dstUrl, false, $newParams );
-               }
-
-               # Try to make a target path for the thumbnail
-               if ( !wfMkdirParents( dirname( $dstPath ), null, __METHOD__ ) ) {
-                       wfDebug( __METHOD__ . ": Unable to create thumbnail destination " .
-                               "directory, falling back to client scaling\n" );
-
-                       return $this->getClientScalingThumbnailImage( $image, $scalerParams );
-               }
-
-               # Transform functions and binaries need a FS source file
-               $thumbnailSource = $image->getThumbnailSource( $params );
-
-               $scalerParams['srcPath'] = $thumbnailSource['path'];
-               $scalerParams['srcWidth'] = $thumbnailSource['width'];
-               $scalerParams['srcHeight'] = $thumbnailSource['height'];
-
-               if ( $scalerParams['srcPath'] === false ) { // Failed to get local copy
-                       wfDebugLog( 'thumbnail',
-                               sprintf( 'Thumbnail failed on %s: could not get local copy of "%s"',
-                                       wfHostname(), $image->getName() ) );
-
-                       return new MediaTransformError( 'thumbnail_error',
-                               $scalerParams['clientWidth'], $scalerParams['clientHeight'],
-                               wfMessage( 'filemissing' )->text()
-                       );
-               }
-
-               # Try a hook
-               $mto = null;
-               wfRunHooks( 'BitmapHandlerTransform', array( $this, $image, &$scalerParams, &$mto ) );
-               if ( !is_null( $mto ) ) {
-                       wfDebug( __METHOD__ . ": Hook to BitmapHandlerTransform created an mto\n" );
-                       $scaler = 'hookaborted';
-               }
-
-               switch ( $scaler ) {
-                       case 'hookaborted':
-                               # Handled by the hook above
-                               /** @var MediaTransformOutput $mto */
-                               $err = $mto->isError() ? $mto : false;
-                               break;
-                       case 'im':
-                               $err = $this->transformImageMagick( $image, $scalerParams );
-                               break;
-                       case 'custom':
-                               $err = $this->transformCustom( $image, $scalerParams );
-                               break;
-                       case 'imext':
-                               $err = $this->transformImageMagickExt( $image, $scalerParams );
-                               break;
-                       case 'gd':
-                       default:
-                               $err = $this->transformGd( $image, $scalerParams );
-                               break;
-               }
-
-               # Remove the file if a zero-byte thumbnail was created, or if there was an error
-               $removed = $this->removeBadFile( $dstPath, (bool)$err );
-               if ( $err ) {
-                       # transform returned MediaTransforError
-                       return $err;
-               } elseif ( $removed ) {
-                       # Thumbnail was zero-byte and had to be removed
-                       return new MediaTransformError( 'thumbnail_error',
-                               $scalerParams['clientWidth'], $scalerParams['clientHeight'],
-                               wfMessage( 'unknown-error' )->text()
-                       );
-               } elseif ( $mto ) {
-                       return $mto;
-               } else {
-                       $newParams = array(
-                               'width' => $scalerParams['clientWidth'],
-                               'height' => $scalerParams['clientHeight']
-                       );
-                       if ( isset( $params['quality'] ) ) {
-                               $newParams['quality'] = $params['quality'];
-                       }
-                       return new ThumbnailImage( $image, $dstUrl, $dstPath, $newParams );
-               }
-       }
+class BitmapHandler extends TransformationalImageHandler {
 
        /**
         * Returns which scaler type should be used. Creates parent directories
@@ -265,9 +34,9 @@ class BitmapHandler extends ImageHandler {
         *
         * @param string $dstPath
         * @param bool $checkDstPath
-        * @return string One of client, im, custom, gd, imext
+        * @return string|Callable One of client, im, custom, gd, imext or an array( object, method )
         */
-       protected static function getScalerType( $dstPath, $checkDstPath = true ) {
+       protected function getScalerType( $dstPath, $checkDstPath = true ) {
                global $wgUseImageResize, $wgUseImageMagick, $wgCustomConvertCommand;
 
                if ( !$dstPath && $checkDstPath ) {
@@ -290,25 +59,6 @@ class BitmapHandler extends ImageHandler {
                return $scaler;
        }
 
-       /**
-        * Get a ThumbnailImage that respresents an image that will be scaled
-        * client side
-        *
-        * @param File $image File associated with this thumbnail
-        * @param array $scalerParams Array with scaler params
-        * @return ThumbnailImage
-        *
-        * @todo FIXME: No rotation support
-        */
-       protected function getClientScalingThumbnailImage( $image, $scalerParams ) {
-               $params = array(
-                       'width' => $scalerParams['clientWidth'],
-                       'height' => $scalerParams['clientHeight']
-               );
-
-               return new ThumbnailImage( $image, $image->getURL(), null, $params );
-       }
-
        /**
         * Transform an image using ImageMagick
         *
@@ -544,18 +294,6 @@ class BitmapHandler extends ImageHandler {
                return false; # No error
        }
 
-       /**
-        * Get a MediaTransformError with error 'thumbnail_error'
-        *
-        * @param array $params Parameter array as passed to the transform* functions
-        * @param string $errMsg Error message
-        * @return MediaTransformError
-        */
-       public function getMediaTransformError( $params, $errMsg ) {
-               return new MediaTransformError( 'thumbnail_error', $params['clientWidth'],
-                       $params['clientHeight'], $errMsg );
-       }
-
        /**
         * Transform an image using the built in GD library
         *
@@ -651,131 +389,8 @@ class BitmapHandler extends ImageHandler {
        }
 
        /**
-        * Escape a string for ImageMagick's property input (e.g. -set -comment)
-        * See InterpretImageProperties() in magick/property.c
-        * @param string $s
-        * @return string
-        */
-       function escapeMagickProperty( $s ) {
-               // Double the backslashes
-               $s = str_replace( '\\', '\\\\', $s );
-               // Double the percents
-               $s = str_replace( '%', '%%', $s );
-               // Escape initial - or @
-               if ( strlen( $s ) > 0 && ( $s[0] === '-' || $s[0] === '@' ) ) {
-                       $s = '\\' . $s;
-               }
-
-               return $s;
-       }
-
-       /**
-        * Escape a string for ImageMagick's input filenames. See ExpandFilenames()
-        * and GetPathComponent() in magick/utility.c.
-        *
-        * This won't work with an initial ~ or @, so input files should be prefixed
-        * with the directory name.
-        *
-        * Glob character unescaping is broken in ImageMagick before 6.6.1-5, but
-        * it's broken in a way that doesn't involve trying to convert every file
-        * in a directory, so we're better off escaping and waiting for the bugfix
-        * to filter down to users.
-        *
-        * @param string $path The file path
-        * @param bool|string $scene The scene specification, or false if there is none
-        * @throws MWException
-        * @return string
-        */
-       function escapeMagickInput( $path, $scene = false ) {
-               # Die on initial metacharacters (caller should prepend path)
-               $firstChar = substr( $path, 0, 1 );
-               if ( $firstChar === '~' || $firstChar === '@' ) {
-                       throw new MWException( __METHOD__ . ': cannot escape this path name' );
-               }
-
-               # Escape glob chars
-               $path = preg_replace( '/[*?\[\]{}]/', '\\\\\0', $path );
-
-               return $this->escapeMagickPath( $path, $scene );
-       }
-
-       /**
-        * Escape a string for ImageMagick's output filename. See
-        * InterpretImageFilename() in magick/image.c.
-        * @param string $path The file path
-        * @param bool|string $scene The scene specification, or false if there is none
-        * @return string
-        */
-       function escapeMagickOutput( $path, $scene = false ) {
-               $path = str_replace( '%', '%%', $path );
-
-               return $this->escapeMagickPath( $path, $scene );
-       }
-
-       /**
-        * Armour a string against ImageMagick's GetPathComponent(). This is a
-        * helper function for escapeMagickInput() and escapeMagickOutput().
-        *
-        * @param string $path The file path
-        * @param bool|string $scene The scene specification, or false if there is none
-        * @throws MWException
-        * @return string
-        */
-       protected function escapeMagickPath( $path, $scene = false ) {
-               # Die on format specifiers (other than drive letters). The regex is
-               # meant to match all the formats you get from "convert -list format"
-               if ( preg_match( '/^([a-zA-Z0-9-]+):/', $path, $m ) ) {
-                       if ( wfIsWindows() && is_dir( $m[0] ) ) {
-                               // OK, it's a drive letter
-                               // ImageMagick has a similar exception, see IsMagickConflict()
-                       } else {
-                               throw new MWException( __METHOD__ . ': unexpected colon character in path name' );
-                       }
-               }
-
-               # If there are square brackets, add a do-nothing scene specification
-               # to force a literal interpretation
-               if ( $scene === false ) {
-                       if ( strpos( $path, '[' ) !== false ) {
-                               $path .= '[0--1]';
-                       }
-               } else {
-                       $path .= "[$scene]";
-               }
-
-               return $path;
-       }
-
-       /**
-        * Retrieve the version of the installed ImageMagick
-        * You can use PHPs version_compare() to use this value
-        * Value is cached for one hour.
-        * @return string Representing the IM version.
+        * Callback for transformGd when transforming jpeg images.
         */
-       protected function getMagickVersion() {
-               global $wgMemc;
-
-               $cache = $wgMemc->get( "imagemagick-version" );
-               if ( !$cache ) {
-                       global $wgImageMagickConvertCommand;
-                       $cmd = wfEscapeShellArg( $wgImageMagickConvertCommand ) . ' -version';
-                       wfDebug( __METHOD__ . ": Running convert -version\n" );
-                       $retval = '';
-                       $return = wfShellExec( $cmd, $retval );
-                       $x = preg_match( '/Version: ImageMagick ([0-9]*\.[0-9]*\.[0-9]*)/', $return, $matches );
-                       if ( $x != 1 ) {
-                               wfDebug( __METHOD__ . ": ImageMagick version check failed\n" );
-
-                               return null;
-                       }
-                       $wgMemc->set( "imagemagick-version", $matches[1], 3600 );
-
-                       return $matches[1];
-               }
-
-               return $cache;
-       }
-
        // FIXME: transformImageMagick() & transformImageMagickExt() uses JPEG quality 80, here it's 95?
        static function imageJpegWrapper( $dst_image, $thumbPath, $quality = 95 ) {
                imageinterlace( $dst_image );
@@ -787,8 +402,8 @@ class BitmapHandler extends ImageHandler {
         *
         * @return bool
         */
-       public static function canRotate() {
-               $scaler = self::getScalerType( null, false );
+       public function canRotate() {
+               $scaler = $this->getScalerType( null, false );
                switch ( $scaler ) {
                        case 'im':
                                # ImageMagick supports autorotation
@@ -810,12 +425,12 @@ class BitmapHandler extends ImageHandler {
         * @see $wgEnableAutoRotation
         * @return bool Whether auto rotation is enabled
         */
-       public static function autoRotateEnabled() {
+       public function autoRotateEnabled() {
                global $wgEnableAutoRotation;
 
                if ( $wgEnableAutoRotation === null ) {
-                       // Only enable auto-rotation when the bitmap handler can rotate
-                       $wgEnableAutoRotation = BitmapHandler::canRotate();
+                       // Only enable auto-rotation when we actually can
+                       return $this->canRotate();
                }
 
                return $wgEnableAutoRotation;
@@ -834,7 +449,7 @@ class BitmapHandler extends ImageHandler {
                $rotation = ( $params['rotation'] + $this->getRotation( $file ) ) % 360;
                $scene = false;
 
-               $scaler = self::getScalerType( null, false );
+               $scaler = $this->getScalerType( null, false );
                switch ( $scaler ) {
                        case 'im':
                                $cmd = wfEscapeShellArg( $wgImageMagickConvertCommand ) . " " .
@@ -872,15 +487,4 @@ class BitmapHandler extends ImageHandler {
                                        "$scaler rotation not implemented" );
                }
        }
-
-       /**
-        * Returns whether the file needs to be rendered. Returns true if the
-        * file requires rotation and we are able to rotate it.
-        *
-        * @param File $file
-        * @return bool
-        */
-       public function mustRender( $file ) {
-               return self::canRotate() && $this->getRotation( $file ) != 0;
-       }
 }
index ae1ff9d..b7657cb 100644 (file)
@@ -173,7 +173,7 @@ class ExifBitmapHandler extends BitmapHandler {
 
                // Don't just call $image->getMetadata(); FSFile::getPropsFromPath() calls us with a bogus object.
                // This may mean we read EXIF data twice on initial upload.
-               if ( BitmapHandler::autoRotateEnabled() ) {
+               if ( $this->autoRotateEnabled() ) {
                        $meta = $this->getMetadata( $image, $path );
                        $rotation = $this->getRotationForExif( $meta );
                } else {
@@ -202,7 +202,7 @@ class ExifBitmapHandler extends BitmapHandler {
         * @return int 0, 90, 180 or 270
         */
        public function getRotation( $file ) {
-               if ( !BitmapHandler::autoRotateEnabled() ) {
+               if ( !$this->autoRotateEnabled() ) {
                        return 0;
                }
 
index 13c2a91..64ca011 100644 (file)
@@ -745,10 +745,10 @@ abstract class MediaHandler {
 
        /**
         * True if the handler can rotate the media
-        * @since 1.21
+        * @since 1.24 non-static. From 1.21-1.23 was static
         * @return bool
         */
-       public static function canRotate() {
+       public function canRotate() {
                return false;
        }
 
diff --git a/includes/media/TransformationalImageHandler.php b/includes/media/TransformationalImageHandler.php
new file mode 100644 (file)
index 0000000..3e3be3d
--- /dev/null
@@ -0,0 +1,593 @@
+<?php
+/**
+ * Base class for handlers which require transforming images in a
+ * similar way as BitmapHandler does.
+ *
+ * This was split from BitmapHandler on the basis that some extensions
+ * might want to work in a similar way to BitmapHandler, but for
+ * different formats.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * @file
+ * @ingroup Media
+ */
+
+/**
+ * Handler for images that need to be transformed
+ *
+ * @since 1.24
+ * @ingroup Media
+ */
+abstract class TransformationalImageHandler extends ImageHandler {
+       /**
+        * @param File $image
+        * @param array $params Transform parameters. Entries with the keys 'width'
+        * and 'height' are the respective screen width and height, while the keys
+        * 'physicalWidth' and 'physicalHeight' indicate the thumbnail dimensions.
+        * @return bool
+        */
+       function normaliseParams( $image, &$params ) {
+               if ( !parent::normaliseParams( $image, $params ) ) {
+                       return false;
+               }
+
+               # Obtain the source, pre-rotation dimensions
+               $srcWidth = $image->getWidth( $params['page'] );
+               $srcHeight = $image->getHeight( $params['page'] );
+
+               # Don't make an image bigger than the source
+               if ( $params['physicalWidth'] >= $srcWidth ) {
+                       $params['physicalWidth'] = $srcWidth;
+                       $params['physicalHeight'] = $srcHeight;
+
+                       # Skip scaling limit checks if no scaling is required
+                       # due to requested size being bigger than source.
+                       if ( !$image->mustRender() ) {
+                               return true;
+                       }
+               }
+
+               # Check if the file is smaller than the maximum image area for thumbnailing
+               # For historical reasons, hook starts with BitmapHandler
+               $checkImageAreaHookResult = null;
+               wfRunHooks(
+                       'BitmapHandlerCheckImageArea',
+                       array( $image, &$params, &$checkImageAreaHookResult )
+               );
+
+               if ( is_null( $checkImageAreaHookResult ) ) {
+                       global $wgMaxImageArea;
+
+                       if ( $srcWidth * $srcHeight > $wgMaxImageArea
+                               && !( $image->getMimeType() == 'image/jpeg'
+                                       && $this->getScalerType( false, false ) == 'im' )
+                       ) {
+                               # Only ImageMagick can efficiently downsize jpg images without loading
+                               # the entire file in memory
+                               return false;
+                       }
+               } else {
+                       return $checkImageAreaHookResult;
+               }
+
+               return true;
+       }
+
+       /**
+        * Extracts the width/height if the image will be scaled before rotating
+        *
+        * This will match the physical size/aspect ratio of the original image
+        * prior to application of the rotation -- so for a portrait image that's
+        * stored as raw landscape with 90-degress rotation, the resulting size
+        * will be wider than it is tall.
+        *
+        * @param array $params Parameters as returned by normaliseParams
+        * @param int $rotation The rotation angle that will be applied
+        * @return array ($width, $height) array
+        */
+       public function extractPreRotationDimensions( $params, $rotation ) {
+               if ( $rotation == 90 || $rotation == 270 ) {
+                       # We'll resize before rotation, so swap the dimensions again
+                       $width = $params['physicalHeight'];
+                       $height = $params['physicalWidth'];
+               } else {
+                       $width = $params['physicalWidth'];
+                       $height = $params['physicalHeight'];
+               }
+
+               return array( $width, $height );
+       }
+
+       /**
+        * Create a thumbnail.
+        *
+        * This sets up various parameters, and then calls a helper method
+        * based on $this->getScalerType in order to scale the image.
+        *
+        * @param File $image
+        * @param string $dstPath
+        * @param string $dstUrl
+        * @param array $params
+        * @param int $flags
+        * @return MediaTransformError|ThumbnailImage|TransformParameterError
+        */
+       function doTransform( $image, $dstPath, $dstUrl, $params, $flags = 0 ) {
+               if ( !$this->normaliseParams( $image, $params ) ) {
+                       return new TransformParameterError( $params );
+               }
+
+               # Create a parameter array to pass to the scaler
+               $scalerParams = array(
+                       # The size to which the image will be resized
+                       'physicalWidth' => $params['physicalWidth'],
+                       'physicalHeight' => $params['physicalHeight'],
+                       'physicalDimensions' => "{$params['physicalWidth']}x{$params['physicalHeight']}",
+                       # The size of the image on the page
+                       'clientWidth' => $params['width'],
+                       'clientHeight' => $params['height'],
+                       # Comment as will be added to the Exif of the thumbnail
+                       'comment' => isset( $params['descriptionUrl'] )
+                               ? "File source: {$params['descriptionUrl']}"
+                               : '',
+                       # Properties of the original image
+                       'srcWidth' => $image->getWidth(),
+                       'srcHeight' => $image->getHeight(),
+                       'mimeType' => $image->getMimeType(),
+                       'dstPath' => $dstPath,
+                       'dstUrl' => $dstUrl,
+               );
+
+               if ( isset( $params['quality'] ) && $params['quality'] === 'low' ) {
+                       $scalerParams['quality'] = 30;
+               }
+
+               // For subclasses that might be paged.
+               if ( $image->isMultipage() && isset( $params['page'] ) ) {
+                       $scalerParams['page'] = intval( $params['page'] );
+               }
+
+               # Determine scaler type
+               $scaler = $this->getScalerType( $dstPath );
+
+               if ( is_array( $scaler ) ) {
+                       $scalerName = get_class( $scaler[0] );
+               } else {
+                       $scalerName = $scaler;
+               }
+
+               wfDebug( __METHOD__ . ": creating {$scalerParams['physicalDimensions']} " .
+                       "thumbnail at $dstPath using scaler $scalerName\n" );
+
+               if ( !$image->mustRender() &&
+                       $scalerParams['physicalWidth'] == $scalerParams['srcWidth']
+                       && $scalerParams['physicalHeight'] == $scalerParams['srcHeight']
+                       && !isset( $scalerParams['quality'] )
+               ) {
+
+                       # normaliseParams (or the user) wants us to return the unscaled image
+                       wfDebug( __METHOD__ . ": returning unscaled image\n" );
+
+                       return $this->getClientScalingThumbnailImage( $image, $scalerParams );
+               }
+
+               if ( $scaler == 'client' ) {
+                       # Client-side image scaling, use the source URL
+                       # Using the destination URL in a TRANSFORM_LATER request would be incorrect
+                       return $this->getClientScalingThumbnailImage( $image, $scalerParams );
+               }
+
+               if ( $flags & self::TRANSFORM_LATER ) {
+                       wfDebug( __METHOD__ . ": Transforming later per flags.\n" );
+                       $newParams = array(
+                               'width' => $scalerParams['clientWidth'],
+                               'height' => $scalerParams['clientHeight']
+                       );
+                       if ( isset( $params['quality'] ) ) {
+                               $newParams['quality'] = $params['quality'];
+                       }
+                       if ( isset( $params['page'] ) && $params['page'] ) {
+                               $newParams['page'] = $params['page'];
+                       }
+                       return new ThumbnailImage( $image, $dstUrl, false, $newParams );
+               }
+
+               # Try to make a target path for the thumbnail
+               if ( !wfMkdirParents( dirname( $dstPath ), null, __METHOD__ ) ) {
+                       wfDebug( __METHOD__ . ": Unable to create thumbnail destination " .
+                               "directory, falling back to client scaling\n" );
+
+                       return $this->getClientScalingThumbnailImage( $image, $scalerParams );
+               }
+
+               # Transform functions and binaries need a FS source file
+               $thumbnailSource = $this->getThumbnailSource( $image, $params );
+
+               $scalerParams['srcPath'] = $thumbnailSource['path'];
+               $scalerParams['srcWidth'] = $thumbnailSource['width'];
+               $scalerParams['srcHeight'] = $thumbnailSource['height'];
+
+               if ( $scalerParams['srcPath'] === false ) { // Failed to get local copy
+                       wfDebugLog( 'thumbnail',
+                               sprintf( 'Thumbnail failed on %s: could not get local copy of "%s"',
+                                       wfHostname(), $image->getName() ) );
+
+                       return new MediaTransformError( 'thumbnail_error',
+                               $scalerParams['clientWidth'], $scalerParams['clientHeight'],
+                               wfMessage( 'filemissing' )->text()
+                       );
+               }
+
+               # Try a hook. Called "Bitmap" for historical reasons.
+               /** @var $mto MediaTransformOutput */
+               $mto = null;
+               wfRunHooks( 'BitmapHandlerTransform', array( $this, $image, &$scalerParams, &$mto ) );
+               if ( !is_null( $mto ) ) {
+                       wfDebug( __METHOD__ . ": Hook to BitmapHandlerTransform created an mto\n" );
+                       $scaler = 'hookaborted';
+               }
+
+               // $scaler will return a MediaTransformError on failure, or false on success.
+               // If the scaler is succesful, it will have created a thumbnail at the destination
+               // path.
+               if ( is_array( $scaler ) && is_callable( $scaler ) ) {
+                       // Allow subclasses to specify their own rendering methods.
+                       $err = call_user_func( $scaler, $image, $scalerParams );
+               } else {
+                       switch ( $scaler ) {
+                               case 'hookaborted':
+                                       # Handled by the hook above
+                                       $err = $mto->isError() ? $mto : false;
+                                       break;
+                               case 'im':
+                                       $err = $this->transformImageMagick( $image, $scalerParams );
+                                       break;
+                               case 'custom':
+                                       $err = $this->transformCustom( $image, $scalerParams );
+                                       break;
+                               case 'imext':
+                                       $err = $this->transformImageMagickExt( $image, $scalerParams );
+                                       break;
+                               case 'gd':
+                               default:
+                                       $err = $this->transformGd( $image, $scalerParams );
+                                       break;
+                       }
+               }
+
+               # Remove the file if a zero-byte thumbnail was created, or if there was an error
+               $removed = $this->removeBadFile( $dstPath, (bool)$err );
+               if ( $err ) {
+                       # transform returned MediaTransforError
+                       return $err;
+               } elseif ( $removed ) {
+                       # Thumbnail was zero-byte and had to be removed
+                       return new MediaTransformError( 'thumbnail_error',
+                               $scalerParams['clientWidth'], $scalerParams['clientHeight'],
+                               wfMessage( 'unknown-error' )->text()
+                       );
+               } elseif ( $mto ) {
+                       return $mto;
+               } else {
+                       $newParams = array(
+                               'width' => $scalerParams['clientWidth'],
+                               'height' => $scalerParams['clientHeight']
+                       );
+                       if ( isset( $params['quality'] ) ) {
+                               $newParams['quality'] = $params['quality'];
+                       }
+                       if ( isset( $params['page'] ) && $params['page'] ) {
+                               $newParams['page'] = $params['page'];
+                       }
+                       return new ThumbnailImage( $image, $dstUrl, $dstPath, $newParams );
+               }
+       }
+
+       /**
+        * Get the source file for the transform
+        *
+        * @param $file File
+        * @param $params Array
+        * @return Array Array with keys  width, height and path.
+        */
+       protected function getThumbnailSource( $file, $params ) {
+               return $file->getThumbnailSource( $params );
+       }
+
+       /**
+        * Returns what sort of scaler type should be used.
+        *
+        * Values can be one of client, im, custom, gd, imext, or an array
+        * of object, method-name to call that specific method.
+        *
+        * If specifying a custom scaler command with array( Obj, method ),
+        * the method in question should take 2 parameters, a File object,
+        * and a $scalerParams array with various options (See doTransform
+        * for what is in $scalerParams). On error it should return a
+        * MediaTransformError object. On success it should return false,
+        * and simply make sure the thumbnail file is located at
+        * $scalerParams['dstPath'].
+        *
+        * If there is a problem with the output path, it returns "client"
+        * to do client side scaling.
+        *
+        * @param string $dstPath
+        * @param bool $checkDstPath Check that $dstPath is valid
+        * @return string|Callable One of client, im, custom, gd, imext, or a Callable array.
+        */
+       abstract protected function getScalerType( $dstPath, $checkDstPath = true );
+
+       /**
+        * Get a ThumbnailImage that respresents an image that will be scaled
+        * client side
+        *
+        * @param File $image File associated with this thumbnail
+        * @param array $scalerParams Array with scaler params
+        * @return ThumbnailImage
+        *
+        * @todo FIXME: No rotation support
+        */
+       protected function getClientScalingThumbnailImage( $image, $scalerParams ) {
+               $params = array(
+                       'width' => $scalerParams['clientWidth'],
+                       'height' => $scalerParams['clientHeight']
+               );
+
+               return new ThumbnailImage( $image, $image->getURL(), null, $params );
+       }
+
+       /**
+        * Transform an image using ImageMagick
+        *
+        * This is a stub method. The real method is in BitmapHander.
+        *
+        * @param File $image File associated with this thumbnail
+        * @param array $params Array with scaler params
+        *
+        * @return MediaTransformError Error object if error occurred, false (=no error) otherwise
+        */
+       protected function transformImageMagick( $image, $params ) {
+               return $this->getMediaTransformError( $params, "Unimplemented" );
+       }
+
+       /**
+        * Transform an image using the Imagick PHP extension
+        *
+        * This is a stub method. The real method is in BitmapHander.
+        *
+        * @param File $image File associated with this thumbnail
+        * @param array $params Array with scaler params
+        *
+        * @return MediaTransformError Error object if error occurred, false (=no error) otherwise
+        */
+       protected function transformImageMagickExt( $image, $params ) {
+               return $this->getMediaTransformError( $params, "Unimplemented" );
+       }
+
+       /**
+        * Transform an image using a custom command
+        *
+        * This is a stub method. The real method is in BitmapHander.
+        *
+        * @param File $image File associated with this thumbnail
+        * @param array $params Array with scaler params
+        *
+        * @return MediaTransformError Error object if error occurred, false (=no error) otherwise
+        */
+       protected function transformCustom( $image, $params ) {
+               return $this->getMediaTransformError( $params, "Unimplemented" );
+       }
+
+       /**
+        * Get a MediaTransformError with error 'thumbnail_error'
+        *
+        * @param array $params Parameter array as passed to the transform* functions
+        * @param string $errMsg Error message
+        * @return MediaTransformError
+        */
+       public function getMediaTransformError( $params, $errMsg ) {
+               return new MediaTransformError( 'thumbnail_error', $params['clientWidth'],
+                       $params['clientHeight'], $errMsg );
+       }
+
+       /**
+        * Transform an image using the built in GD library
+        *
+        * This is a stub method. The real method is in BitmapHander.
+        *
+        * @param File $image File associated with this thumbnail
+        * @param array $params Array with scaler params
+        *
+        * @return MediaTransformError Error object if error occurred, false (=no error) otherwise
+        */
+       protected function transformGd( $image, $params ) {
+               return $this->getMediaTransformError( $params, "Unimplemented" );
+       }
+
+       /**
+        * Escape a string for ImageMagick's property input (e.g. -set -comment)
+        * See InterpretImageProperties() in magick/property.c
+        * @param string $s
+        * @return string
+        */
+       function escapeMagickProperty( $s ) {
+               // Double the backslashes
+               $s = str_replace( '\\', '\\\\', $s );
+               // Double the percents
+               $s = str_replace( '%', '%%', $s );
+               // Escape initial - or @
+               if ( strlen( $s ) > 0 && ( $s[0] === '-' || $s[0] === '@' ) ) {
+                       $s = '\\' . $s;
+               }
+
+               return $s;
+       }
+
+       /**
+        * Escape a string for ImageMagick's input filenames. See ExpandFilenames()
+        * and GetPathComponent() in magick/utility.c.
+        *
+        * This won't work with an initial ~ or @, so input files should be prefixed
+        * with the directory name.
+        *
+        * Glob character unescaping is broken in ImageMagick before 6.6.1-5, but
+        * it's broken in a way that doesn't involve trying to convert every file
+        * in a directory, so we're better off escaping and waiting for the bugfix
+        * to filter down to users.
+        *
+        * @param string $path The file path
+        * @param bool|string $scene The scene specification, or false if there is none
+        * @throws MWException
+        * @return string
+        */
+       function escapeMagickInput( $path, $scene = false ) {
+               # Die on initial metacharacters (caller should prepend path)
+               $firstChar = substr( $path, 0, 1 );
+               if ( $firstChar === '~' || $firstChar === '@' ) {
+                       throw new MWException( __METHOD__ . ': cannot escape this path name' );
+               }
+
+               # Escape glob chars
+               $path = preg_replace( '/[*?\[\]{}]/', '\\\\\0', $path );
+
+               return $this->escapeMagickPath( $path, $scene );
+       }
+
+       /**
+        * Escape a string for ImageMagick's output filename. See
+        * InterpretImageFilename() in magick/image.c.
+        * @param string $path The file path
+        * @param bool|string $scene The scene specification, or false if there is none
+        * @return string
+        */
+       function escapeMagickOutput( $path, $scene = false ) {
+               $path = str_replace( '%', '%%', $path );
+
+               return $this->escapeMagickPath( $path, $scene );
+       }
+
+       /**
+        * Armour a string against ImageMagick's GetPathComponent(). This is a
+        * helper function for escapeMagickInput() and escapeMagickOutput().
+        *
+        * @param string $path The file path
+        * @param bool|string $scene The scene specification, or false if there is none
+        * @throws MWException
+        * @return string
+        */
+       protected function escapeMagickPath( $path, $scene = false ) {
+               # Die on format specifiers (other than drive letters). The regex is
+               # meant to match all the formats you get from "convert -list format"
+               if ( preg_match( '/^([a-zA-Z0-9-]+):/', $path, $m ) ) {
+                       if ( wfIsWindows() && is_dir( $m[0] ) ) {
+                               // OK, it's a drive letter
+                               // ImageMagick has a similar exception, see IsMagickConflict()
+                       } else {
+                               throw new MWException( __METHOD__ . ': unexpected colon character in path name' );
+                       }
+               }
+
+               # If there are square brackets, add a do-nothing scene specification
+               # to force a literal interpretation
+               if ( $scene === false ) {
+                       if ( strpos( $path, '[' ) !== false ) {
+                               $path .= '[0--1]';
+                       }
+               } else {
+                       $path .= "[$scene]";
+               }
+
+               return $path;
+       }
+
+       /**
+        * Retrieve the version of the installed ImageMagick
+        * You can use PHPs version_compare() to use this value
+        * Value is cached for one hour.
+        * @return string Representing the IM version.
+        */
+       protected function getMagickVersion() {
+               global $wgMemc;
+
+               $cache = $wgMemc->get( "imagemagick-version" );
+               if ( !$cache ) {
+                       global $wgImageMagickConvertCommand;
+                       $cmd = wfEscapeShellArg( $wgImageMagickConvertCommand ) . ' -version';
+                       wfDebug( __METHOD__ . ": Running convert -version\n" );
+                       $retval = '';
+                       $return = wfShellExec( $cmd, $retval );
+                       $x = preg_match( '/Version: ImageMagick ([0-9]*\.[0-9]*\.[0-9]*)/', $return, $matches );
+                       if ( $x != 1 ) {
+                               wfDebug( __METHOD__ . ": ImageMagick version check failed\n" );
+
+                               return null;
+                       }
+                       $wgMemc->set( "imagemagick-version", $matches[1], 3600 );
+
+                       return $matches[1];
+               }
+
+               return $cache;
+       }
+
+       /**
+        * Returns whether the current scaler supports rotation.
+        *
+        * @since 1.24 No longer static
+        * @return bool
+        */
+       public function canRotate() {
+               return false;
+       }
+
+       /**
+        * Should we automatically rotate an image based on exif
+        *
+        * @since 1.24 No longer static
+        * @see $wgEnableAutoRotation
+        * @return bool Whether auto rotation is enabled
+        */
+       public function autoRotateEnabled() {
+               return false;
+       }
+
+       /**
+        * Rotate a thumbnail.
+        *
+        * This is a stub. See BitmapHandler::rotate.
+        *
+        * @param File $file
+        * @param array $params Rotate parameters.
+        *   'rotation' clockwise rotation in degrees, allowed are multiples of 90
+        * @since 1.24 Is non-static. From 1.21 it was static
+        * @return bool
+        */
+       public function rotate( $file, $params ) {
+               return new MediaTransformError( 'thumbnail_error', 0, 0,
+                       get_class( $this ) . ' rotation not implemented' );
+       }
+
+       /**
+        * Returns whether the file needs to be rendered. Returns true if the
+        * file requires rotation and we are able to rotate it.
+        *
+        * @param File $file
+        * @return bool
+        */
+       public function mustRender( $file ) {
+               return $this->canRotate() && $this->getRotation( $file ) != 0;
+       }
+}
index aa77fa8..48b7a47 100644 (file)
@@ -209,7 +209,7 @@ class XCFHandler extends BitmapHandler {
         * @param bool $checkDstPath
         * @return string
         */
-       protected static function getScalerType( $dstPath, $checkDstPath = true ) {
+       protected function getScalerType( $dstPath, $checkDstPath = true ) {
                return "im";
        }
 
index b86d7d7..07b2495 100644 (file)
@@ -13,7 +13,7 @@ image/jpeg    [BITMAP]
 image/jp2      [BITMAP]
 image/xbm      [BITMAP]
 image/tiff     [BITMAP]
-image/x-icon image/x-ico       [BITMAP]
+image/x-icon image/x-ico image/vnd.microsoft.icon      [BITMAP]
 image/x-rgb    [BITMAP]
 image/x-portable-pixmap                [BITMAP]
 image/x-portable-graymap image/x-portable-greymap      [BITMAP]
index ae6ca4d..75017db 100644 (file)
@@ -91,6 +91,7 @@ image/png png apng
 image/svg+xml svg
 image/tiff tiff tif
 image/vnd.djvu djvu djv
+image/vnd.microsoft.icon ico
 image/vnd.wap.wbmp wbmp
 image/webp webp
 image/x-cmu-raster ras
index 6f8f9af..1978c3e 100644 (file)
@@ -277,21 +277,6 @@ abstract class BagOStuff {
                return false; // key already set
        }
 
-       /**
-        * @param string $key
-        * @param mixed $value
-        * @param int $exptime
-        * @return bool Success
-        * @deprecated since 1.23
-        */
-       public function replace( $key, $value, $exptime = 0 ) {
-               wfDeprecated( __METHOD__, '1.23' );
-               if ( $this->get( $key ) !== false ) {
-                       return $this->set( $key, $value, $exptime );
-               }
-               return false; // key not already set
-       }
-
        /**
         * Increase stored value of $key by $value while preserving its TTL
         * @param string $key Key to increase
index 497f75d..6a69137 100644 (file)
@@ -115,16 +115,6 @@ class MultiWriteBagOStuff extends BagOStuff {
                return $this->doWrite( 'add', $key, $value, $exptime );
        }
 
-       /**
-        * @param string $key
-        * @param mixed $value
-        * @param int $exptime
-        * @return bool
-        */
-       public function replace( $key, $value, $exptime = 0 ) {
-               return $this->doWrite( 'replace', $key, $value, $exptime );
-       }
-
        /**
         * @param string $key
         * @param int $value
index 9772d4f..daf3311 100644 (file)
@@ -53,25 +53,25 @@ class Article implements Page {
         * @var Content Content of the revision we are working on
         * @since 1.21
         */
-       protected $mContentObject;
+       public $mContentObject;
 
        /** @var bool Is the content ($mContent) already loaded? */
-       protected $mContentLoaded = false;
+       public $mContentLoaded = false;
 
        /** @var int|null The oldid of the article that is to be shown, 0 for the current revision */
-       protected $mOldId;
+       public $mOldId;
 
        /** @var Title Title from which we were redirected here */
-       protected $mRedirectedFrom = null;
+       public $mRedirectedFrom = null;
 
        /** @var string|bool URL to redirect to or false if none */
-       protected $mRedirectUrl = false;
+       public $mRedirectUrl = false;
 
        /** @var int Revision ID of revision we are working on */
-       protected $mRevIdFetched = 0;
+       public $mRevIdFetched = 0;
 
        /** @var Revision Revision we are working on */
-       protected $mRevision = null;
+       public $mRevision = null;
 
        /** @var ParserOutput */
        public $mParserOutput;
@@ -1841,7 +1841,7 @@ class Article implements Page {
 
                $called = true;
                if ( $this->isFileCacheable() ) {
-                       $cache = HTMLFileCache::newFromTitle( $this->getTitle(), 'view' );
+                       $cache = new HTMLFileCache( $this->getTitle(), 'view' );
                        if ( $cache->isCacheGood( $this->mPage->getTouched() ) ) {
                                wfDebug( "Article::tryFileCache(): about to load file\n" );
                                $cache->loadFromFileCache( $this->getContext() );
index c5141a9..8095539 100644 (file)
@@ -402,13 +402,11 @@ abstract class TablePager extends IndexPager {
         * @return string HTML fragment
         */
        function getLimitForm() {
-               global $wgScript;
-
                return Html::rawElement(
                        'form',
                        array(
                                'method' => 'get',
-                               'action' => $wgScript
+                               'action' => wfScript(),
                        ),
                        "\n" . $this->getLimitDropdown()
                ) . "\n";
index 8bf400a..84bb224 100644 (file)
@@ -1402,7 +1402,7 @@ class Parser {
                                $this->getExternalLinkAttribs( $url ) );
                        # Register it in the output object...
                        # Replace unnecessary URL escape codes with their equivalent characters
-                       $pasteurized = self::replaceUnusualEscapes( $url );
+                       $pasteurized = self::normalizeLinkUrl( $url );
                        $this->mOutput->addExternalLink( $pasteurized );
                }
                wfProfileOut( __METHOD__ );
@@ -1710,7 +1710,7 @@ class Parser {
                        # Register link in the output object.
                        # Replace unnecessary URL escape codes with the referenced character
                        # This prevents spammers from hiding links from the filters
-                       $pasteurized = self::replaceUnusualEscapes( $url );
+                       $pasteurized = self::normalizeLinkUrl( $url );
                        $this->mOutput->addExternalLink( $pasteurized );
                }
 
@@ -1759,40 +1759,75 @@ class Parser {
        }
 
        /**
-        * Replace unusual URL escape codes with their equivalent characters
+        * Replace unusual escape codes in a URL with their equivalent characters
         *
+        * @deprecated since 1.24, use normalizeLinkUrl
         * @param string $url
         * @return string
-        *
-        * @todo This can merge genuinely required bits in the path or query string,
-        *       breaking legit URLs. A proper fix would treat the various parts of
-        *       the URL differently; as a workaround, just use the output for
-        *       statistical records, not for actual linking/output.
         */
        public static function replaceUnusualEscapes( $url ) {
-               return preg_replace_callback( '/%[0-9A-Fa-f]{2}/',
-                       array( __CLASS__, 'replaceUnusualEscapesCallback' ), $url );
+               wfDeprecated( __METHOD__, '1.24' );
+               return self::normalizeLinkUrl( $url );
        }
 
        /**
-        * Callback function used in replaceUnusualEscapes().
-        * Replaces unusual URL escape codes with their equivalent character
+        * Replace unusual escape codes in a URL with their equivalent characters
         *
-        * @param array $matches
+        * This generally follows the syntax defined in RFC 3986, with special
+        * consideration for HTTP query strings.
         *
+        * @param string $url
         * @return string
         */
-       private static function replaceUnusualEscapesCallback( $matches ) {
-               $char = urldecode( $matches[0] );
-               $ord = ord( $char );
-               # Is it an unsafe or HTTP reserved character according to RFC 1738?
-               if ( $ord > 32 && $ord < 127 && strpos( '<>"#{}|\^~[]`;/?', $char ) === false ) {
-                       # No, shouldn't be escaped
-                       return $char;
-               } else {
-                       # Yes, leave it escaped
-                       return $matches[0];
+       public static function normalizeLinkUrl( $url ) {
+               # First, make sure unsafe characters are encoded
+               $url = preg_replace_callback( '/[\x00-\x20"<>\[\\\\\]^`{|}\x7F-\xFF]/',
+                       function ( $m ) {
+                               return rawurlencode( $m[0] );
+                       },
+                       $url
+               );
+
+               $ret = '';
+               $end = strlen( $url );
+
+               # Fragment part - 'fragment'
+               $start = strpos( $url, '#' );
+               if ( $start !== false && $start < $end ) {
+                       $ret = self::normalizeUrlComponent(
+                               substr( $url, $start, $end - $start ), '"#%<>[\]^`{|}' ) . $ret;
+                       $end = $start;
+               }
+
+               # Query part - 'query' minus &=+;
+               $start = strpos( $url, '?' );
+               if ( $start !== false && $start < $end ) {
+                       $ret = self::normalizeUrlComponent(
+                               substr( $url, $start, $end - $start ), '"#%<>[\]^`{|}&=+;' ) . $ret;
+                       $end = $start;
                }
+
+               # Scheme and path part - 'pchar'
+               # (we assume no userinfo or encoded colons in the host)
+               $ret = self::normalizeUrlComponent(
+                       substr( $url, 0, $end ), '"#%<>[\]^`{|}/?' ) . $ret;
+
+               return $ret;
+       }
+
+       private static function normalizeUrlComponent( $component, $unsafe ) {
+               $callback = function ( $matches ) use ( $unsafe ) {
+                       $char = urldecode( $matches[0] );
+                       $ord = ord( $char );
+                       if ( $ord > 32 && $ord < 127 && strpos( $unsafe, $char ) === false ) {
+                               # Unescape it
+                               return $char;
+                       } else {
+                               # Leave it escaped, but use uppercase for a-f
+                               return strtoupper( $matches[0] );
+                       }
+               };
+               return preg_replace_callback( '/%[0-9A-Fa-f]{2}/', $callback, $component );
        }
 
        /**
index 2ca9d50..7e4059b 100644 (file)
@@ -211,6 +211,13 @@ class ParserOptions {
         */
        protected $onAccessCallback = null;
 
+       /**
+        * If the page being parsed is a redirect, this should hold the redirect
+        * target.
+        * @var Title|null
+        */
+       private $redirectTarget = null;
+
        public function getInterwikiMagic() {
                return $this->mInterwikiMagic;
        }
@@ -515,6 +522,30 @@ class ParserOptions {
                return wfSetVar( $this->mIsPrintable, $x );
        }
 
+       /**
+        * Set the redirect target.
+        *
+        * Note that setting or changing this does not *make* the page a redirect
+        * or change its target, it merely records the information for reference
+        * during the parse.
+        *
+        * @since 1.24
+        * @param Title|null $title
+        */
+       function setRedirectTarget( $title ) {
+               $this->redirectTarget = $title;
+       }
+
+       /**
+        * Get the previously-set redirect target.
+        *
+        * @since 1.24
+        * @return Title|null
+        */
+       function getRedirectTarget() {
+               return $this->redirectTarget;
+       }
+
        /**
         * Extra key that should be present in the parser cache key.
         * @param string $key
index 38a6436..7ef0ad0 100644 (file)
@@ -58,7 +58,7 @@ class ProfilerSimpleDB extends ProfilerStandard {
                        $dbw = wfGetDB( DB_MASTER );
                        $useTrx = ( $dbw->getType() === 'sqlite' ); // much faster
                        if ( $useTrx ) {
-                               $dbw->begin();
+                               $dbw->startAtomic( __METHOD__ );
                        }
                        foreach ( $this->mCollated as $name => $data ) {
                                $eventCount = $data['count'];
@@ -103,7 +103,7 @@ class ProfilerSimpleDB extends ProfilerStandard {
                                //     "pf_time=pf_time + VALUES(pf_time)";
                        }
                        if ( $useTrx ) {
-                               $dbw->commit();
+                               $dbw->endAtomic( __METHOD__ );
                        }
                } catch ( DBError $e ) {
                }
index 18e6003..519606c 100644 (file)
@@ -39,64 +39,63 @@ abstract class MachineReadableRCFeedFormatter implements RCFeedFormatter {
         */
        public function getLine( array $feed, RecentChange $rc, $actionComment ) {
                global $wgCanonicalServer, $wgServerName, $wgScriptPath;
-               $attrib = $rc->getAttributes();
 
                $packet = array(
                        // Usually, RC ID is exposed only for patrolling purposes,
                        // but there is no real reason not to expose it in other cases,
                        // and I can see how this may be potentially useful for clients.
-                       'id' => $attrib['rc_id'],
-                       'type' => RecentChange::parseFromRCType( $attrib['rc_type'] ),
+                       'id' => $rc->getAttribute( 'rc_id' ),
+                       'type' => RecentChange::parseFromRCType( $rc->getAttribute( 'rc_type' ) ),
                        'namespace' => $rc->getTitle()->getNamespace(),
                        'title' => $rc->getTitle()->getPrefixedText(),
-                       'comment' => $attrib['rc_comment'],
-                       'timestamp' => (int)wfTimestamp( TS_UNIX, $attrib['rc_timestamp'] ),
-                       'user' => $attrib['rc_user_text'],
-                       'bot' => (bool)$attrib['rc_bot'],
+                       'comment' => $rc->getAttribute( 'rc_comment' ),
+                       'timestamp' => (int)wfTimestamp( TS_UNIX, $rc->getAttribute( 'rc_timestamp' ) ),
+                       'user' => $rc->getAttribute( 'rc_user_text' ),
+                       'bot' => (bool)$rc->getAttribute( 'rc_bot' ),
                );
 
                if ( isset( $feed['channel'] ) ) {
                        $packet['channel'] = $feed['channel'];
                }
 
-               $type = $attrib['rc_type'];
+               $type = $rc->getAttribute( 'rc_type' );
                if ( $type == RC_EDIT || $type == RC_NEW ) {
                        global $wgUseRCPatrol, $wgUseNPPatrol;
 
-                       $packet['minor'] = (bool)$attrib['rc_minor'];
+                       $packet['minor'] = (bool)$rc->getAttribute( 'rc_minor' );
                        if ( $wgUseRCPatrol || ( $type == RC_NEW && $wgUseNPPatrol ) ) {
-                               $packet['patrolled'] = (bool)$attrib['rc_patrolled'];
+                               $packet['patrolled'] = (bool)$rc->getAttribute( 'rc_patrolled' );
                        }
                }
 
                switch ( $type ) {
                        case RC_EDIT:
                                $packet['length'] = array(
-                                       'old' => $attrib['rc_old_len'],
-                                       'new' => $attrib['rc_new_len']
+                                       'old' => $rc->getAttribute( 'rc_old_len' ),
+                                       'new' => $rc->getAttribute( 'rc_new_len' )
                                );
                                $packet['revision'] = array(
-                                       'old' => $attrib['rc_last_oldid'],
-                                       'new' => $attrib['rc_this_oldid']
+                                       'old' => $rc->getAttribute( 'rc_last_oldid' ),
+                                       'new' => $rc->getAttribute( 'rc_this_oldid' )
                                );
                                break;
 
                        case RC_NEW:
-                               $packet['length'] = array( 'old' => null, 'new' => $attrib['rc_new_len'] );
-                               $packet['revision'] = array( 'old' => null, 'new' => $attrib['rc_this_oldid'] );
+                               $packet['length'] = array( 'old' => null, 'new' => $rc->getAttribute( 'rc_new_len' ) );
+                               $packet['revision'] = array( 'old' => null, 'new' => $rc->getAttribute( 'rc_this_oldid' ) );
                                break;
 
                        case RC_LOG:
-                               $packet['log_id'] = $attrib['rc_logid'];
-                               $packet['log_type'] = $attrib['rc_log_type'];
-                               $packet['log_action'] = $attrib['rc_log_action'];
-                               if ( $attrib['rc_params'] ) {
+                               $packet['log_id'] = $rc->getAttribute( 'rc_logid' );
+                               $packet['log_type'] = $rc->getAttribute( 'rc_log_type' );
+                               $packet['log_action'] = $rc->getAttribute( 'rc_log_action' );
+                               if ( $rc->getAttribute( 'rc_params' ) ) {
                                        wfSuppressWarnings();
-                                       $params = unserialize( $attrib['rc_params'] );
+                                       $params = unserialize( $rc->getAttribute( 'rc_params' ) );
                                        wfRestoreWarnings();
                                        if (
                                                // If it's an actual serialised false...
-                                               $attrib['rc_params'] == serialize( false ) ||
+                                               $rc->getAttribute( 'rc_params' ) == serialize( false ) ||
                                                // Or if we did not get false back when trying to unserialise
                                                $params !== false
                                        ) {
@@ -113,7 +112,7 @@ abstract class MachineReadableRCFeedFormatter implements RCFeedFormatter {
                                                }
                                                $packet['log_params'] = $logParams;
                                        } else {
-                                               $packet['log_params'] = explode( "\n", $attrib['rc_params'] );
+                                               $packet['log_params'] = explode( "\n", $rc->getAttribute( 'rc_params' ) );
                                        }
                                }
                                $packet['log_action_comment'] = $actionComment;
index 918f8be..4f1414b 100644 (file)
@@ -397,7 +397,7 @@ class ResourceLoader {
         *
         * @param array|string $id Source ID (string), or array( id1 => loadUrl, id2 => loadUrl, ... )
         * @param string|array $loadUrl load.php url (string), or array with loadUrl key for
-        *  backwards-compatability.
+        *  backwards-compatibility.
         * @throws MWException
         */
        public function addSource( $id, $loadUrl = null ) {
@@ -417,7 +417,7 @@ class ResourceLoader {
                        );
                }
 
-               // Pre 1.24 backwards-compatability
+               // Pre 1.24 backwards-compatibility
                if ( is_array( $loadUrl ) ) {
                        if ( !isset( $loadUrl['loadScript'] ) ) {
                                throw new MWException(
@@ -1002,15 +1002,6 @@ class ResourceLoader {
                        if ( count( $states ) ) {
                                $out .= self::makeLoaderStateScript( $states );
                        }
-
-                       if ( $context->getOnly() === 'scripts' ) {
-                               // In only=script requests for modules that are not raw (e.g. not the startup module)
-                               // ensure the execution is conditional to avoid situations where browsers with an
-                               // unsupported environment do unconditionally execute a module's scripts. Otherwise users
-                               // will get things like "ReferenceError: mw is undefined" or "jQuery is undefined" from
-                               // legacy scripts loaded with only=scripts (such as the 'site' module).
-                               $out = self::makeLoaderConditionalScript( $out );
-                       }
                } else {
                        if ( count( $states ) ) {
                                $exceptions .= self::makeComment(
diff --git a/includes/resourceloader/ResourceLoaderEditToolbarModule.php b/includes/resourceloader/ResourceLoaderEditToolbarModule.php
new file mode 100644 (file)
index 0000000..2e07911
--- /dev/null
@@ -0,0 +1,102 @@
+<?php
+/**
+ * Resource loader module for the edit toolbar.
+ *
+ * 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
+ */
+
+/**
+ * ResourceLoader module for the edit toolbar.
+ *
+ * @since 1.24
+ */
+class ResourceLoaderEditToolbarModule extends ResourceLoaderFileModule {
+       /**
+        * Serialize a string (escape and quote) for use as a CSS string value.
+        * http://www.w3.org/TR/2013/WD-cssom-20131205/#serialize-a-string
+        *
+        * @param string $value
+        * @return string
+        */
+       private static function cssSerializeString( $value ) {
+               if ( strstr( $value, "\0" ) ) {
+                       throw new Exception( "Invalid character in CSS string" );
+               }
+               $value = strtr( $value, array( '\\' => '\\\\', '"' => '\\"' ) );
+               $value = preg_replace_callback( '/[\x01-\x1f\x7f-\x9f]/', function ( $match ) {
+                       return '\\' . base_convert( ord( $match[0] ), 10, 16 ) . ' ';
+               }, $value );
+               return '"' . $value . '"';
+       }
+
+       /**
+        * Get language-specific LESS variables for this module.
+        *
+        * @return array
+        */
+       private function getLessVars( ResourceLoaderContext $context ) {
+               $language = Language::factory( $context->getLanguage() );
+
+               // This is very conveniently formatted and we can pass it right through
+               $vars = $language->getImageFiles();
+
+               // lessc tries to be helpful and parse our variables as LESS source code
+               foreach ( $vars as $key => &$value ) {
+                       $value = self::cssSerializeString( $value );
+               }
+
+               return $vars;
+       }
+
+       /**
+        * @param ResourceLoaderContext $context
+        * @return int UNIX timestamp
+        */
+       public function getModifiedTime( ResourceLoaderContext $context ) {
+               return max(
+                       parent::getModifiedTime( $context ),
+                       $this->getHashMtime( $context )
+               );
+       }
+
+       /**
+        * @param ResourceLoaderContext $context
+        * @return string Hash
+        */
+       public function getModifiedHash( ResourceLoaderContext $context ) {
+               return md5(
+                       parent::getModifiedHash( $context ) .
+                       serialize( $this->getLessVars( $context ) )
+               );
+       }
+
+       /**
+        * Get a LESS compiler instance for this module.
+        *
+        * Set our variables in it.
+        *
+        * @throws MWException
+        * @param ResourceLoaderContext $context
+        * @return lessc
+        */
+       protected function getLessCompiler( ResourceLoaderContext $context = null ) {
+               $compiler = parent::getLessCompiler();
+               $compiler->setVariables( $this->getLessVars( $context ) );
+               return $compiler;
+       }
+}
index 6128f19..137ff62 100644 (file)
@@ -168,7 +168,7 @@ class ResourceLoaderFileModule extends ResourceLoaderModule {
         * @param string $localBasePath Base path to prepend to all local paths in $options. Defaults
         *     to $IP
         * @param string $remoteBasePath Base path to prepend to all remote paths in $options. Defaults
-        *     to $wgScriptPath
+        *     to $wgResourceBasePath
         *
         * Below is a description for the $options array:
         * @throws MWException
@@ -177,7 +177,7 @@ class ResourceLoaderFileModule extends ResourceLoaderModule {
         *     array(
         *         // Base path to prepend to all local paths in $options. Defaults to $IP
         *         'localBasePath' => [base path],
-        *         // Base path to prepend to all remote paths in $options. Defaults to $wgScriptPath
+        *         // Base path to prepend to all remote paths in $options. Defaults to $wgResourceBasePath
         *         'remoteBasePath' => [base path],
         *         // Equivalent of remoteBasePath, but relative to $wgExtensionAssetsPath
         *         'remoteExtPath' => [base path],
@@ -291,7 +291,7 @@ class ResourceLoaderFileModule extends ResourceLoaderModule {
         * @param string $localBasePath Path to use if not provided in module definition. Defaults
         *     to $IP
         * @param string $remoteBasePath Path to use if not provided in module definition. Defaults
-        *     to $wgScriptPath
+        *     to $wgResourceBasePath
         * @return array Array( localBasePath, remoteBasePath )
         */
        public static function extractBasePaths(
@@ -299,14 +299,14 @@ class ResourceLoaderFileModule extends ResourceLoaderModule {
                $localBasePath = null,
                $remoteBasePath = null
        ) {
-               global $IP, $wgScriptPath, $wgResourceBasePath;
+               global $IP, $wgResourceBasePath;
 
                // The different ways these checks are done, and their ordering, look very silly,
                // but were preserved for backwards-compatibility just in case. Tread lightly.
 
                $localBasePath = $localBasePath === null ? $IP : $localBasePath;
                if ( $remoteBasePath === null ) {
-                       $remoteBasePath = $wgResourceBasePath === null ? $wgScriptPath : $wgResourceBasePath;
+                       $remoteBasePath = $wgResourceBasePath;
                }
 
                if ( isset( $options['remoteExtPath'] ) ) {
@@ -385,7 +385,8 @@ class ResourceLoaderFileModule extends ResourceLoaderModule {
        public function getStyles( ResourceLoaderContext $context ) {
                $styles = $this->readStyleFiles(
                        $this->getStyleFiles( $context ),
-                       $this->getFlip( $context )
+                       $this->getFlip( $context ),
+                       $context
                );
                // Collect referenced files
                $this->localFileRefs = array_unique( $this->localFileRefs );
@@ -816,14 +817,14 @@ class ResourceLoaderFileModule extends ResourceLoaderModule {
         *
         * @param array $styles List of media type/list of file paths pairs, to read, remap and
         * concetenate
-        *
         * @param bool $flip
+        * @param ResourceLoaderContext $context (optional)
         *
         * @throws MWException
         * @return array List of concatenated and remapped CSS data from $styles,
         *     keyed by media type
         */
-       public function readStyleFiles( array $styles, $flip ) {
+       public function readStyleFiles( array $styles, $flip, $context = null ) {
                if ( empty( $styles ) ) {
                        return array();
                }
@@ -831,7 +832,7 @@ class ResourceLoaderFileModule extends ResourceLoaderModule {
                        $uniqueFiles = array_unique( $files, SORT_REGULAR );
                        $styleFiles = array();
                        foreach ( $uniqueFiles as $file ) {
-                               $styleFiles[] = $this->readStyleFile( $file, $flip );
+                               $styleFiles[] = $this->readStyleFile( $file, $flip, $context );
                        }
                        $styles[$media] = implode( "\n", $styleFiles );
                }
@@ -845,11 +846,12 @@ class ResourceLoaderFileModule extends ResourceLoaderModule {
         *
         * @param string $path File path of style file to read
         * @param bool $flip
+        * @param ResourceLoaderContext $context (optional)
         *
         * @return string CSS data in script file
         * @throws MWException If the file doesn't exist
         */
-       protected function readStyleFile( $path, $flip ) {
+       protected function readStyleFile( $path, $flip, $context = null ) {
                $localPath = $this->getLocalPath( $path );
                $remotePath = $this->getRemotePath( $path );
                if ( !file_exists( $localPath ) ) {
@@ -859,7 +861,8 @@ class ResourceLoaderFileModule extends ResourceLoaderModule {
                }
 
                if ( $this->getStyleSheetLang( $localPath ) === 'less' ) {
-                       $style = $this->compileLessFile( $localPath );
+                       $compiler = $this->getLessCompiler( $context );
+                       $style = $this->compileLessFile( $localPath, $compiler );
                        $this->hasGeneratedStyles = true;
                } else {
                        $style = file_get_contents( $localPath );
@@ -908,12 +911,29 @@ class ResourceLoaderFileModule extends ResourceLoaderModule {
         * @since 1.22
         * @throws Exception If lessc encounters a parse error
         * @param string $fileName File path of LESS source
+        * @param lessc $compiler Compiler to use, if not default
         * @return string CSS source
         */
-       protected function compileLessFile( $fileName ) {
-               $compiler = ResourceLoader::getLessCompiler( $this->getConfig() );
+       protected function compileLessFile( $fileName, $compiler = null ) {
+               if ( !$compiler ) {
+                       $compiler = $this->getLessCompiler();
+               }
                $result = $compiler->compileFile( $fileName );
                $this->localFileRefs += array_keys( $compiler->allParsedFiles() );
                return $result;
        }
+
+       /**
+        * Get a LESS compiler instance for this module in given context.
+        *
+        * Just calls ResourceLoader::getLessCompiler() by default to get a global compiler.
+        *
+        * @param ResourceLoaderContext $context
+        * @throws MWException
+        * @since 1.24
+        * @return lessc
+        */
+       protected function getLessCompiler( ResourceLoaderContext $context = null ) {
+               return ResourceLoader::getLessCompiler( $this->getConfig() );
+       }
 }
diff --git a/includes/resourceloader/ResourceLoaderLESSFunctions.php b/includes/resourceloader/ResourceLoaderLESSFunctions.php
deleted file mode 100644 (file)
index 987b902..0000000
+++ /dev/null
@@ -1,72 +0,0 @@
-<?php
-/**
- * PHP-provided functions for LESS; see docs for $wgResourceLoaderLESSFunctions
- *
- * 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
- */
-
-class ResourceLoaderLESSFunctions {
-       /**
-        * Check if an image file reference is suitable for embedding.
-        * An image is embeddable if it (a) exists, (b) has a suitable MIME-type,
-        * (c) does not exceed IE<9 size limit of 32kb. This is a LESS predicate
-        * function; it returns a LESS boolean value and can thus be used as a
-        * mixin guard.
-        *
-        * @par Example:
-        * @code
-        *   .background-image(@url) when(embeddable(@url)) {
-        *       background-image: url(@url) !ie;
-        *   }
-        * @endcode
-        * @param array $frame
-        * @param lessc $less
-        */
-       public static function embeddable( $frame, $less ) {
-               $base = pathinfo( $less->parser->sourceName, PATHINFO_DIRNAME );
-               $url = trim( $less->compileValue( $frame ), '"\'' );
-               $file = realpath( $base . '/' . $url );
-               return $less->toBool( $file
-                       && strpos( $url, '//' ) === false
-                       && filesize( $file ) < CSSMin::EMBED_SIZE_LIMIT
-                       && CSSMin::getMimeType( $file ) !== false );
-       }
-
-       /**
-        * Convert an image URI to a base64-encoded data URI.
-        *
-        * @par Example:
-        * @code
-        *   .fancy-button {
-        *       background-image: embed('../images/button-bg.png');
-        *   }
-        * @endcode
-        * @param array $frame
-        * @param lessc $less
-        * @return string
-        */
-       public static function embed( $frame, $less ) {
-               $base = pathinfo( $less->parser->sourceName, PATHINFO_DIRNAME );
-               $url = trim( $less->compileValue( $frame ), '"\'' );
-               $file = realpath( $base . '/' . $url );
-
-               $data = CSSMin::encodeImageAsDataURI( $file );
-               $less->addParsedFile( $file );
-               return CSSMin::buildUrlValue( $data );
-       }
-}
index e455ef1..2f3d3f8 100644 (file)
@@ -92,9 +92,6 @@ class ResourceLoaderStartUpModule extends ResourceLoaderModule {
                        'wgSiteName' => $conf->get( 'Sitename' ),
                        'wgFileExtensions' => array_values( array_unique( $conf->get( 'FileExtensions' ) ) ),
                        'wgDBname' => $conf->get( 'DBname' ),
-                       // This sucks, it is only needed on Special:Upload, but I could
-                       // not find a way to add vars only for a certain module
-                       'wgFileCanRotate' => BitmapHandler::canRotate(),
                        'wgAvailableSkins' => Skin::getSkinNames(),
                        'wgExtensionAssetsPath' => $conf->get( 'ExtensionAssetsPath' ),
                        // MediaWiki sets cookies to have this prefix by default
index d45316f..2eaca67 100644 (file)
@@ -96,14 +96,14 @@ abstract class ResourceLoaderWikiModule extends ResourceLoaderModule {
                        return null;
                }
 
-               $model = $content->getModel();
-
-               if ( $model !== CONTENT_MODEL_CSS && $model !== CONTENT_MODEL_JAVASCRIPT ) {
-                       wfDebugLog( 'resourceloader', __METHOD__ . ': bad content model $model for JS/CSS page!' );
+               if ( $content->isSupportedFormat( CONTENT_FORMAT_JAVASCRIPT ) ) {
+                       return $content->serialize( CONTENT_FORMAT_JAVASCRIPT );
+               } elseif ( $content->isSupportedFormat( CONTENT_FORMAT_CSS ) ) {
+                       return $content->serialize( CONTENT_FORMAT_CSS );
+               } else {
+                       wfDebugLog( 'resourceloader', __METHOD__ . ": bad content model {$content->getModel()} for JS/CSS page!" );
                        return null;
                }
-
-               return $content->getNativeData(); //NOTE: this is safe, we know it's JS or CSS
        }
 
        /* Methods */
index de701f7..0d7970d 100644 (file)
@@ -34,10 +34,7 @@ class SearchMssql extends SearchDatabase {
         * @access public
         */
        function searchText( $term ) {
-               $resultSet = $this->db->resultObject(
-                       $this->db->query( $this->getQuery( $this->filter( $term ), true ) )
-               );
-
+               $resultSet = $this->db->query( $this->getQuery( $this->filter( $term ), true ) );
                return new SqlSearchResultSet( $resultSet, $this->searchTerms );
        }
 
@@ -49,10 +46,7 @@ class SearchMssql extends SearchDatabase {
         * @access public
         */
        function searchTitle( $term ) {
-               $resultSet = $this->db->resultObject(
-                       $this->db->query( $this->getQuery( $this->filter( $term ), false ) )
-               );
-
+               $resultSet = $this->db->query( $this->getQuery( $this->filter( $term ), false ) );
                return new SqlSearchResultSet( $resultSet, $this->searchTerms );
        }
 
index 348da79..5821148 100644 (file)
@@ -69,10 +69,7 @@ class SearchOracle extends SearchDatabase {
                        return new SqlSearchResultSet( false, '' );
                }
 
-               $resultSet = $this->db->resultObject(
-                       $this->db->query( $this->getQuery( $this->filter( $term ), true ) )
-               );
-
+               $resultSet = $this->db->query( $this->getQuery( $this->filter( $term ), true ) );
                return new SqlSearchResultSet( $resultSet, $this->searchTerms );
        }
 
@@ -87,10 +84,7 @@ class SearchOracle extends SearchDatabase {
                        return new SqlSearchResultSet( false, '' );
                }
 
-               $resultSet = $this->db->resultObject(
-                       $this->db->query( $this->getQuery( $this->filter( $term ), false ) )
-               );
-
+               $resultSet = $this->db->query( $this->getQuery( $this->filter( $term ), false ) );
                return new SqlSearchResultSet( $resultSet, $this->searchTerms );
        }
 
index c64c845..59b0c31 100644 (file)
@@ -40,7 +40,7 @@ class SearchPostgres extends SearchDatabase {
        function searchTitle( $term ) {
                $q = $this->searchQuery( $term, 'titlevector', 'page_title' );
                $olderror = error_reporting( E_ERROR );
-               $resultSet = $this->db->resultObject( $this->db->query( $q, 'SearchPostgres', true ) );
+               $resultSet = $this->db->query( $q, 'SearchPostgres', true );
                error_reporting( $olderror );
                return new SqlSearchResultSet( $resultSet, $this->searchTerms );
        }
@@ -48,7 +48,7 @@ class SearchPostgres extends SearchDatabase {
        function searchText( $term ) {
                $q = $this->searchQuery( $term, 'textvector', 'old_text' );
                $olderror = error_reporting( E_ERROR );
-               $resultSet = $this->db->resultObject( $this->db->query( $q, 'SearchPostgres', true ) );
+               $resultSet = $this->db->query( $q, 'SearchPostgres', true );
                error_reporting( $olderror );
                return new SqlSearchResultSet( $resultSet, $this->searchTerms );
        }
index 1d28691..aeaba8d 100644 (file)
@@ -61,35 +61,6 @@ class SearchResult {
                return $result;
        }
 
-       /**
-        * Return a new SearchResult and initializes it with a row.
-        *
-        * @param object $row
-        * @return SearchResult
-        */
-       public static function newFromRow( $row ) {
-               $result = new self();
-               $result->initFromRow( $row );
-               return $result;
-       }
-
-       public function __construct( $row = null ) {
-               if ( !is_null( $row ) ) {
-                       // Backwards compatibility with pre-1.17 callers
-                       $this->initFromRow( $row );
-               }
-       }
-
-       /**
-        * Initialize from a database row. Makes a Title and passes that to
-        * initFromTitle.
-        *
-        * @param object $row
-        */
-       protected function initFromRow( $row ) {
-               $this->initFromTitle( Title::makeTitle( $row->page_namespace, $row->page_title ) );
-       }
-
        /**
         * Initialize from a Title and if possible initializes a corresponding
         * Revision and File.
@@ -242,13 +213,6 @@ class SearchResult {
                return strlen( $this->mText );
        }
 
-       /**
-        * @return bool If hit has related articles
-        */
-       function hasRelated() {
-               return false;
-       }
-
        /**
         * @return string Interwiki prefix of the title (return iw even if title is broken)
         */
index 698f93c..406d322 100644 (file)
@@ -161,7 +161,9 @@ class SqlSearchResultSet extends SearchResultSet {
                        return false;
                }
 
-               return SearchResult::newFromRow( $row );
+               return SearchResult::newFromTitle(
+                       Title::makeTitle( $row->page_namespace, $row->page_title )
+               );
        }
 
        function free() {
index 6659407..d133468 100644 (file)
@@ -314,11 +314,7 @@ class SiteSQLStore implements SiteStore {
 
                $dbw = $this->sitesTable->getWriteDbConnection();
 
-               $trx = $dbw->trxLevel();
-
-               if ( $trx == 0 ) {
-                       $dbw->begin( __METHOD__ );
-               }
+               $dbw->startAtomic( __METHOD__ );
 
                $success = true;
 
@@ -360,9 +356,7 @@ class SiteSQLStore implements SiteStore {
                        );
                }
 
-               if ( $trx == 0 ) {
-                       $dbw->commit( __METHOD__ );
-               }
+               $dbw->endAtomic( __METHOD__ );
 
                // purge cache
                $this->reset();
@@ -398,18 +392,10 @@ class SiteSQLStore implements SiteStore {
                wfProfileIn( __METHOD__ );
                $dbw = $this->sitesTable->getWriteDbConnection();
 
-               $trx = $dbw->trxLevel();
-
-               if ( $trx == 0 ) {
-                       $dbw->begin( __METHOD__ );
-               }
-
+               $dbw->startAtomic( __METHOD__ );
                $ok = $dbw->delete( 'sites', '*', __METHOD__ );
                $ok = $dbw->delete( 'site_identifiers', '*', __METHOD__ ) && $ok;
-
-               if ( $trx == 0 ) {
-                       $dbw->commit( __METHOD__ );
-               }
+               $dbw->endAtomic( __METHOD__);
 
                $this->reset();
 
index d68823d..2f6a710 100644 (file)
@@ -827,9 +827,9 @@ abstract class Skin extends ContextSource {
         * @return string
         */
        function getPoweredBy() {
-               global $wgStylePath;
+               global $wgResourceBasePath;
 
-               $url = htmlspecialchars( "$wgStylePath/common/images/poweredby_mediawiki_88x31.png" );
+               $url = htmlspecialchars( "$wgResourceBasePath/resources/assets/poweredby_mediawiki_88x31.png" );
                $text = '<a href="//www.mediawiki.org/"><img src="' . $url
                        . '" height="31" width="88" alt="Powered by MediaWiki" /></a>';
                wfRunHooks( 'SkinGetPoweredBy', array( &$text, $this ) );
index fb40857..ffbe629 100644 (file)
@@ -40,13 +40,6 @@ class SkinFactory {
         * @var array
         */
        private $displayNames = array();
-       /**
-        * Map of name => class name without "Skin" prefix, for legacy skins using the autodiscovery
-        * mechanism
-        *
-        * @var array
-        */
-       private $legacySkins = array();
 
        /**
         * @var SkinFactory
@@ -82,66 +75,6 @@ class SkinFactory {
                $this->displayNames[$name] = $displayName;
        }
 
-       /**
-        * @return array
-        */
-       private function getLegacySkinNames() {
-               static $skinsInitialised = false;
-
-               if ( !$skinsInitialised || !count( $this->legacySkins ) ) {
-                       # Get a list of available skins
-                       # Build using the regular expression '^(.*).php$'
-                       # Array keys are all lower case, array value keep the case used by filename
-                       #
-                       wfProfileIn( __METHOD__ . '-init' );
-
-                       global $wgStyleDirectory;
-
-                       $skinDir = dir( $wgStyleDirectory );
-
-                       if ( $skinDir !== false && $skinDir !== null ) {
-                               # while code from www.php.net
-                               while ( false !== ( $file = $skinDir->read() ) ) {
-                                       // Skip non-PHP files, hidden files, and '.dep' includes
-                                       $matches = array();
-
-                                       if ( preg_match( '/^([^.]*)\.php$/', $file, $matches ) ) {
-                                               $aSkin = $matches[1];
-
-                                               // Explicitly disallow loading core skins via the autodiscovery mechanism.
-                                               //
-                                               // They should be loaded already (in a non-autodicovery way), but old files might still
-                                               // exist on the server because our MW version upgrade process is widely documented as
-                                               // requiring just copying over all files, without removing old ones.
-                                               //
-                                               // This is one of the reasons we should have never used autodiscovery in the first
-                                               // place. This hack can be safely removed when autodiscovery is gone.
-                                               if ( in_array( $aSkin, array( 'CologneBlue', 'Modern', 'MonoBook', 'Vector' ) ) ) {
-                                                       wfLogWarning(
-                                                               "An old copy of the $aSkin skin was found in your skins/ directory. " .
-                                                               "You should remove it to avoid problems in the future." .
-                                                               "See https://www.mediawiki.org/wiki/Manual:Skin_autodiscovery for details."
-                                                       );
-                                                       continue;
-                                               }
-
-                                               wfLogWarning(
-                                                       "A skin using autodiscovery mechanism, $aSkin, was found in your skins/ directory. " .
-                                                       "The mechanism will be removed in MediaWiki 1.25 and the skin will no longer be recognized. " .
-                                                       "See https://www.mediawiki.org/wiki/Manual:Skin_autodiscovery for information how to fix this."
-                                               );
-                                               $this->legacySkins[strtolower( $aSkin )] = $aSkin;
-                                       }
-                               }
-                               $skinDir->close();
-                       }
-                       $skinsInitialised = true;
-                       wfProfileOut( __METHOD__ . '-init' );
-               }
-               return $this->legacySkins;
-
-       }
-
        /**
         * Returns an associative array of:
         *  skin name => human readable name
@@ -149,43 +82,7 @@ class SkinFactory {
         * @return array
         */
        public function getSkinNames() {
-               return array_merge(
-                       $this->getLegacySkinNames(),
-                       $this->displayNames
-               );
-       }
-
-       /**
-        * Get a legacy skin which uses the autodiscovery mechanism.
-        *
-        * @param string $name
-        * @return Skin|bool False if the skin couldn't be constructed
-        */
-       private function getLegacySkin( $name ) {
-               $skinNames = $this->getLegacySkinNames();
-               if ( !isset( $skinNames[$name] ) ) {
-                       return false;
-               }
-               $skinName = $skinNames[$name];
-               $className = "Skin{$skinName}";
-
-               # Grab the skin class and initialise it.
-               if ( !class_exists( $className ) ) {
-                       global $wgStyleDirectory;
-                       require_once "{$wgStyleDirectory}/{$skinName}.php";
-
-                       # Check if we got it
-                       if ( !class_exists( $className ) ) {
-                               # DO NOT die if the class isn't found. This breaks maintenance
-                               # scripts and can cause a user account to be unrecoverable
-                               # except by SQL manipulation if a previously valid skin name
-                               # is no longer valid.
-                               return false;
-                       }
-               }
-               $skin = new $className( $name );
-               return $skin;
-
+               return $this->displayNames;
        }
 
        /**
@@ -197,11 +94,6 @@ class SkinFactory {
         */
        public function makeSkin( $name ) {
                if ( !isset( $this->factoryFunctions[$name] ) ) {
-                       // Check the legacy autodiscovery method of skin loading
-                       $legacy = $this->getLegacySkin( $name );
-                       if ( $legacy ) {
-                               return $legacy;
-                       }
                        throw new SkinException( "No registered builder available for $name." );
                }
                $skin = call_user_func( $this->factoryFunctions[$name], $name );
index ae0003d..b229e06 100644 (file)
@@ -76,6 +76,7 @@ abstract class QueryPage extends SpecialPage {
                                array( 'ListredirectsPage', 'Listredirects' ),
                                array( 'LonelyPagesPage', 'Lonelypages' ),
                                array( 'LongPagesPage', 'Longpages' ),
+                               array( 'MediaStatisticsPage', 'MediaStatistics' ),
                                array( 'MIMEsearchPage', 'MIMEsearch' ),
                                array( 'MostcategoriesPage', 'Mostcategories' ),
                                array( 'MostimagesPage', 'Mostimages' ),
@@ -324,7 +325,7 @@ abstract class QueryPage extends SpecialPage {
                                                        'qc_value' => $value );
                                }
 
-                               $dbw->begin( __METHOD__ );
+                               $dbw->startAtomic( __METHOD__ );
                                # Clear out any old cached data
                                $dbw->delete( 'querycache', array( 'qc_type' => $this->getName() ), $fname );
                                # Save results into the querycache table on the master
@@ -336,7 +337,7 @@ abstract class QueryPage extends SpecialPage {
                                $dbw->insert( 'querycache_info',
                                        array( 'qci_type' => $this->getName(), 'qci_timestamp' => $dbw->timestamp() ),
                                        $fname );
-                               $dbw->commit( __METHOD__ );
+                               $dbw->endAtomic( __METHOD__ );
                        }
                } catch ( DBError $e ) {
                        if ( !$ignoreErrors ) {
@@ -405,7 +406,7 @@ abstract class QueryPage extends SpecialPage {
                        $res = $dbr->query( $sql, $fname );
                }
 
-               return $dbr->resultObject( $res );
+               return $res;
        }
 
        /**
index cd41a1c..4226ee0 100644 (file)
@@ -71,10 +71,13 @@ abstract class RedirectSpecialPage extends UnlistedSpecialPage {
         */
        public function getRedirectQuery() {
                $params = array();
+               $request = $this->getRequest();
 
                foreach ( $this->mAllowedRedirectParams as $arg ) {
-                       if ( $this->getRequest()->getVal( $arg, null ) !== null ) {
-                               $params[$arg] = $this->getRequest()->getVal( $arg );
+                       if ( $request->getVal( $arg, null ) !== null ) {
+                               $params[$arg] = $request->getVal( $arg );
+                       } elseif ( $request->getArray( $arg, null ) !== null ) {
+                               $params[$arg] = $request->getArray( $arg );
                        }
                }
 
@@ -188,7 +191,7 @@ abstract class RedirectSpecialArticle extends RedirectSpecialPage {
                        'action',
                        'redirect', 'rdfrom',
                        # Options for preloaded edits
-                       'preload', 'editintro', 'preloadtitle', 'summary', 'nosummary',
+                       'preload', 'preloadparams', 'editintro', 'preloadtitle', 'summary', 'nosummary',
                        # Options for overriding user settings
                        'preview', 'minor', 'watchthis',
                        # Options for history/diffs
index 8fc28f8..c0a94af 100644 (file)
@@ -39,7 +39,7 @@ class SpecialPage {
 
        // Minimum user level required to access this page, or "" for anyone.
        // Also used to categorise the pages in Special:Specialpages
-       private $mRestriction;
+       protected $mRestriction;
 
        // Listed in Special:Specialpages?
        private $mListed;
index 07b6b4e..48bcb77 100644 (file)
@@ -114,6 +114,7 @@ class SpecialPageFactory {
                // Media reports and uploads
                'Listfiles' => 'SpecialListFiles',
                'Filepath' => 'SpecialFilepath',
+               'MediaStatistics' => 'MediaStatisticsPage',
                'MIMEsearch' => 'MIMEsearchPage',
                'FileDuplicateSearch' => 'FileDuplicateSearchPage',
                'Upload' => 'SpecialUpload',
@@ -176,11 +177,41 @@ class SpecialPageFactory {
        private static $aliases;
 
        /**
-        * Get the special page list
+        * Reset the internal list of special pages. Useful when changing $wgSpecialPages after
+        * the internal list has already been initialized, e.g. during testing.
+        */
+       public static function resetList() {
+               self::$list = null;
+               self::$aliases = null;
+       }
+
+       /**
+        * Returns a list of canonical special page names.
+        * May be used to iterate over all registered special pages.
         *
+        * @return string[]
+        */
+       public static function getNames() {
+               return array_keys( self::getPageList() );
+       }
+
+       /**
+        * Get the special page list as an array
+        *
+        * @deprecated since 1.24, use getNames() instead.
         * @return array
         */
-       static function getList() {
+       public static function getList() {
+               wfDeprecated( __FUNCTION__, '1.24' );
+               return self::getPageList();
+       }
+
+       /**
+        * Get the special page list as an array
+        *
+        * @return array
+        */
+       private static function getPageList() {
                global $wgSpecialPages;
                global $wgDisableCounters, $wgDisableInternalSearch, $wgEmailAuthentication;
                global $wgEnableEmail, $wgEnableJavaScriptTest;
@@ -223,9 +254,6 @@ class SpecialPageFactory {
                        // This hook can be used to remove undesired built-in special pages
                        wfRunHooks( 'SpecialPage_initList', array( &self::$list ) );
 
-                       // Cast to object: func()[$key] doesn't work, but func()->$key does
-                       settype( self::$list, 'object' );
-
                        wfProfileOut( __METHOD__ );
                }
 
@@ -240,13 +268,12 @@ class SpecialPageFactory {
         * contain at least one entry (English fallbacks will be added if necessary).
         * @return object
         */
-       static function getAliasList() {
+       private static function getAliasListObject() {
                if ( !is_object( self::$aliases ) ) {
                        global $wgContLang;
                        $aliases = $wgContLang->getSpecialPageAliases();
 
-                       // Objects are passed by reference by default, need to create a copy
-                       $missingPages = clone self::getList();
+                       $missingPages = self::getPageList();
 
                        self::$aliases = array();
                        // Check for $aliases being an array since Language::getSpecialPageAliases can return null
@@ -283,8 +310,8 @@ class SpecialPageFactory {
 
                $caseFoldedAlias = $wgContLang->caseFold( $bits[0] );
                $caseFoldedAlias = str_replace( ' ', '_', $caseFoldedAlias );
-               if ( isset( self::getAliasList()->$caseFoldedAlias ) ) {
-                       $name = self::getAliasList()->$caseFoldedAlias;
+               if ( isset( self::getAliasListObject()->$caseFoldedAlias ) ) {
+                       $name = self::getAliasListObject()->$caseFoldedAlias;
                } else {
                        return array( null, null );
                }
@@ -335,7 +362,8 @@ class SpecialPageFactory {
        public static function exists( $name ) {
                list( $title, /*...*/ ) = self::resolveAlias( $name );
 
-               return property_exists( self::getList(), $title );
+               $specialPageList = self::getPageList();
+               return isset( $specialPageList[$title] );
        }
 
        /**
@@ -346,21 +374,39 @@ class SpecialPageFactory {
         */
        public static function getPage( $name ) {
                list( $realName, /*...*/ ) = self::resolveAlias( $name );
-               if ( property_exists( self::getList(), $realName ) ) {
-                       $rec = self::getList()->$realName;
+
+               $specialPageList = self::getPageList();
+
+               if ( isset( $specialPageList[$realName] ) ) {
+                       $rec = $specialPageList[$realName];
+
                        if ( is_string( $rec ) ) {
                                $className = $rec;
-
-                               return new $className;
+                               $page = new $className;
+                       } elseif ( is_callable( $rec ) ) {
+                               // Use callback to instantiate the special page
+                               $page = call_user_func( $rec );
                        } elseif ( is_array( $rec ) ) {
                                $className = array_shift( $rec );
                                // @deprecated, officially since 1.18, unofficially since forever
                                wfDeprecated( "Array syntax for \$wgSpecialPages is deprecated ($className), " .
                                        "define a subclass of SpecialPage instead.", '1.18' );
-                               self::getList()->$realName = MWFunction::newObj( $className, $rec );
+                               $page = MWFunction::newObj( $className, $rec );
+                       } elseif ( $rec instanceof SpecialPage ) {
+                               $page = $rec; //XXX: we should deep clone here
+                       } else {
+                               $page = null;
+                       }
+
+                       if ( $page instanceof SpecialPage ) {
+                               return $page;
+                       } else {
+                               // It's not a classname, nor a callback, nor a legacy constructor array,
+                               // nor a special page object. Give up.
+                               wfLogWarning( "Cannot instantiate special page $realName: bad spec!" );
+                               return null;
                        }
 
-                       return self::getList()->$realName;
                } else {
                        return null;
                }
@@ -380,7 +426,7 @@ class SpecialPageFactory {
                        global $wgUser;
                        $user = $wgUser;
                }
-               foreach ( self::getList() as $name => $rec ) {
+               foreach ( self::getPageList() as $name => $rec ) {
                        $page = self::getPage( $name );
                        if ( $page ) { // not null
                                $page->setContext( RequestContext::getMain() );
@@ -402,7 +448,7 @@ class SpecialPageFactory {
         */
        public static function getRegularPages() {
                $pages = array();
-               foreach ( self::getList() as $name => $rec ) {
+               foreach ( self::getPageList() as $name => $rec ) {
                        $page = self::getPage( $name );
                        if ( $page->isListed() && !$page->isRestricted() ) {
                                $pages[$name] = $page;
@@ -425,7 +471,7 @@ class SpecialPageFactory {
                        global $wgUser;
                        $user = $wgUser;
                }
-               foreach ( self::getList() as $name => $rec ) {
+               foreach ( self::getPageList() as $name => $rec ) {
                        $page = self::getPage( $name );
                        if (
                                $page->isListed()
@@ -534,7 +580,7 @@ class SpecialPageFactory {
         * @param IContextSource $context
         * @return string HTML fragment
         */
-       static function capturePath( Title $title, IContextSource $context ) {
+       public static function capturePath( Title $title, IContextSource $context ) {
                global $wgOut, $wgTitle, $wgRequest, $wgUser, $wgLang;
 
                // Save current globals
@@ -571,7 +617,7 @@ class SpecialPageFactory {
         * @param string|bool $subpage
         * @return string
         */
-       static function getLocalNameFor( $name, $subpage = false ) {
+       public static function getLocalNameFor( $name, $subpage = false ) {
                global $wgContLang;
                $aliases = $wgContLang->getSpecialPageAliases();
 
@@ -610,10 +656,10 @@ class SpecialPageFactory {
         * @param string $alias
         * @return Title|null Title or null if there is no such alias
         */
-       static function getTitleForAlias( $alias ) {
-               $name = self::resolveAlias( $alias );
-               if ( $name ) {
-                       return SpecialPage::getTitleFor( $name );
+       public static function getTitleForAlias( $alias ) {
+               list( $name, $subpage ) = self::resolveAlias( $alias );
+               if ( $name != null ) {
+                       return SpecialPage::getTitleFor( $name, $subpage );
                } else {
                        return null;
                }
index 678c803..be2f1e8 100644 (file)
@@ -78,15 +78,9 @@ abstract class WantedQueryPage extends QueryPage {
                $title = Title::makeTitleSafe( $result->namespace, $result->title );
                if ( $title instanceof Title ) {
                        if ( $this->isCached() || $this->forceExistenceCheck() ) {
-                               $pageLink = $title->isKnown()
+                               $pageLink = $this->existenceCheck( $title )
                                        ? '<del>' . Linker::link( $title ) . '</del>'
-                                       : Linker::link(
-                                               $title,
-                                               null,
-                                               array(),
-                                               array(),
-                                               array( 'broken' )
-                                       );
+                                       : Linker::link( $title );
                        } else {
                                $pageLink = Linker::link(
                                        $title,
@@ -102,6 +96,25 @@ abstract class WantedQueryPage extends QueryPage {
                }
        }
 
+       /**
+        * Does the Title currently exists
+        *
+        * This method allows a subclass to override this check
+        * (For example, wantedfiles, would want to check if the file exists
+        * not just that a page in the file namespace exists).
+        *
+        * This will only control if the link is crossed out. Whether or not the link
+        * is blue vs red is controlled by if the title exists.
+        *
+        * @note This will only be run if the page is cached (ie $wgMiserMode = true)
+        *   unless forceExistenceCheck() is true.
+        * @since 1.24
+        * @return boolean
+        */
+       protected function existenceCheck( Title $title ) {
+               return $title->isKnown();
+       }
+
        /**
         * Make a "what links here" link for a given title
         *
index d3e7398..e0be838 100644 (file)
@@ -107,11 +107,11 @@ class SpecialChangeEmail extends FormSpecialPage {
        }
 
        protected function alterForm( HTMLForm $form ) {
+               $form->setDisplayFormat( 'vform' );
                $form->setId( 'mw-changeemail-form' );
                $form->setTableId( 'mw-changeemail-table' );
-               $form->setWrapperLegendMsg( 'changeemail-header' );
+               $form->setWrapperLegend( false );
                $form->setSubmitTextMsg( 'changeemail-submit' );
-               $form->addButton( 'wpCancel',  $this->msg( 'changeemail-cancel' )->text() );
                $form->addHiddenField( 'returnto', $this->getRequest()->getVal( 'returnto' ) );
        }
 
index 0958126..20532a9 100644 (file)
@@ -113,7 +113,8 @@ class SpecialEmailUser extends UnlistedSpecialPage {
                // error out if sending user cannot do this
                $error = self::getPermissionsError(
                        $this->getUser(),
-                       $this->getRequest()->getVal( 'wpEditToken' )
+                       $this->getRequest()->getVal( 'wpEditToken' ),
+                       $this->getConfig()
                );
 
                switch ( $error ) {
@@ -208,12 +209,15 @@ class SpecialEmailUser extends UnlistedSpecialPage {
         *
         * @param User $user
         * @param string $editToken Edit token
+        * @param Config $config optional for backwards compatibility
         * @return string|null Null on success or string on error
         */
-       public static function getPermissionsError( $user, $editToken ) {
-               global $wgEnableEmail, $wgEnableUserEmail;
-
-               if ( !$wgEnableEmail || !$wgEnableUserEmail ) {
+       public static function getPermissionsError( $user, $editToken, Config $config = null ) {
+               if ( $config === null ) {
+                       wfDebug( __METHOD__ . ' called without a Config instance passed to it' );
+                       $config = ConfigFactory::getDefaultInstance()->makeConfig( 'main' );
+               }
+               if ( !$config->get( 'EnableEmail' ) || !$config->get( 'EnableUserEmail' ) ) {
                        return 'usermaildisabled';
                }
 
@@ -256,10 +260,9 @@ class SpecialEmailUser extends UnlistedSpecialPage {
         * @return string Form asking for user name.
         */
        protected function userForm( $name ) {
-               global $wgScript;
                $string = Xml::openElement(
                        'form',
-                       array( 'method' => 'get', 'action' => $wgScript, 'id' => 'askusername' )
+                       array( 'method' => 'get', 'action' => wfScript(), 'id' => 'askusername' )
                ) .
                        Html::hidden( 'title', $this->getPageTitle()->getPrefixedText() ) .
                        Xml::openElement( 'fieldset' ) .
@@ -302,7 +305,7 @@ class SpecialEmailUser extends UnlistedSpecialPage {
         * or maybe even true on success if anything uses the EmailUser hook.
         */
        public static function submit( array $data, IContextSource $context ) {
-               global $wgUserEmailUseReplyTo;
+               $config = $context->getConfig();
 
                $target = self::getTarget( $data['Target'] );
                if ( !$target instanceof User ) {
@@ -310,8 +313,8 @@ class SpecialEmailUser extends UnlistedSpecialPage {
                        return $context->msg( $target . 'text' )->parseAsBlock();
                }
 
-               $to = new MailAddress( $target );
-               $from = new MailAddress( $context->getUser() );
+               $to = MailAddress::newFromUser( $target );
+               $from = MailAddress::newFromUser( $context->getUser() );
                $subject = $data['Subject'];
                $text = $data['Text'];
 
@@ -325,16 +328,14 @@ class SpecialEmailUser extends UnlistedSpecialPage {
                        return $error;
                }
 
-               if ( $wgUserEmailUseReplyTo ) {
+               if ( $config->get( 'UserEmailUseReplyTo' ) ) {
                        // Put the generic wiki autogenerated address in the From:
                        // header and reserve the user for Reply-To.
                        //
                        // This is a bit ugly, but will serve to differentiate
                        // wiki-borne mails from direct mails and protects against
                        // SPF and bounce problems with some mailers (see below).
-                       global $wgPasswordSender;
-
-                       $mailFrom = new MailAddress( $wgPasswordSender,
+                       $mailFrom = new MailAddress( $config->get( 'PasswordSender' ),
                                wfMessage( 'emailsender' )->inContentLanguage()->text() );
                        $replyTo = $from;
                } else {
index b5818ea..5bae28f 100644 (file)
@@ -38,10 +38,6 @@ class SpecialListGroupRights extends SpecialPage {
         * @param string|null $par
         */
        public function execute( $par ) {
-               global $wgImplicitGroups;
-               global $wgGroupPermissions, $wgRevokePermissions, $wgAddGroups, $wgRemoveGroups;
-               global $wgGroupsAddToSelf, $wgGroupsRemoveFromSelf;
-
                $this->setHeaders();
                $this->outputHeader();
 
@@ -58,19 +54,26 @@ class SpecialListGroupRights extends SpecialPage {
                                '</tr>'
                );
 
+               $config = $this->getConfig();
+               $groupPermissions = $config->get( 'GroupPermissions' );
+               $revokePermissions = $config->get( 'RevokePermissions' );
+               $addGroups = $config->get( 'AddGroups' );
+               $removeGroups = $config->get( 'RemoveGroups' );
+               $groupsAddToSelf = $config->get( 'GroupsAddToSelf' );
+               $groupsRemoveFromSelf = $config->get( 'GroupsRemoveFromSelf' );
                $allGroups = array_unique( array_merge(
-                       array_keys( $wgGroupPermissions ),
-                       array_keys( $wgRevokePermissions ),
-                       array_keys( $wgAddGroups ),
-                       array_keys( $wgRemoveGroups ),
-                       array_keys( $wgGroupsAddToSelf ),
-                       array_keys( $wgGroupsRemoveFromSelf )
+                       array_keys( $groupPermissions ),
+                       array_keys( $revokePermissions ),
+                       array_keys( $addGroups ),
+                       array_keys( $removeGroups ),
+                       array_keys( $groupsAddToSelf ),
+                       array_keys( $groupsRemoveFromSelf )
                ) );
                asort( $allGroups );
 
                foreach ( $allGroups as $group ) {
-                       $permissions = isset( $wgGroupPermissions[$group] )
-                               ? $wgGroupPermissions[$group]
+                       $permissions = isset( $groupPermissions[$group] )
+                               ? $groupPermissions[$group]
                                : array();
                        $groupname = ( $group == '*' ) // Replace * with a more descriptive groupname
                                ? 'all'
@@ -100,7 +103,7 @@ class SpecialListGroupRights extends SpecialPage {
                                        SpecialPage::getTitleFor( 'Listusers' ),
                                        $this->msg( 'listgrouprights-members' )->escaped()
                                );
-                       } elseif ( !in_array( $group, $wgImplicitGroups ) ) {
+                       } elseif ( !in_array( $group, $config->get( 'ImplicitGroups' ) ) ) {
                                $grouplink = '<br />' . Linker::linkKnown(
                                        SpecialPage::getTitleFor( 'Listusers' ),
                                        $this->msg( 'listgrouprights-members' )->escaped(),
@@ -112,12 +115,12 @@ class SpecialListGroupRights extends SpecialPage {
                                $grouplink = '';
                        }
 
-                       $revoke = isset( $wgRevokePermissions[$group] ) ? $wgRevokePermissions[$group] : array();
-                       $addgroups = isset( $wgAddGroups[$group] ) ? $wgAddGroups[$group] : array();
-                       $removegroups = isset( $wgRemoveGroups[$group] ) ? $wgRemoveGroups[$group] : array();
-                       $addgroupsSelf = isset( $wgGroupsAddToSelf[$group] ) ? $wgGroupsAddToSelf[$group] : array();
-                       $removegroupsSelf = isset( $wgGroupsRemoveFromSelf[$group] )
-                               ? $wgGroupsRemoveFromSelf[$group]
+                       $revoke = isset( $revokePermissions[$group] ) ? $revokePermissions[$group] : array();
+                       $addgroups = isset( $addGroups[$group] ) ? $addGroups[$group] : array();
+                       $removegroups = isset( $removeGroups[$group] ) ? $removeGroups[$group] : array();
+                       $addgroupsSelf = isset( $groupsAddToSelf[$group] ) ? $groupsAddToSelf[$group] : array();
+                       $removegroupsSelf = isset( $groupsRemoveFromSelf[$group] )
+                               ? $groupsRemoveFromSelf[$group]
                                : array();
 
                        $id = $group == '*' ? false : Sanitizer::escapeId( $group );
@@ -135,10 +138,11 @@ class SpecialListGroupRights extends SpecialPage {
        }
 
        private function outputNamespaceProtectionInfo() {
-               global $wgNamespaceProtection, $wgParser, $wgContLang;
+               global $wgParser, $wgContLang;
                $out = $this->getOutput();
+               $namespaceProtection = $this->getConfig()->get( 'NamespaceProtection' );
 
-               if ( count( $wgNamespaceProtection ) == 0 ) {
+               if ( count( $namespaceProtection ) == 0 ) {
                        return;
                }
 
@@ -161,8 +165,8 @@ class SpecialListGroupRights extends SpecialPage {
                        )
                );
 
-               ksort( $wgNamespaceProtection );
-               foreach ( $wgNamespaceProtection as $namespace => $rights ) {
+               ksort( $namespaceProtection );
+               foreach ( $namespaceProtection as $namespace => $rights ) {
                        if ( !in_array( $namespace, MWNamespace::getValidNamespaces() ) ) {
                                continue;
                        }
@@ -251,45 +255,54 @@ class SpecialListGroupRights extends SpecialPage {
                sort( $r );
 
                $lang = $this->getLanguage();
+               $allGroups = User::getAllGroups();
 
                if ( $add === true ) {
                        $r[] = $this->msg( 'listgrouprights-addgroup-all' )->escaped();
-               } elseif ( is_array( $add ) && count( $add ) ) {
-                       $add = array_values( array_unique( $add ) );
-                       $r[] = $this->msg( 'listgrouprights-addgroup',
-                               $lang->listToText( array_map( array( 'User', 'makeGroupLinkWiki' ), $add ) ),
-                               count( $add )
-                       )->parse();
+               } elseif ( is_array( $add ) ) {
+                       $add = array_intersect( array_values( array_unique( $add ) ), $allGroups );
+                       if ( count( $add ) ) {
+                               $r[] = $this->msg( 'listgrouprights-addgroup',
+                                       $lang->listToText( array_map( array( 'User', 'makeGroupLinkWiki' ), $add ) ),
+                                       count( $add )
+                               )->parse();
+                       }
                }
 
                if ( $remove === true ) {
                        $r[] = $this->msg( 'listgrouprights-removegroup-all' )->escaped();
-               } elseif ( is_array( $remove ) && count( $remove ) ) {
-                       $remove = array_values( array_unique( $remove ) );
-                       $r[] = $this->msg( 'listgrouprights-removegroup',
-                               $lang->listToText( array_map( array( 'User', 'makeGroupLinkWiki' ), $remove ) ),
-                               count( $remove )
-                       )->parse();
+               } elseif ( is_array( $remove ) ) {
+                       $remove = array_intersect( array_values( array_unique( $remove ) ), $allGroups );
+                       if ( count( $remove ) ) {
+                               $r[] = $this->msg( 'listgrouprights-removegroup',
+                                       $lang->listToText( array_map( array( 'User', 'makeGroupLinkWiki' ), $remove ) ),
+                                       count( $remove )
+                               )->parse();
+                       }
                }
 
                if ( $addSelf === true ) {
                        $r[] = $this->msg( 'listgrouprights-addgroup-self-all' )->escaped();
-               } elseif ( is_array( $addSelf ) && count( $addSelf ) ) {
-                       $addSelf = array_values( array_unique( $addSelf ) );
-                       $r[] = $this->msg( 'listgrouprights-addgroup-self',
-                               $lang->listToText( array_map( array( 'User', 'makeGroupLinkWiki' ), $addSelf ) ),
-                               count( $addSelf )
-                       )->parse();
+               } elseif ( is_array( $addSelf ) ) {
+                       $addSelf = array_intersect( array_values( array_unique( $addSelf ) ), $allGroups );
+                       if ( count( $addSelf ) ) {
+                               $r[] = $this->msg( 'listgrouprights-addgroup-self',
+                                       $lang->listToText( array_map( array( 'User', 'makeGroupLinkWiki' ), $addSelf ) ),
+                                       count( $addSelf )
+                               )->parse();
+                       }
                }
 
                if ( $removeSelf === true ) {
                        $r[] = $this->msg( 'listgrouprights-removegroup-self-all' )->parse();
-               } elseif ( is_array( $removeSelf ) && count( $removeSelf ) ) {
-                       $removeSelf = array_values( array_unique( $removeSelf ) );
-                       $r[] = $this->msg( 'listgrouprights-removegroup-self',
-                               $lang->listToText( array_map( array( 'User', 'makeGroupLinkWiki' ), $removeSelf ) ),
-                               count( $removeSelf )
-                       )->parse();
+               } elseif ( is_array( $removeSelf ) ) {
+                       $removeSelf = array_intersect( array_values( array_unique( $removeSelf ) ), $allGroups );
+                       if ( count( $removeSelf ) ) {
+                               $r[] = $this->msg( 'listgrouprights-removegroup-self',
+                                       $lang->listToText( array_map( array( 'User', 'makeGroupLinkWiki' ), $removeSelf ) ),
+                                       count( $removeSelf )
+                               )->parse();
+                       }
                }
 
                if ( empty( $r ) ) {
index cc3226d..dad9074 100644 (file)
@@ -194,10 +194,8 @@ class UsersPager extends AlphabeticPager {
 
                $edits = '';
                if ( !$this->including && $this->getConfig()->get( 'Edititis' ) ) {
-                       // @todo fixme i18n issue: Hardcoded square brackets.
-                       $edits = ' [' .
-                               $this->msg( 'usereditcount' )->numParams( $row->edits )->escaped() .
-                               ']';
+                       $count = $this->msg( 'usereditcount' )->numParams( $row->edits )->escaped();
+                       $edits = $this->msg( 'word-separator' )->escaped() . $this->msg( 'brackets', $count )->escaped();
                }
 
                $created = '';
index 5bd69e0..60225ea 100644 (file)
@@ -28,7 +28,7 @@
  * @ingroup SpecialPage
  */
 class MIMEsearchPage extends QueryPage {
-       protected $major, $minor;
+       protected $major, $minor, $mime;
 
        function __construct( $name = 'MIMEsearch' ) {
                parent::__construct( $name );
@@ -105,32 +105,36 @@ class MIMEsearchPage extends QueryPage {
                return array();
        }
 
-       function execute( $par ) {
-               $mime = $par ? $par : $this->getRequest()->getText( 'mime' );
-               $mime = trim( $mime );
+       /**
+        * Return HTML to put just before the results.
+        */
+       function getPageHeader() {
 
-               $this->setHeaders();
-               $this->outputHeader();
-               $this->getOutput()->addHTML(
-                       Xml::openElement(
+               return Xml::openElement(
                                'form',
                                array( 'id' => 'specialmimesearch', 'method' => 'get', 'action' => wfScript() )
                        ) .
-                               Xml::openElement( 'fieldset' ) .
-                               Html::hidden( 'title', $this->getPageTitle()->getPrefixedText() ) .
-                               Xml::element( 'legend', null, $this->msg( 'mimesearch' )->text() ) .
-                               Xml::inputLabel( $this->msg( 'mimetype' )->text(), 'mime', 'mime', 20, $mime ) .
-                               ' ' .
-                               Xml::submitButton( $this->msg( 'ilsubmit' )->text() ) .
-                               Xml::closeElement( 'fieldset' ) .
-                               Xml::closeElement( 'form' )
-               );
+                       Xml::openElement( 'fieldset' ) .
+                       Html::hidden( 'title', $this->getPageTitle()->getPrefixedText() ) .
+                       Xml::element( 'legend', null, $this->msg( 'mimesearch' )->text() ) .
+                       Xml::inputLabel( $this->msg( 'mimetype' )->text(), 'mime', 'mime', 20, $this->mime ) .
+                       ' ' .
+                       Xml::submitButton( $this->msg( 'ilsubmit' )->text() ) .
+                                       Xml::closeElement( 'fieldset' ) .
+                                       Xml::closeElement( 'form' );
+       }
 
-               list( $this->major, $this->minor ) = File::splitMime( $mime );
+       function execute( $par ) {
+               $this->mime = $par ? $par : $this->getRequest()->getText( 'mime' );
+               $this->mime = trim( $this->mime );
+               list( $this->major, $this->minor ) = File::splitMime( $this->mime );
 
                if ( $this->major == '' || $this->minor == '' || $this->minor == 'unknown' ||
                        !self::isValidType( $this->major )
                ) {
+                       $this->setHeaders();
+                       $this->outputHeader();
+                       $this->getOutput()->addHTML( $this->getPageHeader() );
                        return;
                }
 
diff --git a/includes/specials/SpecialMediaStatistics.php b/includes/specials/SpecialMediaStatistics.php
new file mode 100644 (file)
index 0000000..681c332
--- /dev/null
@@ -0,0 +1,325 @@
+<?php
+/**
+ * Implements Special:MediaStatistics
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * @file
+ * @ingroup SpecialPage
+ * @author Brian Wolff
+ */
+
+/**
+ * @ingroup SpecialPage
+ */
+class MediaStatisticsPage extends QueryPage {
+       protected $totalCount = 0, $totalBytes = 0;
+
+       function __construct( $name = 'MediaStatistics' ) {
+               parent::__construct( $name );
+               // Generally speaking there is only a small number of file types,
+               // so just show all of them.
+               $this->limit = 5000;
+               $this->shownavigation = false;
+       }
+
+       function isExpensive() {
+               return true;
+       }
+
+       /**
+        * Query to do.
+        *
+        * This abuses the query cache table by storing mime types as "titles".
+        *
+        * This will store entries like [[Media:BITMAP;image/jpeg;200;20000]]
+        * where the form is Media type;mime type;count;bytes.
+        *
+        * This relies on the behaviour that when value is tied, the order things
+        * come out of querycache table is the order they went in. Which is hacky.
+        * However, other special pages like Special:Deadendpages and
+        * Special:BrokenRedirects also rely on this.
+        */
+       public function getQueryInfo() {
+               $dbr = wfGetDB( DB_SLAVE );
+               $fakeTitle = $dbr->buildConcat( array(
+                       'img_media_type',
+                       $dbr->addQuotes( ';' ),
+                       'img_major_mime',
+                       $dbr->addQuotes( '/' ),
+                       'img_minor_mime',
+                       $dbr->addQuotes( ';' ),
+                       'COUNT(*)',
+                       $dbr->addQuotes( ';' ),
+                       'SUM( img_size )'
+               ) );
+               return array(
+                       'tables' => array( 'image' ),
+                       'fields' => array(
+                               'title' => $fakeTitle,
+                               'namespace' => NS_MEDIA, /* needs to be something */
+                               'value' => '1'
+                       ),
+                       'options' => array(
+                               'GROUP BY' => array(
+                                       'img_media_type',
+                                       'img_major_mime',
+                                       'img_minor_mime',
+                               )
+                       )
+               );
+       }
+
+       /**
+        * How to sort the results
+        *
+        * It's important that img_media_type come first, otherwise the
+        * tables will be fragmented.
+        * @return Array Fields to sort by
+        */
+       function getOrderFields() {
+               return array( 'img_media_type', 'count(*)', 'img_major_mime', 'img_minor_mime' );
+       }
+
+       /**
+        * Output the results of the query.
+        *
+        * @param $out OutputPage
+        * @param $skin Skin (deprecated presumably)
+        * @param $dbr DatabaseBase
+        * @param $res ResultWrapper Results from query
+        * @param $num integer Number of results
+        * @param $offset integer Paging offset (Should always be 0 in our case)
+        */
+       protected function outputResults( $out, $skin, $dbr, $res, $num, $offset ) {
+               $prevMediaType = null;
+               foreach ( $res as $row ) {
+                       list( $mediaType, $mime, $totalCount, $totalBytes ) = $this->splitFakeTitle( $row->title );
+                       if ( $prevMediaType !== $mediaType ) {
+                               if ( $prevMediaType !== null ) {
+                                       // We're not at beginning, so we have to
+                                       // close the previous table.
+                                       $this->outputTableEnd();
+                               }
+                               $this->outputMediaType( $mediaType );
+                               $this->outputTableStart( $mediaType );
+                               $prevMediaType = $mediaType;
+                       }
+                       $this->outputTableRow( $mime, intval( $totalCount ), intval( $totalBytes ) );
+               }
+               if ( $prevMediaType !== null ) {
+                       $this->outputTableEnd();
+               }
+       }
+
+       /**
+        * Output closing </table>
+        */
+       protected function outputTableEnd() {
+               $this->getOutput()->addHtml( Html::closeElement( 'table' ) );
+       }
+
+       /**
+        * Output a row of the stats table
+        *
+        * @param $mime String mime type (e.g. image/jpeg)
+        * @param $count integer Number of images of this type
+        * @param $totalBytes integer Total space for images of this type
+        */
+       protected function outputTableRow( $mime, $count, $bytes ) {
+               $mimeSearch = SpecialPage::getTitleFor( 'MIMEsearch', $mime );
+               $row = Html::rawElement(
+                       'td',
+                       array(),
+                       Linker::link( $mimeSearch, htmlspecialchars( $mime ) )
+               );
+               $row .= Html::element(
+                       'td',
+                       array(),
+                       $this->getExtensionList( $mime )
+               );
+               $row .= Html::rawElement(
+                       'td',
+                       array(),
+                       $this->msg( 'mediastatistics-nfiles' )
+                               ->numParams( $count )
+                               /** @todo Check to be sure this really should have number formatting */
+                               ->numParams( $this->makePercentPretty( $count / $this->totalCount ) )
+                               ->parse()
+               );
+               $row .= Html::rawElement(
+                       'td',
+                       // Make sure js sorts it in numeric order
+                       array( 'data-sort-value' =>  $bytes ),
+                       $this->msg( 'mediastatistics-nbytes' )
+                               ->numParams( $bytes )
+                               ->sizeParams( $bytes )
+                               /** @todo Check to be sure this really should have number formatting */
+                               ->numParams( $this->makePercentPretty( $bytes / $this->totalBytes ) )
+                               ->parse()
+               );
+
+               $this->getOutput()->addHTML( Html::rawElement( 'tr', array(), $row ) );
+       }
+
+       /**
+        * @param float $decimal A decimal percentage (ie for 12.3%, this would be 0.123)
+        * @return String The percentage formatted so that 3 significant digits are shown.
+        */
+       protected function makePercentPretty( $decimal ) {
+               $decimal *= 100;
+               // Always show three useful digits
+               if ( $decimal == 0 ) {
+                       return '0';
+               }
+               $percent = sprintf( "%." . max( 0, 2 - floor( log10( $decimal ) ) ) . "f", $decimal );
+               // Then remove any trailing 0's
+               return preg_replace( '/\.?0*$/', '', $percent );
+       }
+
+       /**
+        * Given a mime type, return a comma separated list of allowed extensions.
+        *
+        * @param $mime String mime type
+        * @return String Comma separated list of allowed extensions (e.g. ".ogg, .oga")
+        */
+       private function getExtensionList( $mime ) {
+               $exts = MimeMagic::singleton()->getExtensionsForType( $mime );
+               if ( $exts === null ) {
+                       return '';
+               }
+               $extArray = explode( ' ', $exts );
+               $extArray = array_unique( $extArray );
+               foreach ( $extArray as &$ext ) {
+                       $ext = '.' . $ext;
+               }
+
+               return $this->getLanguage()->commaList( $extArray );
+       }
+
+       /**
+        * Output the start of the table
+        *
+        * Including opening <table>, and first <tr> with column headers.
+        */
+       protected function outputTableStart( $mediaType ) {
+               $this->getOutput()->addHTML(
+                       Html::openElement(
+                               'table',
+                               array( 'class' => array(
+                                       'mw-mediastats-table',
+                                       'mw-mediastats-table-' . strtolower( $mediaType ),
+                                       'sortable',
+                                       'wikitable'
+                               ))
+                       )
+               );
+               $this->getOutput()->addHTML( $this->getTableHeaderRow() );
+       }
+
+       /**
+        * Get (not output) the header row for the table
+        *
+        * @return String the header row of the able
+        */
+       protected function getTableHeaderRow() {
+               $headers = array( 'mimetype', 'extensions', 'count', 'totalbytes' );
+               $ths = '';
+               foreach ( $headers as $header ) {
+                       $ths .= Html::rawElement(
+                               'th',
+                               array(),
+                               // for grep:
+                               // mediastatistics-table-mimetype, mediastatistics-table-extensions
+                               // tatistics-table-count, mediastatistics-table-totalbytes
+                               $this->msg( 'mediastatistics-table-' . $header )->parse()
+                       );
+               }
+               return Html::rawElement( 'tr', array(), $ths );
+       }
+
+       /**
+        * Output a header for a new media type section
+        *
+        * @param $mediaType string A media type (e.g. from the MEDIATYPE_xxx constants)
+        */
+       protected function outputMediaType( $mediaType ) {
+               $this->getOutput()->addHTML(
+                       Html::element(
+                               'h2',
+                               array( 'class' => array(
+                                       'mw-mediastats-mediatype',
+                                       'mw-mediastats-mediatype-' . strtolower( $mediaType )
+                               )),
+                               // for grep
+                               // mediastatistics-header-unknown, mediastatistics-header-bitmap,
+                               // mediastatistics-header-drawing, mediastatistics-header-audio,
+                               // mediastatistics-header-video, mediastatistics-header-multimedia,
+                               // mediastatistics-header-office, mediastatistics-header-text,
+                               // mediastatistics-header-executable, mediastatistics-header-archive,
+                               $this->msg( 'mediastatistics-header-' . strtolower( $mediaType ) )->text()
+                       )
+               );
+               /** @todo Possibly could add a message here explaining what the different types are.
+                *    not sure if it is needed though.
+                */
+       }
+
+       /**
+        * parse the fake title format that this special page abuses querycache with.
+        *
+        * @param $fakeTitle String A string formatted as <media type>;<mime type>;<count>;<bytes>
+        * @return Array The constituant parts of $fakeTitle
+        */
+       private function splitFakeTitle( $fakeTitle ) {
+               return explode( ';', $fakeTitle, 4 );
+       }
+
+       /**
+        * What group to put the page in
+        * @return string
+        */
+       protected function getGroupName() {
+               return 'media';
+       }
+
+       /**
+        * This method isn't used, since we override outputResults, but
+        * we need to implement since abstract in parent class.
+        *
+        * @param $skin Skin
+        * @param $result stdObject Result row
+        */
+       public function formatResult( $skin, $result ) {
+               throw new MWException( "unimplemented" );
+       }
+
+       /**
+        * Initialize total values so we can figure out percentages later.
+        *
+        * @param $dbr DatabaseBase
+        * @param $res ResultWrapper
+        */
+       public function preprocessResults( $dbr, $res ) {
+               $this->totalCount = $this->totalBytes = 0;
+               foreach ( $res as $row ) {
+                       list( , , $count, $bytes ) = $this->splitFakeTitle( $row->title );
+                       $this->totalCount += $count;
+                       $this->totalBytes += $bytes;
+               }
+               $res->seek( 0 );
+       }
+}
index 3c9b515..43f5a1b 100644 (file)
@@ -476,8 +476,9 @@ class SpecialMergeHistory extends SpecialPage {
                );
 
                # @todo message should use redirect=no
-               $this->getOutput()->addWikiMsg( 'mergehistory-success',
-                       $targetTitle->getPrefixedText(), $destTitle->getPrefixedText(), $count );
+               $this->getOutput()->addWikiText( $this->msg( 'mergehistory-success',
+                       $targetTitle->getPrefixedText(), $destTitle->getPrefixedText() )->numParams(
+                       $count )->text() );
 
                wfRunHooks( 'ArticleMergeComplete', array( $targetTitle, $destTitle ) );
 
index 5c8794a..2acf23c 100644 (file)
@@ -76,6 +76,7 @@ class SpecialPageLanguage extends FormSpecialPage {
 
                $page['language'] = array(
                        'id' => 'mw-pl-languageselector',
+                       'cssclass' => 'mw-languageselector',
                        'type' => 'select',
                        'options' => $options,
                        'label-message' => 'pagelang-language',
@@ -92,6 +93,7 @@ class SpecialPageLanguage extends FormSpecialPage {
        public function alterForm( HTMLForm $form ) {
                $form->setDisplayFormat( 'vform' );
                $form->setWrapperLegend( false );
+               wfRunHooks( 'LanguageSelector', array( $this->getOutput(), 'mw-languageselector' ) );
        }
 
        /**
index 4cfd445..cea00fa 100644 (file)
@@ -73,6 +73,7 @@ class SpecialPreferences extends SpecialPage {
                $htmlForm = new HTMLForm( array(), $context, 'prefs-restore' );
 
                $htmlForm->setSubmitTextMsg( 'restoreprefs' );
+               $htmlForm->setSubmitDestructive();
                $htmlForm->setSubmitCallback( array( $this, 'submitReset' ) );
                $htmlForm->suppressReset();
 
index 17d7664..e6d8f1c 100644 (file)
@@ -732,7 +732,7 @@ class SpecialRecentChanges extends ChangesListSpecialPage {
 
                        $link = $this->makeOptionsLink( $linkMessage->text(),
                                array( $key => 1 - $options[$key] ), $nondefaults );
-                       $links[] = $this->msg( $msg )->rawParams( $link )->escaped();
+                       $links[] = "<span class=\"$msg rcshowhideoption\">" . $this->msg( $msg )->rawParams( $link )->escaped() . '</span>';
                }
 
                // show from this onward link
@@ -740,13 +740,16 @@ class SpecialRecentChanges extends ChangesListSpecialPage {
                $now = $lang->userTimeAndDate( $timestamp, $user );
                $timenow = $lang->userTime( $timestamp, $user );
                $datenow = $lang->userDate( $timestamp, $user );
-               $rclinks = $this->msg( 'rclinks' )->rawParams( $cl, $dl, $lang->pipeList( $links ) )
-                       ->parse();
-               $rclistfrom = $this->makeOptionsLink(
+               $pipedLinks = '<span class="rcshowhide">' . $lang->pipeList( $links ) . '</span>';
+
+               $rclinks = '<span class="rclinks">' . $this->msg( 'rclinks' )->rawParams( $cl, $dl, $pipedLinks )
+                       ->parse() . '</span>';
+
+               $rclistfrom = '<span class="rclistfrom">' . $this->makeOptionsLink(
                        $this->msg( 'rclistfrom' )->rawParams( $now, $timenow, $datenow )->parse(),
                        array( 'from' => $timestamp ),
                        $nondefaults
-               );
+               ) . '</span>';
 
                return "{$note}$rclinks<br />$rclistfrom";
        }
index 3407476..adc248e 100644 (file)
@@ -673,26 +673,6 @@ class SpecialSearch extends SpecialPage {
 
                $date = $lang->userTimeAndDate( $timestamp, $this->getUser() );
 
-               // link to related articles if supported
-               $related = '';
-               if ( $result->hasRelated() ) {
-                       $stParams = array_merge(
-                               $this->powerSearchOptions(),
-                               array(
-                                       'search' => $this->msg( 'searchrelated' )->inContentLanguage()->text() .
-                                               ':' . $title->getPrefixedText(),
-                                       'fulltext' => $this->msg( 'search' )->text()
-                               )
-                       );
-
-                       $related = ' -- ' . Linker::linkKnown(
-                               $this->getPageTitle(),
-                               $this->msg( 'search-relatedarticle' )->text(),
-                               array(),
-                               $stParams
-                       );
-               }
-
                $fileMatch = '';
                // Include a thumbnail for media files...
                if ( $title->getNamespace() == NS_FILE ) {
@@ -718,7 +698,7 @@ class SpecialSearch extends SpecialPage {
                                                '<td style="vertical-align: top;">' .
                                                "{$link} {$redirect} {$section} {$fileMatch}" .
                                                $extract .
-                                               "<div class='mw-search-result-data'>{$desc} - {$date}{$related}</div>" .
+                                               "<div class='mw-search-result-data'>{$desc} - {$date}</div>" .
                                                '</td>' .
                                                '</tr>' .
                                                '</table>' .
@@ -738,7 +718,7 @@ class SpecialSearch extends SpecialPage {
                ) ) ) {
                        $html = "<li><div class='mw-search-result-heading'>" .
                                "{$link} {$redirect} {$section} {$fileMatch}</div> {$extract}\n" .
-                               "<div class='mw-search-result-data'>{$size} - {$date}{$related}</div>" .
+                               "<div class='mw-search-result-data'>{$size} - {$date}</div>" .
                                "</li>\n";
                }
 
@@ -1095,9 +1075,8 @@ class SpecialSearch extends SpecialPage {
 
                // Results-info
                if ( $totalNum > 0 && $this->offset < $totalNum ) {
-                       $top = $this->msg( 'showingresultsheader' )
+                       $top = $this->msg( 'search-showingresults' )
                                ->numParams( $this->offset + 1, $this->offset + $resultsShown, $totalNum )
-                               ->params( wfEscapeWikiText( $term ) )
                                ->numParams( $resultsShown )
                                ->parse();
                        $out .= Xml::tags( 'div', array( 'class' => 'results-info' ), $top ) .
index 67c96a7..f0e360e 100644 (file)
@@ -151,7 +151,7 @@ class SpecialStatistics extends SpecialPage {
                                        $this->getLanguage()->formatNum( $this->total ),
                                        array( 'class' => 'mw-statistics-pages' ),
                                        'statistics-pages-desc' ) .
-                               $this->formatRow( Linker::linkKnown( SpecialPage::getTitleFor( 'Listfiles' ),
+                               $this->formatRow( Linker::linkKnown( SpecialPage::getTitleFor( 'MediaStatistics' ),
                                        $this->msg( 'statistics-files' )->parse() ),
                                        $this->getLanguage()->formatNum( $this->images ),
                                        array( 'class' => 'mw-statistics-files' ) );
index 96e4dbf..244b889 100644 (file)
@@ -63,8 +63,10 @@ class SpecialUnblock extends SpecialPage {
 
                if ( $form->show() ) {
                        switch ( $this->type ) {
-                               case Block::TYPE_USER:
                                case Block::TYPE_IP:
+                                       $out->addWikiMsg( 'unblocked-ip', wfEscapeWikiText( $this->target ) );
+                                       break;
+                               case Block::TYPE_USER:
                                        $out->addWikiMsg( 'unblocked', wfEscapeWikiText( $this->target ) );
                                        break;
                                case Block::TYPE_RANGE:
@@ -111,8 +113,14 @@ class SpecialUnblock extends SpecialPage {
                                $fields['Target']['default'] = $target;
                                $fields['Target']['type'] = 'hidden';
                                switch ( $type ) {
-                                       case Block::TYPE_USER:
                                        case Block::TYPE_IP:
+                                               $fields['Name']['default'] = Linker::linkKnown(
+                                                       SpecialPage::getTitleFor( 'Contributions', $target->getName() ),
+                                                       $target->getName()
+                                               );
+                                               $fields['Name']['raw'] = true;
+                                               break;
+                                       case Block::TYPE_USER:
                                                $fields['Name']['default'] = Linker::link(
                                                        $target->getUserPage(),
                                                        $target->getName()
index 8acf8a2..c3e871b 100644 (file)
@@ -99,7 +99,7 @@ class PageArchive {
         * @return bool|ResultWrapper
         */
        protected static function listPages( $dbr, $condition ) {
-               return $dbr->resultObject( $dbr->select(
+               return $dbr->select(
                        array( 'archive' ),
                        array(
                                'ar_namespace',
@@ -113,7 +113,7 @@ class PageArchive {
                                'ORDER BY' => array( 'ar_namespace', 'ar_title' ),
                                'LIMIT' => 100,
                        )
-               ) );
+               );
        }
 
        /**
@@ -152,15 +152,13 @@ class PageArchive {
                        $options
                );
 
-               $res = $dbr->select( $tables,
+               return $dbr->select( $tables,
                        $fields,
                        $conds,
                        __METHOD__,
                        $options,
                        $join_conds
                );
-
-               return $dbr->resultObject( $res );
        }
 
        /**
@@ -177,15 +175,13 @@ class PageArchive {
                }
 
                $dbr = wfGetDB( DB_SLAVE );
-               $res = $dbr->select(
+               return $dbr->select(
                        'filearchive',
                        ArchivedFile::selectFields(),
                        array( 'fa_name' => $this->title->getDBkey() ),
                        __METHOD__,
                        array( 'ORDER BY' => 'fa_timestamp DESC' )
                );
-
-               return $dbr->resultObject( $res );
        }
 
        /**
@@ -532,9 +528,8 @@ class PageArchive {
                        __METHOD__,
                        /* options */ array( 'ORDER BY' => 'ar_timestamp' )
                );
-               $ret = $dbw->resultObject( $result );
-               $rev_count = $dbw->numRows( $result );
 
+               $rev_count = $result->numRows();
                if ( !$rev_count ) {
                        wfDebug( __METHOD__ . ": no revisions to restore\n" );
 
@@ -544,10 +539,10 @@ class PageArchive {
                        return $status;
                }
 
-               $ret->seek( $rev_count - 1 ); // move to last
-               $row = $ret->fetchObject(); // get newest archived rev
+               $result->seek( $rev_count - 1 ); // move to last
+               $row = $result->fetchObject(); // get newest archived rev
                $oldPageId = (int)$row->ar_page_id; // pass this to ArticleUndelete hook
-               $ret->seek( 0 ); // move back
+               $result->seek( 0 ); // move back
 
                // grab the content to check consistency with global state before restoring the page.
                $revision = Revision::newFromArchiveRow( $row,
@@ -589,7 +584,7 @@ class PageArchive {
                $revision = null;
                $restored = 0;
 
-               foreach ( $ret as $row ) {
+               foreach ( $result as $row ) {
                        // Check for key dupes due to shitty archive integrity.
                        if ( $row->ar_rev_id ) {
                                $exists = $dbw->selectField( 'revision', '1',
@@ -720,10 +715,10 @@ class SpecialUndelete extends SpecialPage {
                $this->mUnsuppress = $request->getVal( 'wpUnsuppress' ) && $user->isAllowed( 'suppressrevision' );
                $this->mToken = $request->getVal( 'token' );
 
-               if ( $user->isAllowed( 'undelete' ) && !$user->isBlocked() ) {
+               if ( $this->isAllowed( 'undelete' ) && !$user->isBlocked() ) {
                        $this->mAllowed = true; // user can restore
                        $this->mCanView = true; // user can view content
-               } elseif ( $user->isAllowed( 'deletedtext' ) ) {
+               } elseif ( $this->isAllowed( 'deletedtext' ) ) {
                        $this->mAllowed = false; // user cannot restore
                        $this->mCanView = true; // user can view content
                        $this->mRestore = false;
@@ -752,14 +747,35 @@ class SpecialUndelete extends SpecialPage {
                }
        }
 
+       /**
+        * Checks whether a user is allowed the permission for the
+        * specific title if one is set.
+        *
+        * @param string $permission
+        * @param User $user
+        * @return bool
+        */
+       private function isAllowed( $permission, User $user = null ) {
+               $user = $user ? : $this->getUser();
+               if ( $this->mTargetObj !== null ) {
+                       return $this->mTargetObj->userCan( $permission, $user );
+               } else {
+                       return $user->isAllowed( $permission );
+               }
+       }
+
+       function userCanExecute( User $user ) {
+               return $this->isAllowed( $this->mRestriction, $user );
+       }
+
        function execute( $par ) {
-               $this->checkPermissions();
                $user = $this->getUser();
 
                $this->setHeaders();
                $this->outputHeader();
 
                $this->loadRequest( $par );
+               $this->checkPermissions(); // Needs to be after mTargetObj is set
 
                $out = $this->getOutput();
 
@@ -1458,12 +1474,14 @@ class SpecialUndelete extends SpecialPage {
                $ts = wfTimestamp( TS_MW, $row->fa_timestamp );
                $user = $this->getUser();
 
-               if ( $this->mAllowed && $row->fa_storage_key ) {
-                       $checkBox = Xml::check( 'fileid' . $row->fa_id );
+               $checkBox = '';
+               if ( $this->mCanView && $row->fa_storage_key ) {
+                       if ( $this->mAllowed ) {
+                               $checkBox = Xml::check( 'fileid' . $row->fa_id );
+                       }
                        $key = urlencode( $row->fa_storage_key );
                        $pageLink = $this->getFileLink( $file, $this->getPageTitle(), $ts, $key );
                } else {
-                       $checkBox = '';
                        $pageLink = $this->getLanguage()->userTimeAndDate( $ts, $user );
                }
                $userLink = $this->getFileUser( $file );
@@ -1475,8 +1493,8 @@ class SpecialUndelete extends SpecialPage {
                $comment = $this->getFileComment( $file );
 
                // Add show/hide deletion links if available
-               $canHide = $user->isAllowed( 'deleterevision' );
-               if ( $canHide || ( $file->getVisibility() && $user->isAllowed( 'deletedhistory' ) ) ) {
+               $canHide = $this->isAllowed( 'deleterevision' );
+               if ( $canHide || ( $file->getVisibility() && $this->isAllowed( 'deletedhistory' ) ) ) {
                        if ( !$file->userCan( File::DELETED_RESTRICTED, $user ) ) {
                                // Revision was hidden from sysops
                                $revdlink = Linker::revDeleteLinkDisabled( $canHide );
index 13a00ed..51dd7bd 100644 (file)
@@ -738,6 +738,18 @@ class SpecialUpload extends SpecialPage {
        protected function getGroupName() {
                return 'media';
        }
+
+       /**
+        * Should we rotate images in the preview on Special:Upload.
+        *
+        * This controls js: mw.config.get( 'wgFileCanRotate' )
+        *
+        * @todo What about non-BitmapHandler handled files?
+        */
+       static public function rotationEnabled() {
+               $bitmapHandler = new BitmapHandler();
+               return $bitmapHandler->autoRotateEnabled();
+       }
 }
 
 /**
@@ -1130,6 +1142,7 @@ class UploadForm extends HTMLForm {
                        'wgStrictFileExtensions' => $config->get( 'StrictFileExtensions' ),
                        'wgCapitalizeUploads' => MWNamespace::isCapitalized( NS_FILE ),
                        'wgMaxUploadSize' => $this->mMaxUploadSize,
+                       'wgFileCanRotate' => SpecialUpload::rotationEnabled(),
                );
 
                $out = $this->getOutput();
index 97c7704..3508823 100644 (file)
@@ -204,7 +204,7 @@ class SpecialVersion extends SpecialPage {
         *
         * @return string
         */
-       static function softwareInformation() {
+       public static function softwareInformation() {
                $dbr = wfGetDB( DB_SLAVE );
 
                // Put the software in an array of form 'name' => 'version'. All messages should
@@ -428,7 +428,7 @@ class SpecialVersion extends SpecialPage {
         *
         * @return string Wikitext
         */
-       function getExtensionCredits() {
+       public function getExtensionCredits() {
                global $wgExtensionCredits;
 
                if (
@@ -482,7 +482,7 @@ class SpecialVersion extends SpecialPage {
         *
         * @return string Wikitext
         */
-       function getSkinCredits() {
+       public function getSkinCredits() {
                global $wgExtensionCredits;
                if ( !isset( $wgExtensionCredits['skin'] ) || count( $wgExtensionCredits['skin'] ) === 0 ) {
                        return '';
@@ -593,7 +593,7 @@ class SpecialVersion extends SpecialPage {
         * @param array $b
         * @return int
         */
-       function compare( $a, $b ) {
+       public function compare( $a, $b ) {
                if ( $a['name'] === $b['name'] ) {
                        return 0;
                } else {
@@ -620,7 +620,7 @@ class SpecialVersion extends SpecialPage {
         *
         * @return string Raw HTML
         */
-       function getCreditsForExtension( array $extension ) {
+       public function getCreditsForExtension( array $extension ) {
                $out = $this->getOutput();
 
                // We must obtain the information for all the bits and pieces!
@@ -743,13 +743,19 @@ class SpecialVersion extends SpecialPage {
                        $licenseLink = Linker::link(
                                $this->getPageTitle( 'License/' . $extensionName ),
                                $out->parseInline( $extension['license-name'] ),
-                               array( 'class' => 'mw-version-ext-license' )
+                               array(
+                                       'class' => 'mw-version-ext-license',
+                                       'dir' => 'auto',
+                               )
                        );
                } elseif ( $this->getExtLicenseFileName( $extensionPath ) ) {
                        $licenseLink = Linker::link(
                                $this->getPageTitle( 'License/' . $extensionName ),
                                $this->msg( 'version-ext-license' ),
-                               array( 'class' => 'mw-version-ext-license' )
+                               array(
+                                       'class' => 'mw-version-ext-license',
+                                       'dir' => 'auto',
+                               )
                        );
                }
 
@@ -905,7 +911,7 @@ class SpecialVersion extends SpecialPage {
         *
         * @return string HTML fragment
         */
-       function listAuthors( $authors, $extName, $extDir ) {
+       public function listAuthors( $authors, $extName, $extDir ) {
                $hasOthers = false;
 
                $list = array();
@@ -1008,7 +1014,7 @@ class SpecialVersion extends SpecialPage {
         *
         * @return string
         */
-       function listToText( $list, $sort = true ) {
+       public function listToText( $list, $sort = true ) {
                if ( !count( $list ) ) {
                        return '';
                }
index 8269b01..937a503 100644 (file)
@@ -93,6 +93,18 @@ class WantedFilesPage extends WantedQueryPage {
                return true;
        }
 
+       /**
+        * Does the file exist?
+        *
+        * Use wfFindFile so we still think file namespace pages without
+        * files are missing, but valid file redirects and foreign files are ok.
+        *
+        * @return boolean
+        */
+       protected function existenceCheck( Title $title ) {
+               return (bool) wfFindFile( $title );
+       }
+
        function getQueryInfo() {
                return array(
                        'tables' => array(
index 0f9a6ba..5b88dfd 100644 (file)
@@ -72,7 +72,7 @@ if ( !function_exists( 'session_name' ) ) {
                </style>
        </head>
        <body>
-               <img src="<?php echo htmlspecialchars( $path ) ?>assets/mediawiki.png" alt='The MediaWiki logo' />
+               <img src="<?php echo htmlspecialchars( $path ) ?>resources/assets/mediawiki.png" alt='The MediaWiki logo' />
 
                <h1>MediaWiki <?php echo htmlspecialchars( $wgVersion ) ?></h1>
                <div class='error'>
index 9bbccf1..115a918 100644 (file)
@@ -784,6 +784,14 @@ class Language {
                return self::$dataCache->getSubitem( $this->mCode, 'imageFiles', $image );
        }
 
+       /**
+        * @return array
+        * @since 1.24
+        */
+       function getImageFiles() {
+               return self::$dataCache->getItem( $this->mCode, 'imageFiles' );
+       }
+
        /**
         * @return array
         */
index 25941c6..83fa641 100644 (file)
        "passwordreset-emailsent-capture": "أُرسل بريد إلكتروني لإعادة ضبط كلمة السر، وهو معروض بالأسفل.",
        "passwordreset-emailerror-capture": "تم توليد رسالة بريد إلكتروني لتصفير كلمة السر نصّه التالي، إلا أنه تعذّر إرسال الرّسالة إلى {{GENDER:$2|المستخدم|المستخدمة}}: $1",
        "changeemail": "تغيير عنوان البريد الإلكتروني",
-       "changeemail-header": "تغيير عنوان البريد الإلكتروني للحساب",
        "changeemail-text": "أكمل هذا النموذج لتغيير عنوان البريد الإلكتروني. سوف تحتاج إلى إدخال كلمة السر الخاصة بك لتأكيد هذا التغيير.",
        "changeemail-no-info": "يجب تسجيل الدخول للوصول إلى هذه الصفحة مباشرة.",
        "changeemail-oldemail": "عنوان البريد الإلكتروني الحالي:",
        "changeemail-none": "(لا شيء)",
        "changeemail-password": "كلمة سر {{SITENAME}} الخاصة بك:",
        "changeemail-submit": "غيّر البريد الإلكتروني",
-       "changeemail-cancel": "إلغاء",
        "changeemail-throttled": "أنت قمت بمحاولات تسجيل دخول كثيرة.\nمن فضلك انتظر $1 قبل المحاولة ثانية.",
        "resettokens": "غير المفاتيح",
        "resettokens-text": " يمكن تغيير المفاتيح من الاطلاع على البيانات الخصوصية المتعلقة بحسابك.\nغير المفاتيح إذا أطلعت عليها أحدهم عن طريف الخطأ أو إذا كان حسابك قد اخترق.",
        "searchall": "الكل",
        "showingresults": "معروض بالأسفل {{PLURAL:$1|'''1''' نتيجة|'''$1''' نتيجة}} بدءا من رقم '''$2'''.",
        "showingresultsinrange": "بالأسفل {{PLURAL:$1|نتيجة واحدة|<strong>$1</strong> نتائج|<strong>$1</strong> نتيجة}} في النطاق من <strong>$2</strong> إلى <strong>$3</strong>.",
-       "showingresultsheader": "{{PLURAL:$5|النتيجة '''$1''' من'''$3'''|النتائج '''$1 - $2''' من'''$3'''}} ل'''$4'''",
        "search-nonefound": "لا توجد نتائج تطابق الاستعلام.",
        "powersearch-legend": "بحث متقدم",
        "powersearch-ns": "بحث في النطاقات:",
        "userrights-lookup-user": "أدِر مجموعات المستخدم",
        "userrights-user-editname": "أدخل اسم مستخدم:",
        "editusergroup": "عدل مجموعات المستخدم",
-       "editinguser": "تغيير صلاحيات المستخدم '''[[User:$1|$1]]''' $2",
+       "editinguser": "تغيير صلاحيات {{GENDER:$1|المستخدم|المستخدمة}} '''[[User:$1|$1]]''' $2",
        "userrights-editusergroup": "تعديل مجموعات المستخدم",
        "saveusergroups": "احفظ مجموعات المستخدم",
        "userrights-groupsmember": "عضو في:",
        "logentry-rights-rights-legacy": "{{GENDER:$2|غيّر|غيّرت}} $1 عضوية $3",
        "logentry-rights-autopromote": "تمت تلقائيا ترقية {{GENDER:$2|المستخدم|المستخدمة}} $1 من  $4 إلى $5",
        "rightsnone": "(لا شيء)",
+       "revdelete-summary": "ملخص التعديل",
        "feedback-bugornote": "إن كنت مستعدا لشرح  مشكلة تقنية بالتفصيل، رجاءا [$1 قدم تقريرا بالخلل].\nبخلاف ذلك، يمكنك أستخدام الطريقة الأسهل أسفله، سيتم إضافة تعليقك للصفحة \"[$3 $2]\"، بالإضافة إلى اسم المستخدم و نوع المتصفح الذي تستخدمه حاليا.",
        "feedback-subject": "الموضوع:",
        "feedback-message": "الرسالة:",
index bb9952d..208723e 100644 (file)
        "searchrelated": "সম্পৰ্কিত",
        "searchall": "সকলো",
        "showingresults": "তলত #'''$2'''ৰ পৰা {{PLURAL:$1|'''1''' ফলাফল|'''$1''' ফলাফল}} দেখুওৱা হৈছে।",
-       "showingresultsheader": "'''$4'''ৰ বাবে {{PLURAL:$5|'''$3''' ৰ '''$1''' ফলাফল| '''$3''' ৰ '''$1 - $2''' ফলাফলসমূহ}}",
        "search-nonefound": "এই অনুসন্ধানৰ কোনো ফলাফল নাই ।",
        "powersearch-legend": "শক্তিশালী সন্ধান",
        "powersearch-ns": "নামস্থানবোৰত সন্ধান:",
index b471419..bbfc3bb 100644 (file)
@@ -12,9 +12,9 @@
                ]
        },
        "tog-underline": "Linyahan an kilyawan:",
-       "tog-hideminor": "Tagoon an saradít na paghira sa nakakaagi pa sanang pagbabàgo",
+       "tog-hideminor": "Tagoon an saradít na mga pagliwat sa dae pa sana nahaloy na mga pagbabàgo",
        "tog-hidepatrolled": "Tagóa an patrolyadong mga paghirá sa nakakaági pa sanáng pagbabàgo",
-       "tog-newpageshidepatrolled": "Tagoon an patrolyadong mga pahina gikan sa listahan kan bàgong pahina",
+       "tog-newpageshidepatrolled": "Tagoon an patrolyadong mga pahina gikan sa baguhong listahan nin pahina",
        "tog-extendwatchlist": "Palakbanga an bantay-listahan (watchlist) na maipahiling an gabos na pinagbago, bako sana an pinakahurihang binago",
        "tog-usenewrc": "Pangrupong mga kaliwatan sa kada pahina kan mga dae pa sana nahaloy na mga kaliwatan asin bantay-listahan",
        "tog-numberheadings": "Tolos-bilang na mga pamayohán",
@@ -27,7 +27,7 @@
        "tog-watchdeletion": "Idagdag an mga pahina asin mga sagunson na ako an nagpura sa sakong bantay-listahan",
        "tog-minordefault": "Markahán gabos na saradit na pagliwat sa paaging panugmad",
        "tog-previewontop": "Ipahilíng an patànaw bàgo an kahon nin paghirá",
-       "tog-previewonfirst": "Ipahiling an patànaw sa inot na paghira",
+       "tog-previewonfirst": "Ipahiling an patànaw sa enot na pagliwat",
        "tog-enotifwatchlistpages": "E-suratan mo ako kunsoarin an sarong pahina o sagunson na yaon sa sakong bantay-listahan pinagliwat",
        "tog-enotifusertalkpages": "E-koreohan ako pag pigribáyan an pahina kan sakóng olay",
        "tog-enotifminoredits": "E-suratan man ako para sa saraditon na mga pagliwat kan mga pahina asin mga sagunson",
@@ -50,7 +50,7 @@
        "tog-useeditwarning": "Patanidan ako kunsoarin na ako nagbaya sa pahinang pigliliwat na dae naitatagama an mga kaliwatan",
        "tog-prefershttps": "Pirmeng gumamit nin sarong seguradong koneksyon kunsoarin na ika nakalaog na",
        "underline-always": "Parati",
-       "underline-never": "Dai lamang",
+       "underline-never": "Dae pa lamang",
        "underline-default": "Kublit o kilyaw na panugmad",
        "editfont-style": "Baguhon an estilo nin kalwig sa sinasakupan",
        "editfont-default": "Kilyawang tugmad",
        "june-date": "Hunyo $1",
        "july-date": "Hulyo $1",
        "august-date": "Agosto $1",
-       "september-date": "Setyembre $1",
+       "september-date": "Septyembre $1",
        "october-date": "Oktobre $1",
        "november-date": "Nobyembre $1",
-       "december-date": "Desyembre $1",
+       "december-date": "Disyembre $1",
        "pagecategories": "{{PLURAL:$1|Kategorya|Mga kategorya}}",
        "category_header": "Mga pahina sa kategoryang \"$1\"",
        "subcategories": "Mga sub-kategorya",
        "category-media-header": "Media sa kategoryang \"$1\"",
-       "category-empty": "''Ining kategorya mayong laog na mga pahina o media sa ngunyan.''",
+       "category-empty": "''Ining kategorya sa ngunyan mayong laog nin mga pahina o midya.''",
        "hidden-categories": "{{PLURAL:$1|Nakatagong kategorya|Mga nakatagong kategorya}}",
        "hidden-category-category": "Mga nakatagong kategorya",
        "category-subcat-count": "{{PLURAL:$2|Ining kategorya igwa sana kan minasunod na sub-kategorya.|Ining kategorya igwa kan minasunod {{PLURAL:$1|subcategory|$1 subcategories}}, out of $2 total.}}",
        "category-article-count-limited": "An minasunod na {{PLURAL:$1|pahina|$1 mga pahina}} yaon sa presenteng kategorya.",
        "category-file-count": "{{PLURAL:$2|Ining kategorya naglalaman sana kan minasunod na sagunson.|An minasunod {{PLURAL:$1|sagunson iyo|$1 na mga sagunson iyo}} sa kategoryang ini, na ginahi sa $2 sa kabilogan.}}",
        "category-file-count-limited": "An minasunod {{PLURAL:$1|na sagunson|$1 na mga sagunson}} yaon sa presenteng kategorya.",
-       "listingcontinuesabbrev": "sunod",
+       "listingcontinuesabbrev": "kasumpay",
        "index-category": "Panhinukdong mga pahina",
        "noindex-category": "Bakong panhinukdong mga pahina",
        "broken-file-category": "Mga pahina na igwang nagkaparasa na sagunsong kilyawan",
        "about": "Manonongod",
        "article": "Laog na pahina",
        "newwindow": "(minabukas sa bàgong bintanà)",
-       "cancel": "Pondohon",
+       "cancel": "Kanselaron",
        "moredotdotdot": "Kadagdagan...",
-       "morenotlisted": "Kulang ining listahan.",
+       "morenotlisted": "Ining listahan bakong kumpleto.",
        "mypage": "Pahina",
        "mytalk": "Mag-ulay",
-       "anontalk": "Urulay para kaining IP address",
+       "anontalk": "Urulay para kaining IP estada",
        "navigation": "Paglibotlibot",
        "and": "&#32;asin",
        "qbfind": "Maghanap",
        "qbedit": "Liwaton",
        "qbpageoptions": "Ining pahina",
        "qbmyoptions": "Sakong mga pahina",
-       "faq": "PH (Parating Hapot)",
-       "faqpage": "Proyekto:PH (Parating Hapot)",
+       "faq": "PHK (Pirmehang Hinahapot na mga Kahaputan)",
+       "faqpage": "Proyekto:PHK",
        "actions": "Mga paghiro",
        "namespaces": "Mga espasyong ngaran",
-       "variants": "Mga lain pa",
-       "navigation-heading": "Hihilngan nin paglibotlibot",
+       "variants": "Mga Kinalaenan",
+       "navigation-heading": "Hihilngan sa paglibotlibot",
        "errorpagetitle": "Salâ",
        "returnto": "Magbalik sa $1.",
        "tagline": "Gikan sa {{SITENAME}}",
-       "help": "Tabang",
+       "help": "Katabangan",
        "search": "Maghanap",
        "searchbutton": "Maghanap",
        "go": "Dumani",
        "protectthispage": "Protektaran ining pahina",
        "unprotect": "Ribayan an proteksyon",
        "unprotectthispage": "Ribayan an proteksyon kaining pahina",
-       "newpage": "Bàgong pahina",
+       "newpage": "Bàguhong pahina",
        "talkpage": "Urulayan ining pahina",
        "talkpagelinktext": "Mag-ulay",
-       "specialpage": "Sadyang Pahina",
-       "personaltools": "Pansadiring mga kagamitan",
+       "specialpage": "Espesyal na pahina",
+       "personaltools": "Pansadiring mga gamiton",
        "articlepage": "Tànawon an laog kan pahina",
-       "talk": "Urulay",
-       "views": "Mga tànaw",
-       "toolbox": "Mga gamit:",
+       "talk": "Urulayan",
+       "views": "Mga Tanawon",
+       "toolbox": "Mga gamiton:",
        "userpage": "Tànawon an pahina kan paragamit",
        "projectpage": "Tànawon an pahina kan proyekto",
-       "imagepage": "Hilingon an pahina nin sagunson (file)",
+       "imagepage": "Tànawon an pahina nin sagunson (file)",
        "mediawikipage": "Tànawon an pahina kan mensahe",
        "templatepage": "Tànawon an pahina kan panguyog",
        "viewhelppage": "Tànawon an pahina nin pagtabang",
        "categorypage": "Tànawon an pahina nin kategorya",
        "viewtalkpage": "Tànawon an urulay",
-       "otherlanguages": "Sa ibang mga tataramon",
-       "redirectedfrom": "(Inilikay gikan sa $1)",
-       "redirectpagesub": "Likay na pahina",
+       "otherlanguages": "Sa ibang mga lengguwahe",
+       "redirectedfrom": "(Pinagbalikwat gikan sa $1)",
+       "redirectpagesub": "Balikwaton an pahina",
+       "redirectto": "Balikwaton pasiring sa:",
        "lastmodifiedat": "Ining pahina huring pinagbago kan $1, mga alas $2.",
        "viewcount": "Ining pahina pinaglaog nin {{PLURAL:$1|sarong beses|nin $1 beses}}.",
        "protectedpage": "Protektadong pahina",
        "toc": "Mga laog",
        "showtoc": "ipahiling",
        "hidetoc": "tagoon",
-       "collapsible-collapse": "Ibagsak",
-       "collapsible-expand": "Ibuka",
+       "collapsible-collapse": "Pahalipoton",
+       "collapsible-expand": "Pahiwason",
+       "confirmable-yes": "Iyo",
+       "confirmable-no": "Dae",
        "thisisdeleted": "Hilingon o isulit an $1?",
        "viewdeleted": "Hilingon an $1?",
        "restorelink": "{{PLURAL:$1|sarong pinagpurang pagliwat|$1 na pinagpurang mga pagliwat}}",
        "feedlinks": "Hungit:",
        "feed-invalid": "Imbalidong tipo nin hungit sa subkripsyon.",
-       "feed-unavailable": "Mayò an mga sindikasyon na hungit",
+       "feed-unavailable": "Mga sindikasyong hungit dae magagamit",
        "site-rss-feed": "$1 Hungit nin RSS",
        "site-atom-feed": "$1 Hungit Atomo",
        "page-rss-feed": "\"$1\" Hungit na RSS",
        "nosuchspecialpage": "Mayong siring na espesyal na páhina",
        "nospecialpagetext": "<strong>Dai pwede an pahinang espesyal na pinilî mo.</strong>\n\nPwede mong mahiling an lista nin mga marhay na pahina sa [[Special:SpecialPages|{{int:specialpages}}]].",
        "error": "Salâ",
-       "databaseerror": "Salâ sa base nin datos",
+       "databaseerror": "Kasalaan sa datos-sarayan",
        "databaseerror-text": "Sarong hapot sa datos-sarayan na kasalaan an nangyari.\nIni puwedeng minapasabot nin sarong kudol sa panuklob.",
        "databaseerror-textcl": "Sarong hapot sa datos-sarayan na kasalaan an nangyari.",
        "databaseerror-query": "Hapot: $1",
        "directorycreateerror": "Dai nagibo an direktorya na \"$1\".",
        "filenotfound": "Dai nahanap an file na \"$1\".",
        "unexpected": "Dai pighuhunà na balór: \"$1\"=\"$2\".",
-       "formerror": "Salâ: dai pwedeng isumitir an porma",
-       "badarticleerror": "Dai pwedeng gibohon ini sa ining páhina.",
+       "formerror": "Salâ: Dae maisusumiter an porma.",
+       "badarticleerror": "Ining aksyon dae magigibo sa pahinang ini.",
        "cannotdelete": "An pahina o an sagunson (file) na \"$1\" dae tabi napupura.\nIni puwede nang napura kan iba.",
        "cannotdelete-title": "Dae mapura an pahina na \"$1\"",
        "delete-hook-aborted": "An pagpura pinundo kan pangawit.\nIni dae nagtao nin kapaliwanagan.",
        "badtitletext": "An pinaghagad na titulo kan pahina imbalido, daeng laog, o sarong salaon na sinugpunan na titulo kan inter-lengguwahe o inter-wiki.\nIni gayod may laog nin o dakol na mga karakter na dae pinaggagamit sa mga titulo.",
        "perfcached": "An minasunod na datos pinagtago asin bakong gayo napapanahon. An maximum na {{PLURAL:$1|sarong resulta na|$1 mga resulta na}} yaon sana sa pinagtago.",
        "perfcachedts": "An minasunod na datos pinagtago, asin huring pinagdagdagan kan $1. An maximum na {{PLURAL:$4|sarong result na |$4 mga resulta na }} yaon sana sa pinagtago.",
-       "querypage-no-updates": "Pigpopogol mùna an mga pagbabàgo sa pahinang ini. Dai mùna mababàgo an mga datos digdi.",
+       "querypage-no-updates": "Mga kasugponan para sa pahinang ini sa ngunyan pinagpupugulan. An datos na yaon digde dae sa presente maipagpresko.",
        "viewsource": "Hilingón an ginikanan",
        "viewsource-title": "Hilnga an piggikanan para sa $1",
        "actionthrottled": "An aksyon pinagpugulan",
        "actionthrottledtext": "Bilang sarong pangontra sa spam, ika limitadong sanang himoon ining aksyon sa kadakulon na beses sa halipot sanang panahon, asin ika nakasobra na sa limitasyong ini.\nPaki-otroha giraray sa nagkapirang minuto sana.",
        "protectedpagetext": "Ining pahina protektado tanganing malikayan an pagliliwat o ibang aksyon.",
-       "viewsourcetext": "Pwede mong hilingón asin arógon an ginikanan kan pahinang ini:",
+       "viewsourcetext": "Ika makakatanaw asin makakakopya sa ginikanan kaining pahina:",
        "viewyourtext": "Saimong mahihiling asin makokopya an gikanan kan '''saimong mga pinagriliwat''' sa pahinang ini:",
        "protectedinterface": "An pahinang ini nagtatao nin panlaog-olay para sa software, asin protektado tangaring malikayan an abuso.\nSa pagdagdag or pagliwat nin mga dakit-taramon para sa bilog na wiki, gamita tabi an [//translatewiki.net/translatewiki.net], an MediaWiki sa proyektong lokalisasyon.",
        "editinginterface": "'''Patanid:''' Ika nagliliwat kan pahina na ginagamit sa pagtao nin pantahaw-olay na teksto para sa software.\nAn mga pagbabago kaining pahina makaka-apekto sa hitsura kan pantahaw-olay nin paragamit para sa iba man na paragamit.\nPara sa mga pagdadakit-taramon, pakikonsidera man tabi an paggagamit kan [//translatewiki.net/wiki/Main_Page?setlang=en translatewiki.net], an MediaWiking lokalisasyon kan proyekto.",
-       "cascadeprotected": "Pinoprotehirán ining páhina sa mga paghirá, ta sarô ini sa mga minasunod na {{PLURAL:$1|páhina|mga páhina}} na pinoprotehiran kan opsyón na \"katarata\" na nakabuká:\n$2",
-       "namespaceprotected": "Mayô kang permisong maghirá kan mga páhina sa '''$1''' ngaran-espacio.",
+       "cascadeprotected": "Ining pahina pinagprotehiran gikan sa pagliliwat nin huli ta ini pinagbale sa minasunod na {{PLURAL:$1|pahina, na iyo ngani an|mga pahina, na iyo ngani an mga}} protektado kan pinagbukasang opsyon na \"pasurunod-sunudan\":\n$2",
+       "namespaceprotected": "Ika mayong permiso sa pagliwat nin mga pahina sa <strong>$1</strong> na ngarang-espasyo.",
        "customcssprotected": "Ika mayong permiso sa pagliwat kaining pahinang CSS, nin huli ta ini naglalaman kan personal na panuytoy (settings) kan ibang paragamit.",
        "customjsprotected": "Ika mayong permiso sa pagliwat kaining pahinang JavaScript, nin huli ta ini naglalaman kan personal na panuytoy (settings) kan ibang paragamit.",
        "mycustomcssprotected": "Ika mayo nin permiso sa pagliwat kaining CSS na pahina.",
        "mycustomjsprotected": "Ika mayo nin permiso sa pagliwat kaining JavaScript na pahina.",
        "myprivateinfoprotected": "Ika daeng permiso na magliliwat kan pribado mong impormasyon.",
        "mypreferencesprotected": "Ika daeng permiso na magliliwat kan saimong mga kamuyahan.",
-       "ns-specialprotected": "An mga pahinang nasa {{ns:special}} na liang-liang dai pwedeng hirahón.",
+       "ns-specialprotected": "Mga espesyal na pahina dae makakapagliwat.",
        "titleprotected": "Ining titulo pinagprotektaran poon pagkamukna ni [[User:$1|$1]].\nAn rason na pinagtao iyo na \"''$2''\".",
        "filereadonlyerror": "Dae kinayang baguhon an sagunson (file) \"$1$ nin huli ta an repositoryo kan sagunson \"$2\" yaon sa kamugtakan na basahon sana.\n\nAn administrador na iyo an nagkandado kaini nagpahayag kaining kapaliwanagan: \"$3\".",
        "invalidtitle-knownnamespace": "Imbalidong titulo na igwang espasyadong ngaran na \"$2\" asin teksto na \"$3\"",
        "invalidtitle-unknownnamespace": "Imbalidong titulo na igwang nin bakong bistado na bilang kan espasyadong ngaran na $1 asin teksto na \"$2\"",
-       "exception-nologin": "Dai ka nakalaog",
+       "exception-nologin": "Dai ka nakapaglaog",
        "exception-nologin-text": "Pakipalaog tabi tanganing makalangkay sa pahinang ini o aksyon.",
        "exception-nologin-text-manual": "Tabi man $1 na tanganing makalangkay sa pahinang ini o aksyon.",
        "virus-badscanner": "Raot na kasalansanan: Bakong bistadong virus scanner: ''$1''",
        "userlogin-yourname": "Paragamit-na-Ngaran",
        "userlogin-yourname-ph": "Ikaag an saimong paragamit-na-ngaran",
        "createacct-another-username-ph": "Ikaag an paragamit-na-ngaran",
-       "yourpassword": "Sekretong Panlaog",
-       "userlogin-yourpassword": "Sekretong Panlaog",
+       "yourpassword": "Pasa-taramon:",
+       "userlogin-yourpassword": "Pasa-taramon",
        "userlogin-yourpassword-ph": "Ikaag an saimong sekretong panlaog",
        "createacct-yourpassword-ph": "Ikaag an sekretong panlaog",
        "yourpasswordagain": "Pakilaog giraray kan sekretong panlaog:",
        "userlogin-resetlink": "Nakalingaw ka sa panlaog mong detalye?",
        "userlogin-resetpassword-link": "Nalingawan mo an saimong pasa-taramon?",
        "userlogin-helplink2": "Katabangan sa paglalaog",
-       "userlogin-loggedin": "Ika nakalaog na tabi bilang si {{GENDER:$1|$1}}.\nGamita an porma sa ibaba sa paglaog bilang ibang paragamit.",
-       "userlogin-createanother": "Magmukna nin ibang panindog",
        "createacct-emailrequired": "Estada kan e-surat",
        "createacct-emailoptional": "E-surat na estada (opsyonal)",
        "createacct-email-ph": "Pakikaag an saimong e-surat na estada",
        "php-mail-error-unknown": "Bakong bantog na kasalaan sa PHP mail() function.",
        "user-mail-no-addy": "Nagprubar na magpadara nin e-koreo na mayo nin e-koreong address.",
        "user-mail-no-body": "Nagprubar na magpadara nin e-surat na mayong laman o daeng kanultulan na halipot an hawak.",
-       "changepassword": "Ribayan an sekretong panlaog",
+       "changepassword": "Ribayan an pasa-taramon",
        "resetpass_announce": "Sa pagtapos kan paglalaog mo, ika kaipuhanan na magkaag nin sarong baguhong pasa-taramon.",
        "resetpass_text": "<!-- Magdagdag nin teksto digdi -->",
        "resetpass_header": "Ribayan an panindog na sekretong panlaog",
        "resetpass-no-info": "Ika dapat nakalaog na tanganing direktang makagamit kaining pahina.",
        "resetpass-submit-loggedin": "Ribayan an sekretong panlaog",
        "resetpass-submit-cancel": "I-kansela",
-       "resetpass-wrong-oldpass": "Saláng temporaryo o presenteng sekretong panlaog.\nMatriumpo mo nang nailaog an sekretong panlaog o nakua an bàgong temporaryong sekretong panlaog.",
+       "resetpass-wrong-oldpass": "Imbalidong temporaryo o sa ngunyan na pasa-taramon.\nIka matrayumpong nakapagbago na kan saimong pasa-taramon o naghagad nin sarong baguhon na temporaryong pasa-taramon.",
        "resetpass-recycled": "Tabi man pakibaguha an saimong pasa-taramon na magin sarong bagay na ibahon kesa sa ngunyan mong pasa-taramon.",
        "resetpass-temp-emailed": "Ika nakapaglaog na igwa nin sarong temporaryong koda na pinag-esurat saimo. Sa pagtapos kan paglalaog mo, ika kaipuhan na magkaag nin sarong baguhong pasa-taramon digde:",
        "resetpass-temp-password": "Temporaryong sekretong panlaog:",
        "passwordreset-emailsent-capture": "Sarong e-surat sa pagliliwat kan sekretong panlaog an ipinadara na, yaon ipinapahiling sa ibaba.",
        "passwordreset-emailerror-capture": "Sarong e-surat sa pagliliwat kan sekretong panlaog an pinagpuyos na, yaon ipinapahiling sa ibaba, alagad sa pagpapadara kaini sa {{GENDER:$2|paragamit}} nagpalya: $1",
        "changeemail": "Ribayan an e-koreong address",
-       "changeemail-header": "Ribayan an panindog na e-koreong address",
        "changeemail-text": "Kumpletoha ining porma tanganing ribayan an saimong e-koreong address. Kinakaipo mong ilaog an saimong sekretong panlaog tanganing kumpirmaron ining pagribay.",
        "changeemail-no-info": "Ika dapat nakalaog na tanganing direktang makagamit kaining pahina.",
        "changeemail-oldemail": "Presenteng e-koreong address:",
        "changeemail-none": "mayo tabi.",
        "changeemail-password": "An saimong {{SITENAME}} sikretong panlaog:",
        "changeemail-submit": "Ribayan an e-koreo",
-       "changeemail-cancel": "Kanselaha",
        "resettokens": "Pakibaguha an mga paduos",
        "resettokens-text": "Ika makakapagbago kan ma paduos na magtutugot nin kalangkayan pasiring sa siyertong datos na pribado na asosyado sa saimong panindog digde.\n\nGibohon mo ini kun aksidente mong naipagheras sinda sa kiisay man o kun an saimong panindog kompromitido na.",
        "resettokens-no-tokens": "Mayo nin mga paduos na babaguhon.",
        "bold_sample": "Mahìbog na teksto",
        "bold_tip": "Mahìbog na teksto",
        "italic_sample": "Italikong teksto",
-       "italic_tip": "Tekstong Italiko",
+       "italic_tip": "Italikong teksto",
        "link_sample": "Titulo nin sugpon",
        "link_tip": "Panlaog na sugpon",
        "extlink_sample": "http://www.example.com títulong sugpon",
        "sig_tip": "An saimong pirma na igwang tatak-oras",
        "hr_tip": "Pabalagbag na linya (gamiton paminsan-minsan)",
        "summary": "Sumaryo:",
-       "subject": "Tema/pamayohan:",
+       "subject": "Subheto/kapamayuhan:",
        "minoredit": "Ini sarong dikiton na pagliwat",
        "watchthis": "Bantayan ining pahina",
        "savearticle": "Itagáma an pahina",
        "showdiff": "Ipahiling an mga kaliwatan",
        "anoneditwarning": "'''Patanid:''' Ika dae nakapaglaog. An saimong estada kan IP maisusurat sa laog kan historiya nin pagliliwat sa pahinang ini.",
        "anonpreviewwarning": "Dae ka tabi nakalaog. An pagtatagama matala kan saimong IP address sa historya nin pagliwat sa pahinang ini.",
-       "missingsummary": "'''Paisi:''' Dai ka nagkaag nin sumád kan paghirâ. Kun pindotón mo giraray an Itagama, maitatagama an hirá mo na mayô kaini.",
-       "missingcommenttext": "Paki lâgan nin komento sa ibabâ.",
+       "missingsummary": "<strong>Pagiromdom:</strong>Ika dae pa nakapagtao nin sumaryo sa pagliwat. Kun i-klik mo an \"{{int:savearticle}}\" giraray, an saimong pagliwat ipagtatagama na mayo kaiyan.",
+       "missingcommenttext": "Pakikaag nin sarong komento sa ibaba.",
        "missingcommentheader": "'''Pagiromdom:''' Ika dae tabi nagtao nin sarong panultol (subject)/Pamayong linya (headline) para kaining sinambit mo.\nKun saimong pinduton an \"{{int:savearticle}}\" giraray, an saimong pigliwat matatagama na mayo kaiyan.",
-       "summary-preview": "Patànaw nin sumada:",
-       "subject-preview": "Patânaw nin tema/pamayohan:",
-       "blockedtitle": "Pigbágat an parágamit",
+       "summary-preview": "Paenot na patanaw nin sumaryo:",
+       "subject-preview": "Paenot na patanaw sa Subheto/kapamayuhan:",
+       "blockedtitle": "An paragamit pinagbagat",
        "blockedtext": "'''An saimong paragamit na ngaran o IP address pinagkubkob.'''\n\nAn pagkubkob hinimo ni $1.\nAn rason na ipinagtao iyo na ''$2''.\n\n* Pagpoon kan pagkubkob: $8\n* Pagpasó kan pagkubkob: $6\n* Katuyuhan kan parakubkob: $7\n\nIka puwedeng magkontak sa $1 or ibang [[{{MediaWiki:Grouppage-sysop}}|administrador]] tanganing pag-orolayan an pagkubkob.\nIka dae makakagamit kan 'e-koreo kaining paragamit' na panuytuyan laen lang na may sarong balidong e-koreo address na ipinahayag sa saimong [[Special:Preferences|panindog na mga kabotan]] asin ika dae pinagkubkob para sa paggamit kaini.\nAn saimong presenteng IP address iyo $3, asin an kubkob ID iyo #$5.\nPakibale na lang tabi an gabos na mga detalye sa itaas sa anuman na mga kahaputan na saimong himoon.",
        "autoblockedtext": "An saimong IP address awtomatikong pinagkubkob nin huli ta ini pinaggamit kan ibang paragamit, na pinagkubkob ni $1.\nAn rason na ipinagtao iyo na:\n\n:''$2''\n\n* Pagpoon kan pagkubkob: $8\n* Pagpasó kan pagkubkob: $6\n* Katuyuhan kan parakubkob: $7\n\nPuwede mong kontakon si $1 o saro sa [[{{MediaWiki:Grouppage-sysop}}|mga administrador]] tanganing pag-orolayan an kubkob.\n\nPatanid tabi dae mo puwedeng gamiton an \"e-koreo kaining paragamit\" estima laen lang kun ika igwa nin sarong balidong e-koreo address na rehistrado sa saimong [[Special:Preferences|paragamit na mga kabotan]] asin ika dae pinagkubkob para sa paggamit kaini.\n\nAn saimong presenteng IP address iyo an $3, asin and Kubkob ID iyo an #$5.\nPakibale tabi an gabos na mga detalye sa itaas sa arinman na mga kahaputan na saimong himoon.",
-       "blockednoreason": "mayong itinaong rason",
-       "whitelistedittext": "Kaipuhan mong $1 tangarig makahirá nin mga páhina.",
-       "confirmedittext": "Kaipuhan mong kompirmaron an saimong ''e''-surat. Ipwesto tabî asin patunayan an saimong ''e''-surat sa [[Special:Preferences|mga kabôtan kan parágamit]].",
+       "blockednoreason": "mayong rason na ipinagtao",
+       "whitelistedittext": "Tabi man $1 tanganing makapagliwat nin mga pahina.",
+       "confirmedittext": "Ika kaipuhan na magkumpirma kan saimong estada sa e-surat bago makapagliwat nin mga pahina. Tabi man pakikaag asin balidaron an saimong estada sa e-surat sa paagi kan saimong [[Special:Mga Kamuyahan|paragamit na mga kamuyahan]].",
        "nosuchsectiontitle": "Dae managboan an seksyon",
        "nosuchsectiontext": "Ika nagprubar na liwaton an sarong seksyon na bakong eksistido.\nIni puwedeng pinagbalyo o pinagpara na habang saimong pinaghihiling an pahina.",
-       "loginreqtitle": "Kaipuhan Maglaog",
+       "loginreqtitle": "An paglaog pinaghahagad",
        "loginreqlink": "maglaog",
-       "loginreqpagetext": "Kaipuhan kang $1 tangarig makahilíng nin ibang pahina.",
-       "accmailtitle": "Napadará na an sekretong panlaog.",
+       "loginreqpagetext": "Tabi man $1 tanganing makapagtanaw kan ibang mga pahina.",
+       "accmailtitle": "Pasa-taramon naipadara na",
        "accmailtext": "An purak na pinagpuyos na pasa-taramon para ki [[User talk:$1|$1]] ipinagpadara na sa $2. Ini mapupuwedeng pagribayan sa ''[[Special:ChangePassword|change password]]'' na pahina matapos na ika nakalaog na.",
        "newarticle": "(Bàgo)",
-       "newarticletext": "Ika nakapagsunod sa sarong sugpon pasiring sa sarong pahina na bako pang eksistido. Tanganing makapagmukna nin pahina, magpoon sa pagpindot sa laog nin kahon sa ibaba (hilngon an [$1 pahina nin katabangan] para sa kadugangan na impormasyon).\nKun ika napasalang nakadigde, i-klik an  '''ibalik''' na pindutan kan saimong kilyaw.",
+       "newarticletext": "Ika nakapagsunod sa sarong sugpon pasiring sa sarong pahina na bako pang eksistido. Tanganing makapagmukna nin pahina, magpoon sa pagpindot sa laog nin kahon sa ibaba (hilngon an [$1 pahina nin katabangan] para sa kadugangan na impormasyon).\nKun ika napasalang nakadigde, i-klik an  '''ibalik''' na pindutan kan saimong kilyawan.",
        "anontalkpagetext": "----''Ini iyo an pahina kan orolayan para an sarong dae bistadong paragamit na dae pa nakapagmukna nin panindog, o dae pa nakapaggamit kaini.\nKaya kami kaipong gumamit nin numerikal na IP address sa pagbisto saiya.\nAn arog kaining IP address puwedeng maikapagheras sa nagkapirang mga paragamit.\nKun ika sarong dae pa bistadong paragamit asin mati mo na igwang irelebanteng sambit na pinanungod saimo, tabi paki [[Special:UserLogin/signup|mukna nin panindog]] or [[Special:UserLogin|maglaog ka]] tanganing malikayan an pagkaribong sa pag-iriba kan iba pang mga paragamit.''",
        "noarticletext": "Mayo tabi sa presente nin teksto sa pahinang ini.\nIka mapuwedeng [[Special:Search/{{PAGENAME}}|maghanap para sa titulo kan pahinang ini]] sa iba pang mga pahina,\n<span class=\"plainlinks\">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} maghanap sa magkasurundong mga talaan],\no [{{fullurl:{{FULLPAGENAME}}|action=edit}} liwaton ining pahina]</span>.",
        "noarticletext-nopermission": "Mayong sa presente nin teksto an pahinang ini.\nIka mapuwedeng [[Special:Search/{{PAGENAME}}|hanapa para kaining titulo kan pahina]] sa iba pang mga pahina,\no <span class=\"plainlinks\">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} maghanap sa magkasurundong mga talaan]</span>.",
        "sitecsspreview": "'''Giromdoma baya na ika nagtatanaw pa sana kaining CSS.'''\n'''Ini dae pa tabi naitatagama!'''",
        "sitejspreview": "'''Giromdoma baya na ika nagtatatanaw pa sana kaining koda sa JavaScript.'''\n'''Ini dae pa tabi naitatagama!'''",
        "userinvalidcssjstitle": "'''Patanid:''' Mayong ''skin'' na \"$1\". Giromdomon tabî na an .css asin .js na mga páhina naggagamit nin titulong nakasurat sa sadit na letras, halimbawa {{ns:user}}:Foo/vector.css bakong {{ns:user}}:Foo/Vector.css.",
-       "updated": "(Binàgo)",
+       "updated": "(Pinagsugpunan na)",
        "note": "'''Paisi:'''",
        "previewnote": "'''Giromdoma na ini sarong patanaw pa sana.'''\nAn saimong mga pinagriliwat dae pa tabi naitatagama!",
        "continue-editing": "Magduman sa lugar nin pagliliwat",
        "searchrelated": "kauyon",
        "searchall": "gabós",
        "showingresults": "Pigpapahiling sa babâ sagkod sa {{PLURAL:$1|'''1''' resulta|'''$1''' mga resulta}} poon sa #'''$2'''.",
-       "showingresultsheader": "{{PLURAL:$5|Resulta '''$1''' kan '''$3'''|Mga Resulta '''$1 - $2''' kan '''$3'''}} para sa '''$4'''",
        "search-nonefound": "Mayo nin mga resulta na panampok sa kahaputan.",
        "powersearch-legend": "Adbansiyadong paghahanap",
        "powersearch-ns": "Maghanap sa mga espasyong-ngaran:",
index 53dc863..9b3dd35 100644 (file)
        "passwordreset-emailsent-capture": "Ліст пра скіданьне паролю быў дасланы, што паказана ніжэй.",
        "passwordreset-emailerror-capture": "Ліст пра скіданьне паролю быў створаны і паказаны ніжэй, але не ўдалося адправіць яго {{GENDER:$2|ўдзельніку|ўдзельніцы}}: $1",
        "changeemail": "Зьмяніць адрас электроннай пошты",
-       "changeemail-header": "Зьмена адрасу электроннай пошты для рахунку",
        "changeemail-text": "Запоўніце гэтую форму для зьмены адрасу Вашай электроннай пошты. Вам неабходна будзе ўвесьці Ваш пароль для пацьверджаньня зьмены.",
        "changeemail-no-info": "Для непасрэднага доступу да гэтай старонкі Вам неабходна ўвайсьці ў сыстэму.",
        "changeemail-oldemail": "Цяперашні адрас электроннай пошты:",
        "changeemail-none": "(няма)",
        "changeemail-password": "Ваш пароль у {{GRAMMAR:месны|{{SITENAME}}}}:",
        "changeemail-submit": "Зьмяніць адрас электроннай пошты",
-       "changeemail-cancel": "Скасаваць",
        "changeemail-throttled": "Вы зрабілі зашмат спробаў увайсьці ў сыстэму.\nКалі ласка, пачакайце $1 перад наступнай спробай.",
        "resettokens": "Скідваньне токенаў",
        "resettokens-text": "Тут вы можаце скінуць токены, якія даюць вамд доступ да пэўных прыватных зьвестак, асацыяваных з вашым рахункам.\n\nКалі вы выпадкова падзяліліся токенамі зь іншымі, або калі ваш рахунак быў скампрамэтаваны, скарыстайцеся гэтай магчымасьцю і скіньце токены.",
        "searchall": "усе",
        "showingresults": "Ніжэй {{PLURAL:$1|паданы|паданыя|паданыя}} да '''$1''' {{PLURAL:$1|выніку|вынікаў|вынікаў}}, пачынаючы з #<b>$2</b>.",
        "showingresultsinrange": "Ніжэй паказаныя да {{PLURAL:$1|<strong>$1</strong> выніку ў|<strong>$1</strong> вынікаў у}} дыяпазоне ад <strong>$2</strong> да <strong>$3</strong>.",
-       "showingresultsheader": "{{PLURAL:$5|1=Вынік '''$1''' з '''$3'''|Вынікі '''$1—$2''' з '''$3'''}} для '''$4'''",
+       "search-showingresults": "{{PLURAL:$4|1=Вынік <strong>$1</strong> з <strong>$3</strong>|Вынікі <strong>$1—$2</strong> з <strong>$3</strong>}}",
        "search-nonefound": "Супадзеньняў па запыце ня знойдзена.",
        "powersearch-legend": "Удасканалены пошук",
        "powersearch-ns": "Шукаць у прасторах назваў:",
        "prefs-tokenwatchlist": "Токен",
        "prefs-diffs": "Розьніцы вэрсіяў",
        "prefs-help-prefershttps": "Гэтая налада набудзе моц пры наступным уваходзе ў сыстэму.",
+       "prefswarning-warning": "Вы зрабілі зьмены ў вашых наладах, якія яшчэ не былі захаваныя.\nКалі вы закрыеце гэтую старонку і не націсьніце «$1», вашыя налады ня будуць абноўленыя.",
        "prefs-tabs-navigation-hint": "Падказка: вы можаце пераходзіць паміж укладкамі ў сьпісе ўкладак з дапамогай клявішаў налева і направа.",
        "email-address-validity-valid": "Выглядае слушна",
        "email-address-validity-invalid": "Неабходны слушны адрас!",
        "protect-othertime": "Іншы тэрмін:",
        "protect-othertime-op": "іншы тэрмін",
        "protect-existing-expiry": "Наяўны час сканчэньня: $3, $2",
+       "protect-existing-expiry-infinity": "Наяўны тэрмін сканчэньня: бясконца",
        "protect-otherreason": "Іншая/дадатковая прычына:",
        "protect-otherreason-op": "Іншая прычына",
        "protect-dropdown": "*Звычайныя прычыны абароны\n** Часты вандалізм\n** Празьмерны спам\n** Непрадуктыўная вайна рэдагаваньняў\n** Папулярная старонка",
        "unblocked": "[[User:$1|$1]] быў разблякаваны.",
        "unblocked-range": "$1 быў разблякаваны",
        "unblocked-id": "Блякаваньне $1 зьнятае",
+       "unblocked-ip": "[[Special:Contributions/$1|$1]] быў разблякаваны.",
        "blocklist": "Заблякаваныя ўдзельнікі",
        "ipblocklist": "Заблякаваныя ўдзельнікі",
        "ipblocklist-legend": "Пошук заблякаванага ўдзельніка",
        "logentry-upload-overwrite": "$1 {{GENDER:$2|загрузіў|загрузіла}} новую вэрсію $3",
        "logentry-upload-revert": "$1 {{GENDER:$2|загрузіў|загрузіла}} $3",
        "rightsnone": "(няма)",
+       "revdelete-summary": "кароткае апісаньне зьменаў",
        "feedback-bugornote": "Калі Вы гатовы падрабязна апісаць тэхнічную праблему, калі ласка [$1 паведаміце пра памылку]. \nУ адваротным выпадку, Вы можаце выкарыстоўваць простую форму пададзеную ніжэй. Ваш камэнтар будзе дададзены на старонку «[$3 $2]», разам з Вашым іменем удзельніка і выкарыстоўваемым браўзэрам.",
        "feedback-subject": "Тэма:",
        "feedback-message": "Паведамленьне:",
        "log-name-pagelang": "Журнал зьменаў мовы",
        "log-description-pagelang": "Гэта журнал зьменаў мовы старонак.",
        "logentry-pagelang-pagelang": "$1 {{GENDER:$2|зьмяніў|зьмяніла}} мову старонкі $3 з $4 на $5.",
-       "default-skin-not-found": "Упс! Тэма афармленьня па змоўчаньні для вашай вікі (<code>$wgDefaultSkin</code>), <code>$1</code> недаступная.\n\nВашае ўсталяваньне, падобна, уключае наступныя тэмы афармленьня. Глядзіце [https://www.mediawiki.org/wiki/Manual:Skin_configuration Інструкцыя:Наладка тэмаў афармленьня] дзеля інфармацыі, як падключыць іх і абраць тэму па змоўчаньні.\n\n$2\n\n; Калі вы толькі што ўсталявалі MediaWiki:\n: Напэўна вы ўсталявалі з git або наўпрост з крынічнага коду з ужываньнем іншага мэтаду. Гэта чакана. Паспрабуйце ўсталяваць некалькі тэмаў афармленьня з [https://www.mediawiki.org/wiki/Category:All_skins mediawiki.org's каталёгу тэмаў]:\n:* Спампуйце [https://www.mediawiki.org/wiki/Download tarball-усталёўнік], які ўтрымлівае некалькі тэмаў і пашырэньняў. Вы можаце скапіяваць каталёг <code>skins/</code> зь яго.\n:* Зрабіце клон аднаго з сховішчаў <code>mediawiki/skins/*</code> праз git у каталёг <code>skins/</code> вашай усталёўкі MediaWiki.\n: Калі вы распрацоўнік MediaWiki, гэта не павінна ўплываць на вашае git-сховішча.\n\n; Калі вы толькі што абнавілі MediaWiki:\n: MediaWiki вэрсіі 1.24 і навейшыя больш не падключаюць тэмы афармленьня аўтаматычна (глядзіце [https://www.mediawiki.org/wiki/Manual:Skin_autodiscovery Інструкцыя:Аўтаматычнае выяўленьне тэмаў афармленьня]). Вы можаце дадаць наступныя радкі ў <code>LocalSettings.php</code>, каб падключыць усе ўсталяваныя тэмы афармленьня:\n\n<pre>$3</pre>\n\n; Калі вы толькі што зьмянілі <code>LocalSettings.php</code>:\n: Пераправерце назвы тэмаў афармленьня на наяўнасьць памылак.",
-       "default-skin-not-found-no-skins": "Упс! Тэма афармленьня па змоўчаньня для вашай вікі (<code>$wgDefaultSkin</code>), <code>$1</code>, недаступная.\n\nВы ня маеце ўсталяваных тэмаў афармленьня.\n\n; Калі вы толькі што ўсталявалі або абнавілі MediaWiki:\n: Напэўна вы ўсталявалі з git або наўпрост з крынічнага коду з ужываньнем іншага мэтаду. Гэта чакана. MediaWiki вэрсіі 1.24 і навейшыя ня ўтрымліваюць тэмы афармленьня ў галоўным сховішчы. Паспрабуйце ўсталяваць некалькі тэмаў афармленьня з [https://www.mediawiki.org/wiki/Category:All_skins каталёгу тэмаў mediawiki.org]:\n:* Спампуйце [https://www.mediawiki.org/wiki/Download tarball-усталёўнік], які ўтрымлівае некалькі тэмаў і пашырэньняў. Вы можаце скапіяваць каталёг <code>skins/</code> зь яго.\n:* Зрабіце клон аднаго з сховішчаў <code>mediawiki/skins/*</code> праз git у каталёг <code>skins/</code> вашай усталёўкі MediaWiki.\n: Калі вы распрацоўнік MediaWiki, гэта не павінна ўплываць на вашае git-сховішча. Глядзіце [https://www.mediawiki.org/wiki/Manual:Skin_configuration Інструкцыя:Наладка тэмаў афармленьня] дзеля інфармацыі, як падключыць іх і абраць тэму па змоўчаньні.",
+       "default-skin-not-found": "Упс! Тэма афармленьня па змоўчаньні для вашай вікі, вызначаная ў <code dir=\"ltr\">$wgDefaultSkin</code> як <code>$1</code> недаступная.\n\nВашае ўсталяваньне, падобна, уключае наступныя тэмы афармленьня. Глядзіце [https://www.mediawiki.org/wiki/Manual:Skin_configuration Інструкцыя:Наладка тэмаў афармленьня] дзеля інфармацыі, як падключыць іх і абраць тэму па змоўчаньні.\n\n$2\n\n; Калі вы толькі што ўсталявалі MediaWiki:\n: Напэўна вы ўсталявалі з git або наўпрост з крынічнага коду з ужываньнем іншага мэтаду. Гэта чакана. Паспрабуйце ўсталяваць некалькі тэмаў афармленьня з [https://www.mediawiki.org/wiki/Category:All_skins mediawiki.org's каталёгу тэмаў]:\n:* Спампуйце [https://www.mediawiki.org/wiki/Download tarball-усталёўнік], які ўтрымлівае некалькі тэмаў і пашырэньняў. Вы можаце скапіяваць каталёг <code>skins/</code> зь яго.\n:* Зрабіце клон аднаго з сховішчаў <code>mediawiki/skins/*</code> праз git у каталёг <code dir=\"ltr\">skins/</code> вашай усталёўкі MediaWiki.\n: Калі вы распрацоўнік MediaWiki, гэта не павінна ўплываць на вашае git-сховішча.\n\n; Калі вы толькі што абнавілі MediaWiki:\n: MediaWiki вэрсіі 1.24 і навейшыя больш не падключаюць тэмы афармленьня аўтаматычна (глядзіце [https://www.mediawiki.org/wiki/Manual:Skin_autodiscovery Інструкцыя:Аўтаматычнае выяўленьне тэмаў афармленьня]). Вы можаце дадаць наступныя радкі ў <code>LocalSettings.php</code>, каб падключыць усе ўсталяваныя тэмы афармленьня:\n\n<pre dir=\"ltr\">$3</pre>\n\n; Калі вы толькі што зьмянілі <code>LocalSettings.php</code>:\n: Пераправерце назвы тэмаў афармленьня на наяўнасьць памылак.",
+       "default-skin-not-found-no-skins": "Упс! Тэма афармленьня па змоўчаньня для вашай вікі, вызначаная ў <code>$wgDefaultSkin</code> як <code>$1</code>, недаступная.\n\nВы ня маеце ўсталяваных тэмаў афармленьня.\n\n; Калі вы толькі што ўсталявалі або абнавілі MediaWiki:\n: Напэўна вы ўсталявалі з git або наўпрост з крынічнага коду з ужываньнем іншага мэтаду. Гэта чакана. MediaWiki вэрсіі 1.24 і навейшыя ня ўтрымліваюць тэмы афармленьня ў галоўным сховішчы. Паспрабуйце ўсталяваць некалькі тэмаў афармленьня з [https://www.mediawiki.org/wiki/Category:All_skins каталёгу тэмаў mediawiki.org]:\n:* Спампуйце [https://www.mediawiki.org/wiki/Download tarball-усталёўнік], які ўтрымлівае некалькі тэмаў і пашырэньняў. Вы можаце скапіяваць каталёг <code dir=\"ltr\">skins/</code> зь яго.\n:* Зрабіце клон аднаго з сховішчаў <code>mediawiki/skins/*</code> праз git у каталёг <code>skins/</code> вашай усталёўкі MediaWiki.\n: Калі вы распрацоўнік MediaWiki, гэта не павінна ўплываць на вашае git-сховішча. Глядзіце [https://www.mediawiki.org/wiki/Manual:Skin_configuration Інструкцыя:Наладка тэмаў афармленьня] дзеля інфармацыі, як падключыць іх і абраць тэму па змоўчаньні.",
        "default-skin-not-found-row-enabled": "* <code>$1</code> / $2 (уключана)",
-       "default-skin-not-found-row-disabled": "* <code>$1</code> / $2 ('''адключана''')"
+       "default-skin-not-found-row-disabled": "* <code>$1</code> / $2 ('''адключана''')",
+       "mediastatistics": "Статыстыка мэдыяфайлаў"
 }
index fd2d3c4..bc7ea12 100644 (file)
        "otherlanguages": "На іншых мовах",
        "redirectedfrom": "(Пасля перасылкі з $1)",
        "redirectpagesub": "Старонка-перасылка",
+       "redirectto": "Перасылае да",
        "lastmodifiedat": "Апошняе змяненне старонкі адбылося $2, $1.",
        "viewcount": "Гэту старонку адкрывалі {{PLURAL:$1|адзін раз|$1 разы|$1 разоў}}.",
        "protectedpage": "Старонка пад аховай",
        "passwordreset-emailsent-capture": "Ніжэй прыведзены адпраўлены ліст пра скід пароля.",
        "passwordreset-emailerror-capture": "Ніжэй прыведзены створаны ліст пра скід пароля, яго адпраўка не атрымалася па прычыне: $1",
        "changeemail": "Змяніць адрас электроннай пошты",
-       "changeemail-header": "Змена электроннага адрасу акаўнта",
        "changeemail-text": "Запоўніце гэтую форму, каб змяніць свой адрас электроннай пошты. Вам трэба будзе ўвесці пароль, каб пацвердзіць змяненне.",
        "changeemail-no-info": "Каб звяртацца непасрэдна да гэтай старонкі, вам варта прадставіцца сістэме.",
        "changeemail-oldemail": "Бягучы адрас электроннай пошты:",
        "changeemail-none": "(няма)",
        "changeemail-password": "Ваш {{SITENAME}} пароль:",
        "changeemail-submit": "Змяніць адрас электроннай пошты:",
-       "changeemail-cancel": "Адмена",
        "changeemail-throttled": "Надта штмат спробаў увайсці пад гэтым рахункам. Пачакайце $1 перад тым, як спрабаваць ізноў.",
        "resettokens": "Скінуць токены",
        "resettokens-text": "Вы можаце пераўстанавіць токены, якія дазваляюць атрымліваць доступ да пэўных прыватных звестак, звязаных з вашым уліковым запісам.\n\nВы мусіце скінуць токены, калі выпадкова падзяліліся імі з кім-небудзь, ці ваш уліковы запіс быў скампраметаваны.",
        "searchall": "усе",
        "showingresults": "Ніжэй паказаны да {{PLURAL:$1|'''$1''' выніку|'''$1''' вынікаў}}, пачынаючы з нумару '''$2'''.",
        "showingresultsinrange": "Ніжэй паказаны да {{PLURAL:$1|<strong>1</strong> выніку|<strong>$1</strong> вынікаў}} у дыяпазоне ад #<strong>$2</strong> да #<strong>$3</strong>.",
-       "showingresultsheader": "{{PLURAL:$5|Вынік '''$1''' из '''$3'''|Вынікі '''$1 — $2''' из '''$3'''}} для '''$4'''",
        "search-nonefound": "Нічога не было знойдзена.",
        "powersearch-legend": "Падрабязны пошук",
        "powersearch-ns": "Шукаць у прасторах назваў:",
        "logentry-upload-overwrite": "$1 {{GENDER:$2|уклаў|уклала}} новую версію $3",
        "logentry-upload-revert": "$1 {{GENDER:$2|уклаў|уклала}} $3",
        "rightsnone": "(няма)",
+       "revdelete-summary": "тлумачэнне праўкі",
        "feedback-bugornote": "Калі вы гатовыя падрабязна апісаць тэхнічную праблему, калі ласка, [$1 паведаміце пра памылку].\nУ адваротным выпадку вы можаце выкарыстоўваць гэтую простую форму. Ваш каментар будзе дададзены на старонку «[$3 $2]» разам з вашым імем удзельніка і выкарыстоўваемым браўзерам.",
        "feedback-subject": "Тэма:",
        "feedback-message": "Паведамленне",
index f489f9c..24333f0 100644 (file)
        "currentrev": "Текуща версия",
        "currentrev-asof": "Текуща версия към $1",
        "revisionasof": "Версия от $1",
-       "revision-info": "Версия от $1 на $2",
+       "revision-info": "Версия от $1 на {{GENDER:$6|$2}}$7",
        "previousrevision": "←По-стара версия",
        "nextrevision": "По-нова версия→",
        "currentrevisionlink": "преглед на текущата версия",
        "searchrelated": "свързани",
        "searchall": "всички",
        "showingresults": "Показване на до {{PLURAL:$1|'''1''' резултат|'''$1''' резултата}}, като се започва от номер '''$2'''.",
-       "showingresultsheader": "{{PLURAL:$5|Резултат '''$1''' от '''$3'''|Резултати '''$1 - $2''' от '''$3'''}} за '''$4'''",
        "search-nonefound": "Няма резултати, които да отговарят на заявката.",
        "powersearch-legend": "Разширено търсене",
        "powersearch-ns": "Търсене в именни пространства:",
        "ipb-unblock-addr": "Отблокиране на $1",
        "ipb-unblock": "Отблокиране на потребителско име IP-адрес",
        "ipb-blocklist": "Преглед на текущите блокирания",
-       "ipb-blocklist-contribs": "Приноси на $1",
+       "ipb-blocklist-contribs": "Приноси на {{GENDER:$1|$1}}",
        "unblockip": "Отблокиране на потребител",
        "unblockiptext": "Използвайте долния формуляр, за да възстановите правото на писане на по-рано блокиран IP-адрес или потребител.",
        "ipusubmit": "Сваляне на блокирането",
        "import-error-create": "Страницата „$1“ не беше внесена, тъй като нямате права да я създадете.",
        "import-error-interwiki": "Страницата „$1“ не беше внесена, тъй като името ѝ е запазено за външно свързване (междууики).",
        "import-error-special": "Страницата „$1“ не беше внесена, тъй като принадлежи към специално именно пространство, което не позволява страници.",
-       "import-error-invalid": "Страницата „$1“ не беше внесена, тъй като името ѝ е невалидно.",
+       "import-error-invalid": "Страницата „$1“ не беше внесена, тъй като името към което трябваше да бъде внесена е невалидно на това уики.",
        "import-rootpage-invalid": "Посочената основна страница е с невалидно заглавие.",
        "import-rootpage-nosubpage": "Именното пространство „$1“ на основната страница не позволява създаването на подстраници.",
        "importlogpage": "Дневник на внасянията",
        "importlogpagetext": "Административни внасяния на страници с редакционна история от други уикита.",
        "import-logentry-upload": "[[$1]] беше внесена от файл",
-       "import-logentry-upload-detail": "{{PLURAL:$1|една версия|$1 версии}}",
+       "import-logentry-upload-detail": "$1 {{PLURAL:$1|версия беше внесена|версии бяха внесени}}",
        "import-logentry-interwiki": "$1 беше внесена от друго уики",
        "import-logentry-interwiki-detail": "{{PLURAL:$1|една версия|$1 версии}} на $2 бяха внесени",
        "javascripttest": "Тестване на JavaScript",
        "spam_reverting": "Връщане на последната версия, несъдържаща препратки към $1",
        "spam_blanking": "Всички версии, съдържащи препратки към $1, изчистване",
        "spam_deleting": "Всички версии съдържат препратки към $1, изтриване",
-       "simpleantispam-label": "Проверка за спам.\nНеобходимо е да '''НЕ''' попълвате това поле!",
+       "simpleantispam-label": "Проверка за спам.\nНеобходимо е да <strong>НЕ</strong> попълвате това поле!",
        "pageinfo-title": "Информация за \"$1\"",
        "pageinfo-not-current": "За съжаление тази информация не може да бъде предоставена за стари версии.",
        "pageinfo-header-basic": "Основна информация",
        "pageinfo-length": "Дължина на страницата (в байтове)",
        "pageinfo-article-id": "Номер на страницата",
        "pageinfo-language": "Език на съдържанието на страницата",
-       "pageinfo-robot-policy": "СÑ\82аÑ\82Ñ\83Ñ\82 Ð½Ð° Ñ\81Ñ\82Ñ\80аниÑ\86аÑ\82а Ð² Ñ\82Ñ\8aÑ\80Ñ\81аÑ\87киÑ\82е",
-       "pageinfo-robot-index": "Ð\98ндекÑ\81иÑ\80Ñ\83ема",
-       "pageinfo-robot-noindex": "Ð\9dеиндекÑ\81иÑ\80Ñ\83ема",
+       "pageinfo-robot-policy": "Ð\98ндекÑ\81иÑ\80ане Ð¾Ñ\82 Ñ\80обоÑ\82и",
+       "pageinfo-robot-index": "Ð\9fозволено",
+       "pageinfo-robot-noindex": "Ð\9dепозволено",
        "pageinfo-views": "Брой прегледи",
        "pageinfo-watchers": "Брой наблюдаващи страницата",
        "pageinfo-few-watchers": "Под $1 {{PLURAL:$1|наблюдаващ|наблюдаващи}}",
        "logentry-delete-delete": "$1 {{GENDER:$2|изтри}} страницата $3",
        "logentry-delete-restore": "$1 {{GENDER:$2|възстанови}} страницата $3",
        "logentry-suppress-revision": "$1 тайно промени видимостта на {{PLURAL:$5|една версия|$5 версии}} на страницата $3: $4",
-       "logentry-suppress-revision-legacy": "$1 тайно промени видимостта на версиите на страница $3",
+       "logentry-suppress-revision-legacy": "$1 тайно {{GENDER:$2|промени}} видимостта на версиите на страница $3",
        "revdelete-content-hid": "скрито съдържание",
        "revdelete-summary-hid": "скрито резюме на редакцията",
        "revdelete-uname-hid": "скрито потребителско име",
        "logentry-move-move": "$1 {{GENDER:$2|премести}} страница „$3“ като „$4“",
        "logentry-move-move-noredirect": "$1 {{GENDER:$2|премести}} страницата „$3“ като „$4“ без пренасочване",
        "logentry-move-move_redir": "$1 {{GENDER:$2|премести}} страницата $3 като $4 (върху пренасочване)",
-       "logentry-move-move_redir-noredirect": "$1 премести върху пренасочване „$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-newusers-newusers": "Потребителската сметка $1 беше {{GENDER:$2|създадена}}",
        "logentry-newusers-autocreate": "Сметката $1 беше {{GENDER:$2|създадена}} автоматично",
        "logentry-rights-rights": "$1 {{GENDER:$2|промени}} потребителската група на $3 от $4 на $5",
        "logentry-rights-rights-legacy": "$1 {{GENDER:$2|промени}} потребителската група на $3",
-       "logentry-rights-autopromote": "\n$1 е автоматично повишен от $4 до $5",
+       "logentry-rights-autopromote": "$1 е автоматично {{GENDER:$2|повишен|повишена}} от $4 до $5",
        "rightsnone": "(никакви)",
        "feedback-bugornote": "Ако сте готови подробно да опишете технически проблем, моля [$1 докладвайте го тук].\nВ противен случай, можете да използвате лесния формуляр по-долу. Коментарът ви ще бъде добавен към страницата \"[$3 $2]\", наред с вашето потребителско име.",
        "feedback-subject": "Тема:",
index f998a5b..8d28d17 100644 (file)
        "passwordreset-emailsent-capture": "স্মরণ করিয়ে দেয়ার জন্য একটি ইমেইল করা হয়েছে, যা নিচে দেখানো হচ্ছে।",
        "passwordreset-emailerror-capture": "স্মরণ করিয়ে দেয়ার জন্য একটি ইমেইল তৈরী করা হয়েছিল, যা নিচে দেখানো হচ্ছে, তবে $1 {{GENDER:$2|ব্যবহারকারীকে}} এটি পাঠানো যায়নি!",
        "changeemail": "ই-মেইল ঠিকানা পরিবর্তন",
-       "changeemail-header": "অ্যাকাউন্ট ই-মেইল ঠিকানা পরিবর্তন",
        "changeemail-text": "ই-মেইল ঠিকানা পরিবর্তন করতে আপনাকে এই ফরমটি পূরণ করতে হবে। এই পরিবর্তনটি নিশ্চিত করতে আপনার পাসওয়ার্ড প্রদানের প্রয়োজন হবে।",
        "changeemail-no-info": "এই পাতাটিতে সরাসরি প্রবেশাধিকার পেতে আপনাকে অবশ্যই লগইন করতে হবে।",
        "changeemail-oldemail": "বর্তমান ই-মেইল ঠিকানা:",
        "changeemail-none": "(কিছু নাই)",
        "changeemail-password": "আপনার {{SITENAME}} পাসওয়ার্ড:",
        "changeemail-submit": "ই-মেইল পরিবর্তন",
-       "changeemail-cancel": "বাতিল",
        "changeemail-throttled": "আপনি পরপর বেশ কয়েকবার প্রবেশের চেষ্টা করেছেন। পুনরায় চেষ্টা করার পূর্বে অনুগ্রহ করে $1 অপেক্ষা করুন।",
        "resettokens": "রিসেট টোকেন",
        "resettokens-text": "আপনি টোকেন রিসেট করতে পারেন, যা অ্যাকাউন্টের সাথে সম্পর্কিত আপনার ব্যক্তিগত তথ্য দেখার কাজে ব্যবহার করা হয়।",
        "searchall": "সমস্ত",
        "showingresults": "নিচে '''$2''' নং থেকে শুরু করে {{PLURAL:$1|'''1''' ফলাফল|'''$1''' ফলাফলসমূহ}} দেখানো হল।",
        "showingresultsinrange": "#<strong>$2</strong> থেকে #<strong>$3</strong> পরিসীমার মধ্যে {{PLURAL:$1|<strong>১টি</strong> ফলাফল|<strong>$1টি</strong> ফলাফল}} নিচে দেখানো হচ্ছে।",
-       "showingresultsheader": "'''$4''' এর জন্য {{PLURAL:$5|ফলাফল '''$3''' এর '''$1'''|ফলাফলসমূহ '''$3''' এর মধ্যে '''$1 - $2'''}}",
+       "search-showingresults": "{{PLURAL:$4|<strong>$3</strong>-এর মধ্যে <strong>$1</strong>টি ফলাফল|<strong>$3</strong>-এর মধ্যে <strong>$1 - $2</strong>টি ফলাফল}}",
        "search-nonefound": "খোঁজকৃত পাতার সাথে মিলে যায় এমন কোনো ফলাফল নেই।",
        "powersearch-legend": "উন্নত অনুসন্ধান",
        "powersearch-ns": "নামস্থানে অনুসন্ধান করো:",
        "logentry-upload-overwrite": "$1 $3-এর একটি নতুন সংস্করণ {{GENDER:$2|আপলোড করেছেন}}",
        "logentry-upload-revert": "$1 $3 {{GENDER:$2|আপলোড করেছেন}}",
        "rightsnone": "(কিছু নাই)",
+       "revdelete-summary": "সম্পাদনা সারাংশ",
        "feedback-bugornote": "কারিগরী ত্রুটির বিস্তারিত বর্ণনা জানতে [$1 বাগ রিপোর্ট করুন]।\nঅথবা নিচের এই সরল ফর্মটি ব্যবহার করতে পারেন। \"[$3 $2]\" পাতায় আপনার ব্যবহারকারী নাম সহ মন্তব্যটি প্রকাশিত হবে।",
        "feedback-subject": "বিষয়:",
        "feedback-message": "বার্তা:",
index 23b840a..c528646 100644 (file)
        "otherlanguages": "Yezhoù all",
        "redirectedfrom": "(Adkaset eus $1)",
        "redirectpagesub": "Pajenn adkas",
+       "redirectto": "Adkas da :",
        "lastmodifiedat": "Kemmoù diwezhañ degaset d'ar bajenn-mañ, d'an/ar $1 da $2.",
        "viewcount": "Sellet ez eus bet {{PLURAL:$1|$1 wezh|$1 gwezh}} ouzh ar bajenn-mañ.",
        "protectedpage": "Pajenn warezet",
        "jumptonavigation": "merdeiñ",
        "jumptosearch": "klask",
        "view-pool-error": "Ho tigarez, soulgarget eo ar servijerioù evit poent.\nRe a implijerien a glask mont war ar bajenn-mañ war un dro.\nGortozit ur pennadig a-raok klask mont war ar bjann-mañ en-dro.\n\n$1",
+       "generic-pool-error": "Ho tigarez, soulgarget eo ar servijerioù evit poent.\nRe a implijerien a glask mont war ar bajenn-mañ war un dro.\nGortozit ur pennadig a-raok klask mont war ar bajenn-mañ en-dro.",
        "pool-timeout": "Aet eur dreist d'an termen gortoz evit ar stankadenn",
        "pool-queuefull": "Soulgarget eo ar servijerioù",
        "pool-errorunknown": "Fazi dianav",
        "searchrelated": "disoc'hoù kar",
        "searchall": "An holl",
        "showingresults": "Diskouez betek {{PLURAL:$1|'''1''' disoc'h|'''$1''' disoc'h}} o kregiñ gant #'''$2'''.",
-       "showingresultsheader": "{{PLURAL:$5|Disoc'h '''$1''' diwar '''$3'''|Disoc'hoù '''$1 - $2''' diwar '''$3'''}} evit '''$4'''",
        "search-nonefound": "An enklask-mañ ne zisoc'h war netra.",
        "powersearch-legend": "Klask araokaet",
        "powersearch-ns": "Klask en esaouennoù anv :",
index f84897d..675d83f 100644 (file)
        "searcharticle": "Idi",
        "history": "Historija stranice",
        "history_short": "Historija",
-       "updatedmarker": "promjene od moje zadnje posjete",
+       "updatedmarker": "promjene od moje posljednje posjete",
        "printableversion": "Prilagođeno štampanju",
        "permalink": "Trajni link",
        "print": "Štampa",
        "badtitle": "Loš naslov",
        "badtitletext": "Zahtjevani naslov stranice je bio neispravan, prazan ili neispravno povezan međujezički ili interviki naslov.",
        "perfcached": "Slijedeći podaci su keširani i možda neće biti u potpunosti ažurirani. Keš sadrži najviše {{PLURAL:$1|jedan rezultat|$1 rezultata}}.",
-       "perfcachedts": "Slijedeći podaci se nalaze u memoriji i zadnji put su ažurirani $1. Keš sadrži najviše {{PLURAL:$4|jedan rezultat|$4 rezultata}}.",
+       "perfcachedts": "Sljedeći podaci nalaze se u memoriji i posljednji put ažurirani su $1. Keš sadrži najviše {{PLURAL:$4|jedan rezultat|$4 rezultata}}.",
        "querypage-no-updates": "Ažuriranje ove stranice je isključeno.\nPodaci koji se ovdje nalaze ne moraju biti aktuelni.",
        "viewsource": "Pogledaj izvor",
        "viewsource-title": "Prikaz izvora stranice $1",
        "passwordsent": "Nova šifra je poslata na adresu e-pošte korisnika \"$1\".\nMolimo Vas da se prijavite pošto je primite.",
        "blocked-mailpassword": "Da bi se spriječila nedozvoljena akcija, Vašoj IP adresi je onemogućeno uređivanje stranica kao i mogućnost zahtijevanje nove šifre.",
        "eauthentsent": "Na navedenu adresu poslana je e-poruka s potvrdom.\nPrije nego što pošaljemo daljnje poruke, pratite uputstva s e-pošte da biste potvrdili da je račun zaista Vaš.",
-       "throttled-mailpassword": "Već Vam je poslan e-mail za promjenu šifre u {{PLURAL:$1|zadnjih sat vremena|zadnja $1 sata|zadnjih $1 sati}}.\nDa bi se spriječila zloupotreba, može se poslati samo jedan e-mail za promjenu šifre {{PLURAL:$1|svakih sat vremena|svaka $1 sata|svakih $1 sati}}.",
+       "throttled-mailpassword": "Već Vam je poslan e-mail za promjenu šifre u {{PLURAL:$1|posljednjih sat vremena|posljednja $1 sata|posljednjih $1 sati}}.\nDa bi se spriječila zloupotreba, može se poslati samo jedan e-mail za promjenu šifre {{PLURAL:$1|svakih sat vremena|svaka $1 sata|svakih $1 sati}}.",
        "mailerror": "Greška pri slanju e-pošte: $1",
        "acct_creation_throttle_hit": "Posjetioci na ovoj wiki koji koriste Vašu IP adresu su već napravili {{PLURAL:$1|$1 račun|$1 računa}} u zadnjih nekoliko dana, što je najveći broj dopuštenih napravljenih računa za ovaj period.\nKao rezultat, posjetioci koji koriste ovu IP adresu ne mogu trenutno praviti više računa.",
        "emailauthenticated": "Vaša adresa e-pošte potvrđena je $2 u $3.",
        "passwordreset-emailsent-capture": "Poslan je podsjetnik preko e-pošte (prikazano ispod).",
        "passwordreset-emailerror-capture": "E-poruka za resetiranje lozinke, prikazano ispod, poslana je, ali slanje {{GENDER:$2|korisniku|korisnici}} nije uspjelo: $1",
        "changeemail": "Promijeni e-mail adresu",
-       "changeemail-header": "Promijeni e-mail adresu korisničkog računa",
        "changeemail-text": "Ispunite ovaj formular da biste promijenili svoju e-mail adresu. Morat ćete upisati svoj pasvord da potvrdite ovu promjenu.",
        "changeemail-no-info": "Morate biti prijavljeni za direktan pristup ovoj stranici.",
        "changeemail-oldemail": "Trenutna e-mail adresa:",
        "changeemail-none": "(ništa)",
        "changeemail-password": "Tvoja šifra/lozinka za {{SITENAME}}:",
        "changeemail-submit": "Promijeni e-mail",
-       "changeemail-cancel": "Otkaži",
        "resettokens-token-label": "$1 (trenutna vrijednost: $2)",
        "bold_sample": "Podebljan tekst",
        "bold_tip": "Podebljan tekst",
        "next": "slijed",
        "last": "preth",
        "page_first": "prva",
-       "page_last": "zadnja",
+       "page_last": "posljednja",
        "histlegend": "Odabir razlika: označite radio dugme verzija koje uspoređujete i pritistnite enter ili dugme na dnu. <br />\nObjašnjenje: '''(tren)''' = razlika sa trenutnom verzijom,\n'''(preth)''' = razlika sa prethodnom verzijom, '''m''' = mala izmjena.",
        "history-fieldset-title": "Pretraga historije",
        "history-show-deleted": "Samo obrisane",
        "searchrelated": "povezano",
        "searchall": "sve",
        "showingresults": "Dolje {{PLURAL:$1|je prikazan '''1''' rezultat|su prikazana '''$1''' rezultata|je prikazano '''$1''' rezultata}} počev od '''$2'''.",
-       "showingresultsheader": "{{PLURAL:$5|Rezultat '''$1''' od '''$3'''|Rezultati '''$1 - $2''' od '''$3'''}} za '''$4'''",
        "search-nonefound": "Nisu pronađeni rezultati koji odgovaraju upitu.",
        "powersearch-legend": "Napredna pretraga",
        "powersearch-ns": "Pretraga u imenskim prostorima:",
        "statistics-views-peredit": "Pogleda po izmjeni",
        "statistics-users": "Registrovani [[Special:ListUsers|korisnici]]",
        "statistics-users-active": "Aktivni korisnici",
-       "statistics-users-active-desc": "Korisnici koju su izvršili akciju u toku {{PLURAL:$1|zadnjeg dana|zadnja $1 dana|zadnjih $1 dana}}",
+       "statistics-users-active-desc": "Korisnici koji su izvršili akciju u toku {{PLURAL:$1|posljednjeg dana|posljednja $1 dana|posljednjih $1 dana}}",
        "statistics-mostpopular": "Najviše pregledane stranice",
        "pageswithprop-prop": "Naziv svojstva:",
        "pageswithprop-submit": "Idi",
        "listusers-noresult": "Nije pronađen korisnik.",
        "listusers-blocked": "(blokiran)",
        "activeusers": "Spisak aktivnih korisnika",
-       "activeusers-intro": "Ovo je spisak korisnika koji su napravili neku aktivnost u {{PLURAL:$1|zadnji $1 dan|zadnja $1 dana|zadnjih $1 dana}}.",
+       "activeusers-intro": "Ovo je spisak korisnika koji su imali neku aktivnost u {{PLURAL:$1|posljednji $1 dan|posljednja $1 dana|posljednjih $1 dana}}.",
        "activeusers-count": "$1 {{PLURAL:$1|izmjena|izmjene|izmjena}} u {{PLURAL:$3|posljednji $3 dan|posljednja $3 dana|posljednjih $3 dana}}",
        "activeusers-from": "Prikaži korisnike koji počinju sa:",
        "activeusers-hidebots": "Sakrij botove",
        "ipb-hardblock": "Onemogući prijavljene korisnike da uređuju sa ove IP adrese",
        "ipbcreateaccount": "Onemogući pravljenje računa",
        "ipbemailban": "Onemogući korisnika da šalje e-mail",
-       "ipbenableautoblock": "Automatski blokiraj zadnju IP adresu koju je koristio ovaj korisnik i sve druge IP adrese s kojih je on pokušao uređivati",
+       "ipbenableautoblock": "Automatski blokiraj posljednju IP-adresu koju je koristio ovaj korisnik i sve druge IP-adrese s kojih je pokušao uređivati",
        "ipbsubmit": "Blokirajte ovog korisnika",
        "ipbother": "Ostali period:",
        "ipboptions": "2 sata:2 hours,1 dan:1 day,3 dana:3 days,1 sedmica:1 week,2 sedmice:2 weeks,1 mjesec:1 month,3 mjeseca:3 months,6 mjeseci:6 months,1 godine:1 year,zauvijek:infinite",
        "spamprotectiontext": "Strana koju želite da sačuvate je blokirana od strane filtera za neželjene poruke.\nOvo je vjerovatno izazvao vezom ka vanjskoj nepoželjnoj stranici.",
        "spamprotectionmatch": "Slijedeći tekst je izazvao naš filter za neželjene poruke: $1",
        "spambot_username": "MediaWiki čišćenje spama",
-       "spam_reverting": "Vraćanje na zadnju verziju koja ne sadrži linkove ka $1",
+       "spam_reverting": "Vraćanje na posljednju verziju koja ne sadrži linkove ka $1",
        "spam_blanking": "Sve revizije koje sadrže linkove ka $1, očisti",
        "spam_deleting": "Sve revizije koje sadrže linkove na $1, brišem",
        "simpleantispam-label": "Provjera protiv spama.\n'''NE''' popunjavaj ovo!",
        "table_pager_next": "Slijedeća stranica",
        "table_pager_prev": "Prethodna stranica",
        "table_pager_first": "Prva stranica",
-       "table_pager_last": "Zadnja stranica",
+       "table_pager_last": "Posljednja stranica",
        "table_pager_limit": "Pokaži $1 stavki po stranici",
        "table_pager_limit_label": "Stavke po stranici:",
        "table_pager_limit_submit": "Idi",
        "logentry-rights-rights-legacy": "$1 je {{GENDER:$2|promijenio|promijenila|promijenio}} članstvo grupe za $3",
        "logentry-rights-autopromote": "$1 {{GENDER:$1|je automatski promijenjeno članstvo|su automatski promijenjena članstva}} iz $4 u $5",
        "rightsnone": "(nema)",
+       "revdelete-summary": "sažetak",
        "feedback-bugornote": "Ako ste spremni detaljno opisati tehnički problem, molimo [$1 prijavite \"bug\" (grešku)].\nInače, možete ispuniti jednostavan obrazac ispod. Vaš komentar bit će dodan na stranicu \"[$3 $2]\" zajedno s Vašim korisničkim imenom.",
        "feedback-subject": "Tema:",
        "feedback-message": "Poruka:",
index db74996..f706e7a 100644 (file)
        "filedeleteerror": "Diri mapura a file na \"$1\".",
        "directorycreateerror": "Diri magibo a direktoryong \"$1\".",
        "filenotfound": "Diri maturakan a file na \"$1\".",
+       "formerror": "Sala: Diri maisumitir ana porma.",
+       "badarticleerror": "Diri magibo ading aksyon sadi pahina.",
        "cannotdelete-title": "Diri mapura a pahinang \"$1\"",
        "badtitle": "Bukung tamang titulo",
        "viewsource": "Baydon a ginikanan",
        "loginerror": "Sala a pagloog",
        "createacct-error": "Sala a paggibo sa account",
        "createaccounterror": "Diri makagibo sa account: $1",
+       "loginsuccesstitle": "Matriyumpong nakaloog",
+       "loginsuccess": "'''Nakaloog ka na sa {{SITENAME}} bilang si \"$1\".'''",
        "mailmypassword": "Balyowan a password",
        "passwordremindertitle": "Bagong temporaryong password para sa {{SITENAME}}",
        "noemailcreate": "Kaipowan mong ibutang a tamang email adres.",
+       "mailerror": "Sala ana pagpadara ka surat: $1",
+       "emaildisabled": "Diri makapadadarang surat ading sityo.",
        "accountcreated": "Nakagibo na sa account",
        "login-abort-generic": "A kanimong pagloog diri magibo - Pinundo.",
        "loginlanguagelabel": "Sarita: $1",
        "changepassword": "Balyowan a password",
        "oldpassword": "Lumang password:",
        "newpassword": "Bagong password:",
+       "resetpass-submit-cancel": "Kanselaron",
+       "resetpass-temp-password": "Temporaryong password:",
+       "passwordreset": "Balyowan a password",
+       "passwordreset-legend": "Balyowan a password",
        "passwordreset-domain": "Nasasakupan:",
        "passwordreset-email": "Email address:",
        "changeemail": "Ribayan a email adres",
index a56cb47..dfdec02 100644 (file)
@@ -59,6 +59,7 @@
        "tog-watchdefault": "Afegeix les pàgines que vagi editant a la llista de seguiment",
        "tog-watchmoves": "Afegeix les pàgines que reanomeni a la llista de seguiment",
        "tog-watchdeletion": "Afegeix les pàgines que elimini a la llista de seguiment",
+       "tog-watchrollback": "Afegeix les pàgines on he realitzat una reversió a la llista de seguiment",
        "tog-minordefault": "Marca totes les contribucions com a edicions menors per defecte",
        "tog-previewontop": "Mostra una previsualització abans del quadre d'edició",
        "tog-previewonfirst": "Mostra una previsualització en la primera modificació",
        "otherlanguages": "En altres llengües",
        "redirectedfrom": "(S'ha redirigit des de: $1)",
        "redirectpagesub": "Pàgina de redirecció",
+       "redirectto": "Redirigeix a:",
        "lastmodifiedat": "Darrera modificació de la pàgina: $1 a les $2.",
        "viewcount": "S'ha visitat aquesta pàgina {{PLURAL:$1|una vegada|$1 vegades}}.",
        "protectedpage": "Pàgina protegida",
        "createaccount-text": "Algú ha creat un compte d'usuari anomenat $2 al projecte {{SITENAME}}\n($4) amb la vostra adreça de correu electrònic. La contrasenya per a l'usuari «$2» és «$3». Hauríeu d'accedir al compte i canviar-vos aquesta contrasenya quan abans millor.\n\nSi no hi teniu cap relació i aquest compte s'ha creat per error, simplement ignoreu el missatge.",
        "login-throttled": "Heu realitzat massa intents d'accés a la sessió.\nEspereu $1 abans de tornar-ho a provar.",
        "login-abort-generic": "L'entrada al compte d'usuari no ha reeixit - Abortada",
+       "login-migrated-generic": "S'ha migrat el vostre compte, i el vostre nom d'usuari ja no existeix en aquest wiki.",
        "loginlanguagelabel": "Llengua: $1",
        "suspicious-userlogout": "S'ha denegat la vostra petició per tancar la sessió ja què sembla que va ser enviada per un navegador defectuós o un proxy cau.",
        "createacct-another-realname-tip": "El nom real és opcional.\nSi decidiu proporcionar-lo, s'utilitzarà per a reconèixer a l'usuari el seu treball.",
        "passwordreset-emailsent-capture": "S'ha enviat un correu electrònic de reinicialització de contrasenya, tal com es mostra a continuació.",
        "passwordreset-emailerror-capture": "S'ha generat un correu electrònic de renovació de contrasenya, que es mostra a continuació, però ha fallat l'enviament a {{GENDER:$2:l'usuari|la usuària}}: $1",
        "changeemail": "Canvi de correu electrònic",
-       "changeemail-header": "Canvi de l'adreça de correu electrònic del compte",
        "changeemail-text": "Completeu el següent formulari per canviar la vostra adreça de correu electrònic. Haureu d'introduir la contrasenya per confirmar el canvi.",
        "changeemail-no-info": "Heu d'entrar en un compte d'usuari per accedir directament a aquesta pàgina.",
        "changeemail-oldemail": "Adreça de correu electrònic actual:",
        "changeemail-none": "(cap)",
        "changeemail-password": "La vostra contrasenya a {{SITENAME}}:",
        "changeemail-submit": "Canvia de correu electrònic",
-       "changeemail-cancel": "Cancel·la",
        "changeemail-throttled": "Heu realitzat massa intents d'inici de sessió.\nEspereu $1 abans de tornar-ho a provar.",
        "resettokens": "Reinicia els testimonis",
        "resettokens-text": "Des d'aquí podeu reiniciar els testimonis que permeten l'accés a certes dades privades associades amb el vostre compte.\n\nHo hauríeu de fer si accidentalment els heu compartit amb algú o si el vostre compte ha estat compromès.",
        "showpreview": "Mostra una previsualització",
        "showdiff": "Mostra els canvis",
        "blankarticle": "<strong>Avís:</strong> La pàgina que esteu creant és en blanc.\nSi feu clic a «{{int:savearticle}}» un altre cop, la pàgina es crearà sense cap contingut.",
-       "anoneditwarning": "'''Avís:''' No esteu identificats amb un compte d'usuari. Es mostrarà la vostra adreça IP en l'historial d'aquesta pàgina.",
+       "anoneditwarning": "<strong>Avís</strong>: No heu iniciat cap sessió. Per tant, la vostra adreça IP serà visible públicament si feu qualsevol modificació. Si <strong>[$1 inicieu una sessió]</strong> o <strong>[$2 creeu un compte]</strong>, les vostres edicions s'atribuiran al vostre nom d'usuari, juntament amb altres beneficis.",
        "anonpreviewwarning": "''No us heu identificat amb un compte d'usuari. La vostra adreça IP quedarà registrada a l'historial d'aquesta pàgina.''",
        "missingsummary": "'''Recordatori''': Heu deixat en blanc el resum de l'edició. Si torneu a clicar al botó de desar, l'edició es guardarà sense resum.",
        "missingcommenttext": "Introduïu un comentari a continuació.",
        "searchall": "tots",
        "showingresults": "Tot seguit es {{PLURAL:$1|mostra el resultat|mostren els <b>$1</b> resultats començant pel número <b>$2</b>}}.",
        "showingresultsinrange": "Es mostren a continuació fins a {{PLURAL:$1|<strong>1</strong> resultat|<strong>$1</strong> resultats}} de #<strong>$2</strong> a #<strong>$3</strong>.",
-       "showingresultsheader": "{{PLURAL:$5|Resultat '''$1''' de '''$3'''|Resultats '''$1 - $2''' de '''$3'''}} per '''$4'''",
+       "search-showingresults": "{{PLURAL:$4|Resultat <strong>$1</strong> de <strong>$3</strong>|Resultats <strong>$1 - $2</strong> de <strong>$3</strong>}}",
        "search-nonefound": "La cerca no ha donat cap resultat.",
        "powersearch-legend": "Cerca avançada",
        "powersearch-ns": "Cerca als espais de noms:",
        "noindex-category-desc": "La pàgina conté una paraula màgica <code><nowiki>__NOINDEX__</nowiki></code> (i és en un espai de noms on està permesa) i per tant no està indexada per robots.",
        "index-category-desc": "La pàgina conté un <code><nowiki>__INDEX__</nowiki></code> (i és en un espai de noms on està permès) i per tant està indexat per robots quan normalment no ho seria.",
        "post-expand-template-inclusion-category-desc": "La mida de la pàgina és més gran que <code>$wgMaxArticleSize</code> un cop expandides totes les plantilles, per tant algunes plantilles no s'han expandit.",
-       "post-expand-template-argument-category-desc": "Després d'expandir un argument de plantilla (alguna cosa entre claus triples, com <code>{{{Això}}}</code>), la pàgina és més gran que <code>$wgMaxArticleSize</code>.",
+       "post-expand-template-argument-category-desc": "La pàgina és més gran que <code>$wgMaxArticleSize</code> després d'expandir un argument de plantilla (quelcom entre claus triples, com ara <code>{{{Foo}}}</code>).",
        "expensive-parserfunction-category-desc": "La pàgina utilitza massa funcions d'analitzador costoses (com <code>#ifexist</code>). Vegeu [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:$wgExpensiveParserFunctionLimit Manual:$wgExpensiveParserFunctionLimit].",
        "broken-file-category-desc": "La pàgina conté un enllaç de fitxer trencat (un enllaç per inserir un fitxer quan aquest fitxer no existeix).",
-       "hidden-category-category-desc": "Aquesta és una categoria que conté <code><nowiki>__HIDDENCAT__</nowiki></code>, que impedeix que aparegui en la caixa d'enllaços de categoria a les pàgines, per defecte.",
+       "hidden-category-category-desc": "La categoria conté <code><nowiki>__HIDDENCAT__</nowiki></code> en el contingut de la pàgina, fet que impedeix que aparegui en la caixa d'enllaços de categoria a les pàgines per defecte.",
        "trackingcategories-nodesc": "Sense descripció disponible.",
        "trackingcategories-disabled": "La categoria està inhabilitada",
        "mailnologin": "Cap adreça de remitent",
        "watchlist-details": "Teniu $1 {{PLURAL:$1|pàgina|pàgines}} a la llista de seguiment, sense comptar les pàgines de discussió.",
        "wlheader-enotif": "La notificació per correu electrònic està habilitada.",
        "wlheader-showupdated": "Les pàgines que s'han canviat des de la vostra darrera visita es mostren en '''negreta'''.",
-       "wlnote": "A sota hi ha {{PLURAL:$1|el darrer canvi|els darrers '''$1''' canvis}} en {{PLURAL:$2|la darrera hora|les  '''$2''' darreres hores}}, a $4 del $3.",
+       "wlnote": "A sota hi ha {{PLURAL:$1|el darrer canvi|els darrers <strong>$1</strong> canvis}} en {{PLURAL:$2|la darrera hora|les <strong>$2</strong> darreres hores}}, a $4 del $3.",
        "wlshowlast": "<small>- Mostra les darreres $1 hores, els darrers $2 dies o $3</small>",
        "watchlist-options": "Opcions de la llista de seguiment",
        "watching": "S'està vigilant...",
        "exbeforeblank": "el contingut abans de buidar era: '$1'",
        "delete-confirm": "Elimina «$1»",
        "delete-legend": "Elimina",
-       "historywarning": "'''Atenció:''' La pàgina que esteu a punt d'eliminar té un historial amb $1 {{PLURAL:$1|versió|versions}}, aproximadament:",
+       "historywarning": "<strong>Avís:</strong> la pàgina que esteu a punt d'eliminar té un historial amb $1 {{PLURAL:$1|revisió|revisions}}:",
        "confirmdeletetext": "Esteu a punt d'esborrar de forma permanent una pàgina o imatge i tot el seu historial de la base de dades.\nConfirmeu que realment ho voleu fer, que enteneu les\nconseqüències, i que el que esteu fent està d'acord amb la [[{{MediaWiki:Policy-url}}|política]] del projecte.",
        "actioncomplete": "Acció realitzada",
        "actionfailed": "L'acció ha fallat",
        "delete-edit-reasonlist": "Edita els motius d'eliminació",
        "delete-toobig": "Aquesta pàgina té un historial d'edicions molt gran, amb més de $1 {{PLURAL:$1|canvi|canvis}}. L'eliminació d'aquestes pàgines està restringida per a prevenir que hi pugui haver un desajustament seriós de la base de dades de tot el projecte {{SITENAME}} per accident.",
        "delete-warning-toobig": "Aquesta pàgina té un historial d'edicions molt gran, amb més de $1 {{PLURAL:$1|canvi|canvis}}. Eliminar-la podria suposar un seriós desajustament de la base de dades de tot el projecte {{SITENAME}}; aneu en compte abans dur a terme l'acció.",
+       "deleteprotected": "No podeu eliminar la pàgina perquè ha estat protegida.",
        "deleting-backlinks-warning": "'''Avís:''' [[Special:WhatLinksHere/{{FULLPAGENAME}}|Altres pàgines]] enllacen o transclouen de la pàgina que esteu a punt de suprimir.",
        "rollback": "Reverteix edicions",
        "rollback_short": "Revoca",
        "autoblockid": "Autoblocatge #$1",
        "block": "Blocatge d'usuaris",
        "unblock": "Desblocatge d'usuaris",
-       "blockip": "Bloqueig d'usuaris",
+       "blockip": "Bloca {{GENDER:$1|l'usuari|l'usuària}}",
        "blockip-legend": "Bloca l'usuari",
        "blockiptext": "Empreu el següent formulari per blocar l'accés\nd'escriptura des d'una adreça IP específica o des d'un usuari determinat.\naixò només s'hauria de fer per prevenir el vandalisme, i\nd'acord amb la [[{{MediaWiki:Policy-url}}|política del projecte]].\nEmpleneu el diàleg de sota amb un motiu específic (per exemple, citant\nquines pàgines en concret estan sent vandalitzades).",
        "ipaddressorusername": "Adreça IP o nom de l'usuari",
        "ipb-unblock-addr": "Desbloca $1",
        "ipb-unblock": "Desbloca un usuari o una adreça IP",
        "ipb-blocklist": "Llista els bloquejos existents",
-       "ipb-blocklist-contribs": "Contribucions de $1",
+       "ipb-blocklist-contribs": "Contribucions de {{GENDER:$1|$1}}",
        "unblockip": "Desbloca l'usuari",
        "unblockiptext": "Empreu el següent formulari per restaurar\nl'accés a l'escriptura a una adreça IP o un usuari prèviament bloquejat.",
        "ipusubmit": "Desbloca aquesta adreça",
        "unblocked": "S'ha desbloquejat l'{{GENDER:$1|usuari|usuària}} [[User:$1|$1]]",
        "unblocked-range": "s'ha desblocat $1",
        "unblocked-id": "S'ha eliminat el bloqueig de $1",
+       "unblocked-ip": "[[Special:Contributions/$1|$1]] ha estat desbloquejat.",
        "blocklist": "Usuaris blocats",
        "ipblocklist": "Usuaris blocats",
        "ipblocklist-legend": "Cerca un usuari blocat",
        "import": "Importació de pàgines",
        "importinterwiki": "Importa interwiki",
        "import-interwiki-text": "Trieu un web basat en wiki i un títol de pàgina per a importar.\nEs conservaran les dates de les versions i els noms dels editors.\nTotes les accions d'importació interwiki es conserven al [[Special:Log/import|registre d'importacions]].",
+       "import-interwiki-sourcewiki": "Wiki d'origen:",
+       "import-interwiki-sourcepage": "Pàgina d'origen:",
        "import-interwiki-history": "Copia totes les versions de l'historial d'aquesta pàgina",
        "import-interwiki-templates": "Inclou totes les plantilles",
        "import-interwiki-submit": "Importa",
        "logentry-rights-rights": "$1 {{GENDER:$2|ha canviat}} la pertinença de grup per $3 de $4 a $5",
        "logentry-rights-rights-legacy": "$1 {{GENDER:$2|ha canviat}} la pertinença de grup per $3",
        "logentry-rights-autopromote": "$1 ha estat {{GENDER:$2|promogut}} automàticament de $4 a $5",
+       "logentry-upload-upload": "$1 {{GENDER:$2|ha carregat}} $3",
+       "logentry-upload-overwrite": "$1 {{GENDER:$2|ha carregat}} una nova versió de $3",
+       "logentry-upload-revert": "$1 {{GENDER:$2|ha carregat}} $3",
        "rightsnone": "(cap)",
+       "revdelete-summary": "el resum d'edició",
        "feedback-bugornote": "Si podeu descriure un problema tècnic en detall, [$1 informeu-ne].\nAltrament, podeu fer servir un senzill formulari a continuació. El vostre comentari s'afegirà a la pàgina «[$3 $2]», juntament amb el vostre nom d'usuari i el navegador que esteu emprant.",
        "feedback-subject": "Assumpte:",
        "feedback-message": "Missatge:",
index 992180e..cf52484 100644 (file)
        "category-file-count": "{{PLURAL:$2|ХӀокху категори чохь цхьа файл бе яц.|{{PLURAL:$1|Гойту $1 файл|Гойту $1 файлаш}} хӀокху категорешца кху $2.}}",
        "category-file-count-limited": "ХӀокху категори чохь {{PLURAL:$1|$1 файл|$1 файлаш|1=цхьаъ бен файл яц}}.",
        "listingcontinuesabbrev": "(кхин дlа)",
-       "index-category": "Меттигтерахьйо агlонаш",
+       "index-category": "Меттигтерахьйо агӀонаш",
        "noindex-category": "ДӀахьушйоцу агӀонаш",
        "broken-file-category": "{{#switch:{{NAMESPACE}}\n |{{ns:0}}=Болх цабеш файлийн хьажоргаш йолу агӀонаш}}",
        "about": "Цуьнах лаьцна",
        "viewtalkpage": "Хьажа дийцаре",
        "otherlanguages": "Кхечу маттахь дерш",
        "redirectedfrom": "(ДӀасахьажийна кху $1)",
-       "redirectpagesub": "Ð\90гÓ\80о-дÓ\80аÑ\81аÑ\85Ñ\8cажайаÑ\80",
+       "redirectpagesub": "Ð\90гÓ\80о-дÓ\80аÑ\81аÑ\85Ñ\8cажоÑ\80г",
        "redirectto": "ДӀасахьажор тӀе:",
        "lastmodifiedat": "ХӀокху агӀон тӀаьххьаралера хийцам: $2, $1.",
        "viewcount": "ХӀокху агӀонг хьовсийна $1 {{PLURAL:$1|за}}.",
        "passwordreset-emailsent-capture": "Электронан хаам баийтина кхоьссинчу паролах лаьцна хаам чохь болуш. \nцуна йозане хьажа йиш ю лахахь.",
        "passwordreset-emailerror-capture": "Пароль кхоссаран хаам чохь болуш электронан кехат кхоьллина, цуна йоза хьажа йиш ю лахахь, амма иза {{GENDER:$2|декъашхочунга}} дӀадахьийта тар цаделира бахьнехь: $1",
        "changeemail": "Хийца электронан почта",
-       "changeemail-header": "Электронан почтан адрес хийцар",
        "changeemail-text": "Юза хӀара форма хьайн электронан почтан адрес хуьйцуш. Ахьа хийцар бакъдан язъян еза пароль.",
        "changeemail-no-info": "ХӀара агӀо лело системин чугӀо.",
        "changeemail-oldemail": "Карара электронан почтан адрес:",
        "changeemail-none": "(яц)",
        "changeemail-password": "Хьан пароль «{{SITENAME}}» проектан:",
        "changeemail-submit": "Хийца email",
-       "changeemail-cancel": "Цаоьшу",
        "changeemail-throttled": "Хьо дукха гӀиртира.\nДехар до, собар де $1 юха гӀортале.",
        "resettokens": "Токенаш кхоссар",
        "resettokens-text": "Хьан йиш ю токенаш кхосса, цара йиш хуьлуьйту цхьаболу долара хаамашна тӀекхача, уьш ю хьан дӀаяздар ца вовшахтесна. \n\nХьона иза оьшу, ахьа хьай токенаш цхьам гучу яьхна елахь я хьан аккаунт йохийна елахь.",
        "searchresults-title": "Лаха «$1»",
        "titlematches": "АгӀонийн цӀераш цхьаьнанисялар",
        "textmatches": "АгӀонийн йоза цхьаьнанисдалар",
-       "notextmatches": "Агlонаш чура йозанашца цхьатера йогlуш яц",
+       "notextmatches": "АгӀонаш чура йозанашца цхьатера йогlуш яц",
        "prevn": "хьалхарнаш {{PLURAL:$1|$1}}",
        "nextn": "тӀаьхьйогӀурш {{PLURAL:$1|$1}}",
        "prevn-title": "{{PLURAL:$1|1=Хьалхара $1 дӀаяздар|Хьалхара $1 дӀаяздарш}}",
        "viewprevnext": "Хьажа ($1 {{int:pipe-separator}} $2) ($3)",
        "searchmenu-exists": "'''ХӀокху вики чохь йолуш ю ишта агӀо «[[:$1]]»'''",
        "searchmenu-new": "<strong>Кхолла «[[:$1]]» агӀо хӀокху вики-проектехь!</strong>\n{{PLURAL:$2|0=|Хьан лахарца карина.}}",
-       "searchprofile-articles": "Къаьстина агlонаш",
+       "searchprofile-articles": "Къаьстина агӀонаш",
        "searchprofile-images": "Мультимедиа",
        "searchprofile-everything": "Массанхьа",
        "searchprofile-advanced": "Шуьйра",
        "searchall": "массо",
        "showingresults": "Лахахьа {{PLURAL:$1|гойта|гойту|гойту}} <strong>$1</strong> {{PLURAL:$1|хилам|хиламаш|хиламаш}}, дlаболало кху № <strong>$2</strong>.",
        "showingresultsinrange": "Лахахь гайтина {{PLURAL:$1|<strong>1</strong> хилам}} диапазонехь <strong>$2</strong> тӀера <strong>$3</strong> кхаччалц.",
-       "showingresultsheader": "{{PLURAL:$5|1=Хилам '''$1''' кху '''$3'''|Хиламаш '''$1 — $2''' кху '''$3'''}} оцун '''$4'''",
+       "search-showingresults": "{{PLURAL:$4|Хилам <strong>$1</strong> <strong>$3</strong> нах}}",
        "search-nonefound": "Дехаре терра цхьа хӀума ца карийна.",
        "powersearch-legend": "Шуьро лахар",
        "powersearch-ns": "ЦӀерийн меттигашкахь лахар:",
        "right-createtalk": "Дийцаре агӀонаш кхоллар",
        "right-createaccount": "декъашхошна керла дӀаяздарш кхоллар",
        "right-minoredit": "«къезиг хийцам» аьлла билгало хӀоттор",
-       "right-move": "Ð\90гÓ\80онаÑ\88ан цӀераш хийцар",
+       "right-move": "Ð\90гÓ\80онийн цӀераш хийцар",
        "right-move-subpages": "АгӀонашан цӀераш хийцар цера бухара агӀонашцан",
        "right-move-rootuserpages": "декъашхочун ораман агӀонийн цӀераш хийцар",
        "right-move-categorypages": "Категорийн агӀонийн цӀераш хийцар",
        "right-movefile": "Файлийн цӀе хийцар",
-       "right-suppressredirect": "агÓ\80она Ñ\86Ó\80е Ñ\85Ñ\83Ñ\8cйÑ\86Ñ\83Ñ\88 Ñ\88иÑ\80Ñ\87Ñ\83 Ñ\86Ó\80аÑ\80аÑ\85 Ð¼Ð° ÐºÑ\85олла Ð´Ó\80аÑ\81аÑ\85Ñ\8cажаÑ\8fÑ\80",
+       "right-suppressredirect": "агÓ\80она Ñ\86Ó\80е Ñ\85Ñ\83Ñ\8cйÑ\86Ñ\83Ñ\88 Ñ\88иÑ\80Ñ\87Ñ\83 Ñ\86Ó\80аÑ\80аÑ\85 Ð¼Ð° ÐºÑ\85олла Ð´Ó\80аÑ\81аÑ\85Ñ\8cажоÑ\80г",
        "right-upload": "Файлаш чуйаьхар",
        "right-reupload": "йолуш йолу чера тӀехула файлаш дӀаязъяр",
        "right-reupload-own": "тохарлеррачу декъашхочо файлаш юху дӀаязъяр",
        "statistics-header-hooks": "Кхин статистика",
        "statistics-articles": "Яззамаш",
        "statistics-pages": "АгӀонаш",
-       "statistics-pages-desc": "Массо вики агlонаш, дийцаре агlонашцани, дlасахьаждарш а кхин дерш.",
+       "statistics-pages-desc": "Массо вики агӀонаш, дийцаре агӀонашцани, дӀасахьаждарш а кхин дерш.",
        "statistics-files": "Чуяьхна файлаш",
        "statistics-edits": "Нисдаран дукхалла {{grammar:genitive|{{SITENAME}}}} дlа йолайаларца",
        "statistics-edits-average": "АгӀонан нисдарийн юкъара дукхалла",
        "statistics-views-total": "Массо хьажарш",
        "statistics-views-total-desc": "Ма лара дӀаяьхна а белхан а агӀонашка хьажар",
        "statistics-views-peredit": "Нисдаре хьажарш",
-       "statistics-users": "[[Ð\92Ð\9f\94Ó\80аÑ\8fзвалар|ДӀаязбелларш]] берриге декъашхой чохь болу [[Special:ListUsers|(могӀам)]]",
+       "statistics-users": "[[Ð\92Ð\9f\94Ó\80аÑ\8fзбаллар|ДӀаязбелларш]] берриге декъашхой чохь болу [[Special:ListUsers|(могӀам)]]",
        "statistics-users-active": "Жигара декъашхой",
        "statistics-users-active-desc": "Декъашхой, муьлха цхьа хӀум дина болу, кху {{PLURAL:$1|1=тӀаьххьара $1 динахь|тӀаьххьара $1 дийнахь}}",
        "statistics-mostpopular": "Дукху хьоьжу агӀонаш",
        "allpagesfrom": "Гучé яха агӀонаш, йолалуш йолу оцу:",
        "allpagesto": "Арайахар сацадé оцу:",
        "allarticles": "Массо агӀонаш",
-       "allinnamespace": "Массо агlонаш оцу цlери анахь «$1»",
+       "allinnamespace": "Массо агӀонаш оцу цӀерийн анахь «$1»",
        "allpagessubmit": "Кхочушдé",
        "allpagesprefix": "Лаха агӀонаш, дӀайолалуш йолу:",
        "allpagesbadtitle": "Цамагош йолу агӀон цӀе. Коьрта могӀан юкъах ю юкъарвики меттанашан юкъе тӀечӀагӀйина йолу хьаьрк йа магийна доцу оцу коьрта моӀанца символаш йа кхин.",
        "allpages-bad-ns": "{{SITENAME}} кху чохь ана цӀераш яц «$1».",
        "allpages-hide-redirects": "Къайлаяха дӀасахьажийнарш",
+       "cachedspecial-viewing-cached-ttl": "Хьо хьоьжу агӀона верси кэш чура ю, иза карлаяьккхина хила мега $1 хьалха.",
        "cachedspecial-refresh-now": "Хьажа тӀехьарчу версега.",
        "categories": "Категореш",
        "categoriespagetext": "{{PLURAL:$1|1=Лахара категореш чохь ю|Лахара категореш чохь ю}} агӀонаш я медиа-файлаш.\nКхузахь гойтуш яц [[Special:UnusedCategories|лелош йоцу категореш]].\nКхин дӀа [[Special:WantedCategories| хийла еза категореш]].",
        "watchlist-details": "Хьан тергаме могӀанца $1 {{PLURAL:$1|агӀо}} ю, дийцаре агӀонаш йоцуш.",
        "wlheader-enotif": "Электронан почте хаамаш байтар латина ду.",
        "wlheader-showupdated": "Хийцам бина агӀонаш '''Ӏаьржа''' шрифтцан билгальяха ю.",
-       "wlnote": "Лахахьа {{PLURAL:$1|тlаьхьа богlу $1 хийцам|тlаьхьа богlу $1 хийцамаш|тlаьхьа богlу $1 хийцамаш}} хlокху {{PLURAL:$2|тlаьхьар|тlаьхьара|тlаьхьара}} <strong>$2</strong> {{PLURAL:$2|сохьт|сохьатехь|сохьташкахь}}.",
+       "wlnote": "Лахахьа {{PLURAL:$1|тӀаьхьабогӀу $1 хийцам|тӀаьхьабогӀу $1 хийцамаш}} хӀокху {{PLURAL:$2|тӀаьхьар}} <strong>$2</strong> {{PLURAL:$2|сахьтехь}}.",
        "wlshowlast": "Гайта тӀаьххьара $1 сахьт $2 де $3",
        "watchlist-options": "Тергаме могlаман гlирс нисбар",
        "watching": "Тергаме мlогаман юкъаяккха…",
        "deletecomment": "Бахьна:",
        "deleteotherreason": "Кхин бахьна/тӀетохар:",
        "deletereasonotherlist": "Кхин бахьна",
-       "deletereason-dropdown": "* Даржина долу дӀаяккхаран баьхьанаш \n** зулма  \n** авторан лаамца\n** авторан бакъонаш талхор",
+       "deletereason-dropdown": "* Даржина долу дӀаяккхаран баьхьанаш \n** спам\n** зулма  \n** авторан лаамца\n** авторан бакъонаш талхор\n** болх цабо дӀасхьажорг",
        "delete-edit-reasonlist": "Бахьанин могӀам нисбар",
        "deleting-backlinks-warning": "'''ДӀахьедар:''' Ахьа дӀайоккхуш йолчун тӀе товжийна [[Special:WhatLinksHere/{{FULLPAGENAME}}|кхин агӀонаш]] ю.",
        "rollback": "Юхабаккха хийцам",
        "protect-expiring": "чакхйолу $1 (UTC)",
        "protect-expiring-local": "чекхйолу $1",
        "protect-expiry-indefinite": "хан чаккхе йоцуш",
-       "protect-cascade": "Гlаролла йé агlонаш, хlокху агlонца хlоттайелларш (чахчарé гlаролла)",
+       "protect-cascade": "ГӀаролла йé агӀонаш, хӀокху агӀонца хӀоттайелларш (чахчарé гӀаролла)",
        "protect-cantedit": "Хьéга хийцам цабало хӀокху агӀон гlаролли локхалан, хӀуд аьлча хьан бакъо яц оцунна тадар дан.",
        "protect-othertime": "Кхин хан:",
        "protect-othertime-op": "кхин хан",
        "linkshere": "ТӀаьхьайогӀу агӀонаш оцу '''[[:$1]]''': хьажорагца ю",
        "nolinkshere": "ХӀокху '''[[:$1]]''' агӀона тӀе кхечу агӀонашкахь хьажоргаш яц.",
        "nolinkshere-ns": "Хаьржинчу анахь яц '''[[:$1]]''' цӀе йолу агӀонаш",
-       "isredirect": "агÓ\80о-дÓ\80аÑ\81аÑ\85Ñ\8cажайаÑ\80",
+       "isredirect": "агÓ\80о-дÓ\80аÑ\81аÑ\85Ñ\8cажоÑ\80г",
        "istemplate": "юкъаялийнарш",
        "isimage": "Файлан хьажораг",
        "whatlinkshere-prev": "{{PLURAL:$1|1=хьалхайодарг|хьалхайодарш}} $1",
        "movepagetext": "Бухахь йолу форманца агӀон цӀе хийцало. Цул совнах цуьна хийцаман тептар кхоьчу метте доккха. Хьалхалера цӀарахь хиръю керла кхоьллина агӀонан хьажораг.\n\nХьовсалаш [[Special:DoubleRedirects|шалха]] а [[Special:BrokenRedirects|йохна хьажоргаш]] юй техь аьлла.\n\nШу жоьпехь ду хьажоргаш нийса некъ гойтуш хиларан.\n\nТидам бе хьалхалера агӀон цӀе ‘’’хийцалур яц’’’ иштта цӀе йолу агӀо йолуш елахь. Юкъардаккхар: йолуш йолу агӀо кхоьчухьа хьажораг елахь, я еса елахь а, цуьна хийцаме истори яцахь а.\n\nИ бохург ду шун агӀонан цӀе юха а хьалха хилларгчунтӀе хийца йиш ю, амма йолуш йолу агӀо дӀаяккха йиш яц.\n\n'''ДӀАХЬЕДАР!'''\n\nЦӀе хийцар бахьнехь гӀаръяьлла агӀонашна дукха дагахь боцу хийцамаш хила тарло. Цундела цӀе хийцале шеш хила тарлучу тӀехьонашах кхета аьлла тешна хила.",
        "movepagetext-noredirectfixer": "Бухахь йолу форманца агӀон цӀе хийцало. Цул совнах цуьна хийцаман тептар кхоьчу метте доккха. Хьалхалера цӀарахь хиръю керла кхоьллина агӀонан хьажораг.\n\nХьовсалаш [[Special:DoubleRedirects|шалха]] а [[Special:BrokenRedirects|йохна хьажоргаш]] юй техь аьлла.\n\nШу жоьпехь ду хьажоргаш нийса некъ гойтуш хиларан.\n\nТидам бе хьалхалера агӀон цӀе ‘’’хийцалур яц’’’ иштта цӀе йолу агӀо йолуш елахь. Юкъардаккхар: йолуш йолу агӀо кхоьчухьа хьажораг елахь, я еса елахь а, цуьна хийцаме истори яцахь а.\n\nИ бохург ду шун агӀонан цӀе юха а хьалха хилларгчунтӀе хийца йиш ю, амма йолуш йолу агӀо дӀаяккха йиш яц.\n\n'''ДӀАХЬЕДАР!'''\n\nЦӀе хийцар бахьнехь гӀаръяьлла агӀонашна дукха дагахь боцу хийцамаш хила тарло. Цундела цӀе хийцале шеш хила тарлучу тӀехьонашах кхета аьлла тешна хила.",
        "movepagetalktext": "ТӀе хӀоьттина йолу дийцаре агӀо ишта цӀе хийцина хира ю, '''цхьа йолу ханчохь, маца:'''\n\n*Йаьсса йоцу дийцаре агӀо йолуш ю оцу цӀарца йа\n*Ахьа къастаман харжам цабиняхь а къастам хӀотточехь.\n\nИшта чу ханчохь, ахьа дехьа яккха йезар ю йа куьйга хӀоттайар, нагахь иза хьашт йалахь.",
-       "movearticle": "Цle хийца хlокху агlон",
+       "movearticle": "ЦӀе хийца хӀокху агӀон",
        "moveuserpage-warning": "'''Тергам бе.''' Хьо декъашхочун агӀона цӀе хийца гӀерта. Дехар до, тергам бе, декъашхочун агӀона цӀе бен хийца лур яц, декъашхочун дӀаяздаран цӀе хийца лур яц.",
        "movecategorypage-warning": "<strong>ДӀахьедар:</strong> Хьо категорин агӀон цӀе хийца гӀерта. Дехар до, терго йе, хӀокху агӀона бен цӀе хуьйцур яц, шира чу категори чура массо агӀонаш керла категори чу йохур <em>яц</em>.",
        "movenologintext": "АгӀона цӀе хийца [[Special:UserLogin|системин чугӀо]].",
        "movepage-moved-noredirect": "ДӀасхьажорг кхоллар дохина.",
        "articleexists": "ХӀарасанна цӀе йолу агӀо йолуш ю йа ахьа гойтуш йолу цӀе магош яц.\nДехар до, харжа кхин цӀе.",
        "movetalk": "Цуьнца йогӀуш йолу дийцаре агӀон цӀе хийцар",
-       "move-subpages": "ЦӀeрш хийцае бухара агӀонаши ($1 кхаччалц)",
+       "move-subpages": "ЦӀераш хийца бухара агӀонийн ($1 кхаччалц)",
        "move-talk-subpages": "ЦӀе хийца бухара агӀонаши а агӀонашан дийцаре а ($1  кхаччалц)",
        "movepage-page-exists": "Агӏо $1 йолуш ю цундела и ша юху дӏаязъян йиш яц.",
        "movepage-page-moved": "АгӀона $1 цӀе хийцина → $2.",
        "tooltip-ca-unwatch": "ДӀаяккха хӀара агӀо хьай тергаме могӀанан юкъар",
        "tooltip-search": "Лаха иза дош",
        "tooltip-search-go": "Билгала и санна цӀе йолучу агӀон чу дехьа гӀо",
-       "tooltip-search-fulltext": "Лаха агlонаш ше чулацамехь хlара йоза долуш",
+       "tooltip-search-fulltext": "Лаха агӀонаш ше чулацамехь хӀара йоза долуш",
        "tooltip-p-logo": "Коьрта агӀона дехьа гӀо",
        "tooltip-n-mainpage": "Коьрта агӀона дехьа гӀо",
        "tooltip-n-mainpage-description": "Коьрта агӀона дехьа гӀо",
        "fileduplicatesearch-info": "$1 × $2 пиксель<br />Файлан барам: $3<br />MIME-тайп: $4",
        "fileduplicatesearch-result-1": "«$1» файлах тера хӀума яц.",
        "fileduplicatesearch-noresults": "ЦӀе «$1» йолуш файл цакарий.",
-       "specialpages": "Леррина агlонаш",
+       "specialpages": "Леррина агӀонаш",
        "specialpages-note": "* Гуттарлера белха агlонаш.\n* <strong class=\"mw-specialpagerestricted\">Кlеззиг таронаш йолу леррина агlонаш.</strong>",
        "specialpages-group-maintenance": "Жамlаш гlирса хьашташ кхочушдар",
        "specialpages-group-other": "Кхин белхан агӀонаш",
        "logentry-upload-overwrite": "$1 {{GENDER:$2|чуяьккхина}} керла верси $3",
        "logentry-upload-revert": "$1 {{GENDER:$2|чуяьккхина}} $3",
        "rightsnone": "(яц)",
+       "revdelete-summary": "хийцамах лаьцна",
        "feedback-bugornote": "Хьайн техникин халонах лаьцна яздан хӀума делахь, дехар до, [$1 хаам бе тхоьга].\nДацахь хьан йиш ю хӀокху атта кепаца «[$3 $2]» агӀонг къамел тӀетоха хьан декъашхочун цӀарца, кхин лелош йолу браузер билгал еш.",
        "feedback-subject": "Къамел:",
        "feedback-message": "Хаам:",
index 7793b97..1817a9e 100644 (file)
        "category-empty": "''ئەم پۆلە ھەنووکە ھیچ پەڕە یان پەڕگەیەک لە خۆ ناگرێت.‌''",
        "hidden-categories": "{{PLURAL:$1|پۆلی شارداوە|پۆلە شارداوەکان}}",
        "hidden-category-category": "پۆلە شاردراوەکان",
-       "category-subcat-count": "{{PLURAL:$2|ئەم پۆلە تەنیا ژێرپۆلی ژێرەوەی تێدایە.| ئەم پۆلە ئەم {{PLURAL:$1|ژێرپۆلەی|$1 ژێرپۆلانەی}} ژێرەوەی تێدایە، لە کۆی سەرجەم $2 دانە.}}",
+       "category-subcat-count": "{{PLURAL:$2|ئەم پۆلە تەنیا ژێرپۆلی ژێرەوەی تێدایە.|ئەم پۆلە {{PLURAL:$1|ژێرپۆل|$1 ژێرپۆل}}ی ژێرەوەی تێدایە، لە سەرجەم $2 ژێرپۆل.}}",
        "category-subcat-count-limited": "ئەم هاوپۆلە {{PLURAL:$1|ژێرهاوپۆلی}} لەخۆ گرتووە.",
-       "category-article-count": "{{PLURAL:$2|ئەم پۆلە تەنھا ئەم پەڕەی لەخۆگرتووە.|{{PLURAL:$1|پەڕە|$1 پەڕە}} لەم پۆلەدا، لە سەرجەم $2 پەڕە.}}",
+       "category-article-count": "{{PLURAL:$2|ئەم پۆلە تەنیا پەڕەی ژێرەوەی تێدایە.|{{PLURAL:$1|پەڕە|$1 پەڕە}}ی ژێرەوە لەم پۆلەدا{{PLURAL:$1|یە|ن}}، لە سەرجەم $2 پەڕە.}}",
        "category-article-count-limited": "ئەم {{PLURAL:$1|لاپەڕە|$1 لاپەڕانە}}، لەم هاوپۆلەدان.",
        "category-file-count": "{{PLURAL:$2|ئەم هاوپۆلە تەنها ئەم پەڕگەی لەخۆ گرتووە.|ئەم‌ {{PLURAL:$1|پەڕگەیە}} کە بەشێکە لە هەموو $2پەڕگەی ئەم هاوپۆلە‌ دەیبینی.}}",
        "category-file-count-limited": "ئەم {{PLURAL:$1|پەڕگە|پەڕگانە}} لەم هاوپۆلەدایە.",
        "hidetoc": "بیشارەوە",
        "collapsible-collapse": "کۆی بکەوە",
        "collapsible-expand": "بڵاوی بکەوە",
+       "confirmable-yes": "بەڵێ",
+       "confirmable-no": "نا",
        "thisisdeleted": "$1 نیشان بدە یا بھێنەوە؟",
        "viewdeleted": "$1 نیشان بده‌؟",
        "restorelink": "{{PLURAL:$1|یەک گۆڕانکاریی سڕاو|$1 گۆڕانکاریی سڕاو}}",
        "resetpass-submit-cancel": "ھەڵوەشاندنەوە",
        "resetpass-wrong-oldpass": "تێپەڕوشەی ھەنووکەیی یان تێپەڕوشەی کاتی ھەڵەیە.\nوا دیارە تێپەڕوشەکەت بە سەرکەوتوویی گۆڕدراوە یان داوای تێپەڕوشەیەکی نوێت کردووە.",
        "resetpass-temp-password": "تێپەڕوشەی کاتی:",
-       "passwordreset": "دووبارە ڕێکخستنەوەی تێپەڕوشە",
+       "passwordreset": "ڕێکخستنەوەی تێپەڕوشە",
        "passwordreset-legend": "دووبارە ڕێکخستنەوەی تێپەڕوشە",
        "passwordreset-username": "ناوی بەکارھێنەری:",
        "passwordreset-domain": "پاوان:",
        "passwordreset-emailsent": "ئیمەیلێکی ڕیسێتکردنەوەی تێپەڕوشە نێردرا.",
        "passwordreset-emailsent-capture": "ئیمەیلێکی ڕیسێتکردنەوەی تێپەڕوشە نێردرا، کە لە ژێرەوە نیشان دراوە.",
        "passwordreset-emailerror-capture": "ئیمەیلێکی ڕیسێتکردنەوەی تێپەڕوشە نێردرا، کە لە ژێرەوە نیشان دراوە، بەڵام ناردنەکەی بۆ {{GENDER:$2|بەکارھێنەر}} سەرکەوتوو نەبوو: $1",
-       "changeemail": "ناونیشانی ئیمەیل بگۆڕە",
-       "changeemail-header": "ناونیشانی ئیمەیلی ھەژمار بگۆڕە",
+       "changeemail": "گۆڕینی ناونیشانی ئیمەیل",
        "changeemail-no-info": "بۆ گەیشتنی راستەوخۆ بەم پەڕە دەبێت بچیتە ژوورەوە.",
        "changeemail-oldemail": "ئەدرەسی ئیمەیڵی ئێستا:",
        "changeemail-newemail": "ناونیشانی ئیمەیلی نوێ:",
        "changeemail-none": "(ھیچ)",
        "changeemail-password": "تێپەڕوشەکەت لە {{SITENAME}}:",
        "changeemail-submit": "ئەمەیل بگۆڕە",
-       "changeemail-cancel": "ھەڵیوەشێنەوە",
        "bold_sample": "دەقی ئەستوور",
        "bold_tip": "دەقی ئەستوور",
        "italic_sample": "دەقی لار",
        "searchrelated": "پەیوەست",
        "searchall": "ھەموو",
        "showingresults": "لە خوارەوە {{PLURAL:$1|'''یەک''' ئەنجام|'''$1''' ئەنجام}} نیشان دراوە، بە دەست پێ کردن لە ژمارەی '''$2'''ەوە.",
-       "showingresultsheader": "{{PLURAL:$5|ئاکامی '''$1''' لە '''$3'''|ئاکامەکانی '''$1 - $2''' لە '''$3'''}} بۆ '''$4'''",
        "search-nonefound": "ھیچ ئاکامێک کە بە داواکارییەکەت بخوا نەدۆزرایەوە.",
        "powersearch-legend": "گەڕانی پێشکەوتوو",
        "powersearch-ns": "گەڕان لە بۆشاییی ناوەکانی:",
        "mimesearch-summary": "ئەم لاپەڕە پاڵێوتنی هەیە بۆ جۆرەکانی MIME.\nناودراو: جۆرەی ناوەڕۆک\\ژێرجۆرە، وەک <code>image/jpeg</code>.",
        "mimetype": "جۆرەی MIME:",
        "download": "داگرتن",
-       "unwatchedpages": "پەڕە چاودێرینەکراوەکان",
+       "unwatchedpages": "پەڕە چاودێری نەکراوەکان",
        "listredirects": "پێرستی ڕەوانەکەرەکان",
-       "unusedtemplates": "داڕێژە بەکارنەھێنراوەکان",
+       "unusedtemplates": "داڕێژە بەکارنەھاتووەکان",
        "unusedtemplatestext": "ئەم پەڕە هەموو پەڕەکانی بۆشاییی ناوی {{ns:template}} بە لیست دەکات کە لە پەڕەی تردا بەکارنەھێنراون.\nلە بیری نەکەی پێش سڕینەوەیان پشکنینی بەستەرەکانی تر بۆ داڕێژەکان بکەی.",
        "unusedtemplateswlh": "بەستەرەکانی تر",
-       "randompage": "پەڕەیەک بە هەڵکەوت",
+       "randompage": "پەڕەی ھەڕەمەکی",
        "randompage-nopages": "هیچ لاپەڕەیەک لەم {{PLURAL:$2|ناوبۆشاییەدا|ناوبۆشاییانەدا}} نیە: $1.",
-       "randomredirect": "ڕەوانەکەری ھەرمەکی",
+       "randomincategory": "پەڕەی پۆلی ھەڕەمەکی",
+       "randomredirect": "ڕەوانەکەری ھەڕەمەکی",
        "randomredirect-nopages": "لە ناوبۆشایی \"$1\" هیچ ڕەوانکەرێک نییە.",
        "statistics": "ئامارەکان",
        "statistics-header-pages": "ئامارەکانی پەڕەکان",
        "pageswithprop-text": "ئەم پەڕەیە ئەو پەڕانەی تایبەتمەندییەکی پەرەیەکی دیاریکراو بەکاردەھێنن پێرست دەکا.",
        "pageswithprop-prop": "ناوی تایبەتمەندی:",
        "pageswithprop-submit": "بڕۆ",
-       "doubleredirects": "دووجار ڕەوانەکراوەکان",
+       "doubleredirects": "ڕەوانەکەرە دووسەرەکان",
        "doubleredirectstext": "ئەم پەڕە لیستی ئەو پەڕانەیە کە ڕەوانەکراون بۆ پەڕەیەکی ڕەوانەکراوی دیکە.\nهەر ڕیزێک، بەستەرەکانی ڕەوانەکردنەوەی یەکەم و دووەم و ھەروەھا ئامانجی ڕەوانەکراوی دووەمی تێدایە کە حاڵەتی ئاساییدا مەبەستی «ڕاستی»ی ڕەوانەکراوی یەکەمیش دەبێ بۆ ئەوێ بێت.\nئەوانەی <del>هێڵیان بەسەردا کێشراوە</del> چارەسەر کراون.",
        "double-redirect-fixed-move": "[[$1]] گوازرایەوە.\nخۆگەڕ نوێ کرایەوە و ئێستا ڕەوانەکەرە بۆ [[$2]].",
        "double-redirect-fixer": "چارەسەرکەری ڕەوانکەر",
        "withoutinterwiki-summary": "ئەم پەڕانە بەستەریان بۆ وەشانەکانی زمانەکانی تر نیە.",
        "withoutinterwiki-legend": "پێشگر",
        "withoutinterwiki-submit": "پیشاندان",
-       "fewestrevisions": "پەڕەکان بە کەمترین پێداچوونەوەکان",
+       "fewestrevisions": "پەڕەکان بە کەمترین پێداچوونەوە",
        "nbytes": "$1 {{PLURAL:$1|بایت|بایت}}",
        "ncategories": "$1 {{PLURAL:$1|ھاوپۆل|ھاوپۆل}}",
        "ninterwikis": "$1 {{PLURAL:$1|نێوانویکی}}",
        "uncategorizedimages": "پەڕگە پۆلێن نەکراوەکان",
        "uncategorizedtemplates": "داڕێژە پۆلێن نەکراوەکان",
        "unusedcategories": "پۆلە بەکارنەھێنراوەکان",
-       "unusedimages": "پەڕگە بەکارنەھێنراوەکان",
+       "unusedimages": "پەڕگە بەکارنەھاتووەکان",
        "popularpages": "پەڕە مەحبووبەکان",
        "wantedcategories": "پۆلە داواکراوەکان",
        "wantedpages": "پەڕە داواکراوەکان",
        "protectedpages-page": "پەڕە",
        "protectedpages-params": "پارامەترەکانی پاراستن",
        "protectedpages-reason": "ھۆکار",
-       "protectedtitles": "سەرناوە پارێزراوەکان",
+       "protectedtitles": "سەردێڕە پارێزراوەکان",
        "protectedtitlesempty": "ھیچ سەرناوێک بەم سنوورانەوە ئێستا نەپارێزراوە.",
        "listusers": "پێرستی بەکارھێنەران",
        "listusers-editsonly": "تەنیا ئەو بەکارھێنەرانە نیشان بدە کە دەستکارییان کردووە",
        "listusers-submit": "نیشانیبدە",
        "listusers-noresult": "ھیچ بەکارھێنەرێک نەدۆزرایەوە.",
        "listusers-blocked": "(بەربەست کراوە)",
-       "activeusers": "پێرستی بەکارھێنەرە چالاکەکان",
+       "activeusers": "پێرستی بەکارھێنەرانی چالاک",
        "activeusers-intro": "ئەمە لیستێکی ئەو بەکارھێنەرانەیە کە لە  $1 {{PLURAL:$1|ڕۆژ|ڕۆژ}}ی ڕابردوودا بە جۆرێک چالاکییەکیان ھەبووە.",
        "activeusers-count": "$1 {{PLURAL:$1|کردەوە}} لە دوایین {{PLURAL:$3|ڕۆژ|$3 ڕۆژ}}دا",
        "activeusers-from": "نیشاندانی بەکارھێنەران بە دەستپێکردن لە:",
        "listgrouprights-namespaceprotection-header": "سنوورداریی بۆشایی ناو",
        "listgrouprights-namespaceprotection-namespace": "بۆشایی ناو",
        "listgrouprights-namespaceprotection-restrictedto": "مافی رێ‌پێدراوی بەکارھێنەر بۆ دەستکاری",
+       "trackingcategories": "پۆلەکانی شوێنکەوتن",
        "trackingcategories-name": "ناوی پەیام",
        "mailnologin": "ناونیشان بۆ ناردن نییه‌",
        "mailnologintext": "ده‌بێ له‌ [[Special:UserLogin|ژووره‌وه‌]] بیت و ناونیشانێکی بڕواپێ‌کراوی ئی‌مه‌یلت له‌ ناو [[Special:Preferences|هه‌ڵبژارده‌کان]] دیاری کردبێت تا بتوانی ئی‌مه‌یل بنێریت بۆ به‌کارهێنه‌رانی دیکه‌.",
        "whatlinkshere-hidelinks": "$1 بەستەر",
        "whatlinkshere-hideimages": "$1 بەستەرەکانی پەڕگە",
        "whatlinkshere-filters": "پاڵێوکەکان",
-       "block": "بەربەستکردنی بەکارھێنەر",
+       "block": "بەربەستنی بەکارھێنەر",
        "unblock": "لە بەربەست‌دەرهێنانی بەکارهێنەر",
        "blockip": "بەربەستنی بەکارھێنەر",
        "blockip-legend": "بەربەست‌کردنی بەکارهێنەر",
        "ipusubmit": "لابردنی ئەم بەربەستە",
        "unblocked": "[[User:$1|$1]] لە بەربەست دەرهێنرا",
        "unblocked-id": "بەربەستی $1 لابرا",
-       "blocklist": "بەکارھێنەر بەربەستکراوەکان",
+       "blocklist": "بەکارھێنەرانی بەربەسراو",
        "ipblocklist": "بەکارھێنەرە بەربەستکراوەکان",
        "ipblocklist-legend": "دۆزینەوەی بەکارهێنەرێکی بەربەست‌کراو",
        "blocklist-userblocks": "ھەژمارە بەربەستکراوەکان بشارەوە",
        "move-page": "$1 بگوازەوە",
        "move-page-legend": "گواستنەوەی پەڕە",
        "movepagetext": "بەکارھێنانی ئەم فۆرمەی خوارەوە ناوی پەڕەیەک دەگۆڕێت، بە گواستنەوەی ھەموو مێژووەکەی بۆ ناوی نوێ.\nناوە کۆنەکە دەبێتە پەڕەیەکی ئاڕاستەکردنەوە بۆ ناوە نوێکە.\nدەتوانی ئاڕاستەکان بۆ پەڕەی سەرەکی بەشێوەی خۆکار نوێ بکەیتەوە.\nدڵنیا بە کە [[Special:DoubleRedirects|دووجار ڕەوانەکراوەکان]] یان [[Special:BrokenRedirects|ڕەوانەکراوە شکاوەکان]] تاقی بکەیتەوە.\nتۆ بەرپرسیاری لەوەی کە دڵنیا ببیتەوە بەستەرەکان ھەر پێوەندییان ھەیە بەو شوێنە کە چاوەڕوان دەکرێت.\n\nدەبێت بزانی کە پەڕەکە '''ناگوازرێتەوە''' ئەگەر پێشتر پەڕەیەک بە ناوە نوێکەوە ھەبێت، مەگەر ئەوەی کە پەڕەکە واڵا یان ڕەوانەکراوەیەک بێت و ھیچ مێژووی گۆڕاندنی پێشووی نەبێت.\nئەمە بەو واتایە کە ئەگەر ھەڵەیەک بکەی دەتوانی ناوی پەڕەکە دیسانەوە بگۆڕی بۆ ناوی پێشووی، و ناتوانی بیخەیتە جێگەی پەڕەیەک کە ھەنووکە ھەیە.\n\n'''ھۆشیار بە!'''\nئەمە دەتوانێت گۆڕانێکی زۆر نابەجێ و چاوەڕێنەکراو بێت بۆ پەڕەیەکی بەناوبانگ؛\nتکایە پێش گۆڕینی ناو باش بیر لە ئاکامەکەی بکەوە.",
-       "movepagetext-noredirectfixer": "بەکارھێنانی ئەم فۆرمەی خوارەوە ناوی پەڕەیەک دەگۆڕێت، بە گواستنەوەی ھەموو مێژووەکەی بۆ ناوی نوێ.\nناوە کۆنەکە دەبێتە پەڕەیەکی ڕەوانەکردنەوە بۆ ناوە نوێکە.\nدڵنیا بە کە [[Special:DoubleRedirects|دووجار ڕەوانەکراوەکان]] یان [[Special:BrokenRedirects|ڕەوانەکراوە شکاوەکان]] تاقی بکەیتەوە.\nتۆ بەرپرسیاری لەوەی کە دڵنیا ببیتەوە بەستەرەکان ھەر پێوەندییان ھەیە بەو شوێنە کە چاوەڕوان دەکرێت.\n\nدەبێت بزانی کە پەڕەکە '''ناگوازرێتەوە''' ئەگەر پێشتر پەڕەیەک بە ناوە نوێکەوە ھەبێت، مەگەر ئەوەی کە پەڕەکە واڵا یان ڕەوانەکراوەیەک بێت و ھیچ مێژووی گۆڕاندنی پێشووی نەبێت.\nئەمە بەو واتایە کە ئەگەر ھەڵەیەک بکەی دەتوانی ناوی پەڕەکە دیسانەوە بگۆڕی بۆ ناوی پێشووی، و ناتوانی بیخەیتە جێگەی پەڕەیەک کە ھەنووکە ھەیە.\n\n'''ھۆشیار بە!'''\nئەمە دەتوانێت گۆڕانێکی زۆر نابەجێ و چاوەڕێنەکراو بێت بۆ پەڕەیەکی بەناوبانگ؛\nتکایە پێش گۆڕینی ناو باش بیر لە ئاکامەکەی بکەوە.",
-       "movepagetalktext": "Ù¾Û\95Ú\95Û\95Û\8c Ù\88تÙ\88Ù\88Û\8eÚ\98Û\8c Ù¾Û\95Û\8cÙ\88Û\95Ù\86دÛ\8cدارÛ\8c Ø¨Û\95 Ø´Û\8eÙ\88Û\95Û\8c Ø®Û\86کار Ù\84Û\95Ú¯Û\95ÚµÛ\8cدا Ø¯Û\95Ú¯Ù\88ازرÛ\8eتÛ\95Ù\88Û\95Ø\8c '''Ù\85Û\95Ú¯Û\95ر:'''\n* Ù¾Û\95Ú\95Û\95Û\8cÛ\95Ú©Û\8c Ù\88تÙ\88Ù\88Û\8eÚ\98Û\8c Ù\86اÙ\88اڵا Ù¾Û\8eشتر Ú¾Û\95بÛ\8eت Ù\84Û\95 Ú\98Û\8eر Ù\86اÙ\88Û\95 Ù\86Ù\88Û\8eÚ©Û\95داØ\8c Û\8cاÙ\86\n* Ø¦Û\95Ù\88 Ú\86Ù\88ارÚ\86Û\8eÙ\88Û\95Û\8c Ø®Ù\88ارÛ\95Ù\88Û\95 Ù\84Û\8eÙ\86Û\95دراÙ\88 Ø¨Ú©Û\95Û\8c.\n\nÙ\84Û\95Ù\88 Ø­Ø§ÚµÛ\95تÛ\95داØ\8c Ø¦Û\95Ú¯Û\95ر Ø¨ØªÛ\95Ù\88Û\8eت Ø¨Û\8cÚ¯Ù\88ازÛ\8cتÛ\95Ù\88Û\95 Ù\86اÚ\86ار Ø¯Û\95بÛ\8cت Ø¨Û\95 Ø´Û\8eÙ\88Û\95Û\8c Ø¯Û\95ستÛ\8c Ø¨Û\8cÚ¯Ù\88ازÛ\8cتÛ\95Ù\88Û\95 Û\8cاÙ\86 ØªÛ\8eÚ©Û\95ÚµÛ\8cاÙ\86 Ø¨Ú©Û\95Û\8c.",
+       "movepagetext-noredirectfixer": "بەکارھێنانی فۆرمەکەی ژێرەوە ناوی پەڕەیەک دەگۆڕێت، بە گواستنەوەی ھەموو مێژووەکەی بۆ ناوی نوێ.\nناوە کۆنەکە دەبێتە پەڕەیەکی ڕەوانەکەر بۆ ناوە نوێکە.\nلە بیرت بێ ڕەوانەکەرە [[Special:DoubleRedirects|دووسەرەکان]] یان [[Special:BrokenRedirects|شکاوەکان]] تاوتوێ بکەیت.\nتۆ بەرپرسی بۆ ئەوەی دڵنیا ببیتەوە بەستەرەکان ھەر پەیوەندییان ھەیە بەو شوێنەوە کە چاوەڕوان دەکرێت.\n\nئەمە بزانە کە پەڕەکە <strong>ناگوازرێتەوە</strong> ئەگەر پێشتر پەڕەیەک بە ناوە نوێکەوە ھەبێت، مەگەر ئەوەی کە ڕەوانەکەرێک بێت و مێژووی دەستکاریی پێشووی نەبێت.\nئەمە یانی ئەگەر ھەڵەیەک بکەیت دەتوانی ناوی پەڕەکە بگۆڕییەوە بۆ ناوی پێشووی، و ناتوانی بیخەیتە جێگەی پەڕەیەک کە ئێستا ھەیە.\n\n<strong>ھۆشدار!</strong>\nئەمە دەتوانێت گۆڕانێکی زۆر نابەجێ و چاوەڕوان‌نەکراو بێت بۆ پەڕەیەکی بەناوبانگ؛\nتکایە پێش گۆڕینی ناو دڵنیا بە بیرت لە ئاکامەکەی کردووەتەوە.",
+       "movepagetalktext": "Ù¾Û\95Ú\95Û\95Û\8c Ù\84Û\8eدÙ\88اÙ\86Û\8c Ù¾Û\95Û\8cÙ\88Û\95Ù\86دÛ\8cدار Ø¨Û\95 Ø´Û\8eÙ\88Û\95Û\8c Ø®Û\86Ú¯Û\95Ú\95 Ù\84Û\95Ú¯Û\95ÚµÛ\8c Ø¯Û\95Ú¯Ù\88ازرÛ\8eتÛ\95Ù\88Û\95Ø\8c <strong>Ù\85Û\95Ú¯Û\95ر:</strong>\n* Ù¾Û\95Ú\95Û\95Û\8cÛ\95Ú©Û\8c Ù\84Û\8eدÙ\88اÙ\86Û\8c Ù\86اÙ\88اڵا Ù¾Û\8eشتر Ù\84Û\95 Ú\98Û\8eر Ù\86اÙ\88Û\95 Ù\86Ù\88Û\8eÚ©Û\95دا Ú¾Û\95بÛ\8eتØ\8c Û\8cاÙ\86\n* Ø¦Û\95Ù\88 Ú\86Ù\88ارÚ\86Û\8eÙ\88Û\95Û\8c Ú\98Û\8eرÛ\95Ù\88Û\95 Ù\84Û\8eÙ\86Û\95دراÙ\88 Ø¨Ú©Û\95Û\8cت.\n\nÙ\84Û\95Ù\88 Ø¯Û\86خاÙ\86Û\95داØ\8c Ø¦Û\95Ú¯Û\95ر Ø¨ØªÛ\95Ù\88Û\8eت Ø¯Û\95بÛ\8e Ø¨Û\95 Ø¯Û\95ستÛ\8c Ù¾Û\95Ú\95Û\95Ú©Û\95 Ø¨Ú¯Ù\88ازÛ\8cتÛ\95Ù\88Û\95 Û\8cاÙ\86 ØªÛ\8eÚ©Û\95ÚµÛ\8cاÙ\86 Ø¨Ú©Û\95Û\8cت.",
        "movearticle": "ئەم پەڕەیە بگوازەوە:",
+       "moveuserpage-warning": "<strong>ھۆشدار:</strong> تۆ خەریکی گواستنەوەی پەڕەیەکی بەکارھێنەری. تکایە ئەمە لەبەرچاو بگرە تەنیا پەڕەکە دەگوازرێتەوە و ناوی بەکارھێنەر <em>ناگۆڕدرێ</em>.",
        "movecategorypage-warning": "<strong>ھۆشدار:</strong> تۆ خەریکی گواستنەوەی پەڕەی پۆلی. تکایە ئەمە لەبەرچاو بگرە تەنیا پەڕەکە دەگوازرێتەوە و پەڕەکانی ناو پۆلە کۆنەکە <em>ناچێتە</em> ناو پۆلە نوێکەوە.",
        "movenologintext": "بۆ گواستنەوەی پەڕەیەک، ئەشێ ببی بە ئەندام و [[Special:UserLogin|لە ژوورەوە]] بیت.",
        "movenotallowed": "ڕێگەت پێ‌نەدراوە بۆ گواستنەوەی لاپەڕەکان.",
        "version-software-product": "بەرهەم",
        "version-software-version": "وەشان",
        "version-entrypoints-header-url": "ناونیشانی ئینتەرنێتی",
+       "redirect": "ڕەوانەکەر بە پێی پەڕگە، بەکارھێنەر، پەڕە یان پێناسەی پێداچوونەوە",
+       "redirect-legend": "ڕەوانەکەر بۆ پەڕگە یان پەڕەیەک",
+       "redirect-summary": "ئەم پەڕە تایبەتە ڕەوانە دەکرێ بۆ پەڕگەیەک (ناوی پەڕگەکە)، پەڕەیەک (پێناسەی پێداچوونەوەیەک یان پێناسەی پەڕە) یان پەڕەیەکی بەکارھێنەر (پێناسەیەکی  ژمارەیی بەکارھێنەر). بەکارھێنان: [[{{#Special:Redirect}}/file/Example.jpg]]، [[{{#Special:Redirect}}/page/64308]]، [[{{#Special:Redirect}}/revision/328429]] یان [[{{#Special:Redirect}}/user/101]].",
        "redirect-submit": "بڕۆ",
+       "redirect-lookup": "گەڕان لە:",
+       "redirect-value": "نرخ:",
+       "redirect-user": "پێناسەی بەکارھێنەر",
+       "redirect-page": "پێناسەی پەڕە",
+       "redirect-revision": "پێداچوونەوەی پەڕە",
+       "redirect-file": "ناوی پەڕگە",
        "fileduplicatesearch": "گەڕان بۆ پەڕگە دووپات کراوەکان",
        "fileduplicatesearch-summary": "گەڕان بۆ پەڕگە دووبارەکراوەکان لەسەر بنەمای نرخی hash.",
        "fileduplicatesearch-legend": "گەڕان بۆ دووبارەکردنێک",
        "fileduplicatesearch-noresults": "پەڕگەیەک بە ناوی «$1» نەدۆزرایەوە.",
        "specialpages": "پەڕە تایبەتەکان",
        "specialpages-note": "* پەڕە تایبەتە ئاسایییەکان.\n* <span class=\"mw-specialpagerestricted\">پەڕە تایبەتە بەرگری‌لێکراوەکان.</span>",
-       "specialpages-group-maintenance": "Ú\95اپÛ\86رتÛ\95کاÙ\86Û\8c Ú\86اکسازÛ\8c",
+       "specialpages-group-maintenance": "Ú\95اپÛ\86رتÛ\95کاÙ\86Û\8c Ú\95اگرتÙ\86",
        "specialpages-group-other": "پەڕە تایبەتەکانی دیکە",
        "specialpages-group-login": "چوونەژوورەوە / دروستکردنی ھەژمار",
        "specialpages-group-changes": "دوایین گۆڕانکارییەکان و لۆگەکان",
        "specialpages-group-pages": "پێرستەکانی پەڕەکان",
        "specialpages-group-pagetools": "ئامرازەکانی پەڕە",
        "specialpages-group-wiki": "دراوەکان و ئامرازەکان",
-       "specialpages-group-redirects": "پەڕە تایبەتەکانی رەوانکردنەوە",
+       "specialpages-group-redirects": "پەڕە تایبەتەکانی ڕەوانەکردن",
        "specialpages-group-spam": "ئامرازەکانی سپەم",
        "blankpage": "پەڕەی واڵا",
        "intentionallyblankpage": "ئەم پەڕەیە لەقەست واڵا ھێڵراوەتەوە.",
        "external_image_whitelist": " #ئەم دێڕ ھەر بەم جۆرە کە ھەیە بەجێبێڵە<pre>\n#کەرتەکانی regular expression (تەنیا ئە بەشە کە لە نێوان // دا دێت) لە خوارەوە دابنێ\n#These will be matched with the URLs of external (hotlinked) images\n#Those that match will be displayed as images, otherwise only a link to the image will be shown\n#ئەو دێڕانە بە # دەست پێدەکەن وەک شرۆڤە (comments) مامەڵەیان لەگەڵ دەکرێ\n#بە گەورە و بچووکی پیتەکان ھەستیارە (case-insensitive)\n\n#گشت کەرتەکانی regex لە سەرەوەی ئەم دێرەدا دابنێ. ئەم دێڕ ھەر بەم جۆرە کە ھەیە بەجێبێڵە</pre>",
-       "tags": "گۆڕانکاری گونجاوی تاگەکان",
+       "tags": "تاگەکانی گۆڕانکاریی گونجاو",
        "tag-filter": "پاڵێوی [[Special:Tags|تاگ]]:",
        "tag-filter-submit": "پاڵاوتن",
+       "tag-list-wrapper": "([[Special:Tags|{{PLURAL:$1|تاگ|تاگەکان}}]]: $2)",
        "tags-title": "تاگەکان",
        "tags-intro": "ئەم لاپەڕە ئەو تاگانەی لیست دەکات کە لەوانەیە نەرمامێر دەستکاریەکی بۆ نیشان بکات و مەبەستی نیشان بدات.",
        "tags-tag": "ناوی تاگ",
        "logentry-newusers-autocreate": "ھەژماری بەکارھێنەریی $1 بە شێوەی خۆگەڕ {{GENDER:$2|دروست کرا}}",
        "logentry-rights-rights": "$1 ئەندامێتیی $3ی لە $4 بۆ $5 {{GENDER:$2|گۆڕی}}",
        "logentry-upload-upload": "$1 $3ی {{GENDER:$2|بار کرد}}",
+       "logentry-upload-overwrite": "$1 وەشانێکی نوێی $3ی {{GENDER:$2|بار کرد}}",
        "rightsnone": "(ھیچ)",
+       "revdelete-summary": "پوختەی دەستکاری",
        "feedback-subject": "بابەت:",
        "feedback-message": "پەیام:",
        "feedback-cancel": "ھەڵیوەشێنەوە",
        "feedback-submit": "تێبینییەکان بنێرە",
-       "feedback-close": "ئەنجام درا",
+       "feedback-close": "کرا",
        "searchsuggest-search": "گەڕان",
        "searchsuggest-containing": "بە لەبەرگرتنەوەی ...",
        "api-error-empty-file": "ئەو پەڕگەیە کە ناردووتە واڵا بوو.",
index 97f5252..b91f52a 100644 (file)
        "passwordreset-emailsent-capture": "Byl odeslán e-mail pro získání nového hesla, který je zobrazen níže.",
        "passwordreset-emailerror-capture": "Byl vygenerován e-mail pro získání nového hesla, který je zobrazen níže, ale {{GENDER:$2|uživateli|uživatelce}} se ho nepodařilo odeslat: $1",
        "changeemail": "Změna e-mailové adresy",
-       "changeemail-header": "Změna e-mailové adresy k účtu",
        "changeemail-text": "Vyplněním tohoto formuláře si změníte e-mailovou adresu. Pro potvrzení změny budete muset zadat své heslo.",
        "changeemail-no-info": "K této stránce mají přímý přístup jen přihlášení uživatelé.",
        "changeemail-oldemail": "Stávající e-mailová adresa:",
        "changeemail-none": "(žádná)",
        "changeemail-password": "Vaše heslo do {{gender:2sg|{{SITENAME}}}}:",
        "changeemail-submit": "Změnit e-mail",
-       "changeemail-cancel": "Storno",
        "changeemail-throttled": "Provedli jste příliš mnoho pokusů o přihlášení.\nČekejte prosím $1 a zkuste to znovu.",
        "resettokens": "Reinicializace klíčů",
        "resettokens-text": "Na této stránce můžete reinicializovat klíče, které umožňují přístup k jistým soukromým údajům spojeným s vaším účtem.\n\n{{GENDER:|Měl|Měla|Měli}} byste to provést v případě, že jste je omylem někomu {{GENDER:|prozradil|prozradila|prozradili}}, nebo byl váš účet narušen.",
        "searchall": "vše",
        "showingresults": "Níže zobrazuji nejvýše <strong>$1</strong> {{PLURAL:$1|výsledek|výsledky|výsledků}} počínaje od <strong>$2</strong>.",
        "showingresultsinrange": "Níže zobrazuji nejvýše <strong>$1</strong> {{PLURAL:$1|výsledek|výsledky|výsledků}} v rozsahu #<strong>$2</strong>–#<strong>$3</strong>.",
-       "showingresultsheader": "{{PLURAL:$5|Výsledek '''$1''' z '''$3'''|Výsledky '''$1–$2''' z '''$3'''}} pro '''$4'''",
+       "search-showingresults": "{{PLURAL:$4|Výsledek <strong>$1</strong> z <strong>$3</strong>|Výsledky <strong>$1–$2</strong> z <strong>$3</strong>}}",
        "search-nonefound": "Na váš dotaz nebyly nalezeny žádné výsledky.",
        "powersearch-legend": "Rozšířené vyhledávání",
        "powersearch-ns": "Hledat ve jmenných prostorech:",
        "prefs-tokenwatchlist": "Klíč",
        "prefs-diffs": "Porovnání verzí",
        "prefs-help-prefershttps": "Toto nastavení se projeví při příštím přihlášení.",
+       "prefswarning-warning": "Provedli jste změny nastavení, které dosud nejsou uloženy. Pokud tuto stránku opustíte, aniž byste klikli na „$1“, vaše nastavení se nezmění.",
        "prefs-tabs-navigation-hint": "Tip: Pro přepínání mezi záložkami můžete používat šipky vlevo a vpravo.",
        "email-address-validity-valid": "E-mailová adresa vypadá jako platná",
        "email-address-validity-invalid": "Zadejte platnou e-mailovou adresu",
        "protect-othertime": "Jiný čas vypršení:",
        "protect-othertime-op": "jiný čas",
        "protect-existing-expiry": "Současný čas vypršení: $2, $3",
+       "protect-existing-expiry-infinity": "Současný čas vypršení: do odvolání",
        "protect-otherreason": "Jiný/další důvod:",
        "protect-otherreason-op": "Jiný důvod",
        "protect-dropdown": "*Obvyklé důvody zamčení\n** Opakovaný vandalismus\n** Vkládání reklamních externích odkazů\n** Editační válka\n** Často používaná stránka",
        "unblocked": "{{GENDER:$1|||Uživatel}} [[User:$1|$1]] {{GENDER:$1|byl odblokován|byla odblokována|byl odblokován}}.",
        "unblocked-range": "Rozsah $1 byl odblokován.",
        "unblocked-id": "Blok $1 byl zrušen.",
+       "unblocked-ip": "Adresa [[Special:Contributions/$1|$1]] byla odblokována.",
        "blocklist": "Zablokovaní uživatelé",
        "ipblocklist": "Zablokovaní uživatelé",
        "ipblocklist-legend": "Hledat zablokovaného uživatele",
        "tooltip-pt-anonuserpage": "Uživatelská stránka pro IP adresu, ze které editujete",
        "tooltip-pt-mytalk": "Vaše diskusní stránka",
        "tooltip-pt-anontalk": "Diskuse o editacích provedených z této IP adresy",
-       "tooltip-pt-preferences": "Moje nastavení",
-       "tooltip-pt-watchlist": "Seznam stránek, jejichž změny sleduji",
+       "tooltip-pt-preferences": "Vaše nastavení",
+       "tooltip-pt-watchlist": "Seznam stránek, jejichž změny sledujete",
        "tooltip-pt-mycontris": "Seznam vašich příspěvků",
        "tooltip-pt-login": "Doporučujeme vám přihlásit se, ovšem není to povinné.",
        "tooltip-pt-logout": "Odhlásit se",
        "logentry-upload-overwrite": "$1 {{GENDER:$2|načetl|načetla}} novou verzi $3",
        "logentry-upload-revert": "$1 {{GENDER:$2|načetl|načetla}} $3",
        "rightsnone": "(žádné)",
+       "revdelete-summary": "shrnutí editace",
        "feedback-bugornote": "Pokud dokážete podrobně popsat technický problém, můžete [$1 nahlásit chybu].\nJinak můžete využít jednoduchý formulář níže. Váš komentář bude přidán na stránku „[$3 $2]“ spolu s vaším uživatelským jménem a informací o tom, jaký prohlížeč používáte.",
        "feedback-subject": "Předmět:",
        "feedback-message": "Zpráva:",
        "log-name-pagelang": "Kniha změn jazyků",
        "log-description-pagelang": "Toto je protokol změn jazyků stránek.",
        "logentry-pagelang-pagelang": "$1 {{GENDER:$2|změnil|změnila}} jazyk stránky $3 z $4 na $5.",
-       "default-skin-not-found": "Jejda! Výchozí vzhled vaší wiki (<code>$wgDefaultSkin</code>), <code>$1</code>, není dostupný.\n\nVaše instalace zřejmě obsahuje následující vzhledy. Informace o tom, jak je povolit a vybrat výchozí, najdete na stránce [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Skin_configuration/cs Manual:Skin configuration].\n\n$2\n\n; Pokud jste právě nainstalovali MediaWiki:\n: Zřejmě jste instalovali z gitu nebo nějakým jiným způsobem přímo ze zdrojového kódu. Tak to má fungovat. Zkuste nainstalovat některé vzhledy ze [https://www.mediawiki.org/wiki/Category:All_skins seznamu vzhledů na mediawiki.org] buď:\n:* Můžete si stáhnout [https://www.mediawiki.org/wiki/Download/cs instalace v tarballu], která zahrnuje několik vzhledů a rozšíření, a vykopírovat si z ní adresář <code>skins/</code>, nebo\n:* Nebo si můžete gitem naklonovat jeden z repozitářů <code>mediawiki/skins/*</code> do adresáře <code>skins/</code> ve vaší instalaci MediaWiki.\n: Pokud jste vývojářem MediaWiki, nemělo by to nijak narušit váš gitový repozitář.\n\n; Pokud jste právě aktualizovali MediaWiki:\n: MediaWiki 1.24 a novější již automaticky nepovolují nainstalované vzhledy (vizte [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Skin_autodiscovery/cs Manual:Skin autodiscovery]). Pro povolení všech právě nainstalovaných vzhledů vlepte následující řádky do <code>LocalSettings.php</code>:\n\n<pre>$3</pre>\n\n; Pokud jste právě upravili <code>LocalSettings.php</code>:\n: Překontrolujte případné překlepy v názvech vzhledů.",
-       "default-skin-not-found-no-skins": "Jejda! Výchozí vzhled vaší wiki (<code>$wgDefaultSkin</code>), <code>$1</code>, není dostupný.\n\nNemáte nainstalovány žádné vzhledy.\n\n; Pokud jste právě nainstalovali nebo aktualizovali MediaWiki:\n: Zřejmě jste instalovali z gitu nebo nějakým jiným způsobem přímo ze zdrojového kódu. Tak to má fungovat. MediaWiki 1.24 a novější již v hlavním repozitáři neobsahují žádné vzhledy. Zkuste nainstalovat některé vzhledy ze [https://www.mediawiki.org/wiki/Category:All_skins seznamu vzhledů na mediawiki.org] buď:\n:* Můžete si stáhnout [https://www.mediawiki.org/wiki/Download/cs instalace v tarballu], která zahrnuje několik vzhledů a rozšíření, a vykopírovat si z ní adresář <code>skins/</code>, nebo\n:* Nebo si můžete gitem naklonovat jeden z repozitářů <code>mediawiki/skins/*</code> do adresáře <code>skins/</code> ve vaší instalaci MediaWiki.\n: Pokud jste vývojářem MediaWiki, nemělo by to nijak narušit váš gitový repozitář. Informace o tom, jak povolit vzhledy a vybrat výchozí, najdete na stránce [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Skin_configuration/cs Manual:Skin configuration].",
+       "default-skin-not-found": "Jejda! Výchozí vzhled vaší wiki, definovaný ve <code dir=\"ltr\">$wgDefaultSkin</code> jako <code>$1</code>, není dostupný.\n\nVaše instalace zřejmě obsahuje následující vzhledy. Informace o tom, jak je povolit a vybrat výchozí, najdete na stránce [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Skin_configuration/cs Manual:Skin configuration].\n\n$2\n\n; Pokud jste právě nainstalovali MediaWiki:\n: Zřejmě jste instalovali z gitu nebo nějakým jiným způsobem přímo ze zdrojového kódu. Tak to má fungovat. Zkuste nainstalovat některé vzhledy ze [https://www.mediawiki.org/wiki/Category:All_skins seznamu vzhledů na mediawiki.org] buď:\n:* Můžete si stáhnout [https://www.mediawiki.org/wiki/Download/cs instalace v tarballu], která zahrnuje několik vzhledů a rozšíření, a vykopírovat si z ní adresář <code dir=\"ltr\">skins/</code>, nebo\n:* Nebo si můžete gitem naklonovat jeden z repozitářů <code>mediawiki/skins/*</code> do adresáře <code>skins/</code> ve vaší instalaci MediaWiki.\n: Pokud jste vývojářem MediaWiki, nemělo by to nijak narušit váš gitový repozitář.\n\n; Pokud jste právě aktualizovali MediaWiki:\n: MediaWiki 1.24 a novější již automaticky nepovolují nainstalované vzhledy (vizte [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Skin_autodiscovery/cs Manual:Skin autodiscovery]). Pro povolení všech právě nainstalovaných vzhledů vlepte následující řádky do <code>LocalSettings.php</code>:\n\n<pre dir=\"ltr\">$3</pre>\n\n; Pokud jste právě upravili <code>LocalSettings.php</code>:\n: Překontrolujte případné překlepy v názvech vzhledů.",
+       "default-skin-not-found-no-skins": "Jejda! Výchozí vzhled vaší wiki, definovaný ve <code dir=\"ltr\">$wgDefaultSkin</code> jako <code>$1</code>, není dostupný.\n\nNemáte nainstalovány žádné vzhledy.\n\n; Pokud jste právě nainstalovali nebo aktualizovali MediaWiki:\n: Zřejmě jste instalovali z gitu nebo nějakým jiným způsobem přímo ze zdrojového kódu. Tak to má fungovat. MediaWiki 1.24 a novější již v hlavním repozitáři neobsahují žádné vzhledy. Zkuste nainstalovat některé vzhledy ze [https://www.mediawiki.org/wiki/Category:All_skins seznamu vzhledů na mediawiki.org] buď:\n:* Můžete si stáhnout [https://www.mediawiki.org/wiki/Download/cs instalace v tarballu], která zahrnuje několik vzhledů a rozšíření, a vykopírovat si z ní adresář <code>skins/</code>, nebo\n:* Nebo si můžete gitem naklonovat jeden z repozitářů <code>mediawiki/skins/*</code> do adresáře <code dir=\"ltr\">skins/</code> ve vaší instalaci MediaWiki.\n: Pokud jste vývojářem MediaWiki, nemělo by to nijak narušit váš gitový repozitář. Informace o tom, jak povolit vzhledy a vybrat výchozí, najdete na stránce [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Skin_configuration/cs Manual:Skin configuration].",
        "default-skin-not-found-row-enabled": "* <code>$1</code> / $2 (povolený)",
        "default-skin-not-found-row-disabled": "* <code>$1</code> / $2 ('''zakázaný''')"
 }
index f28133e..2470b2e 100644 (file)
        "passwordreset-emailsent-capture": "Eine Passwortzurücksetzungs-E-Mail wurde versandt, die unten angezeigt wird.",
        "passwordreset-emailerror-capture": "Die unten angezeigte Passwortzurücksetzungs-E-Mail wurde generiert, allerdings ist der Versand an {{GENDER:$2|den Benutzer|die Benutzerin}} gescheitert: $1",
        "changeemail": "E-Mail-Adresse ändern",
-       "changeemail-header": "E-Mail-Adresse ändern",
        "changeemail-text": "Fülle dieses Formular vollständig aus, um deine E-Mail-Adresse zu ändern. Du musst dein Passwort angeben, um diese Änderung zu bestätigen.",
        "changeemail-no-info": "Du musst angemeldet sein, um direkt auf diese Seite zugreifen zu können.",
        "changeemail-oldemail": "Aktuelle E-Mail-Adresse:",
        "changeemail-none": "(keine)",
        "changeemail-password": "Dein {{SITENAME}}-Passwort:",
        "changeemail-submit": "E-Mail-Adresse ändern",
-       "changeemail-cancel": "Abbrechen",
        "changeemail-throttled": "Du hast zu viele Anmeldeversuche unternommen.\nBitte warte $1, bevor du es erneut versuchst.",
        "resettokens": "Tokens zurücksetzen",
        "resettokens-text": "Du kannst Tokens zurücksetzen, welche dir den Zugriff auf bestimmte private Daten ermöglichen, die mit deinem Benutzerkonto hier verknüpft sind.\n\nDu solltest dies nur machen, wenn du die Tokens versehentlich mit jemandem geteilt hast oder dein Konto gefährdet ist.",
        "searchall": "alle",
        "showingresults": "Hier {{PLURAL:$1|ist '''1''' Ergebnis|sind '''$1''' Ergebnisse}}, beginnend mit Nummer '''$2.'''",
        "showingresultsinrange": "Unten {{PLURAL:$1|wird <strong>ein</strong> Ergebnis|werden bis zu <strong>$1</strong> Ergebnisse}} im Bereich <strong>$2</strong> bis <strong>$3</strong> angezeigt.",
-       "showingresultsheader": "{{PLURAL:$5|Ergebnis '''$1''' von '''$3'''|Ergebnisse '''$1–$2''' von '''$3'''}} für '''$4'''",
+       "search-showingresults": "{{PLURAL:$4|Ergebnis <strong>$1</strong> von <strong>$3</strong>|Ergebnisse <strong>$1 bis $2</strong> von <strong>$3</strong>}}",
        "search-nonefound": "Zu deiner Suchanfrage wurden keine Ergebnisse gefunden.",
        "powersearch-legend": "Erweiterte Suche",
        "powersearch-ns": "Suche in Namensräumen:",
        "prefs-tokenwatchlist": "Token",
        "prefs-diffs": "Versionsvergleich",
        "prefs-help-prefershttps": "Diese Einstellung wird bei deiner nächsten Anmeldung wirksam.",
+       "prefswarning-warning": "Du hast Änderungen an deinen Einstellungen durchgeführt, die noch nicht gespeichert wurden.\nWenn du diese Seite verlässt ohne auf „$1“ zu klicken, werden deine Einstellungen nicht aktualisiert.",
        "prefs-tabs-navigation-hint": "Tipp: Du kannst die linke und rechte Pfeiltasten benutzen, um zwischen den Registerkarten in der Reiterliste zu navigieren.",
        "email-address-validity-valid": "Diese E-Mail-Adresse scheint gültig zu sein.",
        "email-address-validity-invalid": "Eine gültige E-Mail-Adresse ist erforderlich.",
        "protect-othertime": "Andere Sperrdauer:",
        "protect-othertime-op": "andere Sperrdauer",
        "protect-existing-expiry": "Aktuelles Seitenschutzende: $2, $3 Uhr",
+       "protect-existing-expiry-infinity": "Vorhandene Ablaufzeit: unbeschränkt",
        "protect-otherreason": "Anderer/ergänzender Grund:",
        "protect-otherreason-op": "Anderer Grund",
        "protect-dropdown": "* Allgemeine Schutzgründe\n** Edit-War\n** Wiederkehrender Vandalismus\n** Wiederholtes Einstellen von Werbung\n** Häufig eingebundene Vorlage\n** Seite mit hoher Besucherzahl",
        "unblocked": "[[User:$1|$1]] wurde freigegeben",
        "unblocked-range": "Sperre für $1 wurde aufgehoben",
        "unblocked-id": "Sperr-ID $1 wurde freigegeben",
+       "unblocked-ip": "[[Special:Contributions/$1|$1]] wurde freigegeben.",
        "blocklist": "Gesperrte Benutzer",
        "ipblocklist": "Gesperrte Benutzer",
        "ipblocklist-legend": "Suche nach einem gesperrten Benutzer",
        "logentry-upload-overwrite": "$1 {{GENDER:$2|lud}} eine neue Version von $3 hoch",
        "logentry-upload-revert": "$1 {{GENDER:$2|lud}} $3 hoch",
        "rightsnone": "(–)",
+       "revdelete-summary": "Zusammenfassungskommentar",
        "feedback-bugornote": "Sofern du detailliert ein technisches Problem beschreiben möchtest, melde bitte [$1 einen Fehler].\nAnderenfalls kannst du auch das untenstehende einfache Formular nutzen. Dein Kommentar wird, zusammen mit deinem Benutzernamen und der Version des von dir verwendeten Webbrowsers sowie Betriebssystems, auf der Seite „[$3 $2]“ hinzugefügt.",
        "feedback-subject": "Betreff:",
        "feedback-message": "Nachricht:",
        "default-skin-not-found": "Hoppla! Die in <code dir=\"ltr\">$wgDefaultSkin</code> als <code>$1</code> definierte Standardbenutzeroberfläche für dein Wiki ist nicht verfügbar.\n\nDeine Installation scheint die folgenden Benutzeroberflächen zu enthalten. Siehe [https://www.mediawiki.org/wiki/Manual:Skin_configuration/de das Benutzerhandbuch] zur Aktivierung und Auswahl des Standards.\n\n$2\n\n; Falls du gerade MediaWiki installiert hast:\n: Du hast vermutlich von Git oder direkt vom Quellcode mithilfe einer anderen Methode installiert. Dies wird erwartet. Versuche einige Benutzeroberflächen aus dem  [https://www.mediawiki.org/wiki/Category:All_skins MediaWiki.org-Benutzeroberflächenverzeichnis] zu installieren, indem du:\n:* Den [https://www.mediawiki.org/wiki/Download/de Tarball-Installer] herunterlädst, der mit verschiedenen Benutzeroberflächen und Erweiterungen kommt. Du kannst das Verzeichnis <code>skins/</code> kopieren und einfügen.\n:* Eine der <code>mediawiki/skins/*</code>-Repositorien über Git in das <code dir=\"ltr\">skins/</code>-Verzeichnis deiner MediaWiki-Installation klonst.\n: Dies sollte nicht dein Git-Repositorium beeinträchtigen, falls du ein MediaWiki-Entwickler bist.\n\n; Falls du gerade MediaWiki aktualisiert hast:\n: MediaWiki 1.24 und neuere Versionen aktivieren nicht mehr automatisch installierte Benutzeroberflächen (siehe das [https://www.mediawiki.org/wiki/Manual:Skin_autodiscovery Benutzerhandbuch]). Du kannst die folgenden Zeilen in die Datei <code>LocalSettings.php</code> einfügen, um alle derzeit installierten Benutzeroberflächen zu aktivieren:\n\n<pre dir=\"ltr\">$3</pre>\n\n; Falls du gerade <code>LocalSettings.php</code> geändert hast:\n: Überprüfe die Namen der Benutzeroberflächen auf Tippfehler.",
        "default-skin-not-found-no-skins": "Hoppla! Die in <code>$wgDefaultSkin</code> als <code>$1</code> definierte Standardbenutzeroberfläche für dein Wiki ist nicht verfügbar.\n\nDu hast keine installierten Benutzeroberflächen.\n\n; Falls du gerade MediaWiki installiert oder aktualisiert hast:\n: Du hast vermutlich von Git oder direkt vom Quellcode mithilfe einer anderen Methode installiert. Dies wird erwartet. MediaWiki 1.24 und neuere Versionen enthalten keine Benutzeroberflächen im Haupt-Repositorium. Versuche einige Benutzeroberflächen aus dem [https://www.mediawiki.org/wiki/Category:All_skins MediaWiki.org-Benutzeroberflächenverzeichnis] zu installieren, indem du:\n:* Den [https://www.mediawiki.org/wiki/Download/de Tarball-Installer] herunterlädst, der mit verschiedenen Benutzeroberflächen und Erweiterungen kommt. Du kannst das  <code>skins/</code>-Verzeichnis kopieren und einfügen.\n:* Eine der <code>mediawiki/skins/*</code>-Repositorien über Git in das <code dir=\"ltr\">skins/</code>-Verzeichnis deiner MediaWiki-Installation klonst.\n: Dies sollte nicht dein Git-Repositorium beeinträchtigen, falls du ein MediaWiki-Entwickler bist. Siehe das [https://www.mediawiki.org/wiki/Manual:Skin_configuration/de Benutzerhandbuch] zur Aktivierung von Benutzeroberflächen und Auswahl des Standards.",
        "default-skin-not-found-row-enabled": "* <code>$1</code> / $2 (aktiviert)",
-       "default-skin-not-found-row-disabled": "* <code>$1</code> / $2 ('''deaktiviert''')"
+       "default-skin-not-found-row-disabled": "* <code>$1</code> / $2 ('''deaktiviert''')",
+       "mediastatistics": "Medienstatistiken",
+       "mediastatistics-summary": "Statistiken über hochgeladene Dateitypen. Dies beinhaltet nur die aktuellste Version einer Datei. Alte oder gelöschte Dateiversionen sind ausgeschlossen.",
+       "mediastatistics-nbytes": "{{PLURAL:$1|Ein Byte|$1 Bytes}} ($2; $3%)",
+       "mediastatistics-table-mimetype": "MIME-Typ",
+       "mediastatistics-table-extensions": "Mögliche Erweiterungen",
+       "mediastatistics-table-count": "Anzahl der Dateien",
+       "mediastatistics-table-totalbytes": "Gesamtgröße",
+       "mediastatistics-header-unknown": "Unbekannt",
+       "mediastatistics-header-bitmap": "Bitmap-Bilder",
+       "mediastatistics-header-drawing": "Zeichnungen (Vektorbilder)",
+       "mediastatistics-header-audio": "Audio",
+       "mediastatistics-header-video": "Videos",
+       "mediastatistics-header-multimedia": "Rich Media",
+       "mediastatistics-header-office": "Office",
+       "mediastatistics-header-text": "Text",
+       "mediastatistics-header-executable": "Ausführbare Dateien",
+       "mediastatistics-header-archive": "Komprimierte Formate"
 }
index d50030b..f8f1c7d 100644 (file)
        "otherlanguages": "In êtri léngvi",
        "redirectedfrom": "(Tót còst al deşvîn da <b>$1</b>)",
        "redirectpagesub": "Pàgina 'd partèinsa",
+       "redirectto": "Rimânda a:",
        "lastmodifiedat": "Ûltmi mudéfichi 'dla pàgina: $2, $1.",
        "viewcount": "Cla pàgina ché l'é stêda lişûda {{PLURAL:$1|'na vôlta|$1 vôlti}}.",
        "protectedpage": "Pàgina sòta prutesiòun",
        "createaccount-text": "Quelchidûn l'à fât un inscrisiòun a  {{SITENAME}} ($4) a nòm ed $2 coleghê a cl'indirés ed pôsta eletrônica ché. La cêva 'd ingrès per l'utèint \"$2\" l'é  impustêda a \"$3\". \nÉ necesâri fêr un ingrès préma ch' es pôl e cambiêr subét la cêva 'd ingrès. \nSe l'inscrisiòun l'é stêda fâta per şbâli, es pōl scanşlêr sté mesâg.",
        "login-throttled": "În stê fât trôp tentatîv 'd ingrès in pôch tèimp. Spèta $1 e pó tōrna pruvêr.",
        "login-abort-generic": "An t'é mìa stê arcgnusû - Scanşlê",
+       "login-migrated-generic": "La tó utèinsa l'é stêda spustêda, e al tó nòm utèint al gh'é mìa pió in sém a cla wiki ché.",
        "loginlanguagelabel": "Léngva: $1",
        "suspicious-userlogout": "La tó dmânda per destachêret l'é stēda rifiutêda perchè la sèmbra spidîda da un navigadōr ch' al funsiòuna mìa o da un proxy di caching.",
        "createacct-another-realname-tip": "Druvêr al nòm vèira l'é 'na siēlta personêla; s' es pèinsa 'd druvêrel al gnirâ uşê per dêr la paternitê di lavōr spidî.",
        "passwordreset-emailsent-capture": "É stê spidî un mesâg ed pôsta eletrônica per turnêr a impustêr la cêva 'd ingrès, ché sòta a gh'é al tèst che gh'é scrét.",
        "passwordreset-emailerror-capture": "É stê fât un mesâg ed pôsta eletrônica per turnêr a impustêr la cêva 'd ingrès, scréta ché 'd sègvit. La spedisiòun {{GENDER:$2|a l'utèint}} an n'é mia 'riusîda:$1",
        "changeemail": "Câmbia l'indirés ed la pôsta eletrônica",
-       "changeemail-header": "Câmbia l'indirés ed la pôsta eletrônica 'd la tó inscrisiòun.",
        "changeemail-text": "Impés sté mòdul per cambiêr al tó indirés ed pòsta eletrônica. A srà necesâri mèter dèinter la cêva 'd ingrès per cunfermêr la mudéfica.",
        "changeemail-no-info": "Per andêr dèinter diretamèint a cla pàgina ché 't gh'ê da fêr l'ingrès.",
        "changeemail-oldemail": "L'indirés ed la pôsta eletrànica 'd adès.",
        "changeemail-none": "(nisûn)",
        "changeemail-password": "La cêva 'd ingrès só {{SITENAME}}:",
        "changeemail-submit": "Cambiêr l'indirés ed pôsta eletrônica",
-       "changeemail-cancel": "Scanşèla",
        "changeemail-throttled": "În stê fât trôp tentatîv 'd ingrès in pôch tèimp. Spèta $1 e pó tōrna pruvêr dôp.",
        "resettokens": "Tōrna 'd impustêr la cêva",
        "resettokens-text": "Ché 't pō turnêr a impustêr al cêvi ch'ét permèten l'ingrès a precîşi infurmasiòun privêdi lighêdi a la tó utèinsa. Ét duvrés fêrel se per chêş ét j ê spartîdi cun quelchidûn o se al j infurmasiòun ed la tó utèinsa în  in perécol.",
        "searchall": "tót",
        "showingresults": "Ed sègvit {{PLURAL:$1|a vîn preşentê al mâsim <strong>1</strong> rişultêt| a vînen preşentê al mâsim <strong>$1</strong> rişultêt}} a partîr dal nómer #<strong>$2</strong>.",
        "showingresultsinrange": "{{PLURAL:$1|A vîn mustrê| a vînen mustrê}} sòta {{PLURAL:$1|<strong>1</strong> rişultêt|<strong>$1</strong> rişultêt}} dal #<strong>$2</strong> al #<strong>$3</strong>.",
-       "showingresultsheader": "{{PLURAL:$5|Al risultêt '''$1''' ed '''$3'''|I risultêt '''$1 - $2''' ed '''$3'''}} per '''$4'''",
+       "search-showingresults": "{{PLURAL:$4|Rişultêt <strong>$1</strong> ed <strong>$3</strong>|Rişultêt <strong>$1 - $2</strong> ed <strong>$3</strong>}}",
        "search-nonefound": "La sērca an n'à mìa dê di rişultê.",
        "powersearch-legend": "Sèirca specêla",
        "powersearch-ns": "Sērca int al spâsi di nòm:",
        "prefs-help-email-others": "Ét pō ânca sernîr ed lasêr che chiêter a 's mèten in cuntât  tēgh cun la pôsta eletrônica cun al colegamèint da la tó pàgina utèint o da còla 'd discusiòun.  Al tó indirés al vîn mìa fât savèir a quî ch'ét 's mèten in cuntât tēgh.",
        "prefs-help-email-required": "L'indirés ed pôsta eletrônica l'é ubligatôri.",
        "prefs-info": "Infurmasiòun necesâri",
+       "prefs-i18n": "Internalişasiòun",
        "prefs-signature": "Fîrma",
        "prefs-dateformat": "Fōrma 'd la dâta",
        "prefs-timeoffset": "Ōri 'd diferèinsa",
        "userrights-editusergroup": "Mudéfica gróp utèint",
        "saveusergroups": "Sêlva gróp utèint",
        "userrights-groupsmember": "Al fà pêrt {{PLURAL:$1|al gróp|ai gróp}}:",
+       "userrights-groupsmember-auto": "Al fà pêrt ed sicûr a:",
+       "userrights-groups-help": "L'é pusébil mudifichêr i gróp in dó fà pêrt l'utèint. \n*'Na caşèla sernîda la sègna a che gróp al fà pêrt l'utèint. \n*'Na caşèla mìa serrnîda la sègna che l'utèin al fà mìa pêrt al gróp. \n*Al sègn * al sègna ch' an n'é m'a pusébil scanşlêr che l'utèin al fà pêrt al gróp dōp avèirel sgnê (o invicivêrsa).",
+       "userrights-reason": "Mutîv:",
+       "userrights-no-interwiki": "An es gh'à mìa i permès necesâri per cambiêr i dirét ed j utèint in sém a êter sît.",
+       "userrights-nodatabase": "Al databēş $1 al gh'é mìa o an n' mìa un databêş lochêl.",
+       "userrights-nologin": "Per dêr i dirét a j utèint l'é necesâri [[Special:UserLogin|fêr l'ingrès]] cme aministardōr.",
+       "userrights-notallowed": "An 't gh'ê mìa al permès per zuntêr o tōr via i permès utèint.",
+       "userrights-changeable-col": "Gróp ch'es pōlen mudifichêr.",
+       "userrights-unchangeable-col": "Gróp ch'an 's pōlen mìa mudifichêr.",
+       "userrights-conflict": "Cuntrâst ed mudéfica di dirét utèint! Cuntròla e cunfērma al tó mudéfichi.",
+       "userrights-removed-self": "T'é tôt via cun sucès i tō dirét. E dòunca, an 't prê pió andêr dèinter a cla pàgina ché.",
        "group": "Gróp:",
        "group-user": "Utèint",
        "group-autoconfirmed": "Utèint cunvalidê da per ló",
        "grouppage-suppress": "{{ns:project}}:Oversight",
        "right-read": "Al lēş al pàgini",
        "right-edit": "Mudéfica pàgini",
+       "right-createpage": "Ét pō fêr al pàgini (fōra che 'l pàgini 'd discusiòun).",
+       "right-createtalk": "Fà 'l pàgini 'd discusiòun.",
+       "right-createaccount": "Fà dal j utèinsi nōvi.",
+       "right-minoredit": "Sègna 'l mudéfichi cme céchi.",
+       "right-move": "Spôsta 'l pàgini",
+       "right-move-subpages": "Spôsta 'l pàgini insèm al relatîvi sòt pàgini",
+       "right-move-rootuserpages": "Spôsta 'l pàgini principêli 'd j utèint",
+       "right-move-categorypages": "Spôsta 'l categoréi",
+       "right-movefile": "Spôsta i file",
+       "right-suppressredirect": "An fà mìa un indirés nōv in atvomâtich quând a se spôsta 'na pàgina",
+       "right-upload": "Cârga un file",
+       "right-reupload": "Al scré in sém a 'n file ch' al gh'é bèle",
+       "right-reupload-own": "Al scré in sém a 'n file ch' al gh'é bèle carghê da l'istès utèint",
        "newuserlogpage": "Utèint nōv",
        "action-read": "lēzer cla pàgina ché",
        "action-edit": "Mudifichêr cla pàgina ché",
index 59e5b18..6fdd95b 100644 (file)
        "passwordreset-emailsent-capture": "Έχει αποσταλεί email επαναφοράς κωδικού, το οποίο φαίνεται πιο κάτω.",
        "passwordreset-emailerror-capture": "Ένα email επαναφοράς κωδικού έχει δημιουργηθεί, το οποίο φαίνεται πιο κάτω, αλλά απέτυχε η αποστολή του στο  {{GENDER:$2|χρήστη}}: $1",
        "changeemail": "Αλλαγή της διεύθυνσης ηλεκτρονικού ταχυδρομείου",
-       "changeemail-header": "Αλλαγή λογαριασμού ηλεκτρονικού ταχυδρομείου",
        "changeemail-text": "Συμπληρώστε αυτή τη φόρμα για να αλλάξετε τη διεύθυνση ηλεκτρονικού ταχυδρομείου σας. Θα πρέπει να εισάγετε τον κωδικό σας για να επιβεβαιωθεί αυτή η αλλαγή.",
        "changeemail-no-info": "Πρέπει να έχετε συνδεθεί για άμεση πρόσβαση σε αυτήν τη σελίδα.",
        "changeemail-oldemail": "Τρέχουσα διεύθυνση ηλεκτρονικού ταχυδρομείου:",
        "changeemail-none": "(κανένα)",
        "changeemail-password": "Ο κωδικός πρόσβασής σας στο εγχείρημα {{SITENAME}}:",
        "changeemail-submit": "Αλλαγή διεύθυνσης ηλεκτρονικού ταχυδρομείου",
-       "changeemail-cancel": "Ακύρωση",
        "changeemail-throttled": "Κάνατε πάρα πολλές απόπειρες σύνδεσης.\nΠαρακαλούμε περιμένετε $1 προτού ξαναδοκιμάσετε.",
        "resettokens": "Επαναφορά των κλειδιών",
        "resettokens-text": "Μπορείτε να επαναφέρετε τα κλειδιά, τα οποία επιτρέπουν την πρόσβαση σε ορισμένα ιδιωτικά δεδομένα που συνδέονται με τον λογαριασμό σας εδώ.\n\nΠρέπει να το κάνετε εάν κατά λάθος τα μοιραστήκατε με κάποιον ή αν ο λογαριασμός σας έχει παραβιαστεί.",
        "searchall": "όλα",
        "showingresults": "Παρακάτω {{PLURAL:$1|εμφανίζεται μέχρι <strong>1</strong> αποτέλεσμα|εμφανίζονται μέχρι <strong>$1</strong> αποτελέσματα}} ξεκινώντας από το Νο <strong>$2</strong>.",
        "showingresultsinrange": "Παρακάτω {{PLURAL:$1|εμφανίζεται μέχρι <strong>1</strong> αποτέλεσμα|εμφανίζονται μέχρι <strong>$1</strong> αποτελέσματα}} σε εύρος από το Νο <strong>$2</strong> μέχρι το Νο <strong>$3</strong>.",
-       "showingresultsheader": "{{PLURAL:$5|Αποτέλεσμα '''$1''' από '''$3'''|Αποτελέσματα '''$1 - $2''' από '''$3'''}} για '''$4'''",
        "search-nonefound": "Δεν υπάρχουν αποτελέσματα που να ικανοποιούν το ερώτημα.",
        "powersearch-legend": "Αναλυτική αναζήτηση",
        "powersearch-ns": "Αναζήτηση στις περιοχές ονομάτων:",
        "unusedtemplates": "Αχρησιμοποίητα πρότυπα",
        "unusedtemplatestext": "Αυτή η σελίδα περιέχει όλες τις σελίδες στην περιοχή ονομάτος των {{ns:template}}, οι οποίες δεν περιλαμβάνονται σε άλλη σελίδα. Θυμηθείτε να ελέγξετε για άλλους συνδέσμους προς τα πρότυπα πριν τα διαγράψετε.",
        "unusedtemplateswlh": "άλλοι σύνδεσμοι",
-       "randompage": "ΤÏ\85Ï\87αίο Î»Î®Î¼Î¼α",
+       "randompage": "ΤÏ\85Ï\87αία Ï\83ελίδα",
        "randompage-nopages": "Δεν υπάρχουν σελίδες {{PLURAL:$2|στον ακόλουθο ονοματοχώρο|στους ακόλουθους ονοματοχώρους}}: $1.",
        "randomincategory": "Τυχαία σελίδα στην κατηγορία",
        "randomincategory-invalidcategory": "Το «$1» δεν είναι έγκυρο όνομα κατηγορίας.",
        "logentry-upload-overwrite": "{{GENDER:$2|Ο|Η}} $1 ανέβασε μια νέα έκδοση του $3",
        "logentry-upload-revert": "{{GENDER:$2|Ο|Η}} $1 ανέβασε το $3",
        "rightsnone": "(κανένα)",
+       "revdelete-summary": "επεξεργασία σύνοψης",
        "feedback-bugornote": "Εάν είστε έτοιμοι να περιγράψετε ένα τεχνικό πρόβλημα λεπτομερώς παρακαλούμε [$1  κάντε μια αναφορά σφάλματος].\nΔιαφορετικά, μπορείτε να χρησιμοποιήσετε την παρακάτω απλή φόρμα. Το σχόλιό σας θα προστεθεί στη σελίδα \"[$3  $2]\", μαζί με το όνομα χρήστη σας.",
        "feedback-subject": "Θέμα:",
        "feedback-message": "Μήνυμα:",
index 86b9ed7..5ec4a07 100644 (file)
@@ -4,8 +4,8 @@
        },
        "sidebar": "\n* navigation\n** mainpage|mainpage-description\n** recentchanges-url|recentchanges\n** randompage-url|randompage\n** helppage|help\n* SEARCH\n* TOOLBOX\n* LANGUAGES",
        "tog-underline": "Link underlining:",
-       "tog-hideminor": "Hide minor edits in recent changes",
-       "tog-hidepatrolled": "Hide patrolled edits in recent changes",
+       "tog-hideminor": "Hide minor edits from recent changes",
+       "tog-hidepatrolled": "Hide patrolled edits from recent changes",
        "tog-newpageshidepatrolled": "Hide patrolled pages from new page list",
        "tog-extendwatchlist": "Expand watchlist to show all changes, not just the most recent",
        "tog-usenewrc": "Group changes by page in recent changes and watchlist",
        "passwordreset-emailerror-capture": "A password reset email was generated, which is shown below, but sending it to the {{GENDER:$2|user}} failed: $1",
        "changeemail": "Change email address",
        "changeemail-summary": "",
-       "changeemail-header": "Change account email address",
        "changeemail-text": "Complete this form to change your email address. You will need to enter your password to confirm this change.",
        "changeemail-no-info": "You must be logged in to access this page directly.",
        "changeemail-oldemail": "Current email address:",
        "changeemail-none": "(none)",
        "changeemail-password": "Your {{SITENAME}} password:",
        "changeemail-submit": "Change email",
-       "changeemail-cancel": "Cancel",
        "changeemail-throttled": "You have made too many login attempts.\nPlease wait $1 before trying again.",
        "resettokens": "Reset tokens",
        "resettokens-summary": "",
        "searchall": "all",
        "showingresults": "Showing below up to {{PLURAL:$1|<strong>1</strong> result|<strong>$1</strong> results}} starting with #<strong>$2</strong>.",
        "showingresultsinrange": "Showing below up to {{PLURAL:$1|<strong>1</strong> result|<strong>$1</strong> results}} in range #<strong>$2</strong> to #<strong>$3</strong>.",
-       "showingresultsheader": "{{PLURAL:$5|Result <strong>$1</strong> of <strong>$3</strong>|Results <strong>$1 - $2</strong> of <strong>$3</strong>}} for <strong>$4</strong>",
+       "search-showingresults": "{{PLURAL:$4|Result <strong>$1</strong> of <strong>$3</strong>|Results <strong>$1 - $2</strong> of <strong>$3</strong>}}",
        "search-nonefound": "There were no results matching the query.",
        "powersearch-legend": "Advanced search",
        "powersearch-ns": "Search in namespaces:",
        "preferences-summary": "",
        "mypreferences": "Preferences",
        "prefs-edits": "Number of edits:",
-       "prefsnologintext2": "Please login to change your preferences.",
+       "prefsnologintext2": "Please log in to change your preferences.",
        "prefs-skin": "Skin",
        "skin-preview": "Preview",
        "datedefault": "No preference",
        "prefs-tokenwatchlist": "Token",
        "prefs-diffs": "Diffs",
        "prefs-help-prefershttps": "This preference will take effect on your next login.",
+       "prefswarning-warning": "You've made changes to your preferences that have not been saved yet.\nIf you leave this page without clicking \"$1\" your preferences will not be updated.",
        "prefs-tabs-navigation-hint": "Tip: You can use the left and right arrow keys to navigate between the tabs in the tabs list.",
        "email-address-validity-valid": "Email address appears valid",
        "email-address-validity-invalid": "Enter a valid email address",
        "mywatchlist": "Watchlist",
        "watchlistfor2": "For $1 $2",
        "nowatchlist": "You have no items on your watchlist.",
-       "watchlistanontext": "Please login to view or edit items on your watchlist.",
+       "watchlistanontext": "Please log in to view or edit items on your watchlist.",
        "watchnologin": "Not logged in",
        "addwatch": "Add to watchlist",
        "addedwatchtext": "The page \"[[:$1]]\" has been added to your [[Special:Watchlist|watchlist]].\nFuture changes to this page and its associated talk page will be listed there.",
        "protect-othertime": "Other time:",
        "protect-othertime-op": "other time",
        "protect-existing-expiry": "Existing expiry time: $3, $2",
+       "protect-existing-expiry-infinity": "Existing expiry time: infinite",
        "protect-otherreason": "Other/additional reason:",
        "protect-otherreason-op": "Other reason",
        "protect-dropdown": "*Common protection reasons\n** Excessive vandalism\n** Excessive spamming\n** Counter-productive edit warring\n** High traffic page",
        "unblocked": "[[User:$1|$1]] has been unblocked.",
        "unblocked-range": "$1 has been unblocked.",
        "unblocked-id": "Block $1 has been removed.",
+       "unblocked-ip": "[[Special:Contributions/$1|$1]] has been unblocked.",
        "blocklist": "Blocked users",
        "ipblocklist": "Blocked users",
        "ipblocklist-legend": "Find a blocked user",
        "default-skin-not-found": "Whoops! The default skin for your wiki, defined in <code dir=\"ltr\">$wgDefaultSkin</code> as <code>$1</code>, is not available.\n\nYour installation seems to include the following skins. See [https://www.mediawiki.org/wiki/Manual:Skin_configuration Manual: Skin configuration] for information how to enable them and choose the default.\n\n$2\n\n; If you have just installed MediaWiki:\n: You probably installed from git, or directly from the source code using some other method. This is expected. Try installing some skins from [https://www.mediawiki.org/wiki/Category:All_skins mediawiki.org's skin directory], by:\n:* Downloading the [https://www.mediawiki.org/wiki/Download tarball installer], which comes with several skins and extensions. You can copy and paste the <code>skins/</code> directory from it.\n:* Cloning one of the <code>mediawiki/skins/*</code> repositories via git into the <code dir=\"ltr\">skins/</code> directory of your MediaWiki installation.\n: Doing this should not interfere with your git repository if you're a MediaWiki developer.\n\n; If you have just upgraded MediaWiki:\n: MediaWiki 1.24 and newer no longer automatically enables installed skins (see [https://www.mediawiki.org/wiki/Manual:Skin_autodiscovery Manual: Skin autodiscovery]). You can paste the following lines into <code>LocalSettings.php</code> to enable all currently installed skins:\n\n<pre dir=\"ltr\">$3</pre>\n\n; If you have just modified <code>LocalSettings.php</code>:\n: Double-check the skin names for typos.",
        "default-skin-not-found-no-skins": "Whoops! The default skin for your wiki, defined in <code>$wgDefaultSkin</code> as <code>$1</code>, is not available.\n\nYou have no installed skins.\n\n; If you have just installed or upgraded MediaWiki:\n: You probably installed from git, or directly from the source code using some other method. This is expected. MediaWiki 1.24 and newer doesn't include any skins in the main repository. Try installing some skins from [https://www.mediawiki.org/wiki/Category:All_skins mediawiki.org's skin directory], by:\n:* Downloading the [https://www.mediawiki.org/wiki/Download tarball installer], which comes with several skins and extensions. You can copy and paste the <code>skins/</code> directory from it.\n:* Cloning one of the <code>mediawiki/skins/*</code> repositories via git into the <code dir=\"ltr\">skins/</code> directory of your MediaWiki installation.\n: Doing this should not interfere with your git repository if you're a MediaWiki developer. See [https://www.mediawiki.org/wiki/Manual:Skin_configuration Manual: Skin configuration] for information how to enable skins and choose the default.\n",
        "default-skin-not-found-row-enabled": "* <code>$1</code> / $2 (enabled)",
-       "default-skin-not-found-row-disabled": "* <code>$1</code> / $2 ('''disabled''')"
+       "default-skin-not-found-row-disabled": "* <code>$1</code> / $2 ('''disabled''')",
+       "mediastatistics": "Media statistics",
+       "mediastatistics-summary": "Statistics about uploaded file types. This only includes the most recent version of a file. Old or deleted versions of files are excluded.",
+       "mediastatistics-nfiles": "$1 ($2%)",
+       "mediastatistics-nbytes": "{{PLURAL:$1|$1 byte|$1 bytes}} ($2; $3%)",
+       "mediastatistics-table-mimetype": "MIME type",
+       "mediastatistics-table-extensions": "Possible extensions",
+       "mediastatistics-table-count": "Number of files",
+       "mediastatistics-table-totalbytes": "Combined size",
+       "mediastatistics-header-unknown": "Unknown",
+       "mediastatistics-header-bitmap": "Bitmap images",
+       "mediastatistics-header-drawing": "Drawings (vector images)",
+       "mediastatistics-header-audio": "Audio",
+       "mediastatistics-header-video": "Videos",
+       "mediastatistics-header-multimedia": "Rich media",
+       "mediastatistics-header-office": "Office",
+       "mediastatistics-header-text": "Textual",
+       "mediastatistics-header-executable": "Executables",
+       "mediastatistics-header-archive": "Compressed formats"
 }
index 303a4c6..8649e2f 100644 (file)
        "otherlanguages": "Aliaj lingvoj",
        "redirectedfrom": "(Alidirektita el $1)",
        "redirectpagesub": "Alidirektilo",
+       "redirectto": "Alidirektas al:",
        "lastmodifiedat": "Ĉi tiu paĝo estis lastafoje redaktita je $2, $1.",
        "viewcount": "Montrita {{PLURAL:$1|unufoje|$1 fojojn}}.",
        "protectedpage": "Protektita paĝo",
        "hidetoc": "kaŝi",
        "collapsible-collapse": "kaŝi",
        "collapsible-expand": "Montri",
+       "confirmable-confirm": "Ĉu {{GENDER:$1|vi}} certas?",
        "confirmable-yes": "Jes",
        "confirmable-no": "Ne",
        "thisisdeleted": "Vidi aŭ restarigi $1?",
        "invalidtitle-knownnamespace": "Nevalida titolo kun nomspaco \"$2\" kaj teksto \"$3\"",
        "invalidtitle-unknownnamespace": "Nevalida titolo kun nekonata nomspaca numero $1 kaj teksto \"$2\"",
        "exception-nologin": "Ne ensalutinta",
-       "exception-nologin-text": "Bonvolu [[Special:Userlogin|ensaluti]] por atingi ĉi tiun paĝon aŭ agon.",
+       "exception-nologin-text": "Bonvolu ensaluti por atingi ĉi tiun paĝon aŭ agon.",
        "exception-nologin-text-manual": "Vi devas $1, por povi aliri al ĉi tiu paĝo aŭ ago.",
        "virus-badscanner": "Malbona konfiguro: nekonata virusa skanilo: ''$1''",
        "virus-scanfailed": "skano malsukcesis (kun kodo $1)",
        "userlogin-resetlink": "Ĉu vi forgesis ensalutajn detalojn?",
        "userlogin-resetpassword-link": "Ĉu vi forgesis vian pasvorton?",
        "userlogin-helplink2": "Helpo pri ensaluto",
-       "userlogin-loggedin": "Vi jam estas ensalutita kiel {{GENDER:$1|$1}}.\nUzu la formularon suben por ensaluti kiel alia uzanto.",
-       "userlogin-createanother": "Krei alian konton",
        "createacct-emailrequired": "Retpoŝta adreso",
        "createacct-emailoptional": "Retpoŝta adreso (nedeviga)",
        "createacct-email-ph": "Enigu vian retpoŝtan adreson",
        "passwordreset-emailsent-capture": "Retpoŝto kun renovigita pasvorto estis sendita, kiu estas montrata malsupre.",
        "passwordreset-emailerror-capture": "Retpoŝto kun renovigita pasvorto estis generita, montrata sube, sed sendado al la {{GENDER:$2|uzanto}} malsukcesis: $1",
        "changeemail": "Ŝanĝi retpoŝtadreson",
-       "changeemail-header": "Ŝanĝi retpoŝtadreso por konto",
        "changeemail-text": "Plenumu ĉi tiu formularon por ŝanĝi vian retpoŝtadreson. Vi devas enigi vian pasvorton por konfirmi ĉi tiun ŝanĝon.",
        "changeemail-no-info": "Vi devas ensaluti por atingi ĉi tiun paĝon rekte.",
        "changeemail-oldemail": "Aktuala retpoŝtadreso:",
        "changeemail-none": "(nenio)",
        "changeemail-password": "Via {{SITENAME}}-ensalutado:",
        "changeemail-submit": "Ŝanĝi retpoŝtadreson",
-       "changeemail-cancel": "Nuligi",
        "changeemail-throttled": "Vi tro ofte provis alsaluti.\nBonvolu atendi $1, antaŭ ol vi provos denove.",
        "resettokens": "Renovigi ŝlosilojn",
        "resettokens-text": "Vi povas rekomencigi ĵetonojn, kiuj ebligas aliron al certaj privataj datumoj, kiuj estas ligataj kun via konto de uzanto ĉi tie.\n\nVi faru tion, se vi akcidente kunhavigis ilin kun iu aŭ se via konto estis malkonfidencigita.",
        "preview": "Antaŭrigardo",
        "showpreview": "Antaŭrigardo",
        "showdiff": "Montri ŝanĝojn",
-       "anoneditwarning": "'''Averto:''' Vi ne estas ensalutinta.\nVia IP-adreso enregistriĝos en la redakta historio de tiu ĉi paĝo.",
+       "anoneditwarning": "<strong>Averto:</strong> Vi ne estas ensalutinta.\nVia IP-adreso enregistriĝos en la redakta historio de tiu ĉi paĝo. Se vi <strong>[$1 ensalutas]</strong> aŭ <strong>[$2 kreas konton]</strong>, viaj redaktoj estos atribuitaj al via salutnomo, kune kun aliaj bonaĵoj.",
        "anonpreviewwarning": "''Vi ne estas ensalutita. La konservo de la paĝo registros vian IP-adreson en redakta historio de ĉi tiu paĝo.''",
        "missingsummary": "'''Rememorigilo:''' Vi ne provizis redaktan resumon. Se vi alklakos denove la konservan butonon, via redaktaĵo estos konservita sen resumo.",
        "missingcommenttext": "Bonvolu entajpi komenton malsupre.",
        "searchall": "ĉiuj",
        "showingresults": "Montras {{PLURAL:$1|'''1''' trovitan|'''$1''' trovitajn}} ekde la #'''$2'''-a.",
        "showingresultsinrange": "Malsupre montriĝas {{PLURAL:$1|<strong>1</strong> rezulto|<strong>$1</strong> rezultoj}} en la intervalo #<strong>$2</strong> ĝis #<strong>$3</strong>.",
-       "showingresultsheader": "{{PLURAL:$5|Rezulto '''$1''' el '''$3'''|Rezultoj '''$1 – $2''' el '''$3'''}} por '''$4'''",
        "search-nonefound": "La serĉomendo rezultis kun neniuj trafoj.",
        "powersearch-legend": "Progresa serĉo",
        "powersearch-ns": "Serĉi en nomspacoj:",
        "nolicense": "Neniu elektita",
        "license-nopreview": "(Antaŭvido ne montrebla)",
        "upload_source_url": " (valida, publike atingebla URL-o)",
-       "upload_source_file": " (dosiero en via komputilo)",
+       "upload_source_file": "(dosiero elektita de via komputilo)",
        "listfiles-delete": "forigi",
        "listfiles-summary": "Ĉi tiu speciala paĝo montras ĉiujn alŝutitajn dosierojn.\nKiam oni filtras ĝin laŭ uzanto, nur la aktuala versio de la dosiero estos montrita.",
        "listfiles_search_for": "Serĉi dosieran nomon:",
        "randomincategory": "Hazarda paĝo en kategorio",
        "randomincategory-invalidcategory": "\"$1\" ne estas valida kategoria nomo.",
        "randomincategory-nopages": "Ne estas paĝoj en la kategorio [[:Category:$1|$1]].",
+       "randomincategory-category": "Kategorio:",
+       "randomincategory-legend": "Hazarda paĝo en kategorio",
        "randomredirect": "Hazarda alidirekto",
        "randomredirect-nopages": "Estas neniuj alidirektiloj en la nomspaco \"$1\".",
        "statistics": "Statistiko",
        "exbeforeblank": "antaŭ malplenigo enhavis: '$1'",
        "delete-confirm": "Forigi \"$1\"",
        "delete-legend": "Forigi",
-       "historywarning": "'''Averto:''' La forigota paĝo havas historion kun pli-malpli $1 {{PLURAL:$1|revizio|revizioj}}:",
+       "historywarning": "<strong>Averto:</strong> La forigota paĝo havas historion kun $1 {{PLURAL:$1|revizio|revizioj}}:",
        "confirmdeletetext": "Vi forigos la artikolon aŭ dosieron kaj forviŝos ĝian tutan historion el la datumaro.<br /> Bonvolu konfirmi, ke vi vere intencas tion, kaj ke vi komprenas la sekvojn, kaj ke vi ja sekvas la [[{{MediaWiki:Policy-url}}|regulojn pri forigado]].",
        "actioncomplete": "Ago farita",
        "actionfailed": "Ago malsukcesis",
        "autoblockid": "Aŭtomata forbaro #$1",
        "block": "Forbari uzanton",
        "unblock": "Malforbari uzanton",
-       "blockip": "Forbari uzanton/IP-adreson",
+       "blockip": "Forbari {{GENDER:$1|uzanton}}",
        "blockip-legend": "Forbari uzanton",
        "blockiptext": "Per jena formularo vi povas forpreni de ajna nomo aŭ IP-adreso la rajton skribi en la vikio. Oni faru tion ''nur'' por eviti vandalismon, kaj sekvante la [[{{MediaWiki:Policy-url}}|regulojn pri forbarado]]. Klarigu la precizan kialon malsupre (ekzemple, citu paĝojn, kiuj estis vandaligitaj).",
        "ipaddressorusername": "IP-adreso aŭ salutnomo:",
        "ipb-unblock-addr": "Restarigi $1",
        "ipb-unblock": "Malforbari salutnomon aŭ IP-adreson",
        "ipb-blocklist": "Vidi ekzistantajn forbarojn",
-       "ipb-blocklist-contribs": "Kontribuoj de $1",
+       "ipb-blocklist-contribs": "Kontribuoj de {{GENDER:$1|$1}}",
        "unblockip": "Malforbari IP-adreson/nomon",
        "unblockiptext": "Per la jena formulo vi povas repovigi al iu\nforbarita IP-adreso/nomo la povon enskribi en la vikio.",
        "ipusubmit": "Forigi ĉi tiun forbaron",
        "import": "Importi paĝojn",
        "importinterwiki": "Transvikia importo",
        "import-interwiki-text": "Elektu vikion kaj paĝan titolon por importi.\nDatoj de versioj kaj nomoj de redaktantoj estos preservitaj.\nĈiuj transvikaj importoj estas raportitaj ĉe la [[Special:Log/import|loglibro de importoj]].",
+       "import-interwiki-sourcewiki": "Fonta vikio:",
+       "import-interwiki-sourcepage": "Fonta paĝo:",
        "import-interwiki-history": "Kopiu ĉiujn historiajn versiojn por ĉi tiu pago.",
        "import-interwiki-templates": "Inkluzivi ĉiujn ŝablonojn",
        "import-interwiki-submit": "Importi",
        "import-upload": "Alŝuti XML-datenojn",
        "import-token-mismatch": "Seancaj datenoj perdiĝis. Bonvolu reprovi.",
        "import-invalid-interwiki": "Ne povas importi de la specifita vikio.",
-       "import-error-edit": "Paĝo \"$1\" ne estas importita ĉar vi ne rajtas radakti ĝin.",
-       "import-error-create": "Paĝo \"$1\" ne estas importita ĉar vi ne rajtas krei ĝin.",
+       "import-error-edit": "Paĝo \"$1\" ne estis importita ĉar vi ne rajtas radakti ĝin.",
+       "import-error-create": "Paĝo \"$1\" ne estis importita ĉar vi ne rajtas krei ĝin.",
        "import-error-interwiki": "Paĝo \"$1\" ne estis importita pro sia nomo estas deklarita por ekstera ligado (intervikia).",
-       "import-error-special": "Paĝo \"$1\" ne estas importata, ĉar ĝi apartenas al speciala nomspaco, kiu ne permesas paĝojn.",
-       "import-error-invalid": "Paĝo \"$1\" ne estas importata, ĉar ĝia nomo estas malvalida.",
+       "import-error-special": "Paĝo \"$1\" ne estis importata, ĉar ĝi apartenas al speciala nomspaco, kiu ne permesas paĝojn.",
+       "import-error-invalid": "Paĝo \"$1\" ne estis importata, ĉar ĝia nomo estas malvalida.",
        "import-error-unserialize": "La revizio n-ro $2 de la paĝo nomata \"$1\" ne povis senseriiĝi. La revizio raportiĝis uzi enhavmodelon n-ro $3, kiu seriiĝis kiel n-ro $4.",
        "import-options-wrong": "{{PLURAL:$2|Erara elekto|Eraraj elektoj}}: <nowiki>$1</nowiki>",
        "import-rootpage-invalid": "La provizita paĝo havas nevalidan titolon.",
        "import-logentry-upload": "importita [[$1]] de dosiera alŝuto",
        "import-logentry-upload-detail": "$1 {{PLURAL:$1|versio|versioj}}",
        "import-logentry-interwiki": "transvikiigita $1",
-       "import-logentry-interwiki-detail": "$1 {{PLURAL:$1|versio|versioj}} de $2",
+       "import-logentry-interwiki-detail": "Importis $1 {{PLURAL:$1|revizion|reviziojn}} de $2",
        "javascripttest": "Ĝavoskripta testado",
        "javascripttest-title": "Irigante $1 testoj",
        "javascripttest-pagetext-noframework": "Ĉi tiu paĝo estas konservita por funkciigi testojn de JavaScript.",
        "autosumm-replace": "Anstataŭigis paĝon per '$1'",
        "autoredircomment": "Alidirektigis al [[$1]]",
        "autosumm-new": "Nova paĝo kun '$1'",
+       "autosumm-newblank": "Kreis nulan paĝon",
        "lag-warn-normal": "Ŝanĝoj pli novaj ol $1 {{PLURAL:$1|sekundo|sekundoj}} eble ne estos montrataj en ĉi tiu listo.",
        "lag-warn-high": "Pro malrapideco de la servila datumbazo, ŝanĝoj pli novaj ol $1 {{PLURAL:$1|sekundo|sekundoj}} eble ne montriĝos en ĉi tiu listo.",
        "watchlistedit-normal-title": "Redakti atentaron",
        "logentry-rights-rights": "$1 ŝanĝis grupan membrecon por $3 de $4 al $5",
        "logentry-rights-rights-legacy": "$1 ŝanĝis grupan membrecon por $3",
        "logentry-rights-autopromote": "$1 estis aŭtomate {{GENDER:$2|altrangigita}} de $4 al $5",
+       "logentry-upload-revert": "$1 {{GENDER:$2|alŝutis}} $3",
        "rightsnone": "(nenia)",
+       "revdelete-summary": "redaktoresumon",
        "feedback-bugornote": "Se vi pretas priskribi teknikan problemon detale, bonvolu [$1 raporti cimon].\nAŭ vi povas uzi la facilan formularon sube. Via komento estos aldonita al la paĝo \"[$3 $2]\", kune kun via salutnomo kaj uzita retumilo.",
        "feedback-subject": "Temo:",
        "feedback-message": "Mesaĝo:",
        "action-pagelang": "ŝanĝi la lingvon de la paĝo",
        "log-name-pagelang": "Ŝanĝi la lingvan protokolon",
        "log-description-pagelang": "Jen protokolo pri ŝanĝoj de paĝaj lingvoj.",
-       "logentry-pagelang-pagelang": "$1 {{GENDER:$2|ŝanĝis}} la paĝan lingvon por $3 de $4 al $5."
+       "logentry-pagelang-pagelang": "$1 {{GENDER:$2|ŝanĝis}} la paĝan lingvon por $3 de $4 al $5.",
+       "default-skin-not-found-row-enabled": "* <code>$1</code> / $2 (ŝalta)",
+       "default-skin-not-found-row-disabled": "* <code>$1</code> / $2 ('''malŝalta''')",
+       "mediastatistics-nbytes": "{{PLURAL:$1|$1 bitoko|$1 bitokoj}} ($2; $3%)",
+       "mediastatistics-table-mimetype": "MIME-tipo",
+       "mediastatistics-table-count": "Nombro de dosieroj",
+       "mediastatistics-header-unknown": "Nekonata",
+       "mediastatistics-header-audio": "Sonaj",
+       "mediastatistics-header-video": "Videaj dosieroj",
+       "mediastatistics-header-multimedia": "Multmediaj",
+       "mediastatistics-header-office": "Oficejaj",
+       "mediastatistics-header-text": "Tekstaj"
 }
index 076b5c9..00a866a 100644 (file)
        "otherlanguages": "Otros idiomas",
        "redirectedfrom": "(Redirigido desde «$1»)",
        "redirectpagesub": "Página de redirección",
+       "redirectto": "Redirigir a:",
        "lastmodifiedat": "Esta página fue modificada por última vez el $1 a las $2.",
        "viewcount": "Esta página se ha visitado {{PLURAL:$1|una vez|$1 veces}}.",
        "protectedpage": "Página protegida",
        "searchall": "todos",
        "showingresults": "Abajo se {{PLURAL:$1|muestra '''1''' resultado|muestran hasta '''$1''' resultados}} comenzando por el n.º '''$2'''.",
        "showingresultsinrange": "Abajo se muestran hasta {{PLURAL:$1|<strong>1</strong> resultado|<strong>$1</strong> resultados}} en el rango #<strong>$2</strong> hasta #<strong>$3</strong>.",
-       "showingresultsheader": "{{PLURAL:$5|Resultado '''$1''' de '''$3'''|Resultados '''$1-$2''' de '''$3'''}} para '''$4'''",
        "search-nonefound": "No hay resultados que cumplan los criterios de búsqueda.",
        "powersearch-legend": "Búsqueda avanzada",
        "powersearch-ns": "Buscar en los espacios de nombres:",
index ba9125c..4e43b20 100644 (file)
        "category-file-count": "{{PLURAL:$2|Selles kategoorias on ainult järgmine fail.|{{PLURAL:$1|Järgmine fail |Järgmised $1 faili}} on selles kategoorias (kokku $2).}}",
        "category-file-count-limited": "{{PLURAL:$1|Järgmine fail|Järgmised $1 faili}} on selles kategoorias.",
        "listingcontinuesabbrev": "jätk",
-       "index-category": "Indeksiga leheküljed",
+       "index-category": "Indekseeritud leheküljed",
        "noindex-category": "Indekseerimata leheküljed",
        "broken-file-category": "Katkiste pildilinkidega leheküljed",
        "about": "Tiitelandmed",
        "passwordreset-emailsent-capture": "E-kirjatsi on saadetud allpool näidatav parooli lähtestuskiri.",
        "passwordreset-emailerror-capture": "Koostati allpool näidatav parooli lähtestuskiri, aga selle e-kirjatsi {{GENDER:$2|kasutajale}} saatmine ebaõnnestus: $1",
        "changeemail": "E-posti aadressi muutmine",
-       "changeemail-header": "Konto e-posti aadressi muutmine",
        "changeemail-text": "Täida see vorm, et muuta oma e-posti aadress. Et seda muudatust kinnitada, pead sisestama oma parooli.",
        "changeemail-no-info": "Otselingi kaudu sellele lehele jõudmiseks pead olema sisse loginud.",
        "changeemail-oldemail": "Praegune e-posti aadress:",
        "changeemail-none": "(puudub)",
        "changeemail-password": "Sinu parool {{GRAMMAR:inessive|{{SITENAME}}}}:",
        "changeemail-submit": "Muuda e-posti aadress",
-       "changeemail-cancel": "Loobu",
        "changeemail-throttled": "Oled proovinud liiga palju kordi sisse logida.\nPalun oota $1, enne kui uuesti proovid.",
        "resettokens": "Lubade lähtestamine",
        "resettokens-text": "Saad lähtestada load, mida on vaja siin sinu kontoga seotud kindlatele eraandmetele ligipääsuks.\n\nPeaksid load lähtestama, kui jagasid neid kogemata või kui su konto on kellegi teise võimusesse sattunud.",
        "searchall": "kõik",
        "showingresults": "Allpool näidatakse '''{{PLURAL:$1|ühte|$1}}''' tulemust alates '''$2'''. tulemusest.",
        "showingresultsinrange": "Allpool näidatakse {{PLURAL:$1|<strong>üht</strong>|<strong>$1</strong>}} tulemust vahemikus <strong>$2</strong>–<strong>$3</strong>.",
-       "showingresultsheader": "{{PLURAL:$5|'''$1''' '''$3'''-st vastest|Vasted '''$1–$2''' '''$3'''-st}} päringule '''$4'''",
+       "search-showingresults": "{{PLURAL:$4|<strong>$1</strong>. tulemus <strong>$3</strong>-st|Tulemused <strong>$1–$2</strong> <strong>$3</strong>-st}}",
        "search-nonefound": "Päringule ei leitud vasteid.",
        "powersearch-legend": "Täpsem otsing",
        "powersearch-ns": "Otsing nimeruumidest:",
        "unblocked": "Kasutaja [[User:$1|$1]] blokeering on eemaldatud",
        "unblocked-range": "Vahemiku $1 blokeering on eemaldatud",
        "unblocked-id": "Blokeerimine $1 on lõpetatud",
+       "unblocked-ip": "IP-aadressi [[Special:Contributions/$1|$1]] blokeering on eemaldatud.",
        "blocklist": "Blokeeritud kasutajad",
        "ipblocklist": "Blokeeritud kasutajad",
        "ipblocklist-legend": "Leia blokeeritud kasutaja",
        "logentry-upload-overwrite": "$1 {{GENDER:$2|laadis üles}} uue versiooni failist $3",
        "logentry-upload-revert": "$1 {{GENDER:$2|laadis üles}} faili $3",
        "rightsnone": "(puudub)",
+       "revdelete-summary": "resümee",
        "feedback-bugornote": "Kui arvad, et oskad tehnilist probleemi üksikasjalikult kirjeldada, [$1 teata veast].\nKui ei, kasuta allolevat lihtsat vormi. Sinu kommentaar lisatakse koos kasutajanime ja teabega kasutatava võrgulehitsejaga kohta leheküljele \"[$3 $2]\".",
        "feedback-subject": "Teema:",
        "feedback-message": "Sõnum:",
        "log-name-pagelang": "Keele muutmise logi",
        "log-description-pagelang": "Siia on logitud lehekülgede keele muutmised.",
        "logentry-pagelang-pagelang": "$1 {{GENDER:$2|muutis}} lehekülje \"$3\" keelt: $4 → $5.",
-       "default-skin-not-found": "Oih! Sinu viki vaikekujundus (<code>$wgDefaultSkin</code>) <code>$1</code> pole saadaval.\n\nPaistab, et sinu install sisaldab järgmisi kujundusi. Vaata [https://www.mediawiki.org/wiki/Manual:Skin_configuration kujunduste häälestusjuhendist], kuidas neid lubada ja kuidas valida vaikekujundus.\n\n$2\n\n; Kui oled MediaWiki just paigaldanud:\n: Paigaldasid tarkvara ilmselt Giti kaudu või otse lähtekoodist või mõnel muul viisil. See on ootuspärane. Proovi [https://www.mediawiki.org/wiki/Category:All_skins mediawiki.org-i kujunduste kataloogist] mõni kujundus paigaldada. Selleks saad:\n:* laadida alla [https://www.mediawiki.org/wiki/Download lintarhiivi paigaldaja], mis sisaldab mitut kujundust ja tarkvaralisa. Saad sealt kleepimiseks kopeerida kausta <code>skins/</code>;\n:* kopeerida Giti kaudu ühe hoidla (<code>mediawiki/skins/*</code>) oma MediaWiki installi kausta <code>skins/</code>.\n: Selle tegemine ei tohiks häirida Giti hoidlat, kui oled MediaWiki arendaja.\n\n; Kui oled MediaWikit just täiendanud:\n: MediaWiki 1.24-s ja uuemates versioonides pole paigaldatud kujundused enam automaatselt lubatud (vaata juhendist [https://www.mediawiki.org/wiki/Manual:Skin_autodiscovery kujunduste automaatse leidmise] kohta). Saad kleepida järgmised read leheküljele <code>LocalSettings.php</code>, et lubada kõik praegu paigaldatud kujundused:\n\n<pre>$3</pre>\n\n; Kui oled lehekülge <code>LocalSettings.php</code> just muutnud:\n: Kontrolli üle, ega kujunduste nimedes pole trükivigu.",
-       "default-skin-not-found-no-skins": "Oih! Sinu viki vaikekujundus (<code>$wgDefaultSkin</code>) <code>$1</code> pole saadaval.\n\nÜhtegi kujundust pole paigaldatud.\n\n; Kui oled MediaWiki just paigaldanud või täiendasid seda:\n: Paigaldasid tarkvara ilmselt Giti kaudu või otse lähtekoodist või mõnel muul viisil. See on ootuspärane. MediaWiki 1.24 ja uuemad versioonid ei sisalda peahoidlas ühtegi kujundust. Proovi [https://www.mediawiki.org/wiki/Category:All_skins mediawiki.org-i kujunduste kataloogist] mõni kujundus paigaldada. Selleks saad:\n:* laadida alla [https://www.mediawiki.org/wiki/Download lintarhiivi paigaldaja], mis sisaldab mitut kujundust ja tarkvaralisa. Saad sealt kleepimiseks kopeerida kausta <code>skins/</code>;\n:* kopeerida Giti kaudu ühe hoidla (<code>mediawiki/skins/*</code>) oma MediaWiki installi kausta <code>skins/</code>.\n: Selle tegemine ei tohiks häirida Giti hoidlat, kui oled MediaWiki arendaja. Vaata [https://www.mediawiki.org/wiki/Manual:Skin_configuration kujunduste häälestusjuhendist], kuidas kujundusi lubada ja kuidas valida vaikekujundus.",
+       "default-skin-not-found": "Oih! Sinu viki vaikekujundus, milleks muutuja <code dir=\"ltr\">$wgDefaultSkin</code> järgi on <code>$1</code>, pole saadaval.\n\nPaistab, et sinu install sisaldab järgmisi kujundusi. Vaata [https://www.mediawiki.org/wiki/Manual:Skin_configuration kujunduste häälestusjuhendist], kuidas neid lubada ja kuidas valida vaikekujundus.\n\n$2\n\n; Kui oled MediaWiki just paigaldanud:\n: Paigaldasid tarkvara ilmselt Giti kaudu või otse lähtekoodist või mõnel muul viisil. See on ootuspärane. Proovi [https://www.mediawiki.org/wiki/Category:All_skins mediawiki.org-i kujunduste kataloogist] mõni kujundus paigaldada. Selleks saad:\n:* laadida alla [https://www.mediawiki.org/wiki/Download lintarhiivi paigaldaja], mis sisaldab mitut kujundust ja tarkvaralisa. Saad sealt kleepimiseks kopeerida kausta <code dir=\"ltr\">skins/</code>;\n:* kopeerida Giti kaudu ühe hoidla (<code>mediawiki/skins/*</code>) oma MediaWiki installi kausta <code>skins/</code>.\n: Selle tegemine ei tohiks häirida Giti hoidlat, kui oled MediaWiki arendaja.\n\n; Kui oled MediaWikit just täiendanud:\n: MediaWiki 1.24-s ja uuemates versioonides pole paigaldatud kujundused enam automaatselt lubatud (vaata juhendist [https://www.mediawiki.org/wiki/Manual:Skin_autodiscovery kujunduste automaatse leidmise] kohta). Saad kleepida järgmised read leheküljele <code>LocalSettings.php</code>, et lubada kõik praegu paigaldatud kujundused:\n\n<pre dir=\"ltr\">$3</pre>\n\n; Kui oled lehekülge <code>LocalSettings.php</code> just muutnud:\n: Kontrolli üle, ega kujunduste nimedes pole trükivigu.",
+       "default-skin-not-found-no-skins": "Oih! Sinu viki vaikekujundus, milleks muutuja <code dir=\"ltr\">$wgDefaultSkin</code> järgi on <code>$1</code>, pole saadaval.\n\nÜhtegi kujundust pole paigaldatud.\n\n; Kui oled MediaWiki just paigaldanud või täiendasid seda:\n: Paigaldasid tarkvara ilmselt Giti kaudu või otse lähtekoodist või mõnel muul viisil. See on ootuspärane. MediaWiki 1.24 ja uuemad versioonid ei sisalda peahoidlas ühtegi kujundust. Proovi [https://www.mediawiki.org/wiki/Category:All_skins mediawiki.org-i kujunduste kataloogist] mõni kujundus paigaldada. Selleks saad:\n:* laadida alla [https://www.mediawiki.org/wiki/Download lintarhiivi paigaldaja], mis sisaldab mitut kujundust ja tarkvaralisa. Saad sealt kleepimiseks kopeerida kausta <code dir=\"ltr\">skins/</code>;\n:* kopeerida Giti kaudu ühe hoidla (<code>mediawiki/skins/*</code>) oma MediaWiki installi kausta <code>skins/</code>.\n: Selle tegemine ei tohiks häirida Giti hoidlat, kui oled MediaWiki arendaja. Vaata [https://www.mediawiki.org/wiki/Manual:Skin_configuration kujunduste häälestusjuhendist], kuidas kujundusi lubada ja kuidas valida vaikekujundus.",
        "default-skin-not-found-row-enabled": "* <code>$1</code> / $2 (lubatud)",
        "default-skin-not-found-row-disabled": "* <code>$1</code> / $2 ('''keelatud''')"
 }
index 26a9f3a..53fb8ae 100644 (file)
        "category-file-count-limited": "{{PLURAL:$1|پروندهٔ|$1 پروندهٔ}} زیر در ردهٔ فعلی قرار دارند.",
        "listingcontinuesabbrev": "(ادامه)",
        "index-category": "صفحات فهرست‌شده",
-       "noindex-category": "صفحات فهرست‌نشده",
+       "noindex-category": "صفحه‌های نمایه‌نشده",
        "broken-file-category": "صفحات دارای پیوند خراب به پرونده",
        "about": "درباره",
        "article": "صفحهٔ محتوایی",
        "otherlanguages": "به زبان‌های دیگر",
        "redirectedfrom": "(تغییرمسیر از $1)",
        "redirectpagesub": "صفحهٔ تغییرمسیر",
+       "redirectto": "تغییر مسیر به:",
        "lastmodifiedat": "این صفحه آخرین‌بار در $1 ساعت $2 تغییر یافته‌است.",
        "viewcount": "از این صفحه {{PLURAL:$1|یک‌بار|$1بار}} بازدید شده‌است.",
        "protectedpage": "صفحهٔ محافظت‌شده",
        "passwordreset-emailsent-capture": "یک رایانامهٔ بازنشانی که در پایین نمایش داده شده، فرستاده شده است.",
        "passwordreset-emailerror-capture": "رایانامهٔ بازنشانی، که در زیر نمایش داده شده، ایجاد شد، ولی ارسال آن به {{GENDER:$2|کاربر}} موفقیت‌آمیز نبود: $1",
        "changeemail": "تغییر نشانی رایانامه",
-       "changeemail-header": "تغییر نشانی رایانامهٔ حساب کاربری",
        "changeemail-text": "این فرم را تکمیل کنید تا آدرس رایانامه‌تان تغییر یابد. برای این که این تغییر را تأیید کنید لازم است گذرواژهٔ خود را وارد کنید.",
        "changeemail-no-info": "برای دسترسی مستقیم به این صفحه شما باید به سامانه وارد شده باشید.",
        "changeemail-oldemail": "نشانی رایانامهٔ کنونی:",
        "changeemail-none": "(هیچ)",
        "changeemail-password": " {{SITENAME}} رمز عبور شما:",
        "changeemail-submit": "تغییر رایانامه",
-       "changeemail-cancel": "انصراف",
        "changeemail-throttled": "شما به مراتب برای ورود تلاش کرده‌اید.\nلطفاً پیش از آنکه دوباره تلاش کنید $1 صبر کنید.",
        "resettokens": "بازنشانی شناساننده‌ها",
        "resettokens-text": "شما می توانید شناساننده‌ها که اجازهٔ دسترسی به برخی داده‌های خصوصی مرتبط با حسابتان را می‌دهد بازنشانی کنید.\nدر صورتی باید این کار را انجام دهید که تصادقاً آن‌ها را با کسی در میان گذاشته‌اید یا به حسابتان نفوذ شده است.",
        "mergehistory-go": "نمایش تاریخچه قابل ادغام",
        "mergehistory-submit": "ادغام نسخه‌ها",
        "mergehistory-empty": "هیچ‌یک از نسخه‌ها قابل ادغام نیستند.",
-       "mergehistory-success": "$3 نسخه از [[:$1]]  با موفقیت در [[:$2]] ادغام {{PLURAL:$3|شد|شدند}}.",
+       "mergehistory-success": "$3 نسخه از [[:$1]]  با موفقیت در [[:$2]] ادغام {{PLURAL:$3|شد}}.",
        "mergehistory-fail": "ادغام تاریخچه ممکن نیست، لطفاً گزینه‌های صفحه و زمان را بازبینی کنید.",
        "mergehistory-fail-toobig": "نمی‌توان ادغام تاریخچه را انجام داد که بیشتر از محدودیت $1 {{PLURAL:$1|نسخه}} انتقال داده خواهد شد.",
        "mergehistory-no-source": "صفحهٔ مبدأ $1 وجود ندارد.",
        "searchall": "همه",
        "showingresults": "نمایش حداکثر {{PLURAL:$1|'''۱''' نتیجه|'''$1''' نتیجه}} در پایین، آغاز از شماره '''$2'''.",
        "showingresultsinrange": "نمایش در پائین تا {{PLURAL:$1|<strong>1</strong> نتیجه|<strong>$1</strong> نتیجه}} in range #<strong>$2</strong> تا #<strong>$3</strong>.",
-       "showingresultsheader": "{{PLURAL:$5|نتیجهٔ '''$1''' از '''$3'''|نتایج '''$1 تا $2''' از '''$3'''}} برای '''$4'''",
+       "search-showingresults": "{{PLURAL:$4|نتایج <strong>$1</strong> از <strong>$3</strong>|نتایج <strong>$1 - $2</strong از <strong>$3</strong>}}",
        "search-nonefound": "نتیجه‌ای منطبق با درخواست پیدا نشد.",
        "powersearch-legend": "جستجوی پیشرفته",
        "powersearch-ns": "جستجو در فضاهای نام:",
        "filerevert-comment": "دلیل:",
        "filerevert-defaultcomment": "واگردانی به نسخهٔ $1 ساعت $2",
        "filerevert-submit": "برو",
-       "filerevert-success": "''[[Media:$1|$1]]''' به [$4 نسخهٔ مورخ $2 ساعت $3] واگردانده شد.",
+       "filerevert-success": "<strong>[[Media:$1|$1]]</strong> به [$4 نسخهٔ مورخ $2 ساعت $3] واگردانده شد.",
        "filerevert-badversion": "نسخهٔ قدیمی‌تری از این پرونده وجود نداشت.",
        "filedelete": "حذف $1",
        "filedelete-legend": "حذف پرونده",
        "protect-othertime": "زمانی دیگر:",
        "protect-othertime-op": "زمانی دیگر",
        "protect-existing-expiry": "زمان انقضای موجود: $2، $3",
+       "protect-existing-expiry-infinity": "زمان انقضای موجود: بی‌نهایت",
        "protect-otherreason": "دلیل دیگر/اضافی:",
        "protect-otherreason-op": "دلیل دیگر",
        "protect-dropdown": "*دلایل متداول محافظت\n** خرابکاری گسترده\n** هرزنگاری گسترده\n** جنگ ویرایشی غیر سازنده\n** صفحهٔ پر بازدید",
        "contribsub2": "برای {{GENDER:$3|$1}} ($2)",
        "contributions-userdoesnotexist": "حساب کاربری «$1» ثبت نشده‌است.",
        "nocontribs": "هیچ تغییری با این مشخصات یافت نشد.",
-       "uctop": "(نسخه کنونی)",
+       "uctop": "(نسخهٔ کنونی)",
        "month": "در این ماه (و پیش از آن):",
        "year": "در این سال (و پیش از آن):",
        "sp-contributions-newbies": "فقط مشارکت‌های تازه‌کاران نمایش داده شود",
        "unblocked": "دسترسی [[User:$1|$1]] دوباره برقرار شد",
        "unblocked-range": "$1 باز شد",
        "unblocked-id": "قطع دسترسی شماره $1 خاتمه یافت",
+       "unblocked-ip": "[[Special:Contributions/$1|$1]] رفع قطع دسترسی شد.",
        "blocklist": "کاربران بسته‌شده",
        "ipblocklist": "کاربران بسته‌شده",
        "ipblocklist-legend": "جستجوی کاربر بسته شده",
        "tags": "برچسب‌های تغییر مجاز",
        "tag-filter": "پالایش [[Special:Tags|برچسب‌ها]]:",
        "tag-filter-submit": "پالایه",
-       "tag-list-wrapper": "([[Special:Tags|{{PLURAL:$1|برچسب|برچسب}}]]: $2)",
+       "tag-list-wrapper": "([[Special:Tags|{{PLURAL:$1|برچسب|برچسب‌ها}}]]: $2)",
        "tags-title": "برچسب‌ها",
        "tags-intro": "این صفحه فهرستی‌است از برچسب‌هایی که نرم‌افزار با آن‌ها ویرایش‌ها را علامت‌گذری می‌کند، به همراه معانی آن‌ها.",
        "tags-tag": "نام برچسب",
        "logentry-rights-rights-legacy": "$1 گروه عضویت $3 را {{GENDER:$2|تغییر داد}}",
        "logentry-rights-autopromote": "$1 به طور خودکار از $4 به $5 {{GENDER:$2|ارتقاء داد}}",
        "logentry-upload-upload": "$1 $3 را {{GENDER:$2|بارگذاری کرد}}",
-       "logentry-upload-overwrite": "$1 یک نسخهٔ تازه {{GENDER:$2|بارگذاری‌کرد}} $3",
+       "logentry-upload-overwrite": "$1 نسخهٔ تازه‌ای از $3 را {{GENDER:$2|بارگذاری کرد}}",
        "logentry-upload-revert": "$1 {{GENDER:$2|بارگذاری کرد}} $3",
        "rightsnone": "(هیچ)",
+       "revdelete-summary": "خلاصه ویرایش",
        "feedback-bugornote": "اگر آماده‌اید تا مشکلی فنی را با جزئیاتش شرح دهید لطفاً [$1 یک ایراد گزارش دهید]. در غیر این صورت می‌توانید از فرم سادهٔ زیر استفاده کنید. نظر شما به همراه نام کاربری و مرورگرتان به صفحهٔ «[$3 $2]» افزوده خواهد شد.",
        "feedback-subject": "موضوع:",
        "feedback-message": "پیغام:",
        "log-name-pagelang": "تغییر سیاههٔ زبان",
        "log-description-pagelang": "این سیاههٔ تغییرات صفحهٔ زبان‌ها است.",
        "logentry-pagelang-pagelang": "$1 {{GENDER:$2| تغییریافت}} زبان صفحه برای  $3  از  $4  به  $5 .",
-       "default-skin-not-found": "اوه! پوسته پیش‌فرض برای ویکی شما (<code>$wgDefaultSkin</code>)، <code>$1</code>، در دسترس نیست.\n\nبه نظر می‌آید نصب شما شامل پوسته‌های زیر می‌شود. [https://www.mediawiki.org/wiki/Manual:Skin_configuration راهنما: تنظیمات پوسته] را برای کسب اطلاعات در باره چگونگی فعال‌ساختن آن‌ها و انتخاب پیش‌فرض ببینید.\n\n$2\n\n; اگر اخیراً مدیاویکی را نصب کرده‌اید:\n: احتمالاً از گیت، یا به طور مستقیم از کد مبدأ که از چند متد دیگر استفاده می‌کند نصب کردید. انتظار می‌رود. چند پوسته از [https://www.mediawiki.org/wiki/Category:All_skins فهرست پوسته mediawiki.org] نصب کنید، که همراه چندین پوسته و افزونه هستند. شما می‌توانید شاخه <code>skins/</code> را از آن نسخه‌برداری کرده و بچسبانید.\n\n:* همسانه‌سازی یکی از مخازن <code>mediawiki/skins/*</code> از طریق گیت به داخل شاخه <code>skins/</code> از نصب مدیاویکی‌تان.\n: انجام این کار با مخزن گیت‌تان تداخل نمی‌کند اگر توسعه‌دهنده مدیاویکی هستید.\n\n; اگر اخیراً مدیاویکی را ارتقاء دادید:\n: مدیاویکی ۱٫۲۴ و تازه‌تر دیگر به طور خودکار پوسته‌های نصب‌شده را فعال نمی‌کند ([https://www.mediawiki.org/wiki/Manual:Skin_autodiscovery راهنما: کشف خودکار پوسته] را ببینید). شما می‌توانید خطوط زیر را به داخل <code>LocalSettings.php</code> بچسبانید تا همه پوسته‌های نصب‌شده جاری را فعال کنید:\n\n<pre>$3</pre>\n\n; اگر اخیراً <code>LocalSettings.php</code> را تغییر دادید:\n: نام پوسته‌ها را برای غلط املایی دوباره بررسی کنید.",
-       "default-skin-not-found-no-skins": "پوستهٔ پیش‌فرض برای ویکی شما  (<code>$wgDefaultSkin</code>)، <code>$1</code> هست موجود نیست.\n\nشما پوسته‌ها را نصب نکرده‌اید.\n\n:اگر مدیاویکی را به‌روز یا نصب کرده‌اید:\n:ممکن است از گیت یا از کند منبع با روش های دیگر نصب کرده‌اید. انتظار می‌رود MediaWiki 1.24 یا جدیدتر در پوشهٔ اصلی هیچ پوسته‌ای نداشته باشند.\nسعی کنید تعدادی پوسته از [https://www.mediawiki.org/wiki/Category:All_skins پوشهٔ پوسته‌های مدیاویکی]، با:\n:*دانلود کردن [https://www.mediawiki.org/wiki/Download نصب‌کننده تاربال]، که با چندین پوسته و افزونه هست. شما می توانید پوستهٔ <code>skins/</code> را  از آن کپی و پیست کنید.\n:*کلون کردن یکی از <code>mediawiki/skins/*</code> از ریپوزیتوری در پوشهٔ <code>skins/</code> مدیاویکی‌تان.\n:اگر توسعه‌دهندهٔ مدیاویکی هستید، انجام این کار نباید تعارضی با ریپوزیتوری گیت شما داشته باشد. برای اطلاعات بیشتر و فعال کردن پوسته‌ها و انتخاب آنها به عنوان پیش‌فرض [https://www.mediawiki.org/wiki/Manual:Skin_configuration Manual: تنظیمات پوسته] را مشاهده کنید.",
+       "default-skin-not-found": "اوه! پوسته پیش‌فرض برای ویکی شما تعریف‌شده در <code dir=\"ltr\"<$wgDefaultSkin</code> به‌عنوان <code>$1</code>، در دسترس نیست.\n\nبه نظر می‌آید نصب شما شامل پوسته‌های زیر می‌شود. [https://www.mediawiki.org/wiki/Manual:Skin_configuration راهنما: تنظیمات پوسته] را برای کسب اطلاعات در باره چگونگی فعال‌ساختن آن‌ها و انتخاب پیش‌فرض ببینید.\n\n$2\n\n; اگر اخیراً مدیاویکی را نصب کرده‌اید:\n: احتمالاً از گیت، یا به طور مستقیم از کد مبدأ که از چند متد دیگر استفاده می‌کند نصب کردید. انتظار می‌رود. چند پوسته از [https://www.mediawiki.org/wiki/Category:All_skins فهرست پوسته mediawiki.org] نصب کنید، که همراه چندین پوسته و افزونه هستند. شما می‌توانید شاخه <code>skins/</code> را از آن نسخه‌برداری کرده و بچسبانید.\n\n:* همسانه‌سازی یکی از مخازن <code>mediawiki/skins/*</code> از طریق گیت به داخل شاخه <code dir=\"ltr\">skins/</code> از نصب مدیاویکی‌تان.\n: انجام این کار با مخزن گیت‌تان تداخل نمی‌کند اگر توسعه‌دهنده مدیاویکی هستید.\n\n; اگر اخیراً مدیاویکی را ارتقاء دادید:\n: مدیاویکی ۱٫۲۴ و تازه‌تر دیگر به طور خودکار پوسته‌های نصب‌شده را فعال نمی‌کند ([https://www.mediawiki.org/wiki/Manual:Skin_autodiscovery راهنما: کشف خودکار پوسته] را ببینید). شما می‌توانید خطوط زیر را به داخل <code>LocalSettings.php</code> بچسبانید تا همه پوسته‌های نصب‌شده جاری را فعال کنید:\n\n<pre dir=\"ltr\">$3</pre>\n\n; اگر اخیراً <code>LocalSettings.php</code> را تغییر دادید:\n: نام پوسته‌ها را برای غلط املایی دوباره بررسی کنید.",
+       "default-skin-not-found-no-skins": "پوستهٔ پیش‌فرض برای ویکی شما تعریف‌شده در<code>$wgDefaultSkin</code> به‌عنوان <code>$1</code>، هست موجود نیست.\n\nشما پوسته‌ها را نصب نکرده‌اید.\n\n:اگر مدیاویکی را به‌روز یا نصب کرده‌اید:\n:ممکن است از گیت یا از کند منبع با روش های دیگر نصب کرده‌اید. انتظار می‌رود MediaWiki 1.24 یا جدیدتر در پوشهٔ اصلی هیچ پوسته‌ای نداشته باشند.\nسعی کنید تعدادی پوسته از [https://www.mediawiki.org/wiki/Category:All_skins پوشهٔ پوسته‌های مدیاویکی]، با:\n:*دانلود کردن [https://www.mediawiki.org/wiki/Download نصب‌کننده تاربال]، که با چندین پوسته و افزونه هست. شما می توانید پوستهٔ <code>skins/</code> را  از آن کپی و پیست کنید.\n:*کلون کردن یکی از <code dir=\"ltr\">mediawiki/skins/*</code> از ریپوزیتوری در پوشهٔ <code>skins/</code> مدیاویکی‌تان.\n:اگر توسعه‌دهندهٔ مدیاویکی هستید، انجام این کار نباید تعارضی با ریپوزیتوری گیت شما داشته باشد. برای اطلاعات بیشتر و فعال کردن پوسته‌ها و انتخاب آنها به عنوان پیش‌فرض [https://www.mediawiki.org/wiki/Manual:Skin_configuration Manual: تنظیمات پوسته] را مشاهده کنید.",
        "default-skin-not-found-row-enabled": "* <code>$1</code> / $2 (فعال)",
        "default-skin-not-found-row-disabled": "* <code>$1</code> / $2 ('''غیر فعال''')"
 }
index 30ec391..ca3de45 100644 (file)
@@ -40,7 +40,8 @@
                        "לערי ריינהארט",
                        "아라",
                        "Syreeni",
-                       "MrTapsa"
+                       "MrTapsa",
+                       "SMAUG"
                ]
        },
        "tog-underline": "Linkkien alleviivaus:",
        "passwordreset-emailsent-capture": "Salasanan uudistamisesta kertova sähköpostiviesti on lähetetty, ja se näkyy myös alla.",
        "passwordreset-emailerror-capture": "Allaoleva sähköpostiviesti luotiin, mutta sen lähettäminen {{GENDER:$2|käyttäjälle}} epäonnistui: $1",
        "changeemail": "Muuta sähköpostiosoitetta",
-       "changeemail-header": "Muuta tunnuksen sähköpostiosoite",
        "changeemail-text": "Voit vaihtaa sähköpostiosoitteesi täyttämällä tämän lomakkeen. Muutoksen vahvistamiseen tarvitaan myös salasana.",
        "changeemail-no-info": "Tämän sivun käyttö edellyttää sisäänkirjautumista.",
        "changeemail-oldemail": "Nykyinen sähköpostiosoite:",
        "changeemail-none": "(ei asetettu)",
        "changeemail-password": "{{SITENAME}}-salasanasi:",
        "changeemail-submit": "Muuta sähköpostiosoite",
-       "changeemail-cancel": "Peruuta",
        "changeemail-throttled": "Olet tehnyt liian monta kirjautumisyritystä.\nOdota $1 ennen kuin yrität uudelleen.",
        "resettokens": "Uudista avaimet",
        "resettokens-text": "Tällä sivulla voit uudistaa avaimesi (''eng.'' reset tokens), jotka mahdollistavat pääsyn käyttäjätunnukseesi liittyviin tiettyihin yksityisiin tietoihin.\n\nSinun pitäisi tehdä tämä, jos olet vahingossa jakanut avaimet jonkun kanssa tai jos käyttäjätunnuksesi on vaarannettu.",
        "showpreview": "Esikatsele",
        "showdiff": "Näytä muutokset",
        "blankarticle": "<strong>Varoitus:</strong> Sivu, jota olet luomassa, on tyhjä.\nJos napsautat \"{{int:savearticle}}\" uudelleen, sivu luodaan ilman sisältöä.",
-       "anoneditwarning": "'''Varoitus:''' Et ole kirjautunut sisään.\nIP-osoitteesi kirjataan tämän sivun muutoshistoriaan.",
+       "anoneditwarning": "<strong>Varoitus:</strong> Et ole kirjautunut sisään. IP-osoitteesi näkyy julkisesti kaikille, jos muokkaat. Jos <strong>[$1 kirjaudut sisään]</strong> tai <strong>[$2 luot tunnuksen]</strong>, muokkauksesi kirjataan käyttäjätunnuksesi tekemiksi ja samalla saat käyttöösi hyödyllisiä välineitä.",
        "anonpreviewwarning": "''Et ole kirjautunut sisään. Tallentaminen kirjaa IP-osoitteesi tämän sivun muutoshistoriaan.''",
        "missingsummary": "Et ole antanut yhteenvetoa. Jos valitset Tallenna uudelleen, niin muokkauksesi tallennetaan ilman yhteenvetoa.",
        "missingcommenttext": "Kirjoita viesti alle.",
        "searchall": "kaikki",
        "showingresults": "Alla on vain {{PLURAL:$1|<strong>1</strong> hakutulos|<strong>$1</strong> hakutulosta}} alkaen tuloksesta nro <strong>$2</strong>.",
        "showingresultsinrange": "Alla näytetään {{PLURAL:$1|<strong>1</strong> tulos|<strong>$1</strong> tulosta}} väliltä <strong>$2</strong> – <strong>$3</strong>.",
-       "showingresultsheader": "{{PLURAL:$5|Tulokset '''$1'''–'''$3'''|Tulokset '''$1'''–'''$2''' kaikkiaan '''$3''' osuman joukosta}} haulle '''$4'''",
+       "search-showingresults": "{{PLURAL:$4|Tulos <strong>$1</strong> enimmäismäärästä <strong>$3</strong>|Tulokset <strong>$1 - $2</strong> enimmäismäärästä <strong>$3</strong>}}",
        "search-nonefound": "Hakusi ei tuottanut tulosta.",
        "powersearch-legend": "Laajennettu haku",
        "powersearch-ns": "Hae nimiavaruuksista:",
        "prefs-tokenwatchlist": "Avain",
        "prefs-diffs": "Eroavaisuudet",
        "prefs-help-prefershttps": "Tämä asetus tulee voimaan seuraavan sisäänkirjautumisesi yhteydessä.",
+       "prefswarning-warning": "Olet tehnyt asetuksiisi muutoksia, joita ei ole vielä tallennettu.\nJos poistut sivulta klikkaamatta \"$1\", asetuksiasi ei päivitetä.",
        "prefs-tabs-navigation-hint": "Vihje: Voit käyttää vasenta ja oikeata nuolinäppäintä liikkumiseen välilehtien välillä.",
        "email-address-validity-valid": "Sähköpostiosoite vaikuttaa kelvolliselta",
        "email-address-validity-invalid": "Virheellinen sähköpostiosoite",
        "mywatchlist": "Tarkkailulista",
        "watchlistfor2": "Käyttäjälle $1 $2",
        "nowatchlist": "Tarkkailulistallasi ei ole sivuja.",
-       "watchlistanontext": "Sinun täytyy kirjautua sisään, jos haluat muokata kohteita omalla tarkkailulistallasi.",
+       "watchlistanontext": "Sinun täytyy kirjautua sisään, jos haluat nähdä oman tarkkailulistasi.",
        "watchnologin": "Et ole kirjautunut sisään",
        "addwatch": "Lisää tarkkailulistalle",
        "addedwatchtext": "Sivu '''[[:$1]]''' on lisätty [[Special:Watchlist|tarkkailulistallesi]].\nTulevaisuudessa sivuun ja sen keskustelusivuun tehtävät muutokset listataan täällä.",
        "protect-othertime": "Muu kesto:",
        "protect-othertime-op": "muu kesto",
        "protect-existing-expiry": "Nykyinen vanhentumisaika: $2 kello $3",
+       "protect-existing-expiry-infinity": "Nykyinen kesto: ikuinen",
        "protect-otherreason": "Muu syy tai tarkennus:",
        "protect-otherreason-op": "Muu syy",
        "protect-dropdown": "*Yleiset suojaussyyt\n** Jatkuva vandalismi\n** Jatkuva mainoslinkkien lisääminen\n** Muokkaussota\n** Suuri näkyvyys",
        "sp-contributions-blocked-notice": "Tämä käyttäjä on tällä hetkellä estetty. Alla on viimeisin estolokin tapahtuma:",
        "sp-contributions-blocked-notice-anon": "Tämä IP-osoite on tällä hetkellä estetty.\nAlla on viimeisin estolokin tapahtuma:",
        "sp-contributions-search": "Etsi muokkauksia",
-       "sp-contributions-username": "IP-osoite tai käyttäjätunnus",
+       "sp-contributions-username": "IP-osoite tai käyttäjätunnus:",
        "sp-contributions-toponly": "Näytä vain muokkaukset, jotka ovat viimeisimpiä versioita",
        "sp-contributions-newonly": "Näytä vain muokkaukset, joilla on luotu sivu",
        "sp-contributions-submit": "Hae",
        "blockip": "Estä {{GENDER:$1|käyttäjä}}",
        "blockip-legend": "Estä käyttäjä",
        "blockiptext": "Tällä toiminnolla voit estää käyttäjätunnusta tai IP-osoitetta muokkaamasta.<br />\nTällainen muokkausesto pitäisi asettaa vain vandalismin torjumiseksi ja [[{{MediaWiki:Policy-url}}|käytännön]] mukaisesti.\nKirjoita eston syy alla olevaan kenttään.",
-       "ipaddressorusername": "IP-osoite tai käyttäjätunnus",
+       "ipaddressorusername": "IP-osoite tai käyttäjätunnus:",
        "ipbexpiry": "Vanhentuu:",
        "ipbreason": "Syy:",
        "ipbreason-dropdown": "*Yleiset estosyyt\n** Väärän tiedon lisääminen\n** Sisällön poistaminen\n** Mainoslinkkien lisääminen\n** Sotkeminen tai roskan lisääminen\n** Häiriköinti\n** Useamman käyttäjätunnuksen väärinkäyttö\n** Sopimaton käyttäjätunnus",
        "unblocked": "Käyttäjän [[User:$1|$1]] esto on poistettu",
        "unblocked-range": "$1 ei ole enää estettynä",
        "unblocked-id": "Esto $1 on poistettu",
+       "unblocked-ip": "Käyttäjän [[Special:Contributions/$1|$1]] esto on poistettu.",
        "blocklist": "Estetyt käyttäjät",
        "ipblocklist": "Estetyt käyttäjät",
        "ipblocklist-legend": "Haku",
        "logentry-upload-overwrite": "$1 {{GENDER:$2|tallensi}} uuden version tiedostosta $3",
        "logentry-upload-revert": "$1 {{GENDER:$2|tallensi}} tiedoston $3",
        "rightsnone": "(ei oikeuksia)",
+       "revdelete-summary": "yhteenvedon",
        "feedback-bugornote": "Jos voit kuvailla teknisen ongelman tarkasti – [$1 ilmoita ohjelmointivirheestä].\nMuussa tapauksessa voit käyttää alla olevaa helpompaa lomaketta. Kommenttisi lisätään sivulle [$3 $2], ja siinä on mukana käyttäjätunnuksesi.",
        "feedback-subject": "Otsikko",
        "feedback-message": "Viesti",
        "log-name-pagelang": "Kielenvaihtoloki",
        "log-description-pagelang": "Tämä on loki, johon merkitään muutokset sivujen kieliasetuksissa.",
        "logentry-pagelang-pagelang": "$1 {{GENDER:$2|muutti}} sivun kieltä sivulla $3 kielestä $4 kieleksi $5.",
-       "default-skin-not-found": "Hupsista! Oletuksena tuleva ulkoasu sinun wikillesi (<code>$wgDefaultSkin</code>), <code>$1</code>, ei ole saatavilla.\n\n\n<strong>Alla on ohjeita englanniksi:</strong>\n\n\nYour installation seems to include the following skins. See [https://www.mediawiki.org/wiki/Manual:Skin_configuration Manual: Skin configuration] for information how to enable them and choose the default.\n\n$2\n\n; If you have just installed MediaWiki: \n: You probably installed from git, or directly from the source code using some other method. This is expected. Try installing some skins from [https://www.mediawiki.org/wiki/Category:All_skins mediawiki.org's skin directory], by: :* Downloading the [https://www.mediawiki.org/wiki/Download tarball installer], which comes with several skins and extensions. You can copy and paste the <code>skins/</code> directory from it. \n:* Cloning one of the <code>mediawiki/skins/*</code> repositories via git into the <code>skins/</code> directory of your MediaWiki installation. \n: Doing this should not interfere with your git repository if you're a MediaWiki developer.\n\n\n; If you have just upgraded MediaWiki: \n: MediaWiki 1.24 and newer no longer automatically enables installed skins (see [https://www.mediawiki.org/wiki/Manual:Skin_autodiscovery Manual: Skin autodiscovery]). You can paste the following lines into <code>LocalSettings.php</code> to enable all currently installed skins:\n\n<pre>$3</pre>\n\n; If you have just modified <code>LocalSettings.php</code>: \n: Double-check the skin names for typos.",
+       "default-skin-not-found": "Hupsista! Oletuksena tuleva ulkoasu sinun wikillesi, joka on määritelty koodissa <code dir=\"ltr\">$wgDefaultSkin</code> muotoon <code>$1</code>, ei ole saatavilla.\n\n\n<strong>Alla on ohjeita englanniksi:</strong>\n\n\nYour installation seems to include the following skins. See [https://www.mediawiki.org/wiki/Manual:Skin_configuration Manual: Skin configuration] for information how to enable them and choose the default.\n\n$2\n\n; If you have just installed MediaWiki: \n: You probably installed from git, or directly from the source code using some other method. This is expected. Try installing some skins from [https://www.mediawiki.org/wiki/Category:All_skins mediawiki.org's skin directory], by: :* Downloading the [https://www.mediawiki.org/wiki/Download tarball installer], which comes with several skins and extensions. You can copy and paste the <code>skins/</code> directory from it. \n:* Cloning one of the <code>mediawiki/skins/*</code> repositories via git into the <code>skins/</code> directory of your MediaWiki installation. \n: Doing this should not interfere with your git repository if you're a MediaWiki developer.\n\n\n; If you have just upgraded MediaWiki: \n: MediaWiki 1.24 and newer no longer automatically enables installed skins (see [https://www.mediawiki.org/wiki/Manual:Skin_autodiscovery Manual: Skin autodiscovery]). You can paste the following lines into <code>LocalSettings.php</code> to enable all currently installed skins:\n\n<pre>$3</pre>\n\n; If you have just modified <code>LocalSettings.php</code>: \n: Double-check the skin names for typos.",
        "default-skin-not-found-row-enabled": "* <code>$1</code> / $2 (käytössä)",
        "default-skin-not-found-row-disabled": "* <code>$1</code> / $2 ('''ei käytössä''')"
 }
index 0b4d57d..724f4eb 100644 (file)
                        "Yona b",
                        "SnowedEarth",
                        "Orikrin1998",
-                       "Automatik"
+                       "Automatik",
+                       "Elodark"
                ]
        },
        "tog-underline": "Souligner les liens :",
        "otherlanguages": "Autres langues",
        "redirectedfrom": "(Redirigé depuis $1)",
        "redirectpagesub": "Page de redirection",
+       "redirectto": "Rediriger vers :",
        "lastmodifiedat": "Dernière modification de cette page le $1 à $2.<br />",
        "viewcount": "Cette page a été consultée {{PLURAL:$1|une fois|$1 fois}}.",
        "protectedpage": "Page protégée",
        "passwordreset-emailsent-capture": "Un courriel de réinitialisation de mot de passe a été envoyé, qui est affiché ci-dessous.",
        "passwordreset-emailerror-capture": "Un courriel de réinitialisation de mot de passe a été généré, qui est affiché ci-dessous, mais l'envoi à l'{{GENDER:$2|utilisateur|utilisatrice}} a échoué : $1",
        "changeemail": "Changer l’adresse de courriel",
-       "changeemail-header": "Changer l’adresse de courriel du compte",
        "changeemail-text": "Remplissez ce formulaire pour changer votre adresse de courriel. Vous devrez entrer votre mot de passe pour confirmer ce changement.",
        "changeemail-no-info": "Vous devez être connecté pour pouvoir accéder directement à cette page.",
        "changeemail-oldemail": "Adresse de courriel actuelle :",
        "changeemail-none": "(aucune)",
        "changeemail-password": "Votre mot de passe sur {{SITENAME}} :",
        "changeemail-submit": "Changer l’adresse de courriel",
-       "changeemail-cancel": "Annuler",
        "changeemail-throttled": "Vous avez fait trop de tentatives de connexion.\nVeuillez attendre $1 avant de réessayer.",
        "resettokens": "Réinitialiser les jetons",
        "resettokens-text": "Ici, vous pouvez réinitialiser les jetons qui permettent d’accéder à certaines données privées associées à votre compte.\n\nVous devriez le faire si vous les avez partagés accidentellement avec quelqu'un ou si votre compte a été compromis.",
        "searchall": "tout",
        "showingresults": "Affichage de <b>$1</b> résultat{{PLURAL:$1||s}} à partir du n°<b>$2</b>.",
        "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>.",
-       "showingresultsheader": "{{PLURAL:$5|Résultat '''$1'''|Résultats '''$1–$2'''}} de '''$3''' pour '''$4'''",
+       "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.",
        "powersearch-legend": "Recherche avancée",
        "powersearch-ns": "Rechercher dans les espaces de noms :",
        "unblocked": "[[User:$1|$1]] a été débloqué{{GENDER:$1||e}}",
        "unblocked-range": "Le compte $1 a été débloqué",
        "unblocked-id": "Le blocage $1 a été enlevé",
+       "unblocked-ip": "[[Special:Contributions/$1|$1]] a été débloqué.",
        "blocklist": "Utilisateurs bloqués",
        "ipblocklist": "Utilisateurs bloqués",
        "ipblocklist-legend": "Chercher un utilisateur bloqué",
        "logentry-upload-overwrite": "$1 {{GENDER:$2|a téléchargé}} une nouvelle version de $3",
        "logentry-upload-revert": "$1 {{GENDER:$2|a téléchargé}} $3",
        "rightsnone": "(aucun)",
+       "revdelete-summary": "résumé de modification",
        "feedback-bugornote": "Si vous êtes prêt à décrire un problème technique en détail, veuillez [$1 signaler un bogue].\nSinon, vous pouvez utiliser le formulaire simplifié ci-dessous. Votre commentaire sera ajouté à la page « [$3 $2] », avec votre nom d'utilisateur.",
        "feedback-subject": "Objet :",
        "feedback-message": "Message :",
        "log-name-pagelang": "Tracer les changements de langue",
        "log-description-pagelang": "Ceci est un journal des changements dans les langues des pages.",
        "logentry-pagelang-pagelang": "$1 {{GENDER:$2|a changé}} la langue de la page $3 de $4 à $5.",
-       "default-skin-not-found": "Oups ! L’habillage par défaut pour votre wiki (<code>$wgDefaultSkin</code>), <code>$1</code>, n’est pas disponible.\n\nVotre installation semble inclure les habillages suivants. Voyez [https://www.mediawiki.org/wiki/Manual:Skin_configuration le manuel de configuration des habillages] pour savoir comment les activer et choisir celui par défaut.\n\n$2\n\n; Si vous venez juste d’installer MediaWiki :\n: Vous l’avez probablement installé depuis git, ou directement depuis le code source avec une autre méthode. C’est normal. Essayez d’installer des habillages depuis [https://www.mediawiki.org/wiki/Category:All_skins le répertoire des habillages de mediawiki.org], en:\n:* Téléchargeant le [https://www.mediawiki.org/wiki/Download fichier tar de l’installeur], qui comprend plusieurs habillages et extensions. Vous pouvez copier et coller le répertoire <code>skins/</code> depuis là.\n:* Clonant un des dépôts <code>mediawiki/skins/*</code> via git dans le répertoire <code>skins/</code> de votre installation de MediaWiki.\n: Faire ainsi ne devrait pas interférer avec votre dépôt git, si vous êtes un développeur de MediaWiki.\n\n; Si vous venez juste de mettre à jour MediaWiki :\n: MediaWiki 1.24 et au-delà n’active plus automatiquement les habillages installés (voyez [https://www.mediawiki.org/wiki/Manual:Skin_autodiscovery le manuel sur la découverte automatique des habillages]). Vous pouvez coller les lignes suivantes dans <code>LocalSettings.php</code> pour activer tous les habillages actuellement installés :\n\n<pre>$3</pre>\n\n; Si vous venez de modifier <code>LocalSettings.php</code> :\n: Vérifiez deux fois le nom des habillages pour éviter les erreurs de frappe.",
-       "default-skin-not-found-no-skins": "Oups ! L’habillage par défaut pour votre wiki (<code>$wgDefaultSkin</code>), <code>$1</code>, n’est pas disponible.\n\nVous n’avez aucun habillage d’installé.\n\n; Si vous venez juste d’installer ou de mettre à jour MediaWiki :\n: Vous l’avez sans doute fait depuis git, ou directement depuis le code source avec une autre méthode. C’est normal. MediaWiki 1.24 et au-delà n’inclut aucun habillage dans le dépôt principal. Essayez d’installer des habillages depuis [https://www.mediawiki.org/wiki/Category:All_skins le répertoire des habillages de mediawiki.org], en :\n:* Téléchargeant [https://www.mediawiki.org/wiki/Download le fichier tar de l’installeur], qui comprend différents habillages et extensions. Vous pouvez copier et coller le répertoire <code>skins/</code> depuis là.\n:*Clonant un des dépôts <code>mediawiki/skins/*</code> via git dans le répertoire <code>skins/</code> de votre installation de MediaWiki.\n: Faire ainsi ne devrait pas interférer avec votre dépôt git si vous êtes un développeur de MediaWiki. Voyez [https://www.mediawiki.org/wiki/Manual:Skin_configuration le manuel de la configuration des habillages] pour des instructions sur la manière d’activer les habillages et choisir celui par défaut.",
+       "default-skin-not-found": "Oups ! L’habillage par défaut pour votre wiki, défini par <code dir=\"ltr\">$wgDefaultSkin</code> comme <code>$1</code>, n’est pas disponible.\n\nVotre installation semble inclure les habillages suivants. Voyez [https://www.mediawiki.org/wiki/Manual:Skin_configuration le manuel de configuration des habillages] pour savoir comment les activer et choisir celui par défaut.\n\n$2\n\n; Si vous venez juste d’installer MediaWiki :\n: Vous l’avez probablement installé depuis git, ou directement depuis le code source avec une autre méthode. C’est normal. Essayez d’installer des habillages depuis [https://www.mediawiki.org/wiki/Category:All_skins le répertoire des habillages de mediawiki.org], en:\n:* Téléchargeant le [https://www.mediawiki.org/wiki/Download fichier tar de l’installeur], qui comprend plusieurs habillages et extensions. Vous pouvez copier et coller le répertoire <code>skins/</code> depuis là.\n:* Clonant un des dépôts <code>mediawiki/skins/*</code> via git dans le répertoire <code dir=\"ltr\">skins/</code> de votre installation de MediaWiki.\n: Faire ainsi ne devrait pas interférer avec votre dépôt git, si vous êtes un développeur de MediaWiki.\n\n; Si vous venez juste de mettre à jour MediaWiki :\n: MediaWiki 1.24 et au-delà n’active plus automatiquement les habillages installés (voyez [https://www.mediawiki.org/wiki/Manual:Skin_autodiscovery le manuel sur la découverte automatique des habillages]). Vous pouvez coller les lignes suivantes dans <code>LocalSettings.php</code> pour activer tous les habillages actuellement installés :\n\n<pre dir=\"ltr\">$3</pre>\n\n; Si vous venez de modifier <code>LocalSettings.php</code> :\n: Vérifiez deux fois le nom des habillages pour éviter les erreurs de frappe.",
+       "default-skin-not-found-no-skins": "Oups ! L’habillage par défaut pour votre wiki , défini par <code>$wgDefaultSkin</code> comme <code>$1</code>, n’est pas disponible.\n\nVous n’avez aucun habillage d’installé.\n\n; Si vous venez juste d’installer ou de mettre à jour MediaWiki :\n: Vous l’avez sans doute fait depuis git, ou directement depuis le code source avec une autre méthode. C’est normal. MediaWiki 1.24 et au-delà n’inclut aucun habillage dans le dépôt principal. Essayez d’installer des habillages depuis [https://www.mediawiki.org/wiki/Category:All_skins le répertoire des habillages de mediawiki.org], en :\n:* Téléchargeant [https://www.mediawiki.org/wiki/Download le fichier tar de l’installeur], qui comprend différents habillages et extensions. Vous pouvez copier et coller le répertoire <code>skins/</code> depuis là.\n:*Clonant un des dépôts <code>mediawiki/skins/*</code> via git dans le répertoire <code dir=\"ltr\">skins/</code> de votre installation de MediaWiki.\n: Faire ainsi ne devrait pas interférer avec votre dépôt git si vous êtes un développeur de MediaWiki. Voyez [https://www.mediawiki.org/wiki/Manual:Skin_configuration le manuel de la configuration des habillages] pour des instructions sur la manière d’activer les habillages et choisir celui par défaut.",
        "default-skin-not-found-row-enabled": "* <code>$1</code> / $2 (activé)",
        "default-skin-not-found-row-disabled": "* <code>$1</code> / $2 ('''désactivé''')"
 }
index 56e115d..85f2ad3 100644 (file)
        "moredotdotdot": "Muar ...",
        "morenotlisted": "Detdiar list as ei komplet.",
        "mypage": "Sidj",
-       "mytalk": "Diskusjuun",
+       "mytalk": "Diskuschuun",
        "anontalk": "Diskusjuunssidj faan detdiar IP",
        "navigation": "Nawigatjuun",
        "and": "&#32;an",
        "unprotectthispage": "Sääkering aphääwe",
        "newpage": "Nei sidj",
        "talkpage": "Detdiar sidj diskutiare",
-       "talkpagelinktext": "Diskusjuun",
+       "talkpagelinktext": "Diskuschuun",
        "specialpage": "Spezial-sidj",
        "personaltools": "Min werktjüügen",
        "articlepage": "Artiikel wise",
-       "talk": "Diskusjuun",
+       "talk": "Diskuschuun",
        "views": "Uunsichten",
        "toolbox": "Werktjüügen",
        "userpage": "Brükersidj uunwise",
        "templatepage": "Föörlaagensidj uunwise",
        "viewhelppage": "Halepsidj uunwise",
        "categorypage": "Kategoriisidj uunwise",
-       "viewtalkpage": "Diskusjuun uunluke",
+       "viewtalkpage": "Diskuschuun uunluke",
        "otherlanguages": "Uun ööder spriaken",
        "redirectedfrom": "(Widjerfeerd faan $1)",
        "redirectpagesub": "Widjerfeerang",
        "passwordreset-emailsent-capture": "Detdiar E-Mail, wat oner uunwiset woort, as tu di onerwais.",
        "passwordreset-emailerror-capture": "Detdiar E-Mail, wat oner uunwiset woort, wiar tu di onerwais, oober küd ei tu di {{GENDER:$2|brüker}} ufsjüürd wurd: $1",
        "changeemail": "Feranre det E-Mail-adres",
-       "changeemail-header": "Feranre det E-Mail-adres",
        "changeemail-text": "Fal detdiar formulaar hialandaal ütj, am din E-Mail-adres tu feranrin. Diarför skel dü din paaswurd uundu.",
        "changeemail-no-info": "Dü möist önjmälded weese am ju sid diräkt tu tu gripen.",
        "changeemail-oldemail": "Aktuel e-mail adres",
        "changeemail-none": "(niin)",
        "changeemail-password": "Din {{SITENAME}} paaswurd:",
        "changeemail-submit": "E-mail adres feranre",
-       "changeemail-cancel": "Ufbreeg",
        "changeemail-throttled": "Dü heest tufölsis fersoocht, di uuntumeldin.\nWees so gud an teew $1, iar dü det noch ans ferschükst.",
        "resettokens": "Tokens turagsaat",
        "resettokens-text": "Dü könst 'tokens' turagsaat, am priwoot dooten tu bewerkin, diar mä din brükerkonto ferbünjen san.",
        "undo-failure": "Det feranrang küd ei stregen wurd, auer di kirew uuntesken feranert wurden as.",
        "undo-norev": "Det feranrang küd ei turagsaat wurd, auer diar niks as of auer det sidj stregen wurden as.",
        "undo-nochange": "Detdiar feranrang as wel al ans turagsaat wurden.",
-       "undo-summary": "Feranrang $1 faan [[Special:Contributions/$2|$2]] ([[User talk:$2|Diskusjuun]]) turagsaat.",
+       "undo-summary": "Feranrang $1 faan [[Special:Contributions/$2|$2]] ([[User talk:$2|Diskuschuun]]) turagsaat.",
        "undo-summary-username-hidden": "Feranrang $1 faan en ferbürgenen brüker turagsaat",
        "cantcreateaccounttitle": "Det brükerkonto koon ei iinracht wurd",
        "cantcreateaccount-text": "Det iinrachten faan en brükerkonto faan det IP-adres '''($1)''' as faan [[User:$3|$3]] speret wurden.\n\nGrünj för det sper: ''$2''",
        "searchall": "aaltumaal",
        "showingresults": "Heer {{PLURAL:$1|as '''1''' resultaat|san '''$1''' resultaaten}}, jo began mä numer '''$2.'''",
        "showingresultsinrange": "Oner {{PLURAL:$1|woort <strong>ian</strong> resultaat|wurd bit tu <strong>$1</strong> resultaaten}} tesken <strong>$2</strong> an <strong>$3</strong> uunwiset.",
-       "showingresultsheader": "{{PLURAL:$5|resultaat '''$1''' faan '''$3'''|resultaaten '''$1-$2''' faan '''$3'''}}, för '''$4.'''",
        "search-nonefound": "För din uunfraag san nian resultaaten fünjen wurden.",
        "powersearch-legend": "Ütjwidjet schüken",
        "powersearch-ns": "Schük uun nöömrümer:",
        "rollbacklinkcount-morethan": "Muar üs $1 {{PLURAL:$1|werjuun|werjuunen}} turagsaat",
        "rollbackfailed": "Bi't turagsaaten as wat skiaf gingen.",
        "cantrollback": "Det feranrang koon ei turagsaat wurd, diar san nian ööder skriiwern weesen.",
-       "alreadyrolled": "A anrangen faan [[User:$2|$2]] ([[User talk:$2|Diskusjuun]]{{int:pipe-separator}}[[Special:Contributions/$2|{{int:contribslink}}]]) bi [[:$1]] kön ei turagsaat wurd. Diar hää uuntesken en öödern brüker det sidj feranert.\n\nDet leetst feranrang as faan [[User:$3|$3]] ([[User talk:$3|Diskusjuun]]{{int:pipe-separator}}[[Special:Contributions/$3|{{int:contribslink}}]]).",
+       "alreadyrolled": "A feranrangen faan [[User:$2|$2]] ([[User talk:$2|Diskuschuun]]{{int:pipe-separator}}[[Special:Contributions/$2|{{int:contribslink}}]]) bi [[:$1]] kön ei turagsaat wurd. Diar hää uuntesken en öödern brüker det sidj feranert.\n\nDet leetst feranrang as faan [[User:$3|$3]] ([[User talk:$3|Diskuschuun]]{{int:pipe-separator}}[[Special:Contributions/$3|{{int:contribslink}}]]).",
        "editcomment": "Tuupfaadet feranrang: ''„$1“''.",
-       "revertpage": "Feranrangen faan [[Special:Contributions/$2|$2]] ([[User talk:$2|Diskusjuun]]) san üüb di leetst stant faan [[User:$1|$1]] turagsaat wurden.",
+       "revertpage": "Feranrangen faan [[Special:Contributions/$2|$2]] ([[User talk:$2|Diskuschuun]]) san üüb di leetst stant faan [[User:$1|$1]] turagsaat wurden.",
        "revertpage-nouser": "Feranrangen faan en ferbürgenen brüker turagsaat an det leetst werjuun faan {{GENDER:$1|[[User:$1|$1]]}} weder iinsteld.",
        "rollback-success": "Feranrangen faan $1 turagsaat an det leetst werjuun faan $2 weder iinsteld.",
        "sessionfailure-title": "session feeler",
        "sp-contributions-deleted": "Stregen bidracher",
        "sp-contributions-uploads": "Huuchschüürd bilen",
        "sp-contributions-logs": "Logbuken",
-       "sp-contributions-talk": "Diskusjuun",
+       "sp-contributions-talk": "Diskuschuun",
        "sp-contributions-userrights": "Brükerrochten",
        "sp-contributions-blocked-notice": "Didiar brüker as speret. Det stäänt uun't sperlogbuk:",
        "sp-contributions-blocked-notice-anon": "Detdiar IP-adres as speret. Det stäänt uun't sperlogbuk:",
        "tooltip-pt-userpage": "Din brükersidj",
        "tooltip-pt-anonuserpage": "Brükersidj faan det IP-adres, faan huar ütj dü werkest",
        "tooltip-pt-mytalk": "Din diskusjuunssidj",
-       "tooltip-pt-anontalk": "Diskusjuun auer feranrangen faan detdiar IP-adres",
+       "tooltip-pt-anontalk": "Diskuschuun auer feranrangen faan detdiar IP-adres",
        "tooltip-pt-preferences": "Min iinstelangen",
        "tooltip-pt-watchlist": "Sidjen, diar dü uun't uug behual wel",
        "tooltip-pt-mycontris": "List mä aanj bidracher",
        "tooltip-pt-login": "Wan dü di uunmeldest, heest dü muar mögelkhaiden. Dü säärst det oober ei.",
        "tooltip-pt-logout": "Ufmelde",
-       "tooltip-ca-talk": "Diskusjuun auer di artiikel",
+       "tooltip-ca-talk": "Diskuschuun auer di artiikel",
        "tooltip-ca-edit": "Sidj bewerke. Luke di det iarst ans uun, iar dü det seekerst.",
        "tooltip-ca-addsection": "Nei kirew began",
        "tooltip-ca-viewsource": "Detdiar sidj as seekert wurden.\nDü könst di kweltekst uunluke.",
        "scarytranscludefailed-httpstatus": "[Ufrepen faan föörlaagen för $1 as skiaf gingen: HTTP  $2]",
        "scarytranscludetoolong": "[URL as tu lung]",
        "deletedwhileediting": "'''Paase üüb:''' Det sidj as stregen wurden, üs dü diar jüst bi werket heest!\nUun't [{{fullurl:{{#special:Log}}|type=delete&page={{FULLPAGENAMEE}}}} Strik-logbuk] fanjst dü di grünj för't striken. Wan dü det sidj seekerst, woort det nei uunlaanj.",
-       "confirmrecreate": "Di brüker [[User:$1|$1]] ([[User talk:$1|Diskusjuun]]) hää det sidj stregen, üs dü diar jüst bi werket heest. Di grünj wiar:\n:''$2''\nFerseekre, dat dü det sidj würelk nei maage wel.",
-       "confirmrecreate-noreason": "Di brüker [[User:$1|$1 ]] ([[User talk:$1|Diskusjuun]]) hää det sidj stregen, huar dü jüst bi werket heest. Ferseekre, dat dü det sidj würelk nei maage wel.",
+       "confirmrecreate": "Di brüker [[User:$1|$1]] ([[User talk:$1|Diskuschuun]]) hää det sidj stregen, üs dü diar jüst bi werket heest. Di grünj wiar:\n:''$2''\nFerseekre, dat dü det sidj würelk nei maage wel.",
+       "confirmrecreate-noreason": "Di brüker [[User:$1|$1 ]] ([[User talk:$1|Diskuschuun]]) hää det sidj stregen, huar dü jüst bi werket heest. Ferseekre, dat dü det sidj würelk nei maage wel.",
        "recreate": "Nei maage",
        "confirm_purge_button": "OK",
        "confirm-purge-top": "Det sidj ütj a cache strik?",
        "watchlisttools-view": "Uun't uug behual: Feranrangen",
        "watchlisttools-edit": "Normool bewerke",
        "watchlisttools-raw": "Uun't listenformoot bewerke",
-       "signature": "[[{{ns:user}}:$1|$2]] ([[{{ns:user_talk}}:$1|Diskusjuun]])",
+       "signature": "[[{{ns:user}}:$1|$2]] ([[{{ns:user_talk}}:$1|Diskuschuun]])",
        "unknown_extension_tag": "Ünbekäänd ''tag'' „$1“",
        "duplicate-defaultsort": "'''Paase üüb:''' Di sortiarkai \"$2\" auerskraft di ual sortiarkai \"$1\"",
        "version": "Werjuun",
        "logentry-rights-rights-legacy": "$1 {{GENDER:$2|hää}} det brükerskööl för $3 feranert.",
        "logentry-rights-autopromote": "$1 as automaatisk faan $4 tu $5 {{GENDER:$2|tuwiset}} wurden.",
        "rightsnone": "(-)",
+       "revdelete-summary": "tuhuupefootings-komäntoor",
        "feedback-bugornote": "Wan dü en technisk probleem beskriiw wel, wees so gud an skriiw [$1 am di feeler].\nÖöders könst dü uk det formulaar oner brük. Dan komentaar woort tuup mä dan brükernööm an det werjuun faan dan browser üüb det sidj „[$3 $2]“ skrewen.",
        "feedback-subject": "Teemo:",
        "feedback-message": "Mädialang:",
index 80a9a4c..f8345fe 100644 (file)
        "createaccount-text": "Alguén creou unha conta chamada \"$2\" para o seu enderezo de correo electrónico en {{SITENAME}} ($4), e con contrasinal \"$3\".\nDebe acceder ao sistema e mudar o contrasinal agora.\n\nPode facer caso omiso desta mensaxe se se creou esta conta por erro.",
        "login-throttled": "Fixo demasiados intentos de acceder ao sistema.\nPor favor, agarde $1 antes de probar outra vez.",
        "login-abort-generic": "Acceso ao sistema incorrecto; abortado",
+       "login-migrated-generic": "A súa conta foi migrada, e o seu nome de usuario xa non existe nesta wiki.",
        "loginlanguagelabel": "Lingua: $1",
        "suspicious-userlogout": "Rexeitouse a súa petición de saír do sistema porque semella que a enviou un navegador roto ou a caché dun proxy.",
        "createacct-another-realname-tip": "O nome real é opcional.\nSe escolle dalo utilizarase para atribuír ao usuario o seu traballo.",
        "showpreview": "Mostrar a vista previa",
        "showdiff": "Mostrar os cambios",
        "blankarticle": "<strong>Advertencia:</strong> A páxina que está a piques de crear está baleira.\nSe preme no botón \"{{int:savearticle}}\" outra vez, a páxina crearase sen contido.",
-       "anoneditwarning": "'''Aviso:''' Non accedeu ao sistema.\nO seu enderezo IP quedará rexistrado no historial de revisións desta páxina.",
+       "anoneditwarning": "<strong>Aviso:</strong> Non accedeu ao sistema. O seu enderezo IP será rexistado no histórico de edicións desta páxina. Se <strong>[$1 accede ao sistema]</strong> ou <strong>[$2 crea unha conta]</strong>, as súas edicións serán rexistadas co seu nome de usuario, ademais doutros beneficios.",
        "anonpreviewwarning": "''Non accedeu ao sistema. Se garda a páxina, o seu enderezo IP quedará rexistrado no historial de edicións.''",
        "missingsummary": "'''Aviso:''' Esqueceu incluír o texto do campo resumo.\nSe preme en \"{{int:savearticle}}\" a súa edición gardarase sen ningunha descrición da edición.",
        "missingcommenttext": "Por favor, escriba un comentario a continuación.",
        "searchall": "todo",
        "showingresults": "{{PLURAL:$1|Móstrase '''1''' resultado|Móstranse '''$1''' resultados}}, comezando polo número '''$2'''.",
        "showingresultsinrange": "{{PLURAL:$1|Móstrase <strong>1</strong> resultado|Móstranse <strong>$1</strong> resultados}}, comezando polo número <strong>$2</strong> e rematando polo número <strong>$3</strong>.",
-       "showingresultsheader": "{{PLURAL:$5|Resultado '''$1''' de '''$3'''|Resultados do '''$1''' ao '''$2''', dun total de '''$3''',}} para \"'''$4'''\"",
        "search-nonefound": "Non se atopou ningún resultado que coincidise coa procura.",
        "powersearch-legend": "Busca avanzada",
        "powersearch-ns": "Procurar nos espazos de nomes:",
index cb43f56..cff9ce8 100644 (file)
        "gotaccountlink": "登入",
        "userlogin-resetlink": "毋記得汝嘅登入信息?",
        "userlogin-resetpassword-link": "添忘訖汝嘅密碼?",
-       "userlogin-loggedin": "汝已作為{{GENDER:$1|$1}}登錄。\n利用以下表單以作為另一賬戶登錄。",
        "createacct-emailrequired": "電郵地址:",
        "createacct-emailoptional": "電郵地址(可選)",
        "createacct-email-ph": "設置電郵地址",
        "passwordreset-emailtitle": "在{{SITENAME}}上嘅詳細信息",
        "passwordreset-emailsent": "密碼重置電子郵件已發送。",
        "changeemail": "更改電子郵件地址",
-       "changeemail-header": "更改電子郵件帳戶",
        "changeemail-no-info": "汝必須登入後直接進入邇隻頁面。",
        "changeemail-oldemail": "當前電郵地址:",
        "changeemail-newemail": "新嘅電郵地址:",
        "changeemail-none": "(無)",
        "changeemail-submit": "更改電郵地址",
-       "changeemail-cancel": "取消",
        "bold_sample": "粗體文字",
        "bold_tip": "粗體文字",
        "italic_sample": "斜體文字",
        "template-protected": "(保護)",
        "template-semiprotected": "(半保護)",
        "hiddencategories": "邇頁屬於$1隻隱藏分類嘅成員:",
-       "edittools": "<!-- 邇肚嘅文字將分展示在編寫撈上傳表單以下。 -->",
+       "edittools": "<!-- 邇肚嘅文字將分展示在編寫撈上傳表單以下。 -->\n<div id=\"editpage-specialchars\" class=\"plainlinks edittools-version-test003\" style=\"margin-top: 15px; border-width: 1px; border-style: solid; border-color: #aaaaaa; padding: 2px;\"> <span id=\"edittools_main\">'''Insert:''' <charinsert>– — … ‘ “ ’ ” ° ″ ′ ≈ ≠ ≤ ≥ ± − × ÷ ← → · § </charinsert></span><span id=\"edittools_name\">&nbsp;&nbsp;'''Sign your username:''' <charinsert>--~~&#126;~</charinsert> <small>(on [[Help:Talk pages|talk pages]])</small></span> ---- <small id=\"edittools_newsectionshere\"><span id=\"edittools_hide_for_script_test\"><span id=\"edittools_wikimarkup\">'''Wiki markup:''' <charinsert><nowiki>{{</nowiki>+<nowiki>}}</nowiki> </charinsert> &nbsp; <charinsert><nowiki>{{{</nowiki>+<nowiki>}}}</nowiki> </charinsert> &nbsp; <charinsert><nowiki>|</nowiki></charinsert> &nbsp; <charinsert>[+]</charinsert> &nbsp; <charinsert>[[+]]</charinsert> &nbsp; <charinsert>[[Category:+]]</charinsert> &nbsp; <charinsert>#REDIRECT&#32;[[+]]</charinsert> &nbsp; <charinsert>{{Subst:Fôn-ngiàng}}</charinsert> &nbsp; <charinsert>{{Subst:PAGENAME}}</charinsert> &nbsp; <charinsert>&nbsp;</charinsert> &nbsp; <charinsert><s>+</s></charinsert> &nbsp; <charinsert><sup>+</sup></charinsert> &nbsp; <charinsert><sub>+</sub></charinsert> &nbsp; <charinsert><code>+</code></charinsert> &nbsp; <charinsert><blockquote>+</blockquote></charinsert> &nbsp; <charinsert><ref>+</ref></charinsert> &nbsp; <charinsert><nowiki>{{</nowiki>Reflist<nowiki>}}</nowiki></charinsert> &nbsp; <charinsert><references/></charinsert> &nbsp; <charinsert><includeonly>+</includeonly></charinsert> &nbsp; <charinsert><noinclude>+</noinclude></charinsert> &nbsp; <charinsert><nowiki>{{</nowiki>DEFAULTSORT:+<nowiki>}}</nowiki></charinsert> &nbsp; <charinsert>&lt;nowiki>+</nowiki></charinsert> &nbsp; <charinsert><nowiki><!-- </nowiki>+<nowiki> --></nowiki></charinsert>&nbsp; <charinsert><nowiki><span class=\"plainlinks\"></nowiki>+<nowiki></span></nowiki></charinsert>&nbsp;&nbsp;&bull;&nbsp; ([[Wikipedia:Template messages|templates]])<br/></span> <span id=\"edittools_symbols\">'''Symbols:''' <charinsert> ~ | ¡ ¿ † ‡ ↔ ↑ ↓ • ¶</charinsert> &nbsp; <charinsert> # ½ ⅓ ⅔ ¼ ¾ ⅛ ⅜ ⅝ ⅞ ∞ </charinsert> &nbsp; <charinsert> ‘ “ ’ ” «+»</charinsert> &nbsp; <charinsert> ¤ ₳ ฿ ₵ ¢ ₡ ₢ $ ₫ ₯ € ₠ ₣ ƒ ₴ ₭ ₤ ℳ ₥ ₦ № ₧ ₰ £ ៛ ₨ ₪ ৳ ₮ ₩ ¥ </charinsert> &nbsp; <charinsert> ♠ ♣ ♥ ♦ </charinsert>&nbsp; <charinsert>m²</charinsert>&nbsp;<charinsert>m³</charinsert><br/></span> <span id=\"edittools_characters\">'''Characters:''' <span class=\"latinx\"> <charinsert> Á á Ć ć É é Í í Ĺ ĺ Ḿ ḿ Ń ń Ó ó Ŕ ŕ Ś ś Ú ú Ý ý Ź ź </charinsert> &nbsp; <charinsert> À à È è Ì ì M̀ m̀  Ǹ ǹ Ò ò Ù ù </charinsert> &nbsp; <charinsert> Â â Ĉ ĉ Ê ê Ĝ ĝ Ĥ ĥ Î î Ĵ ĵ Ô ô Ŝ ŝ Û û Ŵ ŵ Ŷ ŷ </charinsert> &nbsp; <charinsert> A̤ a̤ E̤ e̤ I̤ i̤ O̤ o̤ Ṳ ṳ </charinsert> &nbsp;\n<charinsert> A̍ a̍ E̍ e̍ I̍ i̍ O̍ o̍ U̍ u̍ </charinsert> &nbsp; <charinsert> À̤ à̤ È̤ è̤ Ì̤ ì̤ Ò̤ ò̤ Ṳ̀ ṳ̀ </charinsert> &nbsp;\n<charinsert> Á̤ á̤ É̤ é̤ Í̤ í̤ Ó̤ ó̤ Ṳ́ ṳ́ </charinsert> &nbsp; <charinsert> A̤̍ a̤̍ E̤̍ e̤̍ I̤̍ i̤̍ O̤̍ o̤̍ Ṳ̍ ṳ̍ </charinsert> &nbsp;\n<charinsert> Â̤ â̤ Ê̤ ê̤ Î̤ î̤ Ô̤ ô̤ Ṳ̂ ṳ̂ </charinsert> &nbsp; <charinsert> Â â Ĉ ĉ Ê ê Ĝ ĝ Ĥ ĥ Î î Ĵ ĵ Ô ô Ŝ ŝ Û û Ŵ ŵ Ŷ ŷ </charinsert> &nbsp; <charinsert> Ä ä Ë ë Ï ï Ö ö Ü ü Ÿ ÿ </charinsert> &nbsp; <charinsert> ß </charinsert> &nbsp; <charinsert> Ã ã Ẽ ẽ Ĩ ĩ Ñ ñ Õ õ Ũ ũ Ỹ ỹ</charinsert> &nbsp; <charinsert> Ç ç Ģ ģ Ķ ķ Ļ ļ Ņ ņ Ŗ ŗ Ş ş Ţ ţ </charinsert> &nbsp; <charinsert> Đ đ </charinsert> &nbsp; <charinsert> Ů ů </charinsert> &nbsp; <charinsert> Ǎ ǎ Č č Ď ď Ě ě Ǐ ǐ Ľ ľ Ň ň Ǒ ǒ Ř ř Š š Ť ť Ǔ ǔ Ž ž </charinsert> &nbsp; <charinsert> Ā ā Ē ē Ī ī Ō ō Ū ū Ȳ ȳ Ǣ ǣ </charinsert> &nbsp; <charinsert> ǖ ǘ ǚ ǜ </charinsert> &nbsp; <charinsert> Ă ă Ĕ ĕ Ğ ğ Ĭ ĭ Ŏ ŏ Ŭ ŭ </charinsert> &nbsp; <charinsert> Ċ ċ Ė ė Ġ ġ İ ı Ż ż </charinsert> &nbsp; <charinsert> Ą ą Ę ę Į į Ǫ ǫ Ų ų </charinsert> &nbsp; <charinsert> Ḍ ḍ Ḥ ḥ Ḷ ḷ Ḹ ḹ Ṃ ṃ Ṇ ṇ Ṛ ṛ Ṝ ṝ Ṣ ṣ Ṭ ṭ </charinsert> &nbsp; <charinsert> Ł ł </charinsert> &nbsp; <charinsert> Ő ő Ű ű </charinsert> &nbsp; <charinsert> Ŀ ŀ </charinsert> &nbsp; <charinsert> Ħ ħ </charinsert> &nbsp; <charinsert> Ð ð Þ þ </charinsert> &nbsp; <charinsert> Œ œ </charinsert> &nbsp; <charinsert> Æ æ Ø ø Å å </charinsert> &nbsp; <charinsert> Ə ə </charinsert></span>&nbsp;<span id=\"edittools_latinx_template\">&nbsp;&bull;&nbsp; <charinsert><nowiki>{{</nowiki><nowiki>Unicode|</nowiki>+<nowiki>}}</nowiki></charinsert></span><br/></span> <span id=\"edittools_greek\">'''Hî-lia̍p-vùn:''' <charinsert> Ά ά Έ έ Ή ή Ί ί Ό ό Ύ ύ Ώ ώ </charinsert> &nbsp; <charinsert> Α α Β β Γ γ Δ δ </charinsert> &nbsp; <charinsert> Ε ε Ζ ζ Η η Θ θ </charinsert> &nbsp; <charinsert> Ι ι Κ κ Λ λ Μ μ </charinsert> &nbsp; <charinsert> Ν ν Ξ ξ Ο ο Π π </charinsert> &nbsp; <charinsert> Ρ ρ Σ σ ς Τ τ Υ υ </charinsert> &nbsp; <charinsert> Φ φ Χ χ Ψ ψ Ω ω </charinsert> &nbsp;<span id=\"edittools_greek_template\">•&nbsp; <charinsert><nowiki>{{</nowiki><nowiki>Polytonic|</nowiki>+<nowiki>}}</nowiki></charinsert></span> &nbsp;<span id=\"edittools_greek_example\">•&nbsp; ([[Greek diacritics#Computer encoding|polytonic list]])</span><br/></span> <span id=\"edittools_cyrillic\">'''Cyrillic:''' <charinsert> А а Б б В в Г г </charinsert> &nbsp; <charinsert> Ґ ґ Ѓ ѓ Д д Ђ ђ </charinsert> &nbsp; <charinsert> Е е Ё ё Є є Ж ж </charinsert> &nbsp; <charinsert> З з Ѕ ѕ И и І і </charinsert> &nbsp; <charinsert> Ї ї Й й Ј ј К к </charinsert> &nbsp; <charinsert> Ќ ќ Л л Љ љ М м </charinsert> &nbsp; <charinsert> Н н Њ њ О о П п </charinsert> &nbsp; <charinsert> Р р С с Т т Ћ ћ </charinsert> &nbsp; <charinsert> У у Ў ў Ф ф Х х </charinsert> &nbsp; <charinsert> Ц ц Ч ч Џ џ Ш ш </charinsert> &nbsp; <charinsert> Щ щ Ъ ъ Ы ы Ь ь </charinsert> &nbsp; <charinsert> Э э Ю ю Я я </charinsert> &nbsp;<br/></span> <span id=\"edittools_ipa\">'''IPA:''' <span title=\"Pronunciation in IPA\" class=\"IPA\"><charinsert>t̪ d̪ ʈ ɖ ɟ ɡ ɢ ʡ ʔ </charinsert> &nbsp; <charinsert> ɸ ʃ ʒ ɕ ʑ ʂ ʐ ʝ ɣ ʁ ʕ ʜ ʢ ɦ </charinsert> &nbsp; <charinsert> ɱ ɳ ɲ ŋ ɴ </charinsert> &nbsp; <charinsert> ʋ ɹ ɻ ɰ </charinsert> &nbsp; <charinsert> ʙ ʀ ɾ ɽ </charinsert> &nbsp; <charinsert> ɫ ɬ ɮ ɺ ɭ ʎ ʟ </charinsert> &nbsp; <charinsert> ɥ ʍ ɧ </charinsert> &nbsp; <charinsert> ɓ ɗ ʄ ɠ ʛ </charinsert> &nbsp; <charinsert> ʘ ǀ ǃ ǂ ǁ </charinsert> &nbsp; <charinsert> ɨ ʉ ɯ </charinsert> &nbsp; <charinsert> ɪ ʏ ʊ </charinsert> &nbsp; <charinsert> ɘ ɵ ɤ </charinsert> &nbsp; <charinsert> ə ɚ </charinsert> &nbsp; <charinsert> ɛ ɜ ɝ ɞ ʌ ɔ </charinsert> &nbsp; <charinsert> ɐ ɶ ɑ ɒ </charinsert> &nbsp; <charinsert> ʰ ʷ ʲ ˠ ˤ ⁿ ˡ </charinsert> &nbsp; <charinsert> ˈ ˌ ː ˑ ̪ </charinsert>&nbsp;</span> &nbsp;&bull;&nbsp; <charinsert><nowiki>{{</nowiki><nowiki>IPA|</nowiki>+<nowiki>}}</charinsert></small>\n</div>",
        "nocreatetext": "Chhṳ́ mióng-chham han-chṳ chhóng-chho sîn hong-mien ke kûng-yung. ngì khó-yî fán-fì pin phiên-cho yí-kîn yû ke hong-mien, fe̍t-chá [[Special:UserLogin|tên-liu̍k fe̍t-he chhóng-kien sîn chong-fu]].",
        "nocreate-loggedin": "汝並無權限去創建新頁面。",
        "permissionserrors": "權限差錯",
        "searchrelated": "相關",
        "searchall": "全部",
        "showingresults": "Ha-mien hién-sṳ chhiùng thi-'''$2'''-thiàu khôi-sṳ́ ke '''$1'''-thiàu kiet-kó:",
-       "showingresultsheader": "對'''$4'''嘅{{PLURAL:$5|第'''$1'''到第'''$3'''隻結果|第'''$1 - $2'''隻,共'''$3'''隻結果}}",
        "search-nonefound": "在查詢肚無結果相符。",
        "powersearch-legend": "高級搜尋",
        "powersearch-ns": "在下背嘅名字空間肚搜尋:",
        "tag-filter": "[[Special:Tags|標籤]]過濾器:",
        "revdelete-restricted": "yí-kîn yin-yung han-tsṳ tsṳ tshâu-tsok-yèn",
        "revdelete-unrestricted": "yí-kîn yì-tshù yû-kûan tshâu-tsok-yè ke han-tsṳ",
-       "rightsnone": "(無)"
+       "rightsnone": "(無)",
+       "revdelete-summary": "piên-sip tsak-yêu"
 }
index baf960e..4e34e6f 100644 (file)
        "viewsource": "הצגת מקור",
        "viewsource-title": "הצגת המקור של $1",
        "actionthrottled": "הפעולה הוגבלה",
-       "actionthrottledtext": "×\9b×\90×\9eצע×\99 × ×\92×\93 ×¡×¤×\90×\9d, ×\90ת×\9d ×\9e×\95×\92×\91×\9c×\99×\9d ×\9eביצוע פעולה זו פעמים רבות מדי בזמן קצר, וחרגתם מהמגבלה הזו.\nאנא נסו שוב בעוד מספר דקות.",
+       "actionthrottledtext": "×\9b×\90×\9eצע×\99 × ×\92×\93 ×¡×¤×\90×\9d, ×§×\99×\99×\9eת ×\9e×\92×\91×\9c×\94 ×¢×\9c ביצוע פעולה זו פעמים רבות מדי בזמן קצר, וחרגתם מהמגבלה הזו.\nאנא נסו שוב בעוד מספר דקות.",
        "protectedpagetext": "דף זה מוגן כדי למנוע עריכה ופעולות אחרות.",
        "viewsourcetext": "באפשרותך לצפות בטקסט המקור של הדף ולהעתיקו:",
        "viewyourtext": "באפשרותכם לצפות בטקסט המקור של '''העריכות שלכם''' של הדף ולהעתיקו:",
        "passwordreset-emailsent-capture": "נשלח דואר אלקטרוני לאיפוס הסיסמה, והוא מוצג להלן.",
        "passwordreset-emailerror-capture": "נוצר דואר אלקטרוני לאיפוס הסיסמה, והוא מוצג להלן, אך שליחתו ל{{GENDER:$2|משתמש|משתמשת}} נכשלה: $1",
        "changeemail": "שינוי כתובת דוא\"ל",
-       "changeemail-header": "שינוי כתובת הדואר האלקטרוני בחשבון",
        "changeemail-text": "מלאו טופס זה כדי לשנות את כתובת הדואר האלקטרוני שלכם. יהיה עליכם למלא סיסמה כדי לאשר את השינוי.",
        "changeemail-no-info": "יש להיכנס לחשבון כדי לגשת לדף זה ישירות.",
        "changeemail-oldemail": "כתובת דוא\"ל נוכחית:",
        "changeemail-none": "(אין)",
        "changeemail-password": "סיסמה ב{{grammar:תחילית|{{SITENAME}}}}:",
        "changeemail-submit": "שינוי כתובת הדוא\"ל",
-       "changeemail-cancel": "ביטול",
        "changeemail-throttled": "ביצעתם ניסיונות רבים מדי להיכנס לחשבון זה.\nאנא המתינו $1 לפני שתנסו שוב.",
        "resettokens": "איפוס אסימונים",
        "resettokens-text": "בעמוד זה ניתן לאפס אסימונים שמאפשרים גישה לנתונים פרטיים של החשבון שלך.\n\nרצוי לעשות זאת אם שיתפת אותם בטעות עם אחרים או אם חשבונך נפרץ.",
        "subject-preview": "תצוגה מקדימה של הנושא/הכותרת:",
        "blockedtitle": "המשתמש חסום",
        "blockedtext": "'''שם המשתמש או כתובת ה־IP שלכם נחסמו.'''\n\nהחסימה בוצעה על ידי $1. הסיבה שניתנה לכך היא '''$2'''.\n\n* תחילת החסימה: $8\n* פקיעת החסימה: $6\n* החסימה שבוצעה: $7\n\nבאפשרותכם ליצור קשר עם $1 או עם כל אחד מ[[{{MediaWiki:Grouppage-sysop}}|מפעילי המערכת]] האחרים כדי לדון על החסימה.\nאינכם יכולים להשתמש בתכונת \"שליחת דואר אלקטרוני למשתמש זה\" אם לא ציינתם כתובת דוא\"ל תקפה ב[[Special:Preferences|העדפות המשתמש שלכם]] או אם נחסמתם משליחת דוא\"ל.\nכתובת ה־IP שלכם היא $3, ומספר החסימה שלכם הוא #$5.\nאנא ציינו את כל הפרטים הללו בכל פנייה למפעילי המערכת.",
-       "autoblockedtext": "כתובת ה־IP שלכם נחסמה באופן אוטומטי כיוון שמשתמש אחר, שנחסם על־ידי $1, השתמש בה.\nהסיבה שניתנה לחסימה היא:\n\n:<em>$2</em>\n\n* תחילת החסימה: $8\n* פקיעת החסימה: $6\n* החסימה שבוצעה: $7\n\nבאפשרותכם ליצור קשר עם $1 או עם כל אחד מ[[{{MediaWiki:Grouppage-sysop}}|מפעילי המערכת]] האחרים כדי לדון בחסימה.\n\nבאפשרותכם להשתמש בתכונת \"{{int:emailuser}}\", אלא אם לא ציינתם כתובת דוא\"ל תקינה ב[[Special:Preferences|העדפות המשתמש שלכם]] או אם נחסמתם משליחת דוא\"ל.\n\nכתובת ה־IP שלכם היא $3, ומספר החסימה שלכם הוא #$5.\nאנא ציינו את כל הפרטים הללו בכל פנייה למפעילי המערכת.",
+       "autoblockedtext": "כתובת ה־IP שלכם נחסמה באופן אוטומטי כיוון שמשתמש אחר, שנחסם על־ידי $1, השתמש בה.\nהסיבה שניתנה לחסימה היא:\n\n:<em>$2</em>\n\n* תחילת החסימה: $8\n* פקיעת החסימה: $6\n* החסימה שבוצעה: $7\n\nבאפשרותכם ליצור קשר עם $1 או עם כל אחד מ[[{{MediaWiki:Grouppage-sysop}}|מפעילי המערכת]] האחרים כדי לדון בחסימה.\n\nבאפשרותכם להשתמש בתכונת \"שליחת דואר אלקטרוני למשתמש זה\", אלא אם לא ציינתם כתובת דוא\"ל תקינה ב[[Special:Preferences|העדפות המשתמש שלכם]] או אם נחסמתם משליחת דוא\"ל.\n\nכתובת ה־IP שלכם היא $3, ומספר החסימה שלכם הוא #$5.\nאנא ציינו את כל הפרטים הללו בכל פנייה למפעילי המערכת.",
        "blockednoreason": "לא ניתנה סיבה",
        "whitelistedittext": "עליכם $1 כדי לערוך דפים.",
        "confirmedittext": "עליכם לאמת את כתובת הדוא\"ל שלכם לפני שתוכלו לערוך דפים. אנא הגדירו ואמתו את כתובת הדוא\"ל שלכם באמצעות [[Special:Preferences|העדפות המשתמש]] שלכם.",
        "accmailtext": "סיסמה אקראית עבור [[User talk:$1|$1]] נשלחה אל $2. ניתן לשנותה בדף '''[[Special:ChangePassword|שינוי הסיסמה]]''' לאחר הכניסה.",
        "newarticle": "(חדש)",
        "newarticletext": "הגעתם לדף שעדיין איננו קיים.\nכדי ליצור את הדף הזה, התחילו להקליד בתיבת הטקסט למטה (ראו את [$1 דף העזרה] למידע נוסף).\nאם הגעתם לכאן בטעות, לחצו על כפתור ה<strong>חזרה</strong> (Back) בדפדפן שלכם.",
-       "anontalkpagetext": "----\n<em>זהו דף שיחה של משתמש/ת אנונימי/ת שעדיין לא יצר/ה חשבון במערכת, או שהוא/היא לא משתמש/ת בו.</em>\nעלינו להשתמש בכתובת ה־IP כדי לזהותו/ה.\nייתכן שכתובת IP זו תייצג מספר משתמשים.\nאם אתם משתמשים אנונימיים ומרגישים שקיבלתם הודעות בלתי רלוונטיות, אנא [[Special:UserLogin|היכנסו לחשבון]] או [[Special:UserLogin/signup|הירשמו לאתר]] כדי להימנע מבלבול עתידי עם משתמשים אנונימיים נוספים.",
+       "anontalkpagetext": "----\n<em>זהו דף שיחה של משתמש אנונימי שעדיין לא יצר חשבון במערכת, או שהוא לא משתמש בו.</em>\nלכן עלינו להשתמש בכתובת ה־IP המספרית כדי לזהותו.\nייתכן שכתובת IP זו תהיה משותפת למספר משתמשים.\nאם אתם משתמשים אנונימיים ומרגישים שקיבלתם הודעות בלתי רלוונטיות, אנא [[Special:UserLogin/signup|צרו חשבון]] או [[Special:UserLogin|היכנסו לחשבון]] כדי להימנע מבלבול עתידי עם משתמשים אנונימיים נוספים.",
        "noarticletext": "אין כרגע טקסט בדף זה.\nבאפשרותכם [[Special:Search/{{PAGENAME}}|לחפש את כותרת הדף]] בדפים אחרים,\n<span class=\"plainlinks\">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} לחפש ביומנים הרלוונטיים],\nאו [{{fullurl:{{FULLPAGENAME}}|action=edit}} לערוך דף זה]</span>.",
        "noarticletext-nopermission": "אין כרגע טקסט בדף זה.\nבאפשרותכם [[Special:Search/{{PAGENAME}}|לחפש את כותרת הדף]] בדפים אחרים,\nאו <span class=\"plainlinks\">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} לחפש ביומנים הרלוונטיים]</span>,\nאך אינכם מורשים ליצור את הדף.",
        "missing-revision": "גרסה #$1 של הדף \"{{FULLPAGENAME}}\" אינה קיימת.\n\nזה נגרם בדרך כלל על־ידי לחיצה על קישור ישן לגרסה קודמת של דף שנמחק.\nאפשר למצוא פרטים ב[{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} יומן המחיקות].",
        "shown-title": "הצגת {{PLURAL:$1|תוצאה אחת|$1 תוצאות}} בדף",
        "viewprevnext": "צפייה ב: ($1 {{int:pipe-separator}} $2) ($3)",
        "searchmenu-exists": "'''קיים דף בשם \"[[:$1]]\" באתר זה.'''",
-       "searchmenu-new": "<strong>'''×\99צ×\99רת ×\94×\93×£ \"[[:$1]]\" ×\91×\90תר ×\96×\94.'''</strong> \n{{PLURAL:$2|0=|ר×\90×\95 ×\92×\9d ×\90ת ×\94×\93×£ ×©× ×\9eצ×\90 ×\91×\97×\99פ×\95ש ×©×\9c×\9b×\9d.|ר×\90×\95 ×\92×\9d ×\90ת ×ª×\95צ×\90×\95ת ×\94×\97×\99פ×\95ש ×©×\9c×\9b×\9d.}}",
+       "searchmenu-new": "<strong>'''×\99צ×\99רת ×\94×\93×£ \"[[:$1]]\" ×\91×\90תר ×\94×\95×\95×\99ק×\99 ×\94×\96×\94.'''</strong>\n{{PLURAL:$2|0=|ר' ×\92×\9d ×\90ת ×\94×\93×£ ×©× ×\9eצ×\90 ×\91×\97×\99פ×\95ש.|ר' ×\92×\9d ×\90ת ×ª×\95צ×\90×\95ת ×\94×\97×\99פ×\95ש.}}",
        "searchprofile-articles": "דפי תוכן",
        "searchprofile-images": "מולטימדיה",
        "searchprofile-everything": "הכול",
        "searchall": "הכול",
        "showingresults": "{{PLURAL:$1|מוצגת תוצאה <strong>אחת</strong>|מוצגות עד <strong>$1</strong> תוצאות}} החל ממספר <strong>$2</strong>:",
        "showingresultsinrange": "{{PLURAL:$1|מוצגת תוצאה <strong>אחת</strong>|מוצגות עד <strong>$1</strong> תוצאות}} בין המספרים <strong>$2</strong> ו‏‏־<strong>$3</strong>:",
-       "showingresultsheader": "{{PLURAL:$5|תוצאה '''$1''' מתוך '''$3'''|תוצאות '''$1 - $2''' מתוך '''$3'''}} עבור '''$4'''",
+       "search-showingresults": "{{PLURAL:$4|תוצאה <strong>$1</strong> מתוך <strong>$3</strong>|תוצאות <strong>$1 - $2</strong> מתוך <strong>$3</strong>}}",
        "search-nonefound": "לא נמצאו תוצאות המתאימות לחיפוש.",
        "powersearch-legend": "חיפוש מתקדם",
        "powersearch-ns": "חיפוש על־פי מרחבי שם:",
        "prefs-tokenwatchlist": "אסימון",
        "prefs-diffs": "הבדלים בין גרסאות",
        "prefs-help-prefershttps": "העדפה זו תיכנס לתוקף בכניסה הבאה לחשבון.",
+       "prefswarning-warning": "ביצעת שינויים בהעדפות שלך שעדיין לא נשמרו.\nעזיבת דף זה ללא לחיצה על \"$1\" תגרום להעדפות שלך לא להתעדכן.",
        "prefs-tabs-navigation-hint": "טיפ: ניתן להשתמש במקשי החצים הימני והשמאלי כדי לנווט בין הלשוניות ברשימת הלשוניות.",
        "email-address-validity-valid": "כתובת הדוא\"ל נראית תקינה",
        "email-address-validity-invalid": "יש להקליד כתובת דוא\"ל תקינה",
        "action-import": "לייבא דפים מאתר ויקי אחר",
        "action-importupload": "לייבא דפים באמצעות העלאת קובץ",
        "action-patrol": "לסמן עריכות של אחרים כבדוקות",
-       "action-autopatrol": "×\9cס×\9e×\9f ×\90ת ×¢×¨×\99×\9b×\95ת×\99×\9b×\9d כבדוקות",
+       "action-autopatrol": "×\9cס×\9e×\9f ×\90ת ×¢×¨×\99×\9b×\95ת×\99×\9a כבדוקות",
        "action-unwatchedpages": "לצפות ברשימת הדפים שאינם במעקב",
        "action-mergehistory": "למזג את ההיסטוריה של דף זה",
        "action-userrights": "לערוך את כל הרשאות המשתמש",
        "protectedpages-timestamp": "תאריך ושעה",
        "protectedpages-page": "דף",
        "protectedpages-expiry": "זמן פקיעה",
-       "protectedpages-performer": "הוגן על ידי",
+       "protectedpages-performer": "הוגן על־ידי",
        "protectedpages-params": "פרמטרים להגנה",
        "protectedpages-reason": "סיבה",
        "protectedpages-unknown-timestamp": "לא ידוע",
        "protect-othertime": "זמן אחר:",
        "protect-othertime-op": "זמן אחר",
        "protect-existing-expiry": "זמן פקיעה נוכחי: $3, $2",
+       "protect-existing-expiry-infinity": "זמן תפוגה נוכחי: אינסופי",
        "protect-otherreason": "סיבה אחרת/נוספת:",
        "protect-otherreason-op": "סיבה אחרת",
        "protect-dropdown": "* סיבות הגנה נפוצות\n** השחתה רבה\n** ספאם רב\n** מלחמת עריכה בלתי מועילה\n** דף בשימוש רב",
        "unblocked": "[[User:$1|$1]] {{GENDER:$1|שוחרר מחסימתו|שוחררה מחסימתה}}.",
        "unblocked-range": "$1 שוחרר מחסימתו.",
        "unblocked-id": "חסימה מספר $1 שוחררה.",
+       "unblocked-ip": "[[Special:Contributions/$1|$1]] שוחררה מחסימתה.",
        "blocklist": "משתמשים חסומים",
        "ipblocklist": "משתמשים חסומים",
        "ipblocklist-legend": "מציאת משתמש חסום",
        "watchlistedit-clear-explain": "כל הכותרות של הדפים שיוסרו מרשימת המעקב",
        "watchlistedit-clear-titles": "כותרות:",
        "watchlistedit-clear-submit": "ניקוי רשימת המעקב (לצמיתות!)",
-       "watchlistedit-clear-done": "רש×\99×\9eת ×\94×\9eעק×\91 ×©×\9c×\9a × ×\9e×\97קה.",
+       "watchlistedit-clear-done": "רש×\99×\9eת ×\94×\9eעק×\91 ×©×\9c×\9a × ×\95קתה.",
        "watchlistedit-clear-removed": "{{PLURAL:$1|כותרת אחת הוסרה|$1 כותרות הוסרו}}:",
        "watchlistedit-too-many": "יש יותר מדי דפים ולא ניתן להציגם כאן.",
        "watchlisttools-clear": "ניקוי רשימת המעקב",
        "logentry-newusers-create2": "חשבון המשתמש $3 נוצר על־ידי $1",
        "logentry-newusers-byemail": "חשבון המשתמש $3 נוצר על־ידי $1 והסיסמה נשלחה בדוא\"ל",
        "logentry-newusers-autocreate": "חשבון המשתמש $1 {{GENDER:$2|נוצר}} אוטומטית",
-       "logentry-rights-rights": "$1 {{GENDER:$2|שינה|שינתה}} את ההרשאות של $3 מ$4 ל$5&rlm;",
+       "logentry-rights-rights": "$1 {{GENDER:$2|שינה|שינתה}} את ההרשאות של $3 מ{{GRAMMAR:תחילית|$4}} ל{{GRAMMAR:תחילית|$5}}&rlm;",
        "logentry-rights-rights-legacy": "$1 {{GENDER:$2|שינה|שינתה}} את ההרשאות של $3&rlm;",
        "logentry-rights-autopromote": "$1 קודם אוטומטית מ$4 ל$5",
        "logentry-upload-upload": "$1 {{GENDER:$2|העלה|העלתה}} את $3",
        "logentry-upload-overwrite": "$1 {{GENDER:$2|העלה|העלתה}} גרסה חדשה של $3",
        "logentry-upload-revert": "$1 {{GENDER:$2|העלה|העלתה}} את $3",
        "rightsnone": "(כלום)",
+       "revdelete-summary": "תקציר העריכה",
        "feedback-bugornote": "אם אתם מוכנים לתאר בעיה טכנית בפרטים, אנא [$1 דווחו באג].\nאחרת, תוכלו להשתמש בטופס הפשוט שלהלן. הערתכם תתווסף לדף \"[$3 $2]\", יחד עם שם המשתמש שלכם.",
        "feedback-subject": "נושא:",
        "feedback-message": "הודעה:",
        "api-error-timeout": "השרת לא השיב בזמן המצופה.",
        "api-error-unclassified": "אירעה שגיאה בלתי ידועה.",
        "api-error-unknown-code": "שגיאה בלתי ידועה: \"$1\".",
-       "api-error-unknown-error": "ש×\92×\99×\90×\94 ×¤× ×\99×\9e×\99ת: ×\9eש×\94×\95 ×\94שת×\91ש ×\91עת × ×\99ס×\99×\95×\9f ×\9c×\94×¢×\9c×\95ת ×\90ת ×\94ק×\95×\91×¥ ×©×\9c×\9b×\9d.",
+       "api-error-unknown-error": "ש×\92×\99×\90×\94 ×¤× ×\99×\9e×\99ת: ×\9eש×\94×\95 ×\94שת×\91ש ×\91עת × ×\99ס×\99×\95×\9f ×\9c×\94×¢×\9c×\95ת ×\90ת ×\94ק×\95×\91×¥ ×©×\9c×\9a.",
        "api-error-unknown-warning": "אזהרה בלתי ידועה: \"$1\".",
        "api-error-unknownerror": "שגיאה בלתי ידועה: \"$1\".",
        "api-error-uploaddisabled": "ההעלאה מבוטלת באתר הוויקי הזה.",
        "log-name-pagelang": "יומן שינוי שפה",
        "log-description-pagelang": "זהו יומן של שינויים בשפות של הדפים.",
        "logentry-pagelang-pagelang": "$1 {{GENDER:$2|שינה|שינתה}} את שפת הדף $3 מ$4 ל$5.",
-       "default-skin-not-found": "אופס! עיצוב ברירת המחדל עבור אתר הוויקי שלכם (<code dir=\"ltr\">$wgDefaultSkin</code>),&rlm; <code>$1</code>, אינו זמין.\n\nנראה שההתקנה שלכם כוללת את העיצובים הבאים. ראו מידע בדף [https://www.mediawiki.org/wiki/Manual:Skin_configuration \"הגדרת עיצובים\" במדריך] על האפשרות להפעיל אותם ולבחור את עיצוב ברירת המחדל.\n\n$2\n\n; אם כרגע התקנתם את מדיה־ויקי:\n: נראה שזו התקנה מ־git, או ישירות מקוד המקור בשיטה אחרת כלשהי. במקרה הזה, בעיה זו צפויה. נסו להתקין כמה עיצובים מ[https://www.mediawiki.org/wiki/Category:All_skins ספריית העיצובים של mediawiki.org], על־ידי:\n:* הורדת [https://www.mediawiki.org/wiki/Download קובץ ה־tar להתקנה], שכולל מספר עיצובים והרחבות. באפשרותכם להעתיק ולהדביק מתוכו את תיקיית ה‏‏־<code>skins/</code>.\n:* שכפול (clone) אחד מהמאגרים ב־<code>mediawiki/skins/*</code> בעזרת git לתוך תיקיית ה־<code dir=\"ltr\">skins/</code> בהתקנת מדיה־ויקי שלכם.\n: אם תעשו זאת, זה לא אמור להפריע ל‏‏מאגר ה־git שלכם אם אתם מפתחים של מדיה־ויקי.\n\n; אם כרגע שדרגתם את מדיה־ויקי:\n: מדיה־ויקי 1.24 וגרסאות חדשות יותר כבר לא מפעילות עיצובים מותקנים באופן אוטומטי (ראו [https://www.mediawiki.org/wiki/Manual:Skin_autodiscovery \"גילוי אוטומטי של עיצובים\" במדריך]). תוכלו להעתיק את השורות הבאות לתוך הקובץ <code>LocalSettings.php</code> כדי להפעיל את כל העיצובים המותקנים כעת:\n\n<pre dir=\"ltr\">$3</pre>\n\n; אם כרגע שיניתם את <code>LocalSettings.php</code>:\n: בדקו שנית האם עשיתם שגיאות הקלדה בשמות העיצובים.",
-       "default-skin-not-found-no-skins": "אופס! עיצוב ברירת המחדל עבור אתר הוויקי שלכם (<code dir=\"ltr\">$wgDefaultSkin</code>),&rlm; <code>$1</code>, אינו זמין.\n\nאין לכם עיצובים מותקנים.\n\n; אם כרגע התקנתם או שדרגתם את מדיה־ויקי:\n: נראה שזו התקנה מ־git, או ישירות מקוד המקור בשיטה אחרת כלשהי. במקרה הזה, בעיה זו צפויה. מדיה־ויקי 1.24 וגרסאות חדשות יותר אינן כוללות עיצובים ב־git repository הראשי. נסו להתקין כמה עיצובים מ[https://www.mediawiki.org/wiki/Category:All_skins ספריית העיצובים של mediawiki.org], על־ידי:\n:* הורדת [https://www.mediawiki.org/wiki/Download קובץ ה‏‏־tar להתקנה], שכולל מספר עיצובים והרחבות. באפשרותכם להעתיק ולהדביק מתוכו את תיקיית ה‏‏־<code>skins/</code>.\n:* שכפול (clone) אחד ממאגרים ב־<code>mediawiki/skins/*</code> בעזרת git לתוך תיקיית ה־<code dir=\"ltr\">skins/</code> בהתקנת מדיה־ויקי שלכם.\n: אם תעשו זאת, זה לא אמור להפריע ל‏‏מאגר ה־git שלכם (אם אתם מפתחים של מדיה־ויקי). ראו מידע בדף [https://www.mediawiki.org/wiki/Manual:Skin_configuration \"הגדרת עיצובים\" במדריך] על האפשרות להפעיל עיצובים ולבחור את עיצוב ברירת המחדל.",
+       "default-skin-not-found": "אופס! עיצוב ברירת המחדל עבור אתר הוויקי שלכם, שמוגדר ב־<code dir=\"ltr\">$wgDefaultSkin</code> כ־<code>$1</code>, אינו זמין.\n\nנראה שההתקנה שלכם כוללת את העיצובים הבאים. ראו מידע בדף [https://www.mediawiki.org/wiki/Manual:Skin_configuration \"הגדרת עיצובים\" במדריך] על האפשרות להפעיל אותם ולבחור את עיצוב ברירת המחדל.\n\n$2\n\n; אם כרגע התקנתם את מדיה־ויקי:\n: נראה שזו התקנה מ־git, או ישירות מקוד המקור בשיטה אחרת כלשהי. במקרה הזה, בעיה זו צפויה. נסו להתקין כמה עיצובים מ[https://www.mediawiki.org/wiki/Category:All_skins ספריית העיצובים של mediawiki.org], על־ידי:\n:* הורדת [https://www.mediawiki.org/wiki/Download קובץ ה־tar להתקנה], שכולל מספר עיצובים והרחבות. באפשרותכם להעתיק ולהדביק מתוכו את תיקיית ה‏‏־<code>skins/</code>.\n:* שכפול (clone) אחד מהמאגרים ב־<code dir=\"ltr\">mediawiki/skins/*</code> בעזרת git לתוך תיקיית ה־<code dir=\"ltr\">skins/</code> בהתקנת מדיה־ויקי שלכם.\n: אם תעשו זאת, זה לא אמור להפריע ל‏‏מאגר ה־git שלכם אם אתם מפתחים של מדיה־ויקי.\n\n; אם כרגע שדרגתם את מדיה־ויקי:\n: מדיה־ויקי 1.24 וגרסאות חדשות יותר כבר לא מפעילות עיצובים מותקנים באופן אוטומטי (ראו [https://www.mediawiki.org/wiki/Manual:Skin_autodiscovery \"גילוי אוטומטי של עיצובים\" במדריך]). תוכלו להעתיק את השורות הבאות לתוך הקובץ <code>LocalSettings.php</code> כדי להפעיל את כל העיצובים המותקנים כעת:\n\n<pre dir=\"ltr\">$3</pre>\n\n; אם כרגע שיניתם את <code>LocalSettings.php</code>:\n: בדקו שנית האם עשיתם שגיאות הקלדה בשמות העיצובים.",
+       "default-skin-not-found-no-skins": "אופס! עיצוב ברירת המחדל עבור אתר הוויקי שלכם, שמוגדר ב־<code dir=\"ltr\">$wgDefaultSkin</code> כ־<code>$1</code>, אינו זמין.\n\nאין לכם עיצובים מותקנים.\n\n; אם כרגע התקנתם או שדרגתם את מדיה־ויקי:\n: נראה שזו התקנה מ־git, או ישירות מקוד המקור בשיטה אחרת כלשהי. במקרה הזה, בעיה זו צפויה. מדיה־ויקי 1.24 וגרסאות חדשות יותר אינן כוללות עיצובים ב־git repository הראשי. נסו להתקין כמה עיצובים מ[https://www.mediawiki.org/wiki/Category:All_skins ספריית העיצובים של mediawiki.org], על־ידי:\n:* הורדת [https://www.mediawiki.org/wiki/Download קובץ ה‏‏־tar להתקנה], שכולל מספר עיצובים והרחבות. באפשרותכם להעתיק ולהדביק מתוכו את תיקיית ה‏‏־<code>skins/</code>.\n:* שכפול (clone) אחד ממאגרים ב־<code>mediawiki/skins/*</code> בעזרת git לתוך תיקיית ה־<code dir=\"ltr\">skins/</code> בהתקנת מדיה־ויקי שלכם.\n: אם תעשו זאת, זה לא אמור להפריע ל‏‏מאגר ה־git שלכם (אם אתם מפתחים של מדיה־ויקי). ראו מידע בדף [https://www.mediawiki.org/wiki/Manual:Skin_configuration \"הגדרת עיצובים\" במדריך] על האפשרות להפעיל עיצובים ולבחור את עיצוב ברירת המחדל.",
        "default-skin-not-found-row-enabled": "* <code>$1</code> / $2 (מופעל)",
-       "default-skin-not-found-row-disabled": "* <code>$1</code> / $2 ('''מבוטל''')"
+       "default-skin-not-found-row-disabled": "* <code>$1</code> / $2 ('''מבוטל''')",
+       "mediastatistics": "סטטיסטיקות מדיה",
+       "mediastatistics-summary": "סטטיסטיקה על סוגי קבצים שהועלו. זה כולל רק את הגרסה החדשה ביותר של הקובץ. גרסאות ישנות ומחוקות של קבצים אינן כלולות.",
+       "mediastatistics-nbytes": "{{PLURAL:$1|בית אחד|$1 בתים}} ($2; $3%)",
+       "mediastatistics-table-mimetype": "סוג MIME",
+       "mediastatistics-table-extensions": "סיומות אפשריות",
+       "mediastatistics-table-count": "מספר הקבצים",
+       "mediastatistics-table-totalbytes": "גודל כולל",
+       "mediastatistics-header-unknown": "לא ידוע",
+       "mediastatistics-header-bitmap": "תמונות מפת סיביות",
+       "mediastatistics-header-drawing": "ציורים (תמונות וקטוריות)",
+       "mediastatistics-header-audio": "צליל",
+       "mediastatistics-header-video": "וידאו",
+       "mediastatistics-header-multimedia": "מדיה עשירה",
+       "mediastatistics-header-office": "מסמכים",
+       "mediastatistics-header-text": "טקסט",
+       "mediastatistics-header-executable": "בני־הרצה",
+       "mediastatistics-header-archive": "מכווצים"
 }
index 81a03f4..6d34f0b 100644 (file)
        "passwordreset-emailsent-capture": "नीचे दिखाया गया कूटशब्द रीसेट ई-मेल भेज दिया गया है।",
        "passwordreset-emailerror-capture": "नीचे दृष्टित कूटशब्द रीसेट ई-मेल उत्पन्न किया गया था, परंतु उसे {{GENDER:$2|सदस्य}} को भेजना असफल रहा।\nत्रुटि: $1",
        "changeemail": "ई-मेल पता परिवर्तित करें",
-       "changeemail-header": "खाते का ई-मेल पता परिवर्तित करें",
        "changeemail-text": "अपना ई-मेल पता परिवर्तित करने के लिए इस फ़ॉर्म को पूरा करें। इस बदलाव की पुष्टि करने के लिये आपको अपना कूटशब्द पुनः लिखना पड़ेगा।",
        "changeemail-no-info": "इस पृष्ठ का सीधे प्रयोग करने के लिए आपको लॉग इन करना होगा।",
        "changeemail-oldemail": "वर्तमान ई-मेल पता:",
        "changeemail-none": "(कोई नहीं)",
        "changeemail-password": "आपका {{SITENAME}} पासवर्ड:",
        "changeemail-submit": "ई-मेल बदलें",
-       "changeemail-cancel": "रद्द करें",
        "changeemail-throttled": "आपने हाल ही में कई बार लॉग इन करने के प्रयास किये हैं।\nपुनः प्रयास करने से पहले कृपया $1 प्रतीक्षा करें।",
        "resettokens": "टोकन रीसेट करें",
        "resettokens-text": "जो टोकन आपके खाते से सम्बद्ध कुछ विशिष्ट व्यक्तिगत जानकारी प्रदान करते हैं, आप उन्हें यहाँ रीसेट कर सकते हैं।\n\nयदि आपने उन्हें गलती से किसी को दिखा दिया है या फिर आपका खाता हैक हो गया है तो आपको इन्हें रीसेट कर देना चाहिए।",
        "searchrelated": "सम्बंधित",
        "searchall": "सभी",
        "showingresults": "नीचे क्रमांक '''$2''' से प्रारंभ कर के अधिकतम '''$1''' परिणाम {{PLURAL:$1|दिखाया गया है|दिखाए गए हैं}}।",
-       "showingresultsheader": "'''$4''' के खोज परिणाम {{PLURAL:$5|कुल '''$3''' में से #'''$1'''|कुल '''$3''' में से क्रं. '''$1 - $2'''}}",
        "search-nonefound": "आपकी खोज से मेल खाते कोई परिणाम नहीं मिले।",
        "powersearch-legend": "उन्नत खोज",
        "powersearch-ns": "नामस्थानों में खोजें:",
        "filedelete-maintenance": "रखरखाव चल रहा है और रखरखाव के दौरान फ़ाइलों को हटाना और पुनर्स्थापित करना अक्षम है।",
        "filedelete-maintenance-title": "फ़ाइल हटा नहीं सकते",
        "mimesearch": "MIME खोज",
-       "mimesearch-summary": "MIME-प्रकारों के अनुसार फ़ाइलें खोजने के लिये इस पृष्ठ का इस्तेमाल किया जा सकता है।\nइनपुट: फ़ाइल का प्रकार/उपप्रकार या प्रकार/*, उदा. <code>image/jpeg</code>।",
+       "mimesearch-summary": "MIME-प्रकारों के अनुसार फ़ाइलें खोजने के लिये इस पृष्ठ का इस्तेमाल किया जा सकता है।\nइनपुट: फ़ाइल का प्रकार/उपप्रकार या प्रकार/*, उदा <code>image/jpeg</code>।",
        "mimetype": "MIME प्रकार:",
        "download": "डाउनलोड",
        "unwatchedpages": "ध्यान न दिये हुए पृष्ठ",
        "logentry-rights-rights-legacy": "$1 ने $3 के सदस्य समूह {{GENDER:$2|बदले}}",
        "logentry-rights-autopromote": "$1 के सदस्य समूह स्वतः $4 से बदलकर $5 {{GENDER:$2|किये}} गए",
        "rightsnone": "(कोई नहीं)",
+       "revdelete-summary": "संपादन सारांश",
        "feedback-bugornote": "यदि आप किसी तकनीकी परेशानी को विस्तार से समझाने के लिये तैयार हैं तो कृपया [$1 बग फ़ाइल करें]।\nयदि नहीं, तो आप नीचे दिये सरल फ़ॉर्म का प्रयोग कर सकते हैं। आपकी टिप्पणी आपके सदस्य नाम और आपके ब्राउज़र के नाम के सहित \"[$3 $2]\" पृष्ठ में जोड़ दी जाएगी।",
        "feedback-subject": "विषय:",
        "feedback-message": "संदेश:",
index 3dc10e1..93d64c2 100644 (file)
        "hidetoc": "sakrij",
        "collapsible-collapse": "sklopi stablo",
        "collapsible-expand": "raširi stablo",
+       "confirmable-confirm": "Jeste li sigurni?",
+       "confirmable-yes": "Da",
+       "confirmable-no": "Ne",
        "thisisdeleted": "Vidi ili vrati $1?",
        "viewdeleted": "Vidi $1?",
        "restorelink": "{{PLURAL:$1|$1 pobrisanu izmjenu|$1 pobrisane izmjene|$1 pobrisanih izmjena}}",
        "passwordreset-emailsent-capture": "Poslan Vam je podsjetnik kao e-pošta (tekst je prikazan dolje).",
        "passwordreset-emailerror-capture": "Napravljena je e-poruka za ponovno postavljanje zaporke (prikazana ispod), ali njeno slanje suradniku nije uspjelo: $1",
        "changeemail": "Promijeni e-mail adresu",
-       "changeemail-header": "Promijeni adresu e-pošte računa",
        "changeemail-text": "Za promjenu e-mail adrese popunite ovaj obrazac. Morat ćete unijeti svoju lozinku da potvrdite ovu promjenu.",
        "changeemail-no-info": "Morate biti prijavljeni da biste izravno pristupili ovoj stranici.",
        "changeemail-oldemail": "Trenutačna adresa e-pošte:",
        "changeemail-none": "(ništa)",
        "changeemail-password": "Zaporka za {{SITENAME}}:",
        "changeemail-submit": "Promijeni E-mail",
-       "changeemail-cancel": "Odustani",
        "bold_sample": "Podebljani tekst",
        "bold_tip": "Podebljani tekst",
        "italic_sample": "Kurzivni tekst",
        "searchall": "sve",
        "showingresults": "Dolje {{PLURAL:$1|je prikazan '''$1''' rezultat|su prikazana '''$1''' rezultata|je prikazano '''$1''' rezultata}}, počevši od '''$2'''.",
        "showingresultsinrange": "Dolje {{PLURAL:$1|je prikazan '''$1''' rezultat|su prikazana '''$1''' rezultata|je prikazano '''$1''' rezultata}}, u rasponu od '''$2''' do '''$3'''.",
-       "showingresultsheader": "{{PLURAL:$5|Rezultat '''$1''' od '''$3'''|Rezultati '''$1 - $2''' od '''$3'''}} za '''$4'''",
        "search-nonefound": "Ne postoje rezultati koji se podudaraju s upitom.",
        "powersearch-legend": "Napredno pretraživanje",
        "powersearch-ns": "Traži u imenskom prostoru:",
        "recentchanges-noresult": "U zadanom vremenu nema promjena za zadane kriterije.",
        "recentchanges-feed-description": "Na ovoj stranici možete pratiti nedavne promjene u wikiju.",
        "recentchanges-label-newpage": "Ova izmjena stvorila je novu stranicu",
-       "recentchanges-label-minor": "Ovo je manja izmjena",
-       "recentchanges-label-bot": "Ovu izmjenu napravio je bot",
-       "recentchanges-label-unpatrolled": "Ova izmjena još nije pregledana",
+       "recentchanges-label-minor": "Manja izmjena",
+       "recentchanges-label-bot": "Izmjenu napravio bot",
+       "recentchanges-label-unpatrolled": "Nepregledana izmjena",
        "recentchanges-label-plusminus": "Promjena veličine stranice (u bajtovima)",
        "recentchanges-legend-heading": "'''Legenda:'''",
-       "recentchanges-legend-newpage": "$1 - nova stranica",
+       "recentchanges-legend-newpage": "Nova stranica",
        "rcnotefrom": "Slijede promjene od <b>$2</b> (prikazano ih je do <b>$1</b>).",
        "rclistfrom": "Prikaži nove promjene počevši od $3 $2",
        "rcshowhideminor": "$1 manje promjene",
        "listfiles_description": "Opis",
        "listfiles_count": "Inačice",
        "listfiles-show-all": "Uključujući starije inačice slika",
+       "listfiles-latestversion": "Trenutačna inačica",
        "listfiles-latestversion-yes": "Da",
        "listfiles-latestversion-no": "Ne",
        "file-anchor-link": "Slika",
        "pageinfo-length": "Dužina stranice (u bajtovima)",
        "pageinfo-article-id": "ID stranice",
        "pageinfo-language": "Jezik stranice",
+       "pageinfo-content-model": "Tip podataka na stranici",
        "pageinfo-robot-policy": "Status tražilice",
        "pageinfo-robot-index": "Stranicu je moguće indeksirati",
        "pageinfo-robot-noindex": "Indeksiranje stranice onemogućeno",
        "pageinfo-views": "Broj pregleda",
        "pageinfo-watchers": "Broj pratitelja stranice",
+       "pageinfo-few-watchers": "Manje od $1 {{PLURAL:$1|suradnika koji prate ovu stranicu|suradnika koji prate ovu stranicu}}",
        "pageinfo-redirects-name": "Broj preusmjeravanja na ovu stranicu",
        "pageinfo-subpages-name": "Podstranice",
        "pageinfo-subpages-value": "Ukupno $1 ($2 {{PLURAL:$2|preusmjeravanje|preusmjeravanja}}; $3 {{PLURAL:$3|obična podstranica|obične podstranice|običnih podstranica}})",
        "logentry-upload-overwrite": "$1 је {{GENDER:$2|postavio|postavila}} novu inačicu $3",
        "logentry-upload-revert": "$1 је {{GENDER:$2|postavio|postavila}} $3",
        "rightsnone": "(suradnik)",
+       "revdelete-summary": "sažetak",
        "feedback-bugornote": "Ako ste spremni detaljno opisati tehnički problem molimo [$1 prijavite \"bug\"].\nInače, možete ispuniti jednostavan obrazac u nastavku. Vaš komentar biti će dodan na stranicu \"[$3 $2]\", zajedno s vašim suradničkim imenom i imenom internetskog preglednika koji rabite.",
        "feedback-subject": "Tema:",
        "feedback-message": "Poruka:",
index 7f7e3ac..072b533 100644 (file)
@@ -11,7 +11,8 @@
                        "Tchoř",
                        "Tlustulimu",
                        "לערי ריינהארט",
-                       "아라"
+                       "아라",
+                       "Mikławš"
                ]
        },
        "tog-underline": "Wotkazy podšmórnić:",
        "perfcached": "Slědowace daty pochadźeja z pufrowaka a njejsu snano cyle aktualne. Maksimalnje {{PLURAL:$1|jedyn wuslědk|$1 wuslědkaj|$1 wuslědki|$1 wuslědkow}} w pufrowaku k dispoziciji {{PLURAL:$1|steji|stejitej|steja|steji}}.",
        "perfcachedts": "Slědowace daty su z pufrowaka a buchu $1 posledni raz zaktualizowane. Maksimalnje {{PLURAL:$4|jedyn wuslědk|$4 wuslědkaj|$4 wuslědki|$4 wuslědkow}} w pufrowaku k dispoziciji {{PLURAL:$4|steji|stejitej|steja|steji}}.",
        "querypage-no-updates": "Aktualizacije za tutu stronu su tuchwilu znjemóžnjene. Daty so hač na dalše njewobnowja.",
-       "viewsource": "žórÅ\82o wobhladaÄ\87",
+       "viewsource": "ŽórÅ\82owy tekst",
        "viewsource-title": "Žórłowy tekst za $1 sej wobhladać",
        "actionthrottled": "Akcije wobmjezowane",
        "actionthrottledtext": "Jako připrawa přećiwo spamej, je častosć wuwjedźenja tuteje akcije w krótkej dobje wobmjezowana a ty sy tutón limit překročił. Prošu spytaj za něšto mjeńšiny hišće raz.",
        "userlogin-resetlink": "Přizjewjenske daty zabył?",
        "userlogin-resetpassword-link": "Sy swoje hesło zabył?",
        "userlogin-helplink2": "Pomoc při přizjewjenju",
-       "userlogin-loggedin": "Sy hižo jako {{GENDER:$1|$1 přizjewjeny|$1 přizjewjena}}. Wužij slědowacy formular, zo by so jako druhi wužiwar přizjewił.",
-       "userlogin-createanother": "Dalše konto załožić",
        "createacct-emailrequired": "E-mejlowa adresa",
        "createacct-emailoptional": "E-mejlowa adresa (opcionalny)",
        "createacct-email-ph": "Zapodaj swoju e-mejlowu adresu",
        "passwordreset-emailsent-capture": "E-mejl za anulowanje hesła je so pósłała, kotraž so deleka pokazuje.",
        "passwordreset-emailerror-capture": "E-mejl za anulowanje hesła je so wutworiła, kotraž so deleka pokazuje, ale słanje {{GENDER:$2|wužiwarjej|wužiwarce}} je so njeporadźiło: $1",
        "changeemail": "E-mejlowu adresu změnić",
-       "changeemail-header": "Kontowu e-mejlowu adresu změnić",
        "changeemail-text": "Wupjelń tutón formular, zo by swoju e-mejlowu adresu změnił. Dyrbiš swoje hesło zapodać, zo by tutu změnu wobkrućił.",
        "changeemail-no-info": "Dyrbiš so přizjewić, zo by direktny přistup na tutu stronu měł.",
        "changeemail-oldemail": "Aktualna e-mejlowa adresa:",
        "changeemail-none": "(žana)",
        "changeemail-password": "Twoje hesło za {{GRAMMAR:akuzatiw|{{SITENAME}}}}",
        "changeemail-submit": "E-mejlowu adresu změnić",
-       "changeemail-cancel": "Přetorhnyć",
        "changeemail-throttled": "Sy přehusto spytał so přizjewić.\nPočakaj prošu $1, prjedy hač hišće raz spytaš.",
        "resettokens": "Tokeny wróćo stajić",
        "resettokens-text": "Móžeš tokeny wróćo stajić, kotrež přistup na wěste priwatne daty dowoleja, kotrež su z twojim kontom zwjazane.\n\nTy dyrbjał zo činić, jeli sy je zmylnje z někim dźělił abo jelic twoje konto je so napadało.",
        "searchall": "wšě",
        "showingresults": "Deleka so hač {{PLURAL:$1|'''1''' wuslědk pokazuje|'''$1''' wuslědkaj pokazujetej|'''$1''' wuslědki pokazuja|'''$1''' wuslědkow pokazuje}}, započinajo z #'''$2'''.",
        "showingresultsinrange": "Deleka so do {{PLURAL:$1|<strong>1</strong> wuslědka|<strong>$1</strong> wuslědkow}} we wobłuku <strong>$2</strong> hač do <strong>$3</strong> pokazuje.",
-       "showingresultsheader": "{{PLURAL:$5|Wuslědk '''$1''' z '''$3'''|Wuslědki '''$1 - $2''' z '''$3'''}} za '''$4'''",
        "search-nonefound": "Njebuchu wuslědki namakane, kotrež naprašowanju wotpowěduja.",
        "powersearch-legend": "Rozšěrjene pytanje",
        "powersearch-ns": "W mjenowych rumach pytać:",
        "recentchanges-legend-newpage": "{{int:recentchanges-label-newpage}} (hlej tež [[Special:NewPages|lisćinu nowych stronow]])",
        "recentchanges-legend-plusminus": "(''±123'')",
        "rcnotefrom": "Deleka so změny wot <strong>$2</strong> pokazuja (hač k <strong>$1</strong>).",
-       "rclistfrom": "Nowe změny pokazać, započinajo z $3 $2",
+       "rclistfrom": "Jenož změny wot $3, $2 pokazać.",
        "rcshowhideminor": "snadne změny $1",
-       "rcshowhideminor-show": "Pokazać",
-       "rcshowhideminor-hide": "Schować",
+       "rcshowhideminor-show": "pokazać",
+       "rcshowhideminor-hide": "schować",
        "rcshowhidebots": "Boćiki $1",
-       "rcshowhidebots-show": "Pokazać",
-       "rcshowhidebots-hide": "Schować",
+       "rcshowhidebots-show": "pokazać",
+       "rcshowhidebots-hide": "schować",
        "rcshowhideliu": "Zregistrowani wužiwarjo $1",
-       "rcshowhideliu-show": "Pokazać",
-       "rcshowhideliu-hide": "Schować",
+       "rcshowhideliu-show": "pokazać",
+       "rcshowhideliu-hide": "schować",
        "rcshowhideanons": "Anonymni wužiwarjo $1",
-       "rcshowhideanons-show": "Pokazać",
-       "rcshowhideanons-hide": "Schować",
+       "rcshowhideanons-show": "pokazać",
+       "rcshowhideanons-hide": "schować",
        "rcshowhidepatr": "Dohladowane změny $1",
        "rcshowhidepatr-show": "Pokazać",
        "rcshowhidepatr-hide": "Schować",
        "rcshowhidemine": "moje změny $1",
-       "rcshowhidemine-show": "Pokazać",
-       "rcshowhidemine-hide": "Schować",
-       "rclinks": "Poslednje $1 změnow poslednich $2 dnjow pokazać<br />$3",
+       "rcshowhidemine-show": "pokazać",
+       "rcshowhidemine-hide": "schować",
+       "rclinks": "Pokazuj poslednje $1 změny poslednich $2 dnjow.<br />$3",
        "diff": "rozdźěl",
        "hist": "wersije",
        "hide": "schować",
        "randomincategory": "Připadna strona w kategoriji",
        "randomincategory-invalidcategory": "\"$1\" płaćiwe kategorijowe mjeno njeje.",
        "randomincategory-nopages": "W kategoriji [[:Category:$1|$1]] žane strony njejsu.",
+       "randomincategory-category": "Kategorija:",
+       "randomincategory-legend": "Připadna strona w kategoriji",
        "randomredirect": "Připadne daleposrědkowanje",
        "randomredirect-nopages": "Žane daleposrědkowanja w mjenowym rumje \"$1\".",
        "statistics": "Statistika",
        "logentry-upload-overwrite": "$1 je nowu wersiju $3 {{GENDER:$2|nahrał|nahrała}}",
        "logentry-upload-revert": "$1 je $3 {{GENDER:$2|nahrał|nahrała}}",
        "rightsnone": "(ničo)",
+       "revdelete-summary": "zjeće wobdźěłać",
        "feedback-bugornote": "Jeli sy zwólniwy, techniski problem nadrobnje wopisać, [$1 zdźěl prošu zmylk].\nHewak móžeš slědowacy jednory formular wužiwać. Twój komentar přida so stronje \"[$3 $2]\", z twojim wužiwarskim mjenom a z wobhladowakom, kotryž wužiwaš.",
        "feedback-subject": "Tema:",
        "feedback-message": "Powěsć:",
index ac34c51..5e2a26a 100644 (file)
@@ -35,7 +35,8 @@
                        "Xbspiro",
                        "아라",
                        "Csega",
-                       "ViDam"
+                       "ViDam",
+                       "Adam78"
                ]
        },
        "tog-underline": "Hivatkozások aláhúzása:",
        "hidetoc": "elrejtés",
        "collapsible-collapse": "becsuk",
        "collapsible-expand": "kinyit",
+       "confirmable-confirm": "Biztos {{GENDER:$1|vagy}} benne?",
+       "confirmable-yes": "Igen",
+       "confirmable-no": "Nem",
        "thisisdeleted": "$1 megtekintése vagy helyreállítása?",
        "viewdeleted": "$1 megtekintése?",
        "restorelink": "{{PLURAL:$1|Egy|$1}} törölt szerkesztés",
        "passwordreset-emailsent-capture": "Az alább látható jelszó-visszaállító e-mail lett elküldve.",
        "passwordreset-emailerror-capture": "A jelszó-visszaállító e-mail generálása megtörtént, mint az alább látszik, de elküldése a {{GENDER:$2|szerkesztőnek}} nem sikerült: $1",
        "changeemail": "E-mail cím megváltoztatása",
-       "changeemail-header": "A fiókhoz tartozó e-mail cím megváltoztatása",
        "changeemail-text": "Az e-mail címed megváltoztatásához ki kell töltened az alábbi űrlapot. Megerősítésképpen meg kell adnod a jelszavadat is.",
        "changeemail-no-info": "A lap közvetlen eléréséhez be kell jelentkezned.",
        "changeemail-oldemail": "Jelenlegi e-mail cím:",
        "changeemail-none": "(nincs)",
        "changeemail-password": "A {{SITENAME}} jelszavad:",
        "changeemail-submit": "E-mail cím megváltoztatása",
-       "changeemail-cancel": "Mégse",
        "changeemail-throttled": "Túl sok hibás bejelentkezés.\nVárj $1, mielőtt újra próbálkozol.",
        "resettokens": "Tokenek törlése",
        "resettokens-no-tokens": "Nincs újragenerálható token.",
        "showpreview": "Előnézet megtekintése",
        "showdiff": "Változtatások megtekintése",
        "blankarticle": "<strong>Figyelem:</strong> A létrehozandó szócikk üres.\nHa ismét a \"{{int:savearticle}}\" gombra kattintasz, a szócikket tartalom nélkül fogod létrehozni.",
-       "anoneditwarning": "'''Figyelem:''' Nem vagy bejelentkezve, ha szerkesztesz, az IP-címed látható lesz a laptörténetben.",
+       "anoneditwarning": "'''Figyelem:''' Nem vagy bejelentkezve. Ha szerkesztesz, az IP-címed látható lesz a laptörténetben.",
        "anonpreviewwarning": "''Nem vagy bejelentkezve. A mentéskor az IP-címed rögzítve lesz a laptörténetben.''",
        "missingsummary": "'''Emlékeztető:''' Nem adtál meg szerkesztési összefoglalót. Ha összefoglaló nélkül akarod elküldeni a szöveget, kattints újra a mentésre.",
        "missingcommenttext": "Kérjük, írj összefoglalót a szerkesztésedhez.",
        "parser-template-loop-warning": "Végtelen ciklus a következő sablonban: [[$1]]",
        "parser-template-recursion-depth-warning": "A sablon rekurzív beillesztésének mélysége átlépte a határérékét ($1)",
        "language-converter-depth-warning": "A nyelvátalakító rekurzióinak száma túllépve ($1)",
-       "node-count-exceeded-category": "Lapok, ahogy a csomópont szám túl nagy",
-       "node-count-exceeded-category-desc": "Azon oldalaknak a kategóriája, ahol a csomópont szám túl nagy.",
+       "node-count-exceeded-category": "Lapok, ahogy a csomópontszám túl nagy",
+       "node-count-exceeded-category-desc": "Azon oldalaknak a kategóriája, ahol a csomópontszám túl nagy.",
        "node-count-exceeded-warning": "Az oldal meghaladta a csomópont számot",
        "expansion-depth-exceeded-category": "Lapok, melyeken a sablonok kibontása meghaladja a megengedett szintet",
        "expansion-depth-exceeded-warning": "A lap meghaladta az engedélyezett kiterjesztési mélységet",
        "searchrelated": "kapcsolódó",
        "searchall": "mind",
        "showingresults": "Lent '''{{PLURAL:$1|egy|$1}}''' találat látható, az eleje '''$2'''.",
-       "showingresultsheader": "{{PLURAL:$5|'''$1'''|'''$1 - $2'''}}. találat a(z) '''$4''' kifejezésre (összesen: '''$3''')",
        "search-nonefound": "Nincs egyezés a megadott szöveggel.",
        "powersearch-legend": "Részletes keresés",
        "powersearch-ns": "Névterek:",
        "right-move": "lapok átnevezése",
        "right-move-subpages": "lapok átnevezése az allapjukkal együtt",
        "right-move-rootuserpages": "szerkesztői lapok mozgatása",
+       "right-move-categorypages": "kategóriák átnevezése",
        "right-movefile": "fájlok átnevezése",
        "right-suppressredirect": "nem készít átirányítást a régi néven lapok átnevezésekor",
        "right-upload": "fájlok feltöltése",
        "right-proxyunbannable": "proxyk automatikus blokkjainak megkerülése",
        "right-unblockself": "saját felhasználói fiók blokkjának feloldása",
        "right-protect": "védelmi szintek megváltoztatása és kaszkádolt védelemmel rendelkező lapok szerkesztése",
-       "right-editprotected": "\"{{int:protect-level-sysop}}\" védelmi szintű lapok szerkesztése",
+       "right-editprotected": "„{{int:protect-level-sysop}}” védelmi szintű lapok szerkesztése",
+       "right-editsemiprotected": "„{{int:protect-level-autoconfirmed}}” védelmi szintű lapok szerkesztése",
        "right-editinterface": "felhasználói felület szerkesztése",
        "right-editusercssjs": "más felhasználók CSS és JS fájljainak szerkesztése",
        "right-editusercss": "más felhasználók CSS fájljainak szerkesztése",
        "right-edituserjs": "más felhasználók JS fájljainak szerkesztése",
        "right-editmyusercss": "A saját szerkesztői CSS-fájlok szerkesztése",
        "right-editmyuserjs": "Saját szerkesztői JavaScript-fájlok szerkesztése",
-       "right-viewmywatchlist": "Saját figyelőlista megtekintése",
-       "right-editmywatchlist": "Saját figyelőlista szerkesztése. Bizonyos műveletek képesek lapok figyelőlistához adására ezen jog nélkül is.",
-       "right-viewmyprivateinfo": "Saját személyes adatok megtekintése (pl. e-mailcím, valódi név)",
-       "right-editmyprivateinfo": "Saját személyes adatok szerkesztése (pl. e-mailcím, valódi név)",
-       "right-editmyoptions": "Saját beállítások szerkesztése",
+       "right-viewmywatchlist": "saját figyelőlista megtekintése",
+       "right-editmywatchlist": "saját figyelőlista szerkesztése; bizonyos műveletek képesek lapok figyelőlistához adására ezen jog nélkül is",
+       "right-viewmyprivateinfo": "saját személyes adatok megtekintése (pl. e-mail cím, valódi név)",
+       "right-editmyprivateinfo": "saját személyes adatok szerkesztése (pl. e-mail cím, valódi név)",
+       "right-editmyoptions": "saját beállítások szerkesztése",
        "right-rollback": "a lap utolsó szerkesztésének gyors visszaállítása",
        "right-markbotedits": "visszaállított szerkesztések botként való jelölése",
        "right-noratelimit": "sebességkorlát figyelmen kívül hagyása",
        "protect-cascadeon": "A lap jelenleg le van védve, mert {{PLURAL:$1|tartalmazza az alábbi lap, amelyen|tartalmazzák az alábbi lapok, amelyeken}} be van kapcsolva a kaszkád védelem.\nEzen lap védelmi szintjének megváltoztatása nem lesz hatással a kaszkád védelemre.",
        "protect-default": "Minden szerkesztő számára engedélyezett",
        "protect-fallback": "\"$1\" engedély szükséges hozzá",
-       "protect-level-autoconfirmed": "Csak automatikusan ellenőrzött szerkesztőknek engedélyezett (nem vagy frissen regisztráltaknak nem)",
-       "protect-level-sysop": "Csak adminisztrátoroknak engedélyezett",
+       "protect-level-autoconfirmed": "Csak automatikusan megerősített szerkesztőknek engedélyezett (nem vagy frissen regisztráltaknak nem)",
+       "protect-level-sysop": "csak adminisztrátoroknak engedélyezett",
        "protect-summary-cascade": "kaszkád védelem",
        "protect-expiring": "lejár: $1 (UTC)",
        "protect-expiring-local": "lejárat: $1",
        "logentry-rights-rights-legacy": "$1 megváltoztatta $3 csoporttagságát",
        "logentry-rights-autopromote": "$1 automatikusan előléptetve erről: $4 erre: $5",
        "rightsnone": "(semmi)",
+       "revdelete-summary": "a szerkesztési összefoglalóját",
        "feedback-bugornote": "Ha kész technikai problémát részletesen leírni, akkor kérjük [$1 jelents egy hibát]. Egyébként használd az alábbi űrlapot. A hozzászólásod a „[$3 $2]” laphoz kerül felvételre, a szerkesztő neveddel és böngésződ típusával együtt.",
        "feedback-subject": "Tárgy:",
        "feedback-message": "Üzenet:",
index 1b775f0..bea4155 100644 (file)
@@ -16,7 +16,8 @@
                        "Xelgen",
                        "Համլետ",
                        "לערי ריינהארט",
-                       "아라"
+                       "아라",
+                       "Lilitik22"
                ]
        },
        "tog-underline": "ընդգծել հղումները՝",
        "tog-hidepatrolled": "Թաքցնել պարեկված խմբագրումները վերջին փոփոխությունների ցանկից",
        "tog-newpageshidepatrolled": "Թաքցնել պարեկված էջերը նոր էջերի ցանկից",
        "tog-extendwatchlist": "Ընդարձակել հսկացանկը՝ ցույց տալով բոլոր փոփոխությունները, այլ ոչ միայն վերջինները",
-       "tog-usenewrc": "Ô½Õ´Õ¢Õ¡Õ¾Õ¸Ö\80Õ¥Õ¬ Ö\83Õ¸Ö\83Õ¸Õ­Õ¸Ö\82Õ©ÕµÕ¸Ö\82Õ¶Õ¶Õ¥Ö\80Õ¨ Õ\8eերջին փոփոխություններում և հսկացանկում (պահանջում է JavaScript)",
+       "tog-usenewrc": "Ô½Õ´Õ¢Õ¡Õ¾Õ¸Ö\80Õ¥Õ¬ Ö\83Õ¸Ö\83Õ¸Õ­Õ¸Ö\82Õ©ÕµÕ¸Ö\82Õ¶Õ¶Õ¥Ö\80Õ¨ Õ¾երջին փոփոխություններում և հսկացանկում (պահանջում է JavaScript)",
        "tog-numberheadings": "Ինքնաթվագրել վերնագրերը",
        "tog-showtoolbar": "Ցույց տալ խմբագրումների գործիքների վահանակը",
        "tog-editondblclick": "Խմբագրել էջերը կրկնակի մատնահարմամբ",
        "tog-editsectiononrightclick": "Խմբագրել բաժինները վերնագրի աջ մատնահարմամբ",
-       "tog-watchcreations": "Ô±Õ¾Õ¥Õ¬Õ¡Ö\81Õ¶Õ¥Õ¬ Õ«Õ´ Õ½Õ¿Õ¥Õ²Õ®Õ¡Õ® Õ§Õ»Õ¥Ö\80Õ¨ Ö\87 Õ¢Õ¥Õ¼Õ¶Õ¡Õ® Õ¶Õ«Õ·Ö\84Õ¥Ö\80Õ¨ Õ°Õ½Õ¯Õ¡Ö\81Õ¡Õ¶Õ¯Õ«Õ¶",
-       "tog-watchdefault": "Ô±Õ¾Õ¥Õ¬Õ¡Ö\81Õ¶Õ¥Õ¬ Õ«Õ´ Õ­Õ´Õ¢Õ¡Õ£Ö\80Õ¡Õ® Õ§Õ»Õ¥Ö\80Õ¨ Ö\87 Õ¶Õ«Õ·Ö\84Õ¥Ö\80Õ¨ Õ°Õ½Õ¯Õ¡Ö\81Õ¡Õ¶Õ¯Õ«Õ¶",
-       "tog-watchmoves": "Ô±Õ¾Õ¥Õ¬Õ¡Ö\81Õ¶Õ¥Õ¬ Õ«Õ´ Õ¾Õ¥Ö\80Õ¶Õ¡Õ¾Õ¡Õ¶Õ¡Õ® Õ§Õ»Õ¥Ö\80Õ¨ Ö\87 Õ¶Õ«Õ·Ö\84Õ¥Ö\80Õ¨ Õ°Õ½Õ¯Õ¡Ö\81Õ¡Õ¶Õ¯Õ«Õ¶",
-       "tog-watchdeletion": "Ô±Õ¾Õ¥Õ¬Õ¡Ö\81Õ¶Õ¥Õ¬ Õ«Õ´ Õ»Õ¶Õ»Õ¡Õ® Õ§Õ»Õ¥Ö\80Õ¨ Ö\87 Õ¶Õ«Õ·Ö\84Õ¥Ö\80Õ¨ Õ«Õ´ Õ°Õ½Õ¯Õ¡Ö\81Õ¡Õ¶Õ¯Õ«Õ¶",
-       "tog-minordefault": "Նշել խմբագրումները որպես չնչին ըստ լռության",
+       "tog-watchcreations": "Ô±Õ¾Õ¥Õ¬Õ¡Ö\81Õ¶Õ¥Õ¬ Õ«Õ´ Õ½Õ¿Õ¥Õ²Õ®Õ¡Õ® Õ§Õ»Õ¥Ö\80Õ¨ Ö\87 Õ¢Õ¥Õ¼Õ¶Õ¡Õ® Õ¶Õ«Õ·Ö\84Õ¥Ö\80Õ¨ Õ°Õ½Õ¯Õ¡Ö\81Õ¡Õ¶Õ¯Õ¸Ö\82Õ´",
+       "tog-watchdefault": "Ô±Õ¾Õ¥Õ¬Õ¡Ö\81Õ¶Õ¥Õ¬ Õ«Õ´ Õ­Õ´Õ¢Õ¡Õ£Ö\80Õ¡Õ® Õ§Õ»Õ¥Ö\80Õ¨ Ö\87 Õ¶Õ«Õ·Ö\84Õ¥Ö\80Õ¨ Õ°Õ½Õ¯Õ¡Ö\81Õ¡Õ¶Õ¯Õ¸Ö\82Õ´",
+       "tog-watchmoves": "Ô±Õ¾Õ¥Õ¬Õ¡Ö\81Õ¶Õ¥Õ¬ Õ«Õ´ Õ¾Õ¥Ö\80Õ¶Õ¡Õ¾Õ¡Õ¶Õ¡Õ® Õ§Õ»Õ¥Ö\80Õ¨ Ö\87 Õ¶Õ«Õ·Ö\84Õ¥Ö\80Õ¨ Õ°Õ½Õ¯Õ¡Ö\81Õ¡Õ¶Õ¯Õ¸Ö\82Õ´",
+       "tog-watchdeletion": "Ô±Õ¾Õ¥Õ¬Õ¡Ö\81Õ¶Õ¥Õ¬ Õ«Õ´ Õ»Õ¶Õ»Õ¡Õ® Õ§Õ»Õ¥Ö\80Õ¨ Ö\87 Õ¶Õ«Õ·Ö\84Õ¥Ö\80Õ¨ Õ°Õ½Õ¯Õ¡Ö\81Õ¡Õ¶Õ¯Õ¸Ö\82Õ´",
+       "tog-minordefault": "Խմբագրումները լռելյայն նշել որպես չնչին",
        "tog-previewontop": "Ցույց տալ նախադիտումը խմբագրման դաշտից առաջ",
        "tog-previewonfirst": "Նախադիտել մինչև առաջին խմբագրությունը",
        "tog-enotifwatchlistpages": "էլ-փոստով տեղեկացնել հսկվող էջերում փոփոխությունների մասին",
        "permalink": "Մշտական հղում",
        "print": "Տպել",
        "view": "Դիտել",
+       "view-foreign": "Նայել $1-ում",
        "edit": "Խմբագրել",
+       "edit-local": "Խմբագրել տեղական նկարագրությունը",
        "create": "Ստեղծել",
        "editthispage": "Խմբագրել այս էջը",
        "create-this-page": "Ստեղծել այս էջը",
        "otherlanguages": "Այլ լեզուներով",
        "redirectedfrom": "(Վերահղված է $1ից)",
        "redirectpagesub": "Վերահղման էջ",
+       "redirectto": "Վերահղել դեպի՝",
        "lastmodifiedat": "Այս էջը վերջին անգամ փոփոխվել է ժամը $2-ին, $1 թվին։",
        "viewcount": "Այս էջին դիմել են {{PLURAL:$1|մեկ անգամ|$1 անգամ}}։",
        "protectedpage": "Պաշտպանված էջ",
        "jumptonavigation": "նավարկություն",
        "jumptosearch": "որոնում",
        "view-pool-error": "Ներեցեք՝ սերվերները գերբեռնված են այս պահին։\nՉափից շատ օգտվողներ փորձում են դիտել այս էջը։\nԽնդրում ենք սպասել որոշ ժամանակ էջը դիտելու կրկին հայցում անելուց առաջ։\n\n$1",
+       "generic-pool-error": "Ներեցեք՝ սերվերները գերբեռնված են այս պահին։\nՉափից շատ օգտվողներ փորձում են դիտել այս էջը։\nԽնդրում ենք սպասել որոշ ժամանակ էջը դիտելու կրկին հայցում անելուց առաջ։",
        "pool-errorunknown": "Անհայտ սխալ",
        "aboutsite": "{{grammar:genitive|{{SITENAME}}}} մասին",
        "aboutpage": "Project:Էությունը",
        "hidetoc": "թաքցնել",
        "collapsible-collapse": "Ծալել",
        "collapsible-expand": "Բացել",
+       "confirmable-confirm": "{{GENDER:$1|Դուք}} վստա՞հ եք:",
+       "confirmable-yes": "Այո",
+       "confirmable-no": "Ոչ",
        "thisisdeleted": "Դիտե՞լ կամ վերականգնե՞լ $1։",
        "viewdeleted": "Դիտե՞լ $1։",
        "restorelink": "{{PLURAL:$1|մեկ ջնջված խմբագրում|$1 ջնջված խմբագրում}}",
        "viewsource-title": "Դիտել $1 էջի աղբյուրը",
        "actionthrottled": "Գործողությունը արգելափակվեց",
        "actionthrottledtext": "Որպես հակա-սպամային միջոց, այս գործողության չափից շատ կատարումը կարճ ժամանակահատվածի ընթացքում սահմանափակված է։ Խնդրում ենք փորձել կրկին մի քանի րոպե անց։",
-       "protectedpagetext": "Այս էջը կողպված խմբագրման համար։",
+       "protectedpagetext": "Ô±ÕµÕ½ Õ§Õ»Õ¨ Õ¯Õ¸Õ²ÕºÕ¾Õ¡Õ® Õ§ Õ­Õ´Õ¢Õ¡Õ£Ö\80Õ´Õ¡Õ¶ Õ°Õ¡Õ´Õ¡Ö\80Ö\89",
        "viewsourcetext": "Դուք կարող եք դիտել և պատճենել այս էջի ելատեքստը.",
        "viewyourtext": "Դուք կարող եք դիտել «ձեր ներդրումների» աղբյուրը և պատճենել այս էջ",
        "protectedinterface": "Այս էջը պարունակում է ծրագրային ապահովման միջերեսի տեքստ, և պաշտպանված է չարաշահումների կանխարգելման նպատակով։\nԲոլոր վիքիների թարգմանությունները փոփոխելու կամ ավելացնելու համար, խնդրում ենք այցելել ՄեդիաՎիքիի տեղայնացման նախագիծը՝ [//translatewiki.net/ translatewiki.net]։",
        "gotaccountlink": "Մուտք գործեք համակարգ",
        "userlogin-resetlink": "Մոռացե՞լ եք Ձեր հաշվի տվյալները։",
        "userlogin-resetpassword-link": "Մոռացե՞լ եք գաղտնաբառը",
-       "userlogin-createanother": "Ստեղծել այլ հաշիվ",
        "createacct-emailrequired": "Էլ–փոստի հասցե",
        "createacct-emailoptional": "Էլ–փոստի հասցե (ոչ պարտադիր)",
        "createacct-email-ph": "Մուտքագրեք ձեր էլ–փոստի հասցեն",
        "badretype": "Ձեր մուտքագրած գաղտնաբառերը չեն համընկնում։",
        "userexists": "Այս մասնակցի անունը արդեն զբաղված է։ Խնդրում ենք ընտրել մեկ այլ անուն։",
        "loginerror": "Մուտքի սխալ",
+       "createacct-error": "Հաշվի ստեղծման սխալ",
        "createaccounterror": "Չհաջողվեց ստեղծել մասնակցային հաշիվ. $1",
        "nocookiesnew": "Մասնակցային հաշիվը ստեղծված է, սակայն մուտքը համակարգ չհաջողվեց։ {{SITENAME}} կայքը օգտագործում է «քուքիներ» մասնակիցների վավերացման համար։ Ձեր մոտ «քուքիները» արգելված են։ Խնդրում ենք թույլատրել սրանք, ապա մտնել համակարգ ձեր նոր մասնակցի անունով և գաղտնաբառով։",
        "nocookieslogin": "{{SITENAME}} կայքը օգտագործում է «քուքիներ» մասնակիցների վավերացման համար։ Ձեր մոտ «քուքիները» արգելված են։ Խնդրում ենք թույլատրել սրանք և փորձել կրկին։",
        "passwordtooshort": "Գաղտնաբառը պետք է պարունակի առնվազն {{PLURAL:$1|1 սիմվոլ|$1 սիմվոլ}}։",
        "password-name-match": "Գաղտնաբառը պետք է տարբեր լինել ձեր մասնակցի անունից։",
        "password-login-forbidden": "Այս ծածկանվան և գաղտնաբառի օգտագործումն արգելված է",
-       "mailmypassword": "Õ\88Ö\82Õ²Õ¡Ö\80Õ¯Õ¥Õ¬ Õ¶Õ¸Ö\80 Õ£Õ¡Õ²Õ¿Õ¶Õ¡Õ¢Õ¡Õ¼ Õ§Õ¬â\80\93Ö\83Õ¸Õ½Õ¿Õ¸Õ¾",
+       "mailmypassword": "Õ\8eÕ¥Ö\80Õ¡Õ¯Õ¡Õ¶Õ£Õ¶Õ¥Õ¬ Õ£Õ¡Õ²Õ¿Õ¶Õ¡Õ¢Õ¡Õ¼Õ¨",
        "passwordremindertitle": "Նոր ժամանակավոր գաղտնաբառ {{grammar:genitive|{{SITENAME}}}} համար",
        "passwordremindertext": "Ինչ-որ մեկը (հավանաբար դուք՝ $1 IP-հասցեից) խնդրել է նոր գաղտնաբառ {{grammar:genitive|{{SITENAME}}}} ($4)։ «$2» մասնակցի ժամանակավոր գաղտնաբառն է՝ <code>$3</code>։ Եթե սա իսկապես ձեր մտադրություններ, ապա ձեզ հարկավոր է մտնել համակարգ և փոխել գաղտնաբառը։ Ձեր ժամանակավոր գաղտնաբառը գործելու է {{PLURAL:$5|օր|$5 օր}}։\n\nԵթե դուք չեք արել այսպիսի հայցում կամ արդեն հիշել եք ձեր գաղտնաբառը և մտադրություն չունեք այն փոխել, ապա կարող եք անտեսել այս ուղերձը և շարունակել օգտվել ձեր հին գաղտնաբառից։",
        "noemail": "«$1» մասնակցի համար էլ-փոստի հասցե չի նշվել։",
        "invalidemailaddress": "Նշված էլ-փոստի հասցեն անընդունելի է, քանի որ այն ունի անթույլատրելի ֆորմատ։ Խնդրում ենք նշել ճշմարիտ հասցե կամ այս դաշտը թողնել դատարկ։",
        "emaildisabled": "Այս կայքը չի կարող ուղարկել էլ․ նամակներ։",
        "accountcreated": "Հաշիվը ստեղծված է",
-       "accountcreatedtext": "$1 մասնակցի հաշիվը ստեղծված է։",
+       "accountcreatedtext": "[[{{ns:User}}:$1|$1]] ([[{{ns:User talk}}:$1|քննարկում]]) մասնակցի հաշիվը ստեղծված է։",
        "createaccount-title": "{{SITENAME}}. մասնակցային հաշվի ստեղծում",
        "createaccount-text": "Ինչ-որ մեկը ստեղծել է «$2» անվանմամբ մասնակցային հաշիվ «$3» գաղտնաբառով {{SITENAME}} ($4) նախագծում՝ նշելով ձեր էլ-հասցեն։ Ձեզ անհրաժեշտ է մտնել համակարգ և փոխել գաղտնաբառը։\n\nԿարող եք անտեսել այս հաղորդագրությունը, եթե հաշիվը ստեղծվել է սխալմամբ։",
        "login-throttled": "Դուք կատարել եք չափից շատ մուտքի փորձ։\nԽնդրում ենք սպասել որոշ ժամանակ կրկին փորձելուց առաջ։",
        "loginlanguagelabel": "Լեզու՝ $1",
        "pt-login": "Մտնել",
+       "pt-login-button": "Մտնել",
        "pt-createaccount": "Ստեղծել մասնակցի հաշիվ",
        "pt-userlogout": "Դուրս գալ",
        "php-mail-error-unknown": "Անհայտ սխալ PHP-ի mail() ֆունկցիայում",
        "newpassword": "Նոր գաղտնաբառը.",
        "retypenew": "Հաստատեք նոր գաղտնաբառը.",
        "resetpass_submit": "Հաստատել գաղտնաբառը և մտնել համակարգ",
-       "changepassword-success": "Ձեր գաղտնաբառը փոխված է։ Մուտք համակարգ…",
+       "changepassword-success": "Ձեր գաղտնաբառը հաջողությամբ փոխված է։",
        "resetpass_forbidden": "Գաղտնաբառը չի կարող փոխվել",
        "resetpass-no-info": "Այս էջին ուղիղ դիմելու համար անհրաժեշտ է մտնել համակարգ։",
        "resetpass-submit-loggedin": "Փոխել գաղտնաբառը",
        "passwordreset-emailsent-capture": "Ուղարկվեց հիշեցնող էլ․ նամակ։ Այն ներկայացված է ստորև։",
        "passwordreset-emailerror-capture": "Ուղարկվեց հիշեցնող էլ․ նամակ։ Այն ներկայացված է ստորև։ Սակայն մասնակցին ուղարկելը չհաջողվեց․",
        "changeemail": "Փոխել էլ. հասցեն",
-       "changeemail-header": "Փոխել հաշվի էլ․ հասցեն",
        "changeemail-oldemail": "Ներկա էլ․ հասցե․",
        "changeemail-newemail": "Նոր էլ․ հասցե․",
        "changeemail-none": "(ոչ մի)",
        "changeemail-password": "Քո {{SITENAME}} գաղտնաբառը՝",
        "changeemail-submit": "Փոխել էլ․ հասցեն",
-       "changeemail-cancel": "Չեղարկել",
+       "resettokens-tokens": "Կտրոններ՝",
        "bold_sample": "Թավատառ տեքստ",
        "bold_tip": "Թավատառ տեքստ",
        "italic_sample": "Շեղատառ տեքստ",
        "notextmatches": "Չկան համընկած տեքստերով էջեր",
        "prevn": "նախորդ {{PLURAL:$1|$1}}",
        "nextn": "հաջորդ {{PLURAL:$1|$1}}",
+       "prevn-title": "Նախկին $1 {{PLURAL:$1|արդյունքը|արդյունքները}}",
+       "nextn-title": "Հաջորդ $1 {{PLURAL:$1|արդյունքը|արդյունքները}}",
        "viewprevnext": "Դիտել ($1 {{int:pipe-separator}} $2) ($3)",
        "searchmenu-exists": "'''Այս վիքիում, գոյություն ունի \"[[:$1]]\" անվանումով էջը։'''",
        "searchmenu-new": "'''Ստեղծե՛լ \"[[:$1]]\" էջը այս վիքիում'''",
        "searchrelated": "հարակից",
        "searchall": "բոլոր",
        "showingresults": "Ստորև բերված է մինչև {{PLURAL:$1|'''1''' արդյունք|'''$1''' արդյունք}}՝ սկսած №&nbsp;<strong>$2</strong>-ից։",
-       "showingresultsheader": "{{PLURAL:$5|'''$1''' արդյունք '''$3'''-ից|'''$1 - $2''' արդյունքներ '''$3'''-ից}}  '''$4'''-ի համար",
        "search-nonefound": "Որոնմանը համապատասխանող արդյունքներ չեն գտնվել։",
        "powersearch-legend": "Ընդլայնված որոնում",
        "powersearch-ns": "Որոնել անվանատարածքում.",
        "prefs-skin": "Տեսք",
        "skin-preview": "նախադիտել",
        "datedefault": "Առանց նախընտրության",
+       "prefs-user-pages": "Մասնակցային էջերը",
        "prefs-personal": "Անձնական",
        "prefs-rc": "Վերջին փոփոխություններ",
        "prefs-watchlist": "Հսկացանկ",
        "prefs-watchlist-days": "Հսկացանկում ցուցադրվող օրերի թիվը՝",
-       "prefs-watchlist-days-max": "Maximum $1 {{PLURAL:$1|day|days}}",
+       "prefs-watchlist-days-max": "Առավելագույնը $1 {{PLURAL:$1|օր}}",
        "prefs-watchlist-edits": "Ընդարձակված հսկացանկում ցուցադրվող օրերի թիվը՝",
-       "prefs-watchlist-edits-max": "(1000-ից ոչ ավել)",
+       "prefs-watchlist-edits-max": "1000-ից ոչ ավել",
        "prefs-watchlist-token": "Հսկացանկի կտրոն.",
        "prefs-misc": "Այլ",
        "prefs-resetpass": "Փոխել գաղտնաբառը",
        "prefs-email": "Էլ-հասցեի ընտրանքներ",
        "prefs-rendering": "Արտաքին տեսք",
        "saveprefs": "Հիշել",
-       "restoreprefs": "Զրոյացնել, բերելով իլռելայն նախընտրանքներին",
+       "restoreprefs": "Զրոյացնել, բերելով իլռելայն նախընտրանքներին (բոլոր բաժիններում)",
        "prefs-editing": "Խմբագրում",
        "rows": "Տողեր`",
        "columns": "Սյունակներ",
        "searchresultshead": "Որոնում",
        "stub-threshold": "<a href=\"#\" class=\"stub\">Պատառ հոդվածների հղումների</a> ձևավորման որոշման սահմանը.",
+       "stub-threshold-disabled": "Անջատված է",
        "recentchangesdays": "Վերջին փոփոխություններում ցուցադրվող օրերի թիվը՝",
        "recentchangesdays-max": "($1 {{PLURAL:$1|օրից|օրից}} ոչ ավել)",
        "recentchangescount": "Խմբագրումների թիվը ըստ լռության.",
        "prefs-help-recentchangescount": "Ներառում է վերջին փոփոխությունները, էջերի պատմությունը և տեղեկամատյանները։",
+       "prefs-help-watchlist-token2": "Սա գաղտնի բանալի է հսկականկի օգնույամբ նորություն ստանալու համար:\nՈվ որ գիտի այն կարող է կարդալ ձեր հսկացանկը, ուստի մի տարածեք այն:\nԵթե ձեզ պետք է զրոյացնել հսկացանկի կտրոնը, [[Special:ResetTokens| սեղմեք այստեղ]]:",
        "savedprefs": "Ձեր նախընտրությունները հիշված են։",
        "timezonelegend": "Ժամային գոտի.",
        "localtime": "Տեղական ժամանակ.",
-       "timezoneuseserverdefault": "Օգտագործել սերվերի ժամանակը",
+       "timezoneuseserverdefault": "Օգտագործել սերվերի ժամանակը ($1)",
        "timezoneuseoffset": "Այլ (նշեք տարբերությունը)",
        "servertime": "Սերվերի ժամանակ.",
        "guesstimezone": "Լրացնել բրաուզերից",
index 2bf4f09..3edf919 100644 (file)
        "otherlanguages": "In altere linguas",
        "redirectedfrom": "(Redirigite ab $1)",
        "redirectpagesub": "Pagina de redirection",
+       "redirectto": "Rediriger verso:",
        "lastmodifiedat": "Ultime modification de iste pagina: le $1 a $2.",
        "viewcount": "Iste pagina ha essite visitate {{PLURAL:$1|un vice|$1 vices}}.",
        "protectedpage": "Pagina protegite",
        "createaccount-text": "Un persona ha create un conto in tu adresse de e-mail a {{SITENAME}} ($4) denominate \"$2\", con le contrasigno \"$3\".\nTu deberea aperir un session e cambiar tu contrasigno ora.\n\nTu pote ignorar iste message si iste conto ha essite create in error.",
        "login-throttled": "Tu ha facite troppo de tentativas de aperir session.\nPer favor attende $1 ante de probar lo novemente.",
        "login-abort-generic": "Apertura de session non succedite - Abortate",
+       "login-migrated-generic": "Tu conto ha essite migrate, e tu nomine de usator non plus existe in iste wiki.",
        "loginlanguagelabel": "Lingua: $1",
        "suspicious-userlogout": "Le requesta de clauder le session ha essite refusate proque illo pare haber essite inviate per un navigator o proxy de cache defectuose.",
        "createacct-another-realname-tip": "Le nomine real es optional.\nSi tu opta pro dar lo, isto essera usate pro dar al usator attribution pro su contributiones.",
        "searchall": "totes",
        "showingresults": "Infra se monstra non plus de {{PLURAL:$1|'''1''' resultato|'''$1''' resultatos}} a partir del numero '''$2'''.",
        "showingresultsinrange": "In basso es monstrate usque a {{PLURAL:$1|<strong>1</strong> resultato|<strong>$1</strong> resultatos}} inter #<strong>$2</strong> e #<strong>$3</strong>.",
-       "showingresultsheader": "{{PLURAL:$5|Resultato '''$1'''|Resultatos '''$1 - $2'''}} de '''$3''' pro '''$4'''",
        "search-nonefound": "Le recerca non ha producite resultatos.",
        "powersearch-legend": "Recerca avantiate",
        "powersearch-ns": "Cercar in spatios de nomines:",
        "watchlist-details": "{{PLURAL:$1|$1 pagina|$1 paginas}} in tu observatorio. Le paginas de discussion non es contate separatemente.",
        "wlheader-enotif": "Le notification via e-mail es active.",
        "wlheader-showupdated": "Le paginas que ha essite modificate post tu ultime visita se monstra in litteras '''grasse'''.",
-       "wlnote": "Ecce le ultime {{PLURAL:$1|modification|'''$1''' modificationes}} durante le ultime {{PLURAL:$2|hora|'''$2''' horas}}, a partir del $3 a $4.",
+       "wlnote": "Ecce le ultime {{PLURAL:$1|modification|<strong>$1</strong> modificationes}} durante le ultime {{PLURAL:$2|hora|<strong>$2</strong> horas}}, a partir del $3 a $4.",
        "wlshowlast": "Revelar ultime $1 horas $2 dies $3",
        "watchlist-options": "Optiones del observatorio",
        "watching": "Observation in curso...",
        "exbeforeblank": "contento ante radimento esseva: '$1'",
        "delete-confirm": "Deler \"$1\"",
        "delete-legend": "Deler",
-       "historywarning": "'''Attention:''' Le pagina que tu vole deler ha un historia de circa $1 {{PLURAL:$1|version|versiones}}:",
+       "historywarning": "<strong>Attention:</strong> Le pagina que tu vole deler ha un historia de circa $1 {{PLURAL:$1|version|versiones}}:",
        "confirmdeletetext": "Tu va deler un pagina con tote su historia.\nPer favor confirma que tu ha le intention de facer isto, que tu comprende le consequentias, e que tu face isto in accordo con [[{{MediaWiki:Policy-url}}|le politicas]].",
        "actioncomplete": "Action complete",
        "actionfailed": "Action fallite",
index 431a3aa..95db32d 100644 (file)
        "userlogin-resetlink": "Lupa detail info masuk Anda?",
        "userlogin-resetpassword-link": "Lupa kata sandi?",
        "userlogin-helplink2": "Bantuan masuk log",
-       "userlogin-loggedin": "Andan telah masuk log sebagai $1.\nGunakan formulir di bawah untuk masuk log sebagai pengguna lain.",
-       "userlogin-createanother": "Buat akun lain",
        "createacct-emailrequired": "Alamat surel",
        "createacct-emailoptional": "Alamat surel (opsional)",
        "createacct-email-ph": "Masukkan alamat surel Anda",
        "passwordreset-emailsent-capture": "Surel setel ulang kata sandi telah dikirim, yang ditampilkan di bawah.",
        "passwordreset-emailerror-capture": "Surel setel ulang kata sandi telah dibuat, yang ditampilkan di bawah, namun pengiriman pada {{GENDER:$2|pengguna}} gagal: $1",
        "changeemail": "Ubah alamat surel",
-       "changeemail-header": "Ubah alamat surel akun",
        "changeemail-text": "Selesaikan formulir ini untuk mengubah alamat surel Anda. Anda perlu memasukkan sandi untuk mengkonfirmasi perubahan ini.",
        "changeemail-no-info": "Anda harus masuk log untuk mengakses halaman ini secara langsung.",
        "changeemail-oldemail": "Alamat surel saat ini:",
        "changeemail-none": "(tidak ada)",
        "changeemail-password": "Sandi {{SITENAME}} Anda:",
        "changeemail-submit": "Ubah surel",
-       "changeemail-cancel": "Batalkan",
        "changeemail-throttled": "Anda sudah terlalu banyak mencoba masuk log.\nSilakan menunggu $1 sebelum mencoba lagi.",
        "resettokens": "Reset token",
        "resettokens-text": "Anda dapat me-reset Token yang memungkinkan akses ke data pribadi tertentu yang terkait dengan akun Anda di sini.\n\nAnda harus melakukannya jika Anda secara tidak sengaja berbagi dengan seseorang atau jika akun Anda telah disusupi.",
        "searchall": "semua",
        "showingresults": "Di bawah ini ditampilkan hingga {{PLURAL:$1|'''1''' hasil|'''$1''' hasil}}, dimulai dari #'''$2'''.",
        "showingresultsinrange": "Menampilkan sampai dengan {{PLURAL:$1|<strong>1</strong> hasil|<strong>$1</strong> hasil}} dalam jangkauan #<strong>$2</strong> sampai #<strong>$3</strong>.",
-       "showingresultsheader": "{{PLURAL:$5|Hasil '''$1''' dari '''$3'''|Hasil '''$1 - $2''' dari '''$3'''}} untuk '''$4'''",
        "search-nonefound": "Tidak ada hasil yang sesuai dengan kriteria.",
        "powersearch-legend": "Pencarian lanjut",
        "powersearch-ns": "Mencari di ruang nama:",
        "powersearch-togglelabel": "Pilih:",
        "powersearch-toggleall": "Semua",
        "powersearch-togglenone": "Tidak ada",
-       "powersearch-remember": "Ingar pilihan untuk pencarian selanjutnya",
+       "powersearch-remember": "Ingat pilihan untuk pencarian selanjutnya",
        "search-external": "Pencarian eksternal",
        "searchdisabled": "Pencarian {{SITENAME}} sementara dimatikan.\nAnda dapat mencari melalui Google untuk sementara waktu.\nPerlu diingat bahwa indeks Google untuk konten {{SITENAME}} mungkin belum mencakup perubahan-perubahan terakhir.",
        "search-error": "Kesalahan terjadi saat mencari: $1",
        "logentry-rights-rights-legacy": "$1 {{GENDER:$2|mengubah}} keanggotaan grup $3",
        "logentry-rights-autopromote": "$1 secara otomatis {{GENDER:$2|dipromosikan}} dari $4 menjadi $5",
        "rightsnone": "(tidak ada)",
+       "revdelete-summary": "ringkasan",
        "feedback-bugornote": "Jika Anda sudah siap untuk mendeskripsikan masalah teknis secara rinci silakan [$1 melaporkan bug].\nJika tidak, Anda dapat menggunakan formulir mudah di bawah ini. Komentar Anda akan ditambahkan ke halaman \"[$3 $2]\", bersama dengan nama pengguna Anda dan apa browser yang Anda gunakan.",
        "feedback-subject": "Perihal:",
        "feedback-message": "Pesan:",
index 448c2a9..f8c8f34 100644 (file)
        "invalidtitle-knownnamespace": "Ógildur titill í nafnrými \"$2\" og með textann \"$3\"",
        "invalidtitle-unknownnamespace": "Ógildur titill með óþekkt nafnrými númer $1 og texta \"$2\"",
        "exception-nologin": "Óinnskráð(ur)",
-       "exception-nologin-text": "Vinsamlegast [[Special:Userlogin|skráðu þig inn]] til þess að hafa aðgang að þessari síðu eða aðgerð.",
+       "exception-nologin-text": "Vinsamlegast skráðu þig inn til þess að hafa aðgang að þessari síðu eða aðgerð.",
        "virus-badscanner": "Slæm stilling: óþekktur veiruskannari: ''$1''",
        "virus-scanfailed": "skönnun mistókst (kóði $1)",
        "virus-unknownscanner": "óþekkt mótveira:",
        "gotaccountlink": "Skráðu þig inn",
        "userlogin-resetlink": "Gleymdir þú notendaupplýsingunum þínum?",
        "userlogin-resetpassword-link": "Gleymdiru lykilorðinu þínu?",
-       "userlogin-loggedin": "Þú ert búin(n) að skrá þig inn sem {{GENDER:$1|$1}}.\nNotaðu eyðablaðið fyrir neðan til að skrá þig inn sem annar notandi.",
-       "userlogin-createanother": "Stofna annan aðgang",
        "createacct-emailrequired": "Netfang",
        "createacct-emailoptional": "Netfang (valfrjálst)",
        "createacct-email-ph": "Skrifaðu niður netfangið þitt",
        "passwordreset-emailsent-capture": "Tölvupóstur til að endursetja lykilorðið hefur verið sendur í tölvupósti, sem er sýndur hér fyrir neðan.",
        "passwordreset-emailerror-capture": "Tölvupóstur til að endursetja lykilorðið var búinn til, sem er sýndur hér fyrir neðan, en ekki tókst að senda hana til {{GENDER:$2|notandans}}: $1",
        "changeemail": "Breyting netfangs",
-       "changeemail-header": "Breyta skráðu netfangi",
        "changeemail-text": "Fylltu út þetta eyðublað til að breyta netfanginu þínu. Þú þarft að slá inn lykilorðið þitt til að staðfesta breytinguna.",
        "changeemail-no-info": "Þú verður að vera skráð(ur) inn til að hafa aðgang að þessari síðu.",
        "changeemail-oldemail": "Núverandi netfang:",
        "changeemail-none": "(ekkert)",
        "changeemail-password": "{{SITENAME}} lykilorðið þitt:",
        "changeemail-submit": "Breyta netfangi",
-       "changeemail-cancel": "Hætta við",
        "resettokens": "Endurstilla lykla",
        "resettokens-text": "Hér getur þú endurstillt lykla sem veita þér aðgang að ákveðnum persónuupplýsingum um aðganginn þinn.\n\nÞú átt að gera það ef þú ert búin(n) að deila þeim með einhverjum öðrum óviljandi eða ef búið er að brjóta inn í aðganginn þinn.",
        "resettokens-no-tokens": "Það eru engir lyklar að endurstilla.",
        "preview": "Forskoða",
        "showpreview": "Forskoða",
        "showdiff": "Sýna breytingar",
-       "anoneditwarning": "'''Viðvörun:''' Þú ert ekki innskráð(ur). Vistfang þitt skráist í breytingaskrá síðunnar.",
+       "anoneditwarning": "<strong>Viðvörun:</strong> Þú ert ekki innskráð(ur). Vistfang þitt verður sýnt opinberlega ef þú gerir einhverjar breytingar. Ef þú <strong>[$1 skráir þig inn]</strong> eða <strong>[$2 stofnar aðgang]</strong> munu breytingarnar þínar vera tengdar við notendanafn þitt, ásamt öðrum kostum.",
        "anonpreviewwarning": "Þú ert ekki innskráð(ur). Vistfang þitt skráist í breytingaskrá síðunnar.",
        "missingsummary": "'''Áminning:''' Þú hefur ekki skrifað breytingarágrip.\nEf þú smellir á Vista aftur, verður breyting þín vistuð án þess.",
        "missingcommenttext": "Gerðu svo vel og skrifaðu athugasemd fyrir neðan.",
        "searchrelated": "tengt",
        "searchall": "öllum",
        "showingresults": "Sýni <strong>$1</strong> {{PLURAL:$1|niðurstöðu|niðurstöður}} frá og með #<strong>$2</strong>.",
-       "showingresultsheader": "{{PLURAL:$5|Niðurstaða '''$1''' af '''$3'''|Niðurstöður'''$1 - $2''' af '''$3'''}} fyrir '''$4'''",
        "search-nonefound": "Engar niðurstöður pössuðu við fyrirspurnina.",
        "powersearch-legend": "Ítarlegri leit",
        "powersearch-ns": "Leita í nafnrýmum:",
        "right-deletedtext": "Sjá eyddan texta og breytingar á milli eyddra útgáfna",
        "right-browsearchive": "Leita í eyddum síðum",
        "right-undelete": "Endurvekja eydda síðu",
-       "right-suppressrevision": "Skoða og endurvekja breytingar faldar fyrir stjórnendum",
+       "right-suppressrevision": "Skoða, fela og endurvekja ákveðnar breytingar síðna frá öllum notendum",
        "right-suppressionlog": "Skoða einrænar aðgerðaskrár",
        "right-block": "Banna öðrum notendum að gera breytingar",
        "right-blockemail": "Banna notanda að senda tölvupóst",
        "recentchanges-label-bot": "Þessi breyting var gerð af vélmenni",
        "recentchanges-label-unpatrolled": "Þessi breyting hefur ekki verið yfirfarin",
        "recentchanges-legend-newpage": "{{int:recentchanges-label-newpage}} (sjá einng [[Special:NewPages|lista yfir nýjar síður]])",
-       "rcnotefrom": "Að neðan eru breytingar síðan <strong>$2<strong> (allt að <strong>$1<strong> sýndar).",
+       "rcnotefrom": "Að neðan {{PLURAL:$5|er breyting síðan|eru breytingar síðan}} <strong>$3, $4</strong> (allt að <strong>$1</strong> sýndar).",
        "rclistfrom": "Sýna breytingar frá og með $3 $2",
        "rcshowhideminor": "$1 minniháttar breytingar",
        "rcshowhideminor-show": "Sýna",
        "license-header": "Leyfisupplýsingar:",
        "nolicense": "Ekkert valið",
        "license-nopreview": "(Forskoðun ekki fáanleg)",
-       "upload_source_url": "(gild, aðgengileg vefslóð)",
-       "upload_source_file": "(skrá á tölvunni þinni)",
+       "upload_source_url": "(þín valda skrá frá gildri, aðgengilegri vefslóð)",
+       "upload_source_file": "(þín valda skrá frá tölvunni þinni)",
        "listfiles-summary": "Þessi kerfissíða sýnir allar upphlaðnar skrár.",
        "listfiles_search_for": "Leita að miðilsnafni:",
        "imgfile": "skrá",
        "mywatchlist": "Vaktlisti",
        "watchlistfor2": "Eftir $1 $2",
        "nowatchlist": "Vaktlistinn er tómur.",
-       "watchlistanontext": "Vinsamlegast $1ðu þig til að skoða eða breyta vaktlistanum þínum.",
+       "watchlistanontext": "Vinsamlegast skráðu þig til að skoða eða breyta hlutum á vaktlistanum þínum.",
        "watchnologin": "Óinnskráð(ur)",
        "addwatch": "Bæta á vaktlistann",
        "addedwatchtext": "Síðunni „[[:$1]]“ hefur verið bætt á [[Special:Watchlist|vaktlistann]] þinn.\nFrekari breytingar á henni eða spjallsíðu hennar munu verða sýndar þar.",
        "exbeforeblank": "innihald fyrir tæmingu var: '$1'",
        "delete-confirm": "Eyða „$1“",
        "delete-legend": "Eyða",
-       "historywarning": "'''Viðvörun:''' Síðan sem þú ert um það bil að eyða hefur breytingarskrá með $1 {{PLURAL:$1|breytingu|breytingum}}:",
+       "historywarning": "<strong>Viðvörun:</strong> Síðan sem þú ert um það bil að eyða hefur breytingarskrá með $1 {{PLURAL:$1|breytingu|breytingum}}:",
        "confirmdeletetext": "Þú ert um það bil að eyða síðu ásamt breytingaskrá hennar.\nVinsamlegast staðfestu það að þú ætlir að gera svo, það að þú skiljir afleiðingarnar, og að þú sért að gera þetta í samræmi við [[{{MediaWiki:Policy-url}}]].",
        "actioncomplete": "Aðgerð lokið",
        "actionfailed": "Aðgerð mistókst",
        "autoblockid": "Sjálfvirkt bann $1",
        "block": "Banna notanda",
        "unblock": "Afbanna notanda",
-       "blockip": "Banna notanda",
+       "blockip": "Banna {{GENDER:$1|notanda}}",
        "blockip-legend": "Banna notanda",
        "blockiptext": "Notaðu eyðublaðið hér að neðan til þess að banna ákveðið vistfang eða notandanafn.\nÞetta ætti einungis að gera til þess að koma í veg fyrir skemmdarverk, og í samræmi við [[{{MediaWiki:Policy-url}}|samþykktir]].\nGefðu nákvæma skýringu að neðan (til dæmis, með því að vísa í þær síður sem skemmdar voru).",
        "ipaddressorusername": "Vistfang eða notandanafn:",
        "ipb-unblock-addr": "Afbanna $1",
        "ipb-unblock": "Afbanna notanda eða vistfang",
        "ipb-blocklist": "Sjá núverandi bönn",
-       "ipb-blocklist-contribs": "Framlög fyrir $1",
+       "ipb-blocklist-contribs": "Framlög fyrir {{GENDER:$1|$1}}",
        "unblockip": "Afbanna notanda",
        "unblockiptext": "Endurvekja skrifréttindi bannaðra notenda eða vistfanga.",
        "ipusubmit": "Afbanna",
        "import-error-create": "Síðan \"$1\" var ekki flutt inn því þú hefur ekki réttindi til að stofna hana.",
        "import-error-interwiki": "Síðan \"$1\" var ekki flutt inn því nafn hennar er frátekið fyrir ytri tengla (tungumálatengla).",
        "import-error-special": "Síðan \"$1\" var ekki flutt inn því hún tilheyrir ákveðnu nafnrými sem leyfir ekki síður.",
-       "import-error-invalid": "Síðan \"$1\" var ekki flutt inn því nafn hennar er ógilt.",
+       "import-error-invalid": "Síðan \"$1\" var ekki flutt inn því nafnið sem hún yrði flutt á er ógilt á þessum wiki.",
        "import-error-unserialize": "Ekki unnt að afraða útgáfu $2 af síðunni „$1“. Útgáfan var sögð nota innihaldslíkan $3 raðað sem $4.",
        "import-options-wrong": "{{PLURAL:$2|Rangur möguleiki|Rangir möguleikar}}: <nowiki>$1</nowiki>",
        "import-rootpage-invalid": "Uppgefin móðursíða hefur ógildan titil.",
        "importlogpage": "Innflutningsskrá",
        "importlogpagetext": "Hér er listi yfir innflutninga möppdýra á síðum ásamt breytingarskránni frá öðrum wiki.",
        "import-logentry-upload": "flutti inn [[$1]] frá skrá",
-       "import-logentry-upload-detail": "$1 {{PLURAL:$1|breyting|breytingar}}",
+       "import-logentry-upload-detail": "$1 {{PLURAL:$1|breyting flutt|breytingar fluttar}} inn",
        "import-logentry-interwiki": "flutti inn $1",
-       "import-logentry-interwiki-detail": "$1 {{PLURAL:$1|breyting|breytingar}} frá $2",
+       "import-logentry-interwiki-detail": "$1 {{PLURAL:$1|breyting flutt|breytingar fluttar}} inn frá $2",
        "javascripttest": "JavaScript prófun",
        "javascripttest-title": "Keyri $1 prófun",
        "javascripttest-pagetext-noframework": "Þessi síða er frátekin fyrir JavaScript prófanir.",
index 3045212..44b13d3 100644 (file)
        "passwordreset-emailsent-capture": "È stata inviata una email di reimpostazione della password, il contenuto è riportato di seguito.",
        "passwordreset-emailerror-capture": "È stata generata una email di reimpostazione della password, riportata di seguito. L'invio {{GENDER:$2|all'utente}} non è riuscito: $1",
        "changeemail": "Modifica indirizzo email",
-       "changeemail-header": "Modifica l'indirizzo email dell'account",
        "changeemail-text": "Completa questo modulo per cambiare il tuo indirizzo email. Sarà necessario inserire la password per confermare la modifica.",
        "changeemail-no-info": "Devi aver effettuato l'accesso per accedere a questa pagina direttamente.",
        "changeemail-oldemail": "Indirizzo email attuale:",
        "changeemail-none": "(nessuno)",
        "changeemail-password": "La password su {{SITENAME}}:",
        "changeemail-submit": "Modifica email",
-       "changeemail-cancel": "Annulla",
        "changeemail-throttled": "Sono stati effettuati troppi tentativi di accesso.\nAttendi $1 e riprova in seguito.",
        "resettokens": "Reimposta token",
        "resettokens-text": "Qui puoi reimpostare le chiavi che permettono l'accesso a determinati dati privati associati alla tua utenza.\n\nDovresti farlo se le hai accidentalmente condivise con qualcuno o se la tua utenza è stato compromessa.",
        "revdelete-show-file-confirm": "Si desidera visualizzare la versione cancellata del file \"<nowiki>$1</nowiki>\" del $2 alle $3?",
        "revdelete-show-file-submit": "Sì",
        "revdelete-selected-text": "{{PLURAL:$1|Versione selezionata|Versioni selezionate}} di [[:$2]]:",
-       "revdelete-selected-file": "{{PLURAL:$1|Versione selezionata|Versioni selezionate}} del file di [[:$2]]:",
-       "logdelete-selected": "{{PLURAL:$1|Evento del registro selezionato|Eventi del registro selezionati}}:",
+       "revdelete-selected-file": "{{PLURAL:$1|Versione selezionata|Versioni selezionate}} del file [[:$2]]:",
+       "logdelete-selected": "{{PLURAL:$1|Evento del registro selezionato|Eventi del registro selezionato}}:",
        "revdelete-text-text": "Le versioni cancellate appariranno ancora nella cronologia della pagina, ma parte del loro contenuto sarà inaccessibile al pubblico.",
        "revdelete-text-file": "Le versioni di file cancellati appariranno ancora nella cronologia del file, ma parti del loro contenuto sarà inaccessibile al pubblico.",
        "logdelete-text": "Gli eventi cancellati appariranno ancora nei registri, ma parti del loro contenuto sarà inaccessibile al pubblico.",
        "searchall": "tutti",
        "showingresults": "Di seguito {{PLURAL:$1|viene presentato al massimo '''1''' risultato|vengono presentati al massimo '''$1''' risultati}} a partire dal numero '''$2'''.",
        "showingresultsinrange": "{{PLURAL:$1|Viene mostrato|Vengono mostrati}} sotto {{PLURAL:$1|<strong>1</strong> risultato|<strong>$1</strong> risultati}} dal <strong>$2</strong> al <strong>$3</strong>.",
-       "showingresultsheader": "{{PLURAL:$5|Risultato '''$1''' di '''$3'''|Risultati '''$1 - $2''' di '''$3'''}} per '''$4'''",
+       "search-showingresults": "{{PLURAL:$4|Risultato <strong>$1</strong> di <strong>$3</strong>|Risultati <strong>$1 - $2</strong> di <strong>$3</strong>}}",
        "search-nonefound": "La ricerca non ha prodotto risultati.",
        "powersearch-legend": "Ricerca avanzata",
        "powersearch-ns": "Cerca nei namespace:",
        "prefs-tokenwatchlist": "Token",
        "prefs-diffs": "Differenze",
        "prefs-help-prefershttps": "Questa preferenza avrà effetto dal prossimo accesso.",
+       "prefswarning-warning": "Hai fatto modifiche alle tue preferenze che non sono state ancora salvate.\nSe esci da questa pagina senza cliccare \"$1\" le preferenze non verranno aggiornate.",
        "prefs-tabs-navigation-hint": "Suggerimento: è possibile utilizzare i tasti freccia sinistra e destra per spostarsi tra le schede nell'elenco delle schede.",
        "email-address-validity-valid": "L'indirizzo e-mail sembra valido",
        "email-address-validity-invalid": "Inserisci un indirizzo e-mail valido",
        "protect-othertime": "Durata non in elenco:",
        "protect-othertime-op": "durata non in elenco",
        "protect-existing-expiry": "Scadenza attuale: $2, $3",
+       "protect-existing-expiry-infinity": "Scadenza attuale: infinito",
        "protect-otherreason": "Altri motivi/dettagli:",
        "protect-otherreason-op": "Altra motivazione",
        "protect-dropdown": "*Motivi comuni di protezione\n** Reiterati vandalismi\n** Reiterati inserimenti di spam\n** Edit war\n** Pagina molto usata",
        "unblocked": "L'utente [[User:$1|$1]] è stato sbloccato",
        "unblocked-range": "$1 è stato sbloccato",
        "unblocked-id": "Il blocco $1 è stato rimosso",
+       "unblocked-ip": "[[Special:Contributions/$1|$1]] è stato sbloccato.",
        "blocklist": "Utenti bloccati",
        "ipblocklist": "Utenti bloccati",
        "ipblocklist-legend": "Cerca un utente bloccato",
        "logentry-upload-overwrite": "$1 {{GENDER:$2|ha caricato}} una nuova versione di $3.",
        "logentry-upload-revert": "$1 {{GENDER:$2|ha caricato}} $3",
        "rightsnone": "(nessuno)",
+       "revdelete-summary": "oggetto della modifica",
        "feedback-bugornote": "Se si è in grado di descrivere il problema tecnico riscontrato in maniera precisa, [$1 segnalate il bug]. In alternativa, si può usare il modulo semplificato sottostante. Il commento inserito sarà aggiunto alla pagina \"[$3 $2]\", insieme al proprio nome utente e al browser in uso.",
        "feedback-subject": "Oggetto:",
        "feedback-message": "Messaggio:",
        "log-name-pagelang": "Modifiche lingua",
        "log-description-pagelang": "Questo è un registro delle modifiche alla lingua delle pagine.",
        "logentry-pagelang-pagelang": "$1 {{GENDER:$2|ha modificato}} la lingua della pagina $3 da $4 a $5.",
-       "default-skin-not-found": "Oops! La skin predefinita per il tuo wiki (<code>$wgDefaultSkin</code>), <code>$1</code>, non è disponibile.\n\nLa tua installazione sembra includere le seguenti skin. Vedi [https://www.mediawiki.org/wiki/Manual:Skin_configuration Manuale: configurazione skin] per informazioni su come abilitarle e scegliere quella predefinita.\n\n$2\n\n; Se hai appena installato MediaWiki:\n: Probabilmente lo hai installato da git, o direttamente dal codice sorgente usando qualche altro metodo. Ciò era previsto. Prova ad installare alcune skin dalla [https://www.mediawiki.org/wiki/Category:All_skins directory su mediawiki.org], tramite:\n:* Scaricando il [https://www.mediawiki.org/wiki/Download programma di installazione tarball], che viene fornito con diverse skin ed estensioni. Puoi fare copia ed incolla della directory <code>skins/</code> da lì.\n:* Clonando uno dei repository <code>mediawiki/skins/*</code> tramite git nella directory <code>skins/</code> della tua installazione MediaWiki.\n: In questo modo non dovrebbe interferire con il tuo repository git se sei uno sviluppatore MediaWiki.\n\n; Se hai appena aggiornato MediaWiki:\n: MediaWiki 1.24 e versioni successive non abilità più automaticamente le skin installate (vedi [https://www.mediawiki.org/wiki/Manual:Skin_autodiscovery Manuale: rilevamento automatico skin]). Puoi copiare le seguenti linee nel <code>LocalSettings.php</code> per abilitare tutte le skin attualmente installate:\n\n<pre>$3</pre>\n\n; Se hai appena modificato <code>LocalSettings.php</code>:\n: Ricontrolla i nomi delle skin per errori di battitura.",
-       "default-skin-not-found-no-skins": "Oops! La skin predefinita per il tuo wiki (<code>$wgDefaultSkin</code>), <code>$1</code>, non è disponibile.\n\nNon hai skin installate.\n\n; Se hai appena installato o aggiornato MediaWiki:\n: Probabilmente lo hai installato da git, o direttamente dal codice sorgente usando qualche altro metodo. Ciò era previsto. MediaWiki 1.24 e versioni successive non include alcuna skin nel repository principale. Prova ad installare alcune skin dalla [https://www.mediawiki.org/wiki/Category:All_skins directory su mediawiki.org], tramite:\n:* Scaricando il [https://www.mediawiki.org/wiki/Download programma di installazione tarball], che viene fornito con diverse skin ed estensioni. Puoi fare copia ed incolla della directory <code>skins/</code> da lì.\n:* Clonando uno dei repository <code>mediawiki/skins/*</code> tramite git nella directory <code>skins/</code> della tua installazione MediaWiki.\n: In questo modo non dovrebbe interferire con il tuo repository git se sei uno sviluppatore MediaWiki. Vedi [https://www.mediawiki.org/wiki/Manual:Skin_configuration Manuale: configurazione skin] per informazioni su come abilitarle e scegliere quella predefinita.",
+       "default-skin-not-found": "Oops! La skin predefinita per il tuo wiki, definita in <code dir=\"ltr\">$wgDefaultSkin</code> come <code>$1</code>, non è disponibile.\n\nLa tua installazione sembra includere le seguenti skin. Vedi [https://www.mediawiki.org/wiki/Manual:Skin_configuration Manuale: configurazione skin] per informazioni su come abilitarle e scegliere quella predefinita.\n\n$2\n\n; Se hai appena installato MediaWiki:\n: Probabilmente lo hai installato da git, o direttamente dal codice sorgente usando qualche altro metodo. Ciò era previsto. Prova ad installare alcune skin dalla [https://www.mediawiki.org/wiki/Category:All_skins directory su mediawiki.org], tramite:\n:* Scaricando il [https://www.mediawiki.org/wiki/Download programma di installazione tarball], che viene fornito con diverse skin ed estensioni. Puoi fare copia ed incolla della directory <code dir=\"ltr\">skins/</code> da lì.\n:* Clonando uno dei repository <code>mediawiki/skins/*</code> tramite git nella directory <code>skins/</code> della tua installazione MediaWiki.\n: In questo modo non dovrebbe interferire con il tuo repository git se sei uno sviluppatore MediaWiki.\n\n; Se hai appena aggiornato MediaWiki:\n: MediaWiki 1.24 e versioni successive non abilità più automaticamente le skin installate (vedi [https://www.mediawiki.org/wiki/Manual:Skin_autodiscovery Manuale: rilevamento automatico skin]). Puoi copiare le seguenti linee nel <code>LocalSettings.php</code> per abilitare tutte le skin attualmente installate:\n\n<pre dir=\"ltr\">$3</pre>\n\n; Se hai appena modificato <code>LocalSettings.php</code>:\n: Ricontrolla i nomi delle skin per errori di battitura.",
+       "default-skin-not-found-no-skins": "Oops! La skin predefinita per il tuo wiki, definita in <code>$wgDefaultSkin</code> come <code>$1</code>, non è disponibile.\n\nNon hai skin installate.\n\n; Se hai appena installato o aggiornato MediaWiki:\n: Probabilmente lo hai installato da git, o direttamente dal codice sorgente usando qualche altro metodo. Ciò era previsto. MediaWiki 1.24 e versioni successive non include alcuna skin nel repository principale. Prova ad installare alcune skin dalla [https://www.mediawiki.org/wiki/Category:All_skins directory su mediawiki.org], tramite:\n:* Scaricando il [https://www.mediawiki.org/wiki/Download programma di installazione tarball], che viene fornito con diverse skin ed estensioni. Puoi fare copia ed incolla della directory <code>skins/</code> da lì.\n:* Clonando uno dei repository <code>mediawiki/skins/*</code> tramite git nella directory <code dir=\"ltr\">skins/</code> della tua installazione MediaWiki.\n: In questo modo non dovrebbe interferire con il tuo repository git se sei uno sviluppatore MediaWiki. Vedi [https://www.mediawiki.org/wiki/Manual:Skin_configuration Manuale: configurazione skin] per informazioni su come abilitarle e scegliere quella predefinita.",
        "default-skin-not-found-row-enabled": "* <code>$1</code> / $2 (abilitata)",
        "default-skin-not-found-row-disabled": "* <code>$1</code> / $2 ('''disabilitata''')"
 }
index 73ebeb0..8f0443d 100644 (file)
        "passwordreset-emailsent-capture": "下記の内容の、パスワード再設定メールをお送りしました。",
        "passwordreset-emailerror-capture": "以下の内容のパスワード再設定メールを生成しましたが、{{GENDER:$2|利用者}}への送信に失敗しました: $1",
        "changeemail": "メールアドレスの変更",
-       "changeemail-header": "アカウントのメールアドレスの変更",
        "changeemail-text": "このフォームではメールアドレスを変更できます。この変更を確認するためにパスワードを入力する必要があります。",
        "changeemail-no-info": "このページに直接アクセスするためにはログインしている必要があります。",
        "changeemail-oldemail": "現在のメールアドレス:",
        "changeemail-none": "(なし)",
        "changeemail-password": "{{SITENAME}}のパスワード:",
        "changeemail-submit": "メールアドレスを変更",
-       "changeemail-cancel": "中止",
        "changeemail-throttled": "ログインの試行回数が多すぎます。\n$1待ってから再度試してください。",
        "resettokens": "トークンの再設定",
        "resettokens-text": "ここでは、アカウントに関連付けられた特定の非公開データにアクセスするためのトークンを再設定できます。\n\nトークンを誤って他人に教えてしまった場合やあなたのアカウントが侵害された場合は、必ず再設定してください。",
        "searchall": "すべて",
        "showingresults": "<strong>$2</strong> 件目以降の最大 {{PLURAL:$1|<strong>$1</strong> 件の結果}}を表示しています。",
        "showingresultsinrange": "<strong>$2</strong> 件目から<strong>$3</strong> 件目までの範囲内で最大 {{PLURAL:$1|<strong>$1</strong> 件の結果}}を表示しています。",
-       "showingresultsheader": "「<strong>$4</strong>」の検索結果 {{PLURAL:$5|<strong>$3</strong> 件中の <strong>$1</strong> 件目|<strong>$3</strong> 件中の <strong>$1</strong> 件目から <strong>$2</strong> 件目}}",
        "search-nonefound": "問い合わせに合致する検索結果はありませんでした。",
        "powersearch-legend": "高度な検索",
        "powersearch-ns": "名前空間を指定して検索:",
        "signature": "[[{{ns:user}}:$1|$2]] ([[{{ns:user_talk}}:$1|トーク]])",
        "unknown_extension_tag": "不明な拡張機能タグ「$1」です",
        "duplicate-defaultsort": "<strong>警告:</strong> 既定のソートキー「$2」が、その前に書かれている既定のソートキー「$1」を上書きしています。",
-       "duplicate-displaytitle": "<strong>警告:</strong> 既定のDISPLAYTITLE「$2」が、その前に書かれている既定のDISPLAYTITLE「$1」を上書きしています。",
+       "duplicate-displaytitle": "<strong>警告:</strong> DISPLAYTITLE「$2」が、その前に書かれているDISPLAYTITLE「$1」を上書きしています。",
        "version": "バージョン情報",
        "version-extensions": "インストール済み拡張機能",
        "version-skins": "インストール済み外装",
        "logentry-upload-overwrite": "$1 が $3 の新しいバージョンを {{GENDER:$2|アップロードしました}}",
        "logentry-upload-revert": "$1 が $3 を {{GENDER:$2|アップロードしました}}",
        "rightsnone": "(なし)",
+       "revdelete-summary": "編集内容の要約",
        "feedback-bugornote": "技術的な問題の詳細を説明する準備ができている場合は、[$1 バグ報告]をお願いします。\n準備ができていない場合は、下の簡易フォームを使用してください。あなたのコメントと利用者名が、ページ「[$3 $2]」に追加されます。",
        "feedback-subject": "件名:",
        "feedback-message": "メッセージ:",
        "log-name-pagelang": "言語変更記録",
        "log-description-pagelang": "これはページ言語の変更の記録です。",
        "logentry-pagelang-pagelang": "$1 がページ $3 の言語を $4 から $5 に{{GENDER:$2|変更しました}}",
-       "default-skin-not-found": "おっと! あなたのウィキのデフォルト外装「<code>$1</code>」 (<code>$wgDefaultSkin</code>)は利用できません。\n\nあなたのインストールには以下の外装が含まれています。外装の有効化とデフォルトの選択については、[https://www.mediawiki.org/wiki/Manual:Skin_configuration マニュアル: 外装設定] をご覧ください。\n\n$2\n\n; MediaWikiをインストールしたばかりの場合:\n: gitからインストールしたか、その他の何らかの方法でソースコードから直接インストールした場合には、これは期待されたとおりの動作です。\n:* [https://www.mediawiki.org/wiki/Category:All_skins mediawiki.org's skin directory] から外装をインストールしてみてください。\n:* [https://www.mediawiki.org/wiki/Download tarball installer] をダウンロードしてみてください。これにはいくつかの外装と拡張機能が含まれています。 <code>skins/</code> ディレクトリからコピー&ペーストできます。\n: あなたがMediaWiki開発者の場合、これを行うことであなたのgitレポジトリに干渉することはありません。\n\n; MediaWiki をアップグレードした場合:\n: MediaWiki 1.24 以降のバージョンでは、インストール済みの外装は自動的には有効になりません。 ([https://www.mediawiki.org/wiki/Manual:Skin_autodiscovery マニュアル: 外装の自動探索] をご覧ください。)。<code>LocalSettings.php</code> に以下の行をペーストして、現在インストールされている外装を有効にできます。\n\n<pre>$3</pre>\n\n; <code>LocalSettings.php</code>を編集したばかりの場合:\n: 外装名に打ち間違いがないか再度確認して下さい。",
-       "default-skin-not-found-no-skins": "おっと! あなたのWikiのデフォルト外装「<code>$1</code>」 (<code>$wgDefaultSkin</code>)は利用できません。\n\n外装をインストールしていません。\n\n; MediaWikiをインストールしたばかりの場合:\n: gitからインストールしたか、その他の何らかの方法でソースコードから直接インストールした場合には、これは期待されたとおりの動作です。\n:* [https://www.mediawiki.org/wiki/Category:All_skins mediawiki.org's skin directory] から外装をインストールしてみてください。\n:* [https://www.mediawiki.org/wiki/Download tarball installer] をダウンロードしてみてください。これには外装と拡張機能がいくつか含まれています。 <code>skins/</code> ディレクトリからコピー&ペーストできます。\n: あなたがMediaWiki開発者の場合、これを行うことであなたのgitレポジトリに干渉することはありません。外装の有効化とデフォルトの選択についての情報は、[https://www.mediawiki.org/wiki/Manual:Skin_configuration マニュアル: 外装設定] をご覧ください。",
+       "default-skin-not-found": "おっと! あなたのウィキの既定の外装「<code>$1</code>」 (<code>$wgDefaultSkin</code>)は利用できません。\n\nあなたのインストールには以下の外装が含まれています。外装の有効化と既定の選択については、[https://www.mediawiki.org/wiki/Manual:Skin_configuration マニュアル: 外装設定] をご覧ください。\n\n$2\n\n; MediaWikiをインストールしたばかりの場合:\n: gitからインストールしたか、その他の何らかの方法でソースコードから直接インストールした場合には、これは期待されたとおりの動作です。\n:* [https://www.mediawiki.org/wiki/Category:All_skins mediawiki.org's skin directory] から外装をインストールしてみてください。\n:* [https://www.mediawiki.org/wiki/Download tarball installer] をダウンロードしてみてください。これにはいくつかの外装と拡張機能が含まれています。 <code>skins/</code> ディレクトリからコピー&ペーストできます。\n: あなたがMediaWiki開発者の場合、これを行うことであなたのgitリポジトリに干渉することはありません。\n\n; MediaWiki をアップグレードした場合:\n: MediaWiki 1.24 以降のバージョンでは、インストール済みの外装は自動的には有効になりません。 ([https://www.mediawiki.org/wiki/Manual:Skin_autodiscovery マニュアル:外装の自動探索] をご覧ください)。<code>LocalSettings.php</code> に以下の行をペーストして、現在インストールされている外装を有効にできます。\n\n<pre>$3</pre>\n\n; <code>LocalSettings.php</code>を編集したばかりの場合:\n: 外装名に打ち間違いがないか再度確認してください。",
+       "default-skin-not-found-no-skins": "おっと! あなたのウィキの既定の外装「<code>$1</code>」 (<code>$wgDefaultSkin</code>)は利用できません。\n\n外装をインストールしていません。\n\n; MediaWikiをインストールしたばかりの場合:\n: gitからインストールしたか、その他の何らかの方法でソースコードから直接インストールした場合には、これは期待されたとおりの動作です。\n:* [https://www.mediawiki.org/wiki/Category:All_skins mediawiki.org's skin directory] から外装をインストールしてみてください。\n:* [https://www.mediawiki.org/wiki/Download tarball installer] をダウンロードしてみてください。これには外装と拡張機能がいくつか含まれています。 <code>skins/</code> ディレクトリからコピー&ペーストできます。\n: あなたがMediaWiki開発者の場合、これを行うことであなたのgitリポジトリに干渉することはありません。外装の有効化と既定の選択についての情報は、[https://www.mediawiki.org/wiki/Manual:Skin_configuration マニュアル:外装設定] をご覧ください。",
        "default-skin-not-found-row-enabled": "* <code>$1</code> / $2 (有効)",
        "default-skin-not-found-row-disabled": "* <code>$1</code> / $2 ('''無効''')"
 }
index 71bb713..7b1335f 100644 (file)
        "passwordreset-emailsent-capture": "ქვემოთ ნაჩვენები პაროლის თავიდან დასაყენებელი წერილი გაიგზავნა.",
        "passwordreset-emailerror-capture": "ქვემოთ მოცემულია შექმნილი პაროლის დასაყენებელი წერილი, რომლის გაგზავნაც {{GENDER:$2|მომხმარებელთან}} ვერ მოხერხდა: $1 გამო",
        "changeemail": "ელ-ფოსტის მისამართის შეცვლა",
-       "changeemail-header": "ანგარიშის ელ-ფოსტის მისამართის შეცვლა",
        "changeemail-text": "შეავსეთ ეს ფორმა თქვენი ელ-ფოსტის მისამართის შესაცვლელად. თქვენი პაროლის შეყვანა დაგჭირდებათ ამ ცვლილების დასადასტურებლად.",
        "changeemail-no-info": "თქვენ ავტირიზებული უნდა იყოთ ამ გვერდთან უშუალო წვდომისთვის.",
        "changeemail-oldemail": "ელ-ფოსტის ამჟამინდელი მისამართი:",
        "changeemail-none": "(არაფერი)",
        "changeemail-password": "თქვენი პაროლი პროექტში {{SITENAME}}:",
        "changeemail-submit": "ელ-ფოსტის შეცვლა",
-       "changeemail-cancel": "გაუქმება",
        "resettokens-tokens": "ჟეტონები:",
        "resettokens-token-label": "$1 (მიმდინარე მნიშვნელობა: $2)",
        "bold_sample": "მუქი ტექსტი",
        "searchrelated": "მიბმული",
        "searchall": "ყველა",
        "showingresults": "ქვემოთ იხილეთ <b>$1</b>-მდე შედეგი დაწყებული #<b>$2</b>-იდან.",
-       "showingresultsheader": "{{PLURAL:$5|რეზულტატი '''$1'''  '''$3'''-დან|რეზულტატები '''$1 — $2''' -დან '''$3'''}}  '''$4'''-თვის",
        "search-nonefound": "მოთხოვნის შესაბამისობა არ არის ნაპოვნი.",
        "powersearch-legend": "გაფართოებული ძიება",
        "powersearch-ns": "ძიება სახელთა სივრცეებში:",
        "listusers": "მომხმარებლების სია",
        "listusers-editsonly": "აჩვენთ მხოლოდ ის მომხმარებლები, რომლებსაც ერთი შესწორება აქვს გაკეთებული.",
        "listusers-creationsort": "დაალაგეთ შექმნის თარიღის მიხედვით.",
+       "listusers-desc": "კლების მიხედვით დალაგება",
        "usereditcount": "$1 რედაქტირება",
        "usercreated": "{{GENDER:$3|შექმნილია}} $2-ზე $1-ში",
        "newpages": "ახალი გვერდები",
        "logentry-rights-rights-legacy": "მომხმარებელმა $1 {{GENDER:$2|შეცვალა}} ჯგუფის წევრობა $3-თვის",
        "logentry-rights-autopromote": "მომხმარებელი $1 ავტომატურად იქნა {{GENDER:$2|გადაყვანილი}} $4–დან $5–ში",
        "rightsnone": "(არცერთი)",
+       "revdelete-summary": "ცვლილებების აღწერა",
        "feedback-bugornote": "თუ თქვენ მზად ხართ დეტალურად აღწეროთ ტექნიკური პრობლემა, გთხოვთ, [$1 შეგვატყობინეთ შეცდომის შესახებ].\nწინააღმდეგ შემთხვევაში თქვენ შეგიძლიათ ისარგებლოთ ამ მარტივი ფორმით. თქვენი კომენტარი დაემატება  „[$3 $2]“ გვერდზე თქვენი მომხმარებლის სახელთან და გამოყენებულ ბრაუზერთან ერთად.",
        "feedback-subject": "თემა:",
        "feedback-message": "შეტყობინება:",
index 04320f1..2dfbeb2 100644 (file)
        "passwordreset-emailsent-capture": "Құпия сөзді өзгерту электронды пошта арқылы жөнелтілді, ол төменде көрсетілген.",
        "passwordreset-emailerror-capture": "Жазылған ескертпе-хат төменде көрсетілген, оның жөнелтілмеу себебі: $1",
        "changeemail": "Е-пошта мекен-жайын өзгерту",
-       "changeemail-header": "Е-пошта мекен-жайының өзгертілуі",
        "changeemail-text": "Е-поштаның мекен-жайын өзгерту үшін мына пішінді толтырыңыз. Өзгертулерді растау үшін құпия сөздіңізді енгізу керек.",
        "changeemail-no-info": "Бұл бетке тікелей ену үшін жүйеге кіруіңіз керек.",
        "changeemail-oldemail": "Е-поштаның қазіргі уақыттағы мекен-жайы:",
        "changeemail-none": "(ешкім)",
        "changeemail-password": "{{SITENAME}} жобасындағы құпия сөзіңіз:",
        "changeemail-submit": "Е-поштаны өзгерту",
-       "changeemail-cancel": "Болдырмау",
        "changeemail-throttled": "Сіз жақында кіруге тым көп әрекет жасадыңыз.\nҚайта байқап көру үшін $1 уақыт күте тұрыңыз.",
        "bold_sample": "Жуан мәтін",
        "bold_tip": "Жуан мәтін",
        "searchrelated": "қатысты",
        "searchall": "барлық",
        "showingresults": "Төменде нөмір '''$2''' орнынан бастап барынша '''$1''' нәтиже көрсетіледі.",
-       "showingresultsheader": "«<strong>$4</strong>» сұранысына {{PLURAL:$5|тек <strong>$1</strong> нәтиже табылды|табылған <strong>$3</strong> нәтиженің <strong>$1 - $2</strong> аралығы көрсетілген}}",
        "search-nonefound": "Сұрауға сәйкес нәтижелер табылмады.",
        "powersearch-legend": "Кеңейтілген іздеу",
        "powersearch-ns": "Атау кеңістіктері бойынша іздеу:",
        "rollbacklinkcount-morethan": "$1-нан аса {{PLURAL:$1|өңдемені|өңдемелерді}} шегіндіру",
        "rollbackfailed": "Шегіндіру орындалмады",
        "cantrollback": "Өңдеме қайтарылмады;\nсоңғы үлескері тек осы беттің бастаушысы болды.",
-       "alreadyrolled": "[[User:$2|$2]] ([[User talk:$2|талқылауы]]{{int:pipe-separator}}[[Special:Contributions/$2|{{int:contribslink}}]]) істеген [[:$1]] соңғы өңдемесі шегіндірілмеді;\nбасқа біреу бұл бетті әлдеқашан өңдеген немесе шегіндірген.\n\nБетті [[User:$3|$3]] ([[User talk:$3|talk]]{{int:pipe-separator}}[[Special:Contributions/$3|{{int:contribslink}}]]) соңғы рет өңдеген.",
+       "alreadyrolled": "[[User:$2|$2]] ([[User talk:$2|талқылауы]]{{int:pipe-separator}}[[Special:Contributions/$2|{{int:contribslink}}]]) істеген [[:$1]] бетіндегі соңғы өңдемесі шегіндірілмеді, себебі басқа біреу бұл бетті әлдеқашан өңдеген немесе шегіндірген.\n\nБетті [[User:$3|$3]] ([[User talk:$3|талқылауы]]{{int:pipe-separator}}[[Special:Contributions/$3|{{int:contribslink}}]]) соңғы рет өңдеген.",
        "editcomment": "Болған өңдеме түйіндемесі: «''$1''».",
        "revertpage": "[[Special:Contributions/$2|$2]] ([[User talk:$2|т]]) өңдемелерінен [[User:$1|$1]] соңғы нұсқасына қайтарды",
        "revertpage-nouser": "Жасырылған қатысушы өңдемелерінен {{GENDER:$1|[[User:$1|$1]]}} соңғы нұсқасына қайтарды",
        "tooltip-recreate": "Бет жойылғанына қарамастан қайта бастау",
        "tooltip-upload": "Жүктеуді бастау",
        "tooltip-rollback": "\"Шегіндіру\" сілтемесін бір рет басу арқылы соңға редактордың барлық қатар өңдемелерін өшіру",
+       "tooltip-undo": "«Жоққа шығару» сілтемесін бассаңыз бұл өңдеме болдырылмайды және өңдеу пішіні қарап шығу режимінде ашылады. Ол өңдеу түйіндемесіне себебін қосуға мүмкіндік береді.",
        "tooltip-preferences-save": "Бапталымдарыңызды сақтау",
        "tooltip-summary": "Қысқаша түйіндемесін енгізіңіз",
        "interlanguage-link-title-nonlang": "$1 – $2",
        "logentry-rights-rights": "$1 $3 үшін топ мүшелігін $4 дегеннен $5 дегенге {{GENDER:$2|өзгерті}}",
        "logentry-rights-rights-legacy": "$1 $3 үшін топ мүшелігін {{GENDER:$2|өзгерті}}",
        "rightsnone": "(ешқандай)",
+       "revdelete-summary": "өңдеменің қысқаша мазмұндамасы",
        "feedback-subject": "Тақырып:",
        "feedback-message": "Хабарлама:",
        "feedback-cancel": "Болдырмау",
index 5af0774..5f7c262 100644 (file)
@@ -39,7 +39,8 @@
                        "아라",
                        "Keysuck",
                        "Infinity",
-                       "Bluemersen"
+                       "Bluemersen",
+                       "Revi"
                ]
        },
        "tog-underline": "링크에 밑줄:",
        "otherlanguages": "다른 언어",
        "redirectedfrom": "($1에서 넘어옴)",
        "redirectpagesub": "넘겨주기 문서",
+       "redirectto": "넘겨줄 대상:",
        "lastmodifiedat": "이 문서는 $1 $2에 마지막으로 바뀌었습니다.",
        "viewcount": "이 문서는 {{PLURAL:$1|한 번|$1번}} 읽혔습니다.",
        "protectedpage": "보호된 문서",
        "loginerror": "로그인 오류",
        "createacct-error": "계정 만들기 오류",
        "createaccounterror": "계정을 만들수 없습니다: $1",
-       "nocookiesnew": "사용자 계정을 만들었지만, 아직 로그인하지 않았습니다.\n{{SITENAME}}에서는 로그인 정보를 저장하기 위해 쿠키를 사용합니다.\n지금 사용하는 웹 브라우저는 쿠키를 사용하지 않도록 설정되어 있습니다.\n로그인하기 전에 웹 브라우저에서 쿠키를 사용하도록 설정해주세요.",
+       "nocookiesnew": "사용자 계정을 만들었지만, 아직 로그인하고 있지 않습니다.\n{{SITENAME}}에서는 로그인 정보를 저장하기 위해 쿠키를 사용합니다.\n지금 사용하는 웹 브라우저는 쿠키를 사용하지 않도록 설정되어 있습니다.\n로그인하기 전에 웹 브라우저에서 쿠키를 사용하도록 설정해주세요.",
        "nocookieslogin": "{{SITENAME}}에서는 로그인을 위해 쿠키를 사용합니다.\n쿠키가 비활성되어 있습니다.\n쿠키 사용을 활성화한 다음 다시 시도하세요.",
        "nocookiesfornew": "요청의 출처를 확인할 수 없기 때문에 사용자 계정이 만들어지지 않았습니다.\n쿠키를 허용한 것을 확인한 후에 이 문서를 새로 고치고 나서 다시 시도하세요.",
        "noname": "사용자 계정 이름이 올바르지 않습니다.",
        "createaccount-text": "누군가가 {{SITENAME}} ($4)에서 사용자 이름 \"$2\", 비밀번호 \"$3\"로 당신의 이메일 주소가 등록된 계정을 만들었습니다. \n지금 로그인하여 비밀번호를 바꾸십시오.\n\n실수로 계정을 잘못 만들었다면 이 메시지는 무시해도 됩니다.",
        "login-throttled": "로그인에 연속으로 실패하였습니다.\n$1 기다렸다가 다시 시도하세요.",
        "login-abort-generic": "로그인에 실패했습니다 - 중지됨",
+       "login-migrated-generic": "당신의 계정이 마이그레이션되었으며, 당신의 사용자 이름이 더 이상 이 위키에 존재하지 않습니다.",
        "loginlanguagelabel": "언어: $1",
        "suspicious-userlogout": "브라우저에 이상이 있거나 캐싱 프록시에서 로그아웃을 요청했기 때문에 로그아웃이 거부되었습니다.",
        "createacct-another-realname-tip": "실명은 선택 사항입니다.\n실명을 입력하면 문서 기여에 사용자의 이름이 들어가게 됩니다.",
        "passwordreset-emailsent-capture": "비밀번호 재설정 이메일이 발송되었으며, 아래에 나타나 있습니다.",
        "passwordreset-emailerror-capture": "비밀번호 재설정 이메일이 생성되어 아래에 보여져 있지만, {{GENDER:$2|사용자}}에게 발송하는 데에는 실패했습니다: $1",
        "changeemail": "이메일 주소 바꾸기",
-       "changeemail-header": "계정 이메일 주소 바꾸기",
        "changeemail-text": "이메일 주소를 바꾸려면 이 양식을 채우세요. 이 바뀜을 확인하기 위해 비밀번호를 입력해야 합니다.",
        "changeemail-no-info": "이 특수 문서에 직접 접근하려면 반드시 로그인해야 합니다.",
        "changeemail-oldemail": "현재 이메일 주소 :",
        "changeemail-none": "(없음)",
        "changeemail-password": "{{SITENAME}} 비밀번호:",
        "changeemail-submit": "이메일 주소 바꾸기",
-       "changeemail-cancel": "취소",
        "changeemail-throttled": "로그인에 연속으로 너무 많이 실패하였습니다.\n$1 기다렸다가 다시 시도하세요.",
        "resettokens": "토큰 재설정",
        "resettokens-text": "여기에 당신의 계정과 관련된 특정 개인 데이터에 접근을 허용하는 토큰을 재설정합니다.\n\n토큰이 다른 사람에게 알려졌거나 계정이 침해되었을 때는 재설정해야 합니다.",
        "showpreview": "미리 보기",
        "showdiff": "차이 보기",
        "blankarticle": "<strong>경고:</strong> 만들려는 문서가 비어 있습니다.\n\"{{int:savearticle}}\"을 다시 클릭하면, 문서에 내용이 없이 만들어집니다.",
-       "anoneditwarning": "'''경고''': 로그인하고 있지 않습니다.\nIP 주소가 문서 역사에 남게 됩니다.",
-       "anonpreviewwarning": "'''로그인하고 있지 않습니다. 문서를 저장하면 당신의 IP 주소가 문서 역사에 남게 됩니다.'''",
+       "anoneditwarning": "<strong>경고:</strong> 로그인하고 있지 않습니다. 편집하면 당신의 IP 주소가 공개적으로 보여집니다. <strong>[$1 로그인]</strong>하거나 <strong>[$2 계정을 만들면]</strong>, 당신의 편집에 다른 이익과 함께, 사용자 이름이 표시됩니다.",
+       "anonpreviewwarning": "<em>로그인하고 있지 않습니다. 문서를 저장하면 당신의 IP 주소가 문서의 편집 역사에 남게 됩니다.</em>",
        "missingsummary": "'''알림:''' 편집 요약을 적지 않았습니다.\n이대로 \"{{int:savearticle}}\"을 클릭하면 편집 요약 없이 저장됩니다.",
        "missingcommenttext": "아래에 내용을 채워 넣어 주세요.",
        "missingcommentheader": "'''알림:''' 글의 제목을 입력하지 않았습니다.\n다시 \"{{int:savearticle}}\" 버튼을 클릭하면 글이 제목 없이 저장됩니다.",
        "searchall": "모두",
        "showingresults": "'''$2'''번 부터의 {{PLURAL:$1|결과 '''1'''개|결과 '''$1'''개}}입니다.",
        "showingresultsinrange": "#<strong>$2</strong>부터 #<strong>$3</strong>까지의 범위에서 <strong>$1</strong>개의 {{PLURAL:$1|결과}}가 아래에 보입니다.",
-       "showingresultsheader": "'''$4''' 검색어에 대한 {{PLURAL:$5|결과 '''$3'''개 중 '''$1'''개|결과 '''$3'''개 중 '''$1 - $2'''번째}}",
        "search-nonefound": "검색어와 일치하는 결과가 없습니다.",
        "powersearch-legend": "고급 검색",
        "powersearch-ns": "다음 이름공간에서 검색:",
        "delete-edit-reasonlist": "삭제 이유 편집",
        "delete-toobig": "이 문서에는 {{PLURAL:$1|편집 역사}}가 $1개 있습니다.\n편집 역사가 긴 문서를 삭제하면 {{SITENAME}}에 큰 혼란을 줄 수 있기 때문에 삭제할 수 없습니다.",
        "delete-warning-toobig": "이 문서에는 {{PLURAL:$1|편집 역사}}가 $1개 있습니다.\n편집 역사가 긴 문서를 삭제하면 {{SITENAME}} 데이터베이스 동작에 큰 영향을 줄 수 있습니다.\n주의해 주세요.",
+       "deleteprotected": "이 문서가 잠겨 있기 때문에 삭제할 수 없습니다.",
        "deleting-backlinks-warning": "'''경고:''' 삭제하려는 문서가 [[Special:WhatLinksHere/{{FULLPAGENAME}}|다른 문서]]에 링크되어 있거나 끼워져 있습니다.",
        "rollback": "편집 되돌리기",
        "rollback_short": "되돌리기",
        "unblocked": "[[User:$1|$1]] 사용자의 차단을 해제했습니다.",
        "unblocked-range": "$1 대역이 차단 해제되었습니다.",
        "unblocked-id": "$1 차단이 해제되었습니다.",
+       "unblocked-ip": "[[Special:Contributions/$1|$1]] 사용자가 차단 해제되었습니다.",
        "blocklist": "차단된 사용자 목록",
        "ipblocklist": "차단된 사용자",
        "ipblocklist-legend": "차단된 사용자 찾기",
        "logentry-upload-overwrite": "$1 사용자가 $3의 새 판을 {{GENDER:$2|올렸습니다}}",
        "logentry-upload-revert": "$1 사용자가 $3 파일을 {{GENDER:$2|올렸습니다}}",
        "rightsnone": "(없음)",
+       "revdelete-summary": "편집 요약",
        "feedback-bugornote": "기술적 문제를 구체적으로 설명할 준비가 되었다면 [$1 버그를 신고]해 주세요.\n아니면 아래에 쉬운 양식을 쓸 수 있습니다. 의견은 사용자 이름과 함께 \"[$3 $2]\"에 남겨질 것입니다.",
        "feedback-subject": "제목:",
        "feedback-message": "내용:",
index 07a1d75..2761b73 100644 (file)
        "userlogin-resetpassword-link": "Şîfreyê ji nû ve çêke",
        "userlogin-helplink2": "Alîkariya têketinê",
        "createacct-emailrequired": "E-name",
+       "createacct-emailoptional": "E-name",
+       "createacct-email-ph": "E-nameya xwe binivîse",
        "createaccountmail": "Use a temporary random password and send it to the email address specified below",
        "createaccountreason": "Sedem:",
        "createacct-reason": "Sedem",
+       "createacct-imgcaptcha-ph": "Nivîsa ku tu li jor dibînî binivîse",
        "createacct-submit": "Hesabê xwe biafirîne",
        "createacct-benefit-body2": "{{PLURAL:$1|rûpel}}",
        "badretype": "Her du şîfreyên ku te nivîsîn li hevdu nayên.",
        "changeemail-newemail": "Navnîşana E-nameya nû:",
        "changeemail-none": "(nîne)",
        "changeemail-submit": "E-nameyê biguherîne",
-       "changeemail-cancel": "Betal bike",
        "bold_sample": "Nivîsa stûr",
        "bold_tip": "Nivîsa stûr",
        "italic_sample": "Nivîsa xwehr (îtalîk)",
        "searchrelated": "pêwendîdar",
        "searchall": "hemû",
        "showingresults": "{{PLURAL:$1|Encamek|'''$1''' encam}}, bi #'''$2''' dest pê dike.",
-       "showingresultsheader": "{{PLURAL:$5|Encam '''$1''' ên '''$3'''|Encam '''$1 - $2''' ên '''$3'''}} ji bo '''$4'''",
        "search-nonefound": "Ti rûpelên wek ya daxwazkirî nînin.",
        "powersearch-legend": "Lê bigere",
        "powersearch-ns": "Di valahiya navan de lêbigere:",
        "logentry-newusers-newusers": "$1 hesabekî bikarhêneriyê çêkir",
        "logentry-newusers-create": "$1 hesabekî bikarhêneriyê çêkir",
        "rightsnone": "(tune)",
+       "revdelete-summary": "kurteyê biguherîne",
        "feedback-subject": "Mijar:",
        "feedback-message": "Peyam:",
        "feedback-cancel": "Betal bike",
index 415e051..fe20168 100644 (file)
        "otherlanguages": "An anere Sproochen",
        "redirectedfrom": "(Virugeleet vu(n) $1)",
        "redirectpagesub": "Viruleedungssäit",
+       "redirectto": "Viruleeden op:",
        "lastmodifiedat": "Dës Säit gouf de(n) $1 ëm $2 Auer fir d'lescht geännert.",
        "viewcount": "Dës Säit gouf bis elo {{PLURAL:$1|emol|$1-mol}} ofgefrot.",
        "protectedpage": "Gespaart Säit",
        "passwordreset-emailsent-capture": "Eng Mail fir d'Passwuert zréckzesetze gouf geschéckt, Dir gesitt se hei drënner.",
        "passwordreset-emailerror-capture": "Eng Mail fir d'Passwuert zréckzesetze gouf geschéckt, Dir gesitt se hei drënner, awer de {{GENDER:$2|Benotzer}} konnt se net kréien: $1",
        "changeemail": "Mailadress änneren",
-       "changeemail-header": "Mailadress vum Benotzerkont änneren",
        "changeemail-text": "Fëllt dëse Formulaire aus fir Är Mailadress z'änneren. Dir musst Äert Passwuert aginn fir dës Ännerung ze confirméieren.",
        "changeemail-no-info": "Dir musst ageloggt sinn, fir direkt op dës Säit ze kommen.",
        "changeemail-oldemail": "Aktuell Mailadress:",
        "changeemail-none": "(keng)",
        "changeemail-password": "Äert {{SITENAME}}-Passwuert:",
        "changeemail-submit": "Mailadress änneren",
-       "changeemail-cancel": "Ofbriechen",
        "changeemail-throttled": "Dir hutt zevill dacks versicht Iech anzeloggen.\nWaart w.e.g. $1 ier Dir et nach eng Kéier probéiert.",
        "resettokens": "Token zrécksetzen",
        "resettokens-no-tokens": "Et gëtt keng Tokens fir zréck ze setzen.",
        "searchrelated": "a Verbindng",
        "searchall": "all",
        "showingresults": "Hei gesitt der  {{PLURAL:$1| '''1''' Resultat|'''$1''' Resultater}}, ugefaange mat #'''$2'''.",
-       "showingresultsheader": "{{PLURAL:$5|Resultat '''$1''' vu(n) '''$3'''|Resultater '''$1 - $2''' vu(n) '''$3'''}} fir '''$4'''",
        "search-nonefound": "Fir Är Ufro gouf näischt fonnt.",
        "powersearch-legend": "Erweidert Sich",
        "powersearch-ns": "Sichen an den Nummraim:",
        "unblocked": "D'Spär fir de [[User:$1|Benotzer $1]] gouf opgehuewen",
        "unblocked-range": "D'Spär vum $1 gouf opgehuewen",
        "unblocked-id": "D'Spär $1 gouf opgehuewen",
+       "unblocked-ip": "D'Spär vum [[Special:Contributions/$1|$1]] gouf opgehuewen.",
        "blocklist": "Gespaart Benotzer",
        "ipblocklist": "Gespaart Benotzer",
        "ipblocklist-legend": "No engem gespaarte Benotzer sichen",
        "logentry-upload-overwrite": "$1 huet eng nei Versioun vu(n) $3 {{GENDER:$2|eropgelueden}}",
        "logentry-upload-revert": "$1 huet $3 {{GENDER:$2|eropgelueden}}",
        "rightsnone": "(keen)",
+       "revdelete-summary": "Resumé änneren",
        "feedback-bugornote": "Wann Dir bereet sidd fir en technesche Problem am Detail ze beschreiwen da [$1 mellt w.e.g. e Feeler (Bug)].\nSoss kënnt Dir den einfache Formulär hei drënner benotzen. Är Bemierkung gëtt op d'Säit \"[$3 $2]\" derbäigesat, zesumme mat Ärem Benotzernumm an dem Numm vum Browser deen Dir benotzt.",
        "feedback-subject": "Sujet:",
        "feedback-message": "Message:",
index bd84f86..915ae29 100644 (file)
        "index-category": "بلگيا سيائه دار",
        "noindex-category": "بلگيا بی سيائه",
        "broken-file-category": "بلگیایی که هوم پیوند فایلیا اشکسه دارن",
+       "categoryviewer-pagedlinks": "($1) ($2)",
        "about": "دباره",
        "article": "محتوا بلگه",
        "newwindow": "(نيمدری  تازه وا کو)",
        "versionrequired": "یه نسقه د نیازمنیا ویکی رسانه\n$1",
        "versionrequiredtext": "نسقه $1 ویکی مدیا سی وه کار بستن د ای بلگه لازم هئی .\nوه نه بوینیت [[ویجه:نسقه|نسقه بلگه]].",
        "ok": "خوئه",
+       "pagetitle": "$1 - {{SITENAME}}",
+       "pagetitle-view-mainpage": "{{SITENAME}}",
+       "backlinksubtitle": "← $1",
        "retrievedfrom": "بازيافته د\"$1\"",
        "youhavenewmessages": "شما داريت $1($2)",
        "youhavenewmessagesfromusers": "{{جمی:$4|شما }} $1 د {{جمی:$3|کارور هنی|$3 کاروریا}}داریتو($2).",
        "site-atom-feed": "خور حون Atom سی $1",
        "page-rss-feed": "خورحو RSS سی «$1»",
        "page-atom-feed": "خور حون Atom سی $1",
+       "feed-atom": "اتم",
+       "feed-rss": "آر اس اس",
        "red-link-title": "$1(بلگه وجود ناره)",
        "sort-descending": "كم بيئن منظم",
        "sort-ascending": "زياد بيئن منظم",
        "nocookiesnew": "حساو کاروری راس بی،اما شما وامئن نیامایئته.{{نوم مالگه}} د کوکیا سی اومائن د سیستم کاروریا استفاده می که.کوکیا شما د کار افتائه.لطفن وا کارشو بونیت، اوسه وا نوم کاروری تازه و پسورد هنی بیایت وا مئن.",
        "nocookieslogin": "{{نوم مالگه}} د کوکیا سی وامئن اومائن کاروریا استفاده می که. کوکیا شما د کار افتائه.\nلطف بکید د کارشو بونیت و دوواره تلاش بکید.",
        "nocookiesfornew": "حساو کاروری راس نبیه، سی یه ایما نتونیم سرچشمه ونه مئکم بکیم.\nمطمئن بوئیت که کوکیا فعال بینه، ای بلگه نه د نو سوار بکید و د نو تلاش بکید.",
+       "nocookiesforlogin": "{{int:nocookieslogin}}",
        "noname": "شما یه گل نوم کاروری خو ناریت",
        "loginsuccesstitle": "اومائن د سيستم موفق بی",
        "loginsuccess": "شما ایسه وارد بیته {{SITENAME}} د دعنوان \"$1\".'",
        "user-mail-no-body": "سی کل کردن ایمیل وا مینونه حالی یا کؤچک بیئن سی دلیل غیر علقمنی تلاش بکید.",
        "changepassword": "پاسورد نه آلشت بكيت",
        "resetpass_announce": "سی تموم کردن وا مین اومائن، شما باید یه گل پاسورد هنی وارد بکیتو.",
+       "resetpass_text": "<!-- یه گل نیسسه ایچه اضاف بکیت -->",
        "resetpass_header": "پاسورد حساوتونه آلشت بکید",
        "oldpassword": "پاسورد قدیمی:",
        "newpassword": "پاسورد تازه:",
        "passwordreset-emailsent-capture": "پاسورد تازه تو د ایمیلتو که د هار نشو دئه بیه کل بیه",
        "passwordreset-emailerror-capture": "رازینه گواردن د انجومانامه د نو زنه کننه راس بیه، و وه د هار دیاری می که، اما کل بیین وه د{{جنس:$2|کاریار}} شکست حرده:$1",
        "changeemail": "ایمیل تو نه آلشت بکید",
-       "changeemail-header": "ایمیل حساوتونه آلشت بکید",
        "changeemail-text": "ای نوم بلگه نه سی آلشت دئن تیرنشون انجومانامه تو پر بکیت. شما سی پشت راس کردن ای آلشت واس رازینه گواردن خوتونه وارد بکیت.",
        "changeemail-no-info": "شما با بیایت د سیستم تا د ای بلگه دسرسی داشتویت",
        "changeemail-oldemail": "نشونی ایمیل تازه باو:",
        "changeemail-none": "(هيش كوم)",
        "changeemail-password": "شما {{SITENAME}} پاسورد:",
        "changeemail-submit": "آلشت کردن ایمیل",
-       "changeemail-cancel": "انجوم شیوسن",
        "changeemail-throttled": "شما ایسنی فره سی وامین اومائن تلاش کردیته.\n$1 لطفن سی تلاش هنی صبر بکید.",
        "resettokens": "تازه کردن نشونه یا",
        "resettokens-text": "شما سی صلا دئن دسرسی وه رسینه یا خصوصی که ها د حساو ایچنی تو می تونیت دیارگریا نه د نو زنه بکیت.\n\nشما اوسنی واس ای کار بکیت که رسینه یا شما سی یه کسی تر بئر بیه یا د حساو شما چل بیه.",
        "headline_tip": "قدم 2 خط سر ون",
        "nowiki_sample": "د ایچه یه گل متن بی شلک وارد بکید",
        "nowiki_tip": "شلک ویکی نه ندید بگر",
+       "image_sample": "Example.jpg",
        "image_tip": "جانیا محاط بيه",
+       "media_sample": "Example.ogg",
        "media_tip": "فایل هوم پیوند",
        "sig_tip": "امضا شما و برچسو وخت",
        "hr_tip": "خط افق ونه(سوا سوا دش استفاده کو)",
        "template-protected": "(حمايت بيه)",
        "template-semiprotected": "(نيم-حفاظت بيه)",
        "hiddencategories": "ای بلگه يه اندوم د{{PLURAL:$1|1 hidden category|$1 hidden categories}}: هئ",
+       "edittools-upload": "-",
        "nocreatetext": "{{نوم مالگه}} سی راس کردن بلگه یا تازه محدود بیه.\nشما تونید روئیت وادما و بلگه ای که هئیش ویرایشت بکید ، یا [[ویجه:وامین اومائن کاریار|بیایت وامین یا یه گل حساو بسازیت]].",
        "nocreate-loggedin": "شما حق ناریت  که بلگه یا تازه نه راس بکید.",
        "sectioneditnotsupported-title": "ویرایشت بخش حمایت نبوئه",
        "mergehistory-comment": " [[:$1]]وا[[:$2]] یکی بیه:$3",
        "mergehistory-same-destination": "سرچشمه و بلگه یا مقصد نبوئه یکی بوئن",
        "mergehistory-reason": "دليل:",
+       "mergehistory-revisionrow": "$1 ($2) $3 . . $4 $5 $6",
        "mergelog": "سریک سازی پهرستنومه",
        "pagemerge-logentry": " [[$1]] وا [[$2]] سریک سازی بی (وانیریا که د $3 فره تر هئن)",
        "revertmerge": "بی لوئه",
        "searchall": "همه",
        "showingresults": "نمائشت بیشترونه {{PLURAL:$1|'''۱''' نتیجه|'''$1''' نتیجه}} د هار، شرو د شماره'''$2'''.",
        "showingresultsinrange": "نمائشت بیشترونه {{PLURAL:$1|'''۱''' نتیجه|'''$1''' نتیجه}} د هار، شرو د شماره'''$2''' تا شماره '''$3'''.",
-       "showingresultsheader": "{{PLURAL:$5|نتيجه '''$1''' د'''$3'''|نتيجه يا '''$1 - $2''' د'''$3'''}} سيli'''$4'''",
+       "search-showingresults": "{{PLURAL:$4|نتیجه یا<strong>$1</strong> د <strong>$3</strong>|نتیجه یا<strong>$1 - $2</strong د <strong>$3</strong>}}",
        "search-nonefound": "هیژ نتیجه یی سی پی جست تو مطاوقت نکرده",
        "powersearch-legend": "پی جوری پیشبرده",
        "powersearch-ns": "نوم جايا نوم ديار بگرد:",
        "youremail": "ايميل:",
        "username": "{{جنس:$1|نوم کاروری}}:",
        "prefs-memberingroups": "{{جنس:$2|اندوم}}  {{جمی:$1|گرویا|گرویا}}:",
+       "prefs-memberingroups-type": "$1",
        "prefs-registration": "موقع ثوت نام:",
+       "prefs-registration-date-time": "$1",
        "yourrealname": "نوم راستكی:",
        "yourlanguage": "زون:",
        "yourvariant": "محتوا آلشتگر زون:",
        "saveusergroups": "اماییه کردن گرویا کاریاری",
        "userrights-groupsmember": "اندوم:",
        "userrights-groupsmember-auto": "اندوم ضمنی:",
+       "userrights-groupsmember-type": "$1",
        "userrights-groups-help": "شما می تونیت دسه یای که ای کاریار ها دشو آلشت بئیتو:\n* جعوه نشودار وه ای مئنیه که کاریار ها د او دسه.\n* جعوه بی نشون وه ای مئنیه که کاریار د او دسه نئ.\n* نشون* د ای مئنیه که ار شما او دسه نه اضاف بکیتو د نهاتر نموئه ؤردارینش یا برعسگش.",
        "userrights-reason": "دليل:",
        "userrights-no-interwiki": "شما سی ویرایشت حقوق کارور د ویکی یا هنی دسرسی ناریت.",
        "userrights-notallowed": "شما سی اضاف کردن  حقوق کارور یا ورداشتنش دسرسی ناریت.",
        "userrights-changeable-col": "گرویایی که شما تونیت ویرایشت بکید",
        "userrights-unchangeable-col": "گرویایی که شما نتونیت ویرایشت بکید",
+       "userrights-irreversible-marker": "$1*",
        "userrights-conflict": "تعارض دسرسیا کاریاری! لطف بکیت یه گل وارسی انجوم بئیت و آلشتانه پشت راس بکیت.",
        "userrights-removed-self": "شما د خوئی حقوق خوتونه ؤرداشتیته، چی یه که مثلا شما تر نمی تونیت وه ای بلگه دسرسی داشتویت.",
        "group": "گرو",
        "recentchanges-label-plusminus": "انازه بلگه وه شمار ای بایتیا آلشت کرده.",
        "recentchanges-legend-heading": "'''میراث:'''",
        "recentchanges-legend-newpage": "{{int:recentchanges-label-newpage}} (همچنو بوینیت [[ویجه:بلگیا تازه|نوم گه بلگیا تازه]])",
+       "recentchanges-legend-plusminus": "(<em>±123</em>)",
        "rcnotefrom": "د هار آلشتیا د $2 هیئن(د بال د $1 نشون دئه بیه)",
        "rclistfrom": "آلشتیا تازه ایی که وا $3 $2 شرو بیه نشونش بئه",
        "rcshowhideminor": "ويرايشتيا کؤچک $1",
        "minoreditletter": "م",
        "newpageletter": "ن",
        "boteditletter": "ب",
+       "unpatrolledletter": "!",
        "number_of_watching_users_pageview": "[$1 دینه {{جمی:$1|کاریار|کاریاریا}}]",
        "rc_categories": "دسه یا نه محدود کو(وا \"|\" جگا بوئن",
        "rc_categories_any": "هرکوم",
+       "rc-change-size": "$1",
        "rc-change-size-new": "$1 {{جمی:$1|بایت|بایتیا}} نها آلشت",
        "newsectionsummary": "/* $1 */ بخش تازه",
        "rc-enhanced-expand": "جزيات نشون بيئه",
        "backend-fail-create": "نبوئه د جانیا\"$1\" نوشته با.",
        "backend-fail-maxsize": "نبوئه ری جانیا $1 دونسمنیایی نی سن سی یه که گپتر د{{PLURAL:$2|به بایت|$2 بایت}} ئه.",
        "backend-fail-readonly": "حامین «$1» د ایسنی د حال و بار فقط حننیه.دلیل دئه بیه ینه: «$2»",
+       "backend-fail-synced": "جانیا «$1» ها د حامین داریا اماییه بیه مینونه دار که حال و بارش لیزنگرته یه.",
+       "backend-fail-connect": "وا حامین دار اماییه «$1» ارتواط جاگیری نبی.",
+       "backend-fail-internal": "خطا نادیاری د حامین دار اماییه «$1»  پیش اوما.",
+       "backend-fail-contenttype": "دیارکرد نوع مینونه جانیا سی اماییه «$1» د انجومشیو بی.",
+       "backend-fail-batchsize": "یه گل دسه مینونه دار $1 {{PLURAL:$1|انجومگری|انجومگری}} جانیا وه حامین اماییه دئه بیه؛ بیشترونه مجاز $2 {{PLURAL:$2|انجومگر|انجومگر}} ئه.",
+       "backend-fail-usable": "امکان حنن یا نیسنن جانیا $1 وجود ناشت سی یه که ری تراز دسرسی خو نئ یا لشک/اماییه دار حاستنی نیئش.",
+       "filejournal-fail-dbconnect": "امکان وصل بیئن د رسینه گا نوشتگه سی حامین داری د اماییه کاری «$1» وجود ناشت.",
+       "filejournal-fail-dbquery": "امکان وصل بیئن د رسینه گا نوشتگه سی حامین داری د اماییه کاری «$1» وجود ناشت.",
        "lockmanager-notlocked": "نبوئه قلف $1 نه وا بکیت؛ سی یه که وه قلف نبیه.",
        "lockmanager-fail-closelock": "نبوئه قلف جانیا سی \"$1\" بسه بوئه.",
        "lockmanager-fail-deletelock": "نبوئه قلف جانیا سی \"$1\" پاکسا بوئه.",
        "lockmanager-fail-acquirelock": "نبوئه سی «$1» قلف وه دس اورد.",
        "lockmanager-fail-openlock": "نبوئه قلف جانیا سی \"$1\" وا بوئه.",
        "lockmanager-fail-releaselock": "نبوئه قلف «$1» نه وا کرد .",
+       "lockmanager-fail-db-bucket": "امکان ارتواط خو وا رسینه گا قلفیا د اماییه دار $1 وجود ناشت.",
+       "lockmanager-fail-db-release": "نبوئه قلفیا سرور $1 نه وا بکیت.",
        "lockmanager-fail-svr-acquire": "نبوئه سی «$1» قلف وه دس اورد.",
        "lockmanager-fail-svr-release": "نبوئه قلفیا سرور $1 نه وا بکیت.",
+       "zip-file-open-error": "د گات واکردن جانیا زیپ سی وارسی مینونه ش یه گل خطا پیش اومائه.",
        "zip-wrong-format": "جانیا تیار بیه جانیا زیپ نئ.",
+       "zip-bad": "جانیا زیپ خرؤ یا حننی نئ.\nنبوئه مینونه شه د لحاظ امنیتی وه خوئی وارسی کرد.",
+       "zip-unsupported": "جانیا زیپ چیایی نه وه کار بسه که ویکی وارسگر حامین دارشو نئ.\nنبوئه مینونه ونه د لحاظ امنیتی وه خوئی وارسی کرد.",
        "uploadstash": "اماییه جا سوارکرد",
+       "uploadstash-summary": "ای بلگه سی دسرسی وه جانیایایی یه  که سوار بینه(یا د حالت سوارکردن) ولی تا ایسه د ویکی درتیچ نبینه.ای جانیایا فقط وا کاریاریایی که ونونه سوارکردنه قاول دیئن هئن.",
        "uploadstash-clear": "پاک کردن جانیایا اماییه بیه",
        "uploadstash-nofiles": "شما هیژ جانیا اماییه بیه ای ناریت.",
+       "uploadstash-badtoken": "انجوم دئن ای کاریا د خوئی صورت نگرت، شایت سی یه با که اعتوار ویرایشت شما تموم بیه. هنی تلاش بکیت.",
        "uploadstash-errclear": "پاک کردن جانیایا د خوئی شکل نگرت.",
        "uploadstash-refresh": "نومه گه جانیایا نه د نو تازه کو",
        "invalid-chunk-offset": "جا وه جایی نامعتور برشت",
        "img-auth-accessdenied": "دسرسی منع بی",
+       "img-auth-nopathinfo": "PATH_INFO نیئش.\nسرور شما سی گواردن ای انازه میزونکاری نبیه.\n شات د پایه سی جی آی با و حامین دار img_auth نبا.\nhttps://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Image_Authorization سیل بکیت.",
+       "img-auth-notindir": "مسیر حاسته بیه د لشک سوارکرد میزونکاری بیه نئ.",
+       "img-auth-badtitle": "امکان راس کردن یه سرون مجازی د «$1» وجود ناره.",
+       "img-auth-nologinnWL": "شما هنی نیومایته وامین و «$1» د نوم گه اسبئ نیئش.",
        "img-auth-nofile": "فایل $1 وجود ناره.",
+       "img-auth-isdir": "شما سی رسسن وه لشگ «$1» تلاش کردیته.\nتئنا می تونیت وه جانیا دسرسی داشتویت.",
        "img-auth-streaming": "د حال کل کردن \"$1\".",
+       "img-auth-public": "آلشت ون img_auth.php درده ای د جانیایا یه گل ویکی خصوصیه.\nای ویکی وه عنوان یه گل ویکی خلک من میزونکاری بیه.\nسی امنیت خوتر، img_auth.php ناکنشتگر بیه.",
        "img-auth-noread": "کاریار وه حنن «$1» دسرسی ناره.",
        "http-invalid-url": "یو آر ال نامعتور:$1",
+       "http-invalid-scheme": "تیرنشونیا اینترنتی وا شمایه «$1» حامین داری نبوئن.",
+       "http-request-error": "درحاست اچ تی تی پی سی یه گل خطا نادیار، انجومشیو بیه.",
        "http-read-error": "خطا د حنن اچ تی تی پی.",
        "http-timed-out": "گات حاستن اچ تی تی پی وه سر اوما.",
        "http-curl-error": "خطا د اوردن تیرنشون اینترنتی: $1",
        "http-bad-status": "د گات حاستن اچ تی تی پی  خطایی پیش اوما: $1 $2",
        "upload-curl-error6": "نبوئه د یو آر ال برسیت",
+       "upload-curl-error6-text": "تیرنشون اینترنتی که دئیته د دسرس نئ.\nلطف بکیت درستیشه و یه نه که تیرنشون اینترنی میزونکاری بیه وارسی بکیت.",
        "upload-curl-error28": "تموم بیئن مئلت سی سوار کرد",
+       "upload-curl-error28-text": "ای دیارگه فره دیر دتو واکنشت نشو دئه.\nلطف بکیت سی یه که دیارگه کنشگتر و ری خطه یه گل وارسی بکیت، اوسه یه گر واستید و هنی تلاش بکیت.\nشایت بیتر با که د گات خلوتری هنی تلاش بکیت.",
        "license": "ليانس دار بيئن",
        "license-header": "د شكل ليسانس دار بيئن",
        "nolicense": "هیچی انتخاو نبیه",
        "filehist-comment": "نظر",
        "imagelinks": "استفاده د فايل",
        "linkstoimage": "دمال بيه {{PLURAL:$1|ديس ونيا بلگه|$1 ديس ون بلگيا}} دای فایل:",
+       "linkstoimage-more": "بیشتر د $1 بلگه د ای جانیا هوم پیوند {{PLURAL:$1|بیه|بینه}}.\nنومگه هاری تئنا {{PLURAL:$1|اولین هوم پیوند|اولین $1 هوم پیوند}} د ای بلگه نه نشو می ئه.\n[[Special:WhatLinksHere/$2|نومگه کامل]] ئم هیئش.",
        "nolinkstoimage": "ایچه هیژ بلگه ای سی هوم پیوند بیئن وا ای فایل نی",
        "morelinkstoimage": " [[ویجه:چه هوم پیوندی ها ایچه/$1|هوم پیوندیا هنی]]سی ای جانیا نه بونیت.",
        "linkstoimage-redirect": "$1 (واگردونی جانیا) $2",
+       "duplicatesoffile": "{{PLURAL:$1|جانیا|جانیایا}} هاری نسقه تکراری ای جانیا {{PLURAL:$1|هئ|هئن}} ([[Special:FileDuplicateSearch/$2|دونسمنیا هنی]]):",
        "sharedupload": "ای جانیا که د $1 هئ شایت د پروجه یا هنی استفاده بیه.",
+       "sharedupload-desc-there": "ای جانیا ها د $1و شایت د پروجه یا هنی وه کار گرته بوئه.\nسی دونسمنیا هنی لطفن [$2 بلگه توضیحیا جانیا] نه سیل بکیت.",
        "sharedupload-desc-here": "فایلی که د $1 شایت د مئن پروجیا هنی استفاده بیه.\nتوضی دباره[$2 file description page] د هار نشو دئئه بیه",
+       "sharedupload-desc-edit": "ای جانیا د $1 ئه و می تونه د پروجه یا هنی وه کار گرت بوئه.\nار حاستیت می تونیت توضیحیا حانیا نه د [$2 بلگه توضیحیا خوش] د اوچه ویرایشت بکیت.",
+       "sharedupload-desc-create": "ای جانیا د $1 ئه و می تونه د پروجه یا هنی وه کار گرت بوئه.\nار حاستیت می تونیت توضیحیا حانیا نه د [$2 بلگه توضیحیا خوش] د اوچه ویرایشت بکیت.",
        "filepage-nofile": "چنو فایلی وا ای نوم نئ.",
+       "filepage-nofile-link": "جانیایی د ای نوم نیئش، اما شما تونیت ونه د [$1 سوار بکیت].",
        "uploadnewversion-linktext": "یه گل نسقه تازه د ای جانیا سوار بکید",
        "shared-repo-from": "د $1",
        "shared-repo": "یه گنجینه هومبئر",
        "upload-disallowed-here": "شما نمی تونیت ای جانیانه د نو سوار بکیت",
        "filerevert": "د سرگرتن سی $1",
        "filerevert-legend": "د سرگرتن جانیا",
+       "filerevert-intro": "شما د حال و بار لرسن'''[[Media:$1|$1]]''' وه [$4 نسقه ای که ها د ویرگار$2 ساعت $3] هیئت.",
        "filerevert-comment": "دليل:",
+       "filerevert-defaultcomment": "لرسن وه نسقه $1 ساعت $2",
        "filerevert-submit": "ورگنین",
+       "filerevert-success": "''[[Media:$1|$1]]''' وه[$4 نسقه ای که ها د ویرگار$2 ساعت $3] لرسه بی.",
+       "filerevert-badversion": "نسقه دماتری د ای نسقه وجود ناشت.",
        "filedelete": "$1 پاکسا کو",
        "filedelete-legend": "فایل نه پاک کو",
+       "filedelete-intro": "شما د حال و بار پاکسا کردن جانیا'''[[Media:$1|$1]]''' وا تموم ویرگارچه وه هیئت.",
+       "filedelete-intro-old": "شما د حال و بار پاکسا کردن نسقه'''[[Media:$1|$1]]''' که ها د ویرگار[$4 $2 ساعت $3] هیئت.",
        "filedelete-comment": "دليل:",
        "filedelete-submit": "پاكسا كردن",
        "filedelete-success": "$1 پاکسا بیه.",
+       "filedelete-success-old": "نسقه'''[[Media:$1|$1]]''' که ها د ویرگار $2 ساعت $3 پاکسا بیه.",
        "filedelete-nofile": "'''$1''' وجود ناره.",
+       "filedelete-nofile-old": "نسقه مال دیاری  بیه ای د '''$1''' وا چیا دئه بیه، وجود ناره.",
        "filedelete-otherreason": "دلیل هنی:",
        "filedelete-reason-otherlist": "دليل هنی",
+       "filedelete-reason-dropdown": "* دلیلیا جاافتائه سی پاکسا کردن\n** تیه پوشی د کپی رایت\n** جانیا تکراری",
        "filedelete-edit-reasonlist": "دلیلیا پاک کردنه نه ویرایشت بکید",
+       "filedelete-maintenance": "پاکسا کردن و د نو زنه کردن د گات واداشتن تقریبا ناکشتگر بیه.",
        "filedelete-maintenance-title": "نبوئه ای فایل پاکسا بوئه",
        "mimesearch": "پی جوری ام آی ام ای",
+       "mimesearch-summary": "وا هومیاری ای بلگه شما می تونیت جانیایایی که حال و بارMIME ویجه ای دارن نه بجوریت.\nدرینده: وه شکلcontenttype/subtype یا contenttype/*&lrm;، چی <code>image/jpeg</code>.",
        "mimetype": "نوع MIME:",
        "download": "گرتن",
        "unwatchedpages": "بلگه یا ندئیه بیه",
        "listredirects": "نوم گه واگردونیا",
        "listduplicatedfiles": "نومگه همه جانیایا واگرد دواره اومائه یا",
+       "listduplicatedfiles-summary": "ای نومگه د جانیایا وا نسقه یا ایسنی ای جانیا تکراریه که نسقه یا ایسنی جانیایا هنیه. فقط جانیایا ولات نشین هان د ویر و باور ایما.",
+       "listduplicatedfiles-entry": "[[:جانیا:$1|$1]][[$3|{{PLURAL:$2|یه گل تکرار|$2 تکرار}}]] داره.",
        "unusedtemplates": "قالویا وه کار نبرده بیه.",
+       "unusedtemplatestext": "ای بلگه همه بلگه یایی که هان د نومجا {{ns:template}}و د هیچ بلگه ای وه کار گرته نبینه، نوم بنی می که.\nد ویرتو با که دما یه که بهایت بلگه یا هوم پیوند هنی نه پاکسا بکیت دشو وارسی ای انجوم بئیت.",
        "unusedtemplateswlh": "هوم پیوندیا هنی",
        "randompage": "بلگه بختكی",
+       "randompage-nopages": "هیچ بلگه ای د ای {{PLURAL:$2|نومجا|نومجایا}}  نئ:$1.",
        "randomincategory": "بلگه بختی د ای دسه",
        "randomincategory-invalidcategory": "\"$1\"  نوم دسه معتوری نئ.",
        "randomincategory-nopages": "هیچ بلگه ای د ای  [[:دسه نئ:$1|$1]] دسه.",
        "randomincategory-category": "دسه:",
        "randomincategory-legend": "بلگه بختی د ای دسه",
        "randomredirect": "واگردونی بختکی",
+       "randomredirect-nopages": "هیچ واگردونی د نومجا \"$1\" نئ.",
        "statistics": "آماريا",
        "statistics-header-pages": "بلگه آماریا",
        "statistics-header-edits": "آماریا نه ویرایشت بکید",
        "statistics-pages": "بلگیا",
        "statistics-pages-desc": "همه بلگه یا د ویکی،د ور گیرنه بلگه یا چک چنه،واگردونیا و چیا هنیه.",
        "statistics-files": "جانیا یا سوار بیه",
+       "statistics-edits": "ویرایشت بلگه یا د گاتی که  {{SITENAME}} دروس بیه",
        "statistics-edits-average": "میانگین ویرایشت یا سی هر بلگه",
        "statistics-views-total": "همه نه بوینیت",
+       "statistics-views-total-desc": "دیئن بلگه یایی که وجود نارن و بلگه یا ویجه د ور گرته نئ",
        "statistics-views-peredit": "هر ویرایشت نه بوینیت",
        "statistics-users": "ثوت نام بیه [[ویجه:نوم گه کاریاریا|کاریاریا]]",
        "statistics-users-active": "کاروریا کارکو",
+       "statistics-users-active-desc": "کاریاریایی که د {{PLURAL:$1|رو|$1 رو}} دماتر کنشتگر بینه",
        "statistics-mostpopular": "بلگه یایی که بیشتر دیئه بینه",
        "pageswithprop": "بلگه یایی که خاصیت صفحه ها دشو",
        "pageswithprop-legend": "بلگه یایی که خاصیت صفحه ها دشو",
+       "pageswithprop-text": "ای بلگه نومگه ای یه د بلگه یایی که یه گل ویجه گی د یه بلگه خاص نه وه کار می بنن.",
        "pageswithprop-prop": "نوم خاصیت:",
        "pageswithprop-submit": "رو",
+       "pageswithprop-prophidden-long": "جزییات قام بیه یه گل نیسه دراز($1)",
+       "pageswithprop-prophidden-binary": "جزییات انازه قام بیه دوتا دوتایی ($1)",
        "doubleredirects": "واگردونیا دوتایی",
+       "doubleredirectstext": "ای بلگه نومگه ای د بلگه واگردونی نه نشو می یه که وه یه گل بلگه واگردونی هنی هشاره می کن.\nهر خط مینونه دار هوم پیوندیا واگردونی اول و دویم و همچنو مقصد واگردونی دویمه، که معمولند بلگه مقصد راستکی یه و اولین واگردونی واس د وه هشاره بکه.\nچیا <del>خط حرده</del> دروس بینه.",
        "double-redirect-fixed-move": "[[$1]]جا وه جا بیه .\nوه خودکارونه وه روز بیه و ایسه وه د[[$2]] واگردونی بیه.",
+       "double-redirect-fixed-maintenance": "برطرف بیین خودانجوم دوتای د [[$1]] وه [[$2]] د مسیر واداشت.",
        "double-redirect-fixer": "تعمیر کننه واگردونی",
        "brokenredirects": "واگردونیا بی سرانجوم",
        "brokenredirectstext": "واگردونیا نهاتر د بلگه یایی که وجود نارن هوم پیوند بینه.",
        "ntransclusions": "$1 {{جمی:$1|بلگه|بلگيا}} استفاده بیه",
        "specialpage-empty": "نتیجه ای د ای گزارشت نئ.",
        "lonelypages": "بلگه یا تک منه",
+       "lonelypagestext": "د بلگه یا هاری هیچ بلگه هنی د {{SITENAME}} هوم پیوند نبیه و د هیچ بلگه هنی مین چین نبیه.",
        "uncategorizedpages": "بلگه یا دسه بنی نبیه",
        "uncategorizedcategories": "دسه یا دسه بنی نبیه",
        "uncategorizedimages": "فایلیا دسه بنی نبیه",
        "popularpages": "بلگه یا حاستنی",
        "wantedcategories": "بلگه یا حاستنی",
        "wantedpages": "بلگه یا حاستنی",
+       "wantedpages-badtitle": "سرون نامعتور د کومله نتیجه یا:$1",
        "wantedfiles": "فایلیا حاستنی",
+       "wantedfiletext-cat": "جانیایا هاری وه کار گرته بوئن ولی وجود نارن. همچنو شایت جانیایا وه دری وا یه که ایچه هیئشون نومگه کاری بینه.هر گرینج مثبت دورویی  <del>خط مئوره.</del> به اضافه یه، بلگه یایی که که جانیایا بی وجودن نه د خوشو دارن د [[:$1]] نومگه کاری بینه.",
+       "wantedfiletext-cat-noforeign": "جانیایا هاری وه کار گرته بوئن ولی نیئشو. اضافه وه یه بلگه یایی که جانیایا نادیار د خوشو دارن هان د [[:$1]].",
+       "wantedfiletext-nocat": "جانیایا هاری که وه کار گرته بوئن نیئشو. همچنو شایت جانیا اماییه داریا خارجی وه شرطی که بان وه کار گرته بوئن. هر گرینج خو ولی الکی <del> خط مئوره. <del>",
+       "wantedfiletext-nocat-noforeign": "جانیایا هاری وه کار گرته بوئن ولی نیئشو.",
        "wantedtemplates": "قالویا حاستنی",
        "mostlinked": "بلگه یا که بیشتر هوم پیوند بینه",
        "mostlinkedcategories": "دسه یایی که بیشتر هوم پیوند بیه",
        "mostinterwikis": "بلگه یایی که بیشتری مینجا ویکی نه دارن",
        "mostrevisions": "بلگه یایی که بیشتری وانئری نه دارن",
        "prefixindex": "همه بلگيا وا پيشون",
+       "prefixindex-namespace": "تموم بلگه یا وا دماون(نومجا $1)",
+       "prefixindex-strip": "پاکسا کردن دماون د نومگه",
        "shortpages": "بلگه یا کؤچک",
        "longpages": "بلگه یا گپ",
        "deadendpages": "بلگه یا نابود بیئنی",
+       "deadendpagestext": "بلگه یا هاری وه هیچ بلگه هنی د {{SITENAME}} هوم پیوند نبینه.",
        "protectedpages": "بلگه یا حفاظت بيه",
+       "protectedpages-indef": "فقط پر و پیم بیین یا بی زمون",
+       "protectedpages-summary": "د ای بلگه نومگه بلگه یایی هیئن که د ایسنی پر و پیم بینه. سی نومگه سرونیا که نبوئه دروس بان، سیل[[{{#special:ProtectedTitles}}|{{int:protectedtitles}}]]  بکیت.",
+       "protectedpages-cascade": "فقط پر و پیم بیین تافنمایی",
        "protectedpages-noredirect": "واگردونیا قام بیه",
+       "protectedpagesempty": "د ایسنی هیچ بلگه ای پر و پیم نبیه.",
        "protectedpages-timestamp": "سردیس گات",
        "protectedpages-page": "بلگه",
        "protectedpages-expiry": "تموم بیه آ",
        "protectedpages-performer": "کارور حفاظت بیه",
+       "protectedpages-params": "پارامتریا پر و پیم کردن",
        "protectedpages-reason": "دلیل",
        "protectedpages-unknown-timestamp": "ناشناس",
        "protectedpages-unknown-performer": "کارور ناشناس",
+       "protectedtitles": "سرونیا پر و پیم بیه",
+       "protectedtitles-summary": "د ای بلگه نومگه بلگه یایی هیئن که د ایسنی پر و پیم بینه. سی نومگه سرونیا که نبوئه دروس بان، سیل[[{{#special:ProtectedTitles}}|{{int:protectedtitles}}]]  بکیت.",
+       "protectedtitlesempty": "د ایسنی هیچ سرونی وا ای پارامتریا پر و پیم نبیه",
        "listusers": "نوم گه کارور",
        "listusers-editsonly": "فقط کاروریایی که ویرایشت می کن نشو بیه",
        "listusers-creationsort": "سرجاخودگری د اساس گات دروس بیین",
        "ancientpages": "بلگه یا نهاتر",
        "move": "جاوه جا بوئيت",
        "movethispage": "ای بگله نه جا وه جا كو",
+       "unusedcategoriestext": "ای دسه یا هیئشو ولی د ایسنی هیچ گوتار یا دسه ای ونونه وه کار نمی بنه.",
        "notargettitle": "رسینه جایی نئ",
+       "notargettext": "شما بلگه یا کاریاری مقصدی سی انجوم دئن ای کنشت ریش انتخاو نکردیته.",
        "nopagetitle": "چنی بلگه ای نیئش",
+       "nopagetext": "بلگه حاستنی که شما دیاری کردیته وجود ناره.",
        "pager-newer-n": "{{جمی:$1|وانها تر 1وانها تر $1}}",
        "pager-older-n": "{{جمی:$1|گپسالتر 1|گپسالتر $1}}",
        "suppress": "پائیئن",
+       "querypage-disabled": "ای بلگه ویجه سی دلیلیا انجومکاری ناکشتگر بیه.",
        "booksources": "سرچشمه يل كتاو",
        "booksources-search-legend": "پی جوری سی سرچشمه یا کتاو",
+       "booksources-isbn": "آی اس بی ان:",
        "booksources-go": "رو",
        "specialloguserlabel": "انجومکار:",
        "speciallogtitlelabel": "حاستنی(موضوع یا کاریار):",
        "log": "نیسنن رخ ونیا",
        "all-logs-page": "همه پهرستنومه یا عمومی",
+       "logempty": "او چی ای که شما میهایت د پهرستنومه نیئش.",
+       "log-title-wildcard": "بلگه یایی نه پی جوری کو که وا ای سرون شرو موئن",
        "showhideselectedlogentries": "آلشت دئن ورتیه گر پهرستنومه یا انتخاو بیه",
        "allpages": "همه بلگيا",
        "nextpage": "بلگه نهایی($1)",
        "allpagesbadtitle": "عنوان بلگه حاسته بیه معتور نی،یا  یه گل مئن زونی یا مئن ویکی عنوان غلطه.\nیه شایت شومل یکی با یا بیشتر کاراکتریا نبوئه که سی ای موضوعیا استفاده بوئن",
        "allpages-bad-ns": "{{نوم دیارگه}} د ای نوم جا نئ \"$1\".",
        "allpages-hide-redirects": "واگردونیا قام بیه",
+       "cachedspecial-viewing-cached-ttl": "شما د حال و بار دیئن یه گل نسقه ای د ای بلگه که ها د مینجاگیر هیئت که شایت سی $1 دماتر با.",
        "cachedspecial-refresh-now": "دیئن آخری.",
        "categories": "دسه يا",
        "categoriesfrom": "دسه یایی که د شرو بینه نشو بیه:",
        "listusers-noresult": "هیچ کاروری پیدا نبی",
        "listusers-blocked": "(قلف بيه)",
        "activeusers": "نوم گه کاروریا کارکو",
+       "activeusers-count": "$1 {{PLURAL:$1|کنشت|کنشت}} در {{PLURAL:$3|رو|$3 رو}} دماتر",
        "activeusers-from": "کاریاریایی که د شرو بینه نشو بیه:",
        "activeusers-hidebots": "بوتیا قام کو",
        "activeusers-hidesysops": "دیوون داریا نه قام کو",
        "listgrouprights-rights": "حقوقیا",
        "listgrouprights-helppage": "هومیاری:حقوق گرو",
        "listgrouprights-members": "(نوم گه اندومیا)",
+       "listgrouprights-right-display": "<span class=\"listgrouprights-granted\">$1 <code>($2)</code></span>",
+       "listgrouprights-right-revoked": "<span class=\"listgrouprights-revoked\">$1 <code>($2)</code></span>",
        "listgrouprights-addgroup": "{{جمی:$2|گرویا|گرویا}} اضاف بکیتو: $1",
        "listgrouprights-removegroup": "{{جمی:$2|گرویا|گرویا}} ورداریت: $1",
        "listgrouprights-addgroup-all": "همه گرویا نه اضاف کو",
        "listgrouprights-removegroup-self": "{{جمی:$2|گرویا|گرویا}} نه د حساو ورداریت: $1",
        "listgrouprights-addgroup-self-all": "همه گرویا نه د حساو خوشو اضاف بکیت",
        "listgrouprights-removegroup-self-all": "همه گرویا نه د حساو خوشو ورداریت",
+       "listgrouprights-namespaceprotection-header": "محدودیت نومجا",
        "listgrouprights-namespaceprotection-namespace": "نوم جا",
+       "listgrouprights-namespaceprotection-restrictedto": "دسرسیا مجاز کاریار سی ویرایشت",
        "trackingcategories": "دما گری دسه یا",
        "trackingcategories-msg": "دماگری دسه",
        "trackingcategories-name": "نوم پیغوم",
+       "trackingcategories-desc": "جادیارکنیا گنجایشت دسه",
+       "trackingcategories-nodesc": "هیچ شرحی د دسرس نئ.",
        "trackingcategories-disabled": "دسه ناکشتگر بیه",
        "mailnologin": "هیپچ نشونی یی کل نبیه",
        "emailuser": "ای كارور نه ايميل كو",
        "emailpage": "ایمیل کارور",
        "defemailsubject": "{{نوم سیل جا}} ایمیل د کارور \"$1\"",
        "usermaildisabled": "ایمیل کارور د کار افتائه",
+       "usermaildisabledtext": "شما نمی تونیت سی کاریار هنی د ای ویکی انجومانامه کل بکیت",
        "noemailtitle": "هیچ نشونی ایمیلی نئ",
+       "noemailtext": "ای کاریار تیرنشون انجومانامه خووی ناره.",
+       "nowikiemailtext": "ای کاریار میها که د کاریاریا هنی انجومانامه نگره.",
+       "emailnotarget": "نوم کاریاری که وجود ناره یا سی گیرنه نامعتوره",
        "emailtarget": "یه گل نوم کاریاری سی پذریشتگر وارد بکیت",
        "emailusername": "نوم كاروری:",
        "emailusernamesubmit": "دئن",
+       "email-legend": "کل کردن یه گل انجومانامه سی یه گل کاریار هنی د {{SITENAME}}",
        "emailfrom": "د:",
        "emailto": "سی:",
        "emailsubject": "سرون:",
        "emailsenttext": "پیغوم ایمیلی تو کل بیه.",
        "usermessage-summary": "رئتن د سامونه پیغوم",
        "usermessage-editor": "پیغوم فرسن سیستم",
+       "usermessage-template": "ویکی وارسگر:پیغوم کاریار",
        "watchlist": "سیل برگ",
        "mywatchlist": "سیل برگ",
        "watchlistfor2": "سي $1 $2",
        "nowatchlist": "شما هیچی د سیل برگ خوتو ناریت",
+       "watchlistanontext": "لطفن بیایت وامین و ویرایشتیا نه د سیل برگتو سیل بکیت.",
        "watchnologin": "وارد نبیه",
        "addwatch": "اضاف کردن د سیل برگ",
+       "addedwatchtext-short": "بلگه \"$1\" وه سیل برگ شما اضاف بیه.",
        "removewatch": "جا وه جا کردن د سیل برگ",
        "removedwatchtext": "بلگه\"[[:$1]]\" د [[Special:سیل برگ|سیل برگ خوتو]] جا وه جا بیه.",
        "removedwatchtext-short": "بلگه \"$1\" د سیل برگ جا وه جا بیه.",
        "unwatchthispage": "واداشتن دیئن",
        "notanarticle": "مینونه هیچ بلگه ای نئ",
        "notvisiblerev": "آخری وانئری که د دس یه کاریار هنی انجوم بیه پاکسا بیه.",
-       "watchlist-details": "{{جمی:$1|$1 بلگه|$1 بلگیا}} د سیل برگتو هیش بلگه قسه کردن نی .",
+       "watchlist-details": "{{جمی:$1|$1 بلگه|$1 بلگیا}} د سیل برگتو هیش بلگه قسه کردن نی.",
        "wlheader-enotif": "وارسیاری ایمیل فعال بیه.",
        "wlheader-showupdated": "بلگه یایی که د آخرین کرتی که شما دشو دیئن کردیته آلشت بینه د <strong>توپر</strong>نشون دئه بینه",
+       "wlnote": "د هار {{PLURAL:$1|آلشت|<strong>$1</strong> آلشتی}} که د {{PLURAL:$2|ساعت|<strong>$2</strong> ساعت}} دماتر انجوم بیه هیئش، ویرگار آخرین واجوری انجام شده موجود است، ویرگار آخری واجوری: $3، $4",
        "wlshowlast": "آخرین$1 ساعتیا $2و روزیا $3 نشو بیئه",
        "watchlist-options": "گزینیا سیل برگ",
        "watching": "د حال دیئن...",
        "unwatching": "د حال ندیئن...",
        "enotif_reset": "همه بلگه یا دیئه بینه نشودار بکید",
        "enotif_impersonal_salutation": "{{نوم سیلجا}} کارور",
+       "enotif_subject_deleted": "{{SITENAME}} بلگه$1 وه دس{{gender:$2|$2}} پاکسا بیه.",
+       "enotif_subject_created": "{{SITENAME}} بلگه$1 وه دس{{gender:$2|$2}} دروس بیه.",
+       "enotif_subject_moved": "{{SITENAME}} بلگه$1 وه دس{{gender:$2|$2}} جا وه جا بیه.",
+       "enotif_subject_restored": "{{SITENAME}} بلگه$1 وه دس{{gender:$2|$2}} د نو زنه بیه.",
+       "enotif_subject_changed": "{{SITENAME}} بلگه$1 وه دس{{gender:$2|$2}} آلشت بیه.",
        "enotif_lastvisited": "همه آلشتیا$1 د اوسه که شما د آخرین بار دیئته بوینیت.",
+       "enotif_lastdiff": "سی دیئن ای آلشتیا $1 نه سیل بکیت.",
        "enotif_anon_editor": "کارو ناشناس$1",
+       "created": "دروس بیه",
+       "changed": "آلشت بیه",
        "deletepage": "پاک کردن بلگه",
        "confirm": "مئكم كردن",
        "excontent": "مینونه :\"$1\" بی",
        "actioncomplete": "عملكرد كامل بيه",
        "actionfailed": "عملكرد شكست حرده",
        "dellogpage": "لاگ پاك كردن",
+       "dellogpagetext": "نومگه هاری یه گل نومگه د آخری چیا پاکسا بیه هئ.",
        "deletionlog": "پهرستنومه پاک بیئن",
+       "reverted": "لرسه د نزیکترین وانئری",
        "deletecomment": "دليل:",
        "deleteotherreason": "دليليا هنی:",
        "deletereasonotherlist": "دلیل هنی",
        "deletereason-dropdown": "* دلیلیا پاکسا کردن رسم بیه\n** اسپم\n** خراوکاری\n** رعایت نبین کپی رایت\n** درحاست نیسنه\n** نهاورگشت شکست حرده",
        "delete-edit-reasonlist": "دلیلیا پاکسا کردنه نه ویرایشت بکید",
+       "deleteprotected": "شما نمی تونیت ای بلگه نه پاکسا بکیت سی یه که وه پر و پیم بیه.",
        "rollback": "چواشه کردن ویرایشتیا",
        "rollback_short": "چواشه کردن",
        "rollbacklink": "ورگشتن",
+       "rollbacklinkcount": "چواشه کردن $1 {{PLURAL:$1|ویرایشت|ویرایشتیا}}",
+       "rollbacklinkcount-morethan": "چواشه کردن بیشتر د$1 {{PLURAL:$1|ویرایشت|ویرایشتیا}}",
        "rollbackfailed": "چواشه کردن د خوئی انجوم نبی",
        "editcomment": "ویرایشت چکشه وه: \"''$1''\" بی.",
        "sessionfailure-title": "شکست حردن نشینگه",
        "protectedarticle": "حفاظت بيه [[$1]]",
        "modifiedarticleprotection": "ریتراز حفاظت د \"[[$1]]\" آلشت بیه",
        "protect-title": "ریتراز حفاظت د \"$1\" آلشت بیه",
+       "protect-title-notallowed": "دیئن ریتراز پر و پیم \"$1\"",
        "prot_1movedto2": "[[$1]] د [[$2]] جا وه جا بی",
+       "protect-badnamespace-title": "نوم جا بی پر و پیم",
+       "protect-norestrictiontypes-title": "بلگه بی حامین گر",
+       "protect-legend": "پشت راس کردن حامین گری",
        "protectcomment": "دلیل:",
+       "protectexpiry": "تموم بين:",
+       "protect_expiry_invalid": "گات تموم بیین نامعتوره.",
+       "protect_expiry_old": "گات تموم بیین مال دماتره.",
        "protect-default": "همه کاروریا اجازه دارن",
+       "protect-level-sysop": "فقط دیوونداریا",
+       "protect-summary-desc": "[$1=$2] ($3)",
+       "protect-summary-cascade": "د حال و بال تافنمایی",
+       "protect-expiring": "گات تموم بیین $1 (یو تی سی)",
+       "protect-expiring-local": "گات تموم بیین $1",
+       "protect-expiry-indefinite": "بی زمون",
        "protect-othertime": "وخت هنی:",
        "protect-othertime-op": "گات هنی",
+       "protect-otherreason": "دلیل اضافی/هنی:",
        "protect-otherreason-op": "دلیل هنی",
+       "protect-edit-reasonlist": "دلیلا پر و پیم بیین ویرایشت",
        "protect-expiry-options": "1 ساعت:1 ساعت,1 روز:1 روز,1 هفته:1 هفته,2 هفته:2 هفته,1 ما:1 ما,3 ما:3 ما,6 ما:6 ما,1 سال:1 سال,بی حساو:بی حساو",
        "restriction-type": "دسرسی:",
+       "restriction-level": "ریتراز محدودیت:",
        "minimum-size": "انازه کمترونه",
        "maximum-size": "انازه بیشترونه",
        "pagesize": "(بایتیا)",
        "undelete": "دیئن بلگه یا پاکسا بیه",
        "undeletepage": "دیئن و  ؤرگشتن بلگه یا پاکسا بیه",
        "viewdeletedpage": "دیئن بلگه یا پاکسا بیه",
+       "undeletebtn": "د نو زنه کردن",
        "undeletelink": "بوين/دوواره آماده با",
        "undeleteviewlink": "ديئن",
+       "undeleteinvert": "انتخاو برعسك بوئه",
        "undeletecomment": "دليل:",
+       "undeletedfiles": "{{PLURAL:$1|1 جانیا|$1 جانیایا}} د نو زنه بیه",
        "cannotundelete": "زنه کردن انجوم نبی:$1",
        "undelete-search-title": "بلگه یا پاکسا بیه نه پی جوری کو",
        "undelete-search-box": "پی جوری بلگه یا پاکسا بیه",
        "undelete-search-submit": "پی جوری",
        "undelete-error-short": "خطا پاک نبیئن جانیا:$1",
        "undelete-show-file-submit": "هری",
+       "undelete-revision-row": "$1 $2 ($3) $4 . . $5 $6 $7 $8 $9",
        "namespace": "نوم جا:",
        "invert": "انتخاو برعسك بوئه",
        "blanknamespace": "اصلی",
        "whatlinkshere-hidelinks": "هوم پیوندیا $1",
        "whatlinkshere-hideimages": "فایل هوم پیوندیا $1",
        "whatlinkshere-filters": "فيلتريا",
+       "autoblockid": "خود نهاگری #$1",
        "block": "منع کارور",
-       "blockip": "منع کارور",
+       "unblock": "کاریار نهاگری نبیه",
+       "blockip": "نهاگری{{GENDER:$1|کاریار}}",
+       "blockip-legend": "نهاگری کاریار",
        "ipaddressorusername": "نوم نشون آی پی يا نوم كاروری:",
+       "ipbexpiry": "تموم بين:",
        "ipbreason": "دليل:",
+       "ipbcreateaccount": "نهاگری دروس کردن حساو",
        "ipbemailban": "نهاگرتن کاریار د کل کردن انجومانامه",
+       "ipbsubmit": "نهاگری ای کاریار",
        "ipbother": "وخت هنی:",
        "ipboptions": "2 ساعتیا:2 ساعت,1 رو:1 رو,3 روزا:3 رو,1 هفته:1 هفته,2 هفته یا:2 هفته,1 ما:1 ما,3 ما:3 میا,6 ما:6 مایا,1 سال:1سال,بی حساو:بی حساو",
        "ipbhidename": "نوم کاروری نه سی ویرایشت یا و نوم گه یا قام کو",
        "ipb-confirm": "پشت راس کردن قلف",
        "badipaddress": "تیرنشون نامعتور آی پی",
        "blockipsuccesssub": "قلف کردن د خوئی انجوم بی",
+       "ipb-edit-dropdown": "ویرایشت دلیلیا نهاگرتن",
+       "ipb-unblock-addr": "وا کردن قلف $1",
        "unblockip": "کارور منع نبیه",
        "ipusubmit": "ای قلف نه ؤردار",
        "blocklist": "كاروريا منع بيه",
        "ipblocklist": "كاروريا منع بيه",
        "ipblocklist-legend": "یه گل کارور منع بیه بجوریت",
+       "blocklist-userblocks": "قام کردن حساو قلف بیه",
        "blocklist-timestamp": "چسب ون وخت",
+       "blocklist-target": "مقصد",
+       "blocklist-expiry": "تموم بين",
+       "blocklist-by": "دیووندار نهاگیرنه",
+       "blocklist-params": "پارامتریا قلف کردن",
+       "blocklist-reason": "دلیل",
        "ipblocklist-submit": "پی جوری",
+       "ipblocklist-localblock": "نهاگری ولات نشینی",
+       "ipblocklist-otherblocks": "هنی{{PLURAL:$1|نهاگرتن|نهاگرتنیا}}",
+       "infiniteblock": "بی زمون",
+       "emailblock": "انجومانامه ناکشتگر بیه",
        "blocklist-nousertalk": "نبوئه بلگه چک چنه خوتونه ویرایشت بکید",
        "ipblocklist-empty": "جاگه نوم گه حالیه",
        "blocklink": "بسته بوئه",
        "emaillink": "انجومانامه نه کل کو",
        "blocklogpage": "قلف",
        "blocklogentry": " [[$1]] وا یه گل وخت تموم بیئن $2 و $3  قلف بیه",
+       "block-log-flags-anononly": "فقط کاریاریایی که نادیارن",
        "block-log-flags-nocreate": "حساو راس کردن عاجز بیه.",
+       "block-log-flags-noautoblock": "بستن خودانجوم ناکشتگر بیه",
+       "block-log-flags-noemail": "انجومانامه ناکشتگر بیه",
        "block-log-flags-nousertalk": "نبوئه بلگه چک چنه خوتونه ویرایشت بکید",
+       "block-log-flags-hiddenname": "نوم کاروری قام بیه",
+       "ipb_expiry_invalid": "گات تموم بیین نامعتوره.",
+       "ipb_already_blocked": "\"$1\" ایسه نهاگری بیه.",
+       "ipb-otherblocks-header": "هنی{{PLURAL:$1|نهاگرتن|نهاگرتنیا}}",
        "ip_range_invalid": "پوشگر نامعتور آی پی",
        "proxyblocker": "قلف کننه پروکسی",
+       "sorbs": "دی ان اس بی ال",
        "lockdb": "قلف کردن رسینه گا",
        "unlockdb": "رسینه گا قلف نبیه",
        "unlockconfirm": "هره، مه واقعند میهام که رسینه گا وا بوئه.",
        "movearticle": "جا وه جا کردن بلگه:",
        "movenotallowed": "شما وه جا وه جا کردن بلگه دسرسی ناریت",
        "movenotallowedfile": "شما وه جا وه جا کردن جانیایا دسرسی ناریت",
+       "newtitle": "سی سرون هنی:",
        "movepagebtn": "بلگه جا وه جا کو",
        "pagemovedsub": "د خوئی جا وه جا بیه",
        "movepage-moved-redirect": "یه گل واگردونی دروس بیه.",
        "movereason": "دلیل:",
        "revertmove": "لرستن",
        "delete_and_move": "پاکسا و جا وه جا بوئه",
+       "delete_and_move_confirm": "هری بلگه نه پاکسا کو",
+       "immobile-source-page": "ای بلگه جا وه جا کردنی نئ.",
+       "move-leave-redirect": "وه جا نیائن یه گل واگردونی",
+       "protectedpagemovewarning": "<strong>زئنار:ای بلگه سی یه پر و پیم بیه که کاریاریایی که دسرسی دیوونداری دارن فقط بتونن دش ویرایشت بکن.</strong>\nآخرین سیائه سی سرچشمه یا د هار اماییه کاری بیه:",
+       "semiprotectedpagemovewarning": "<strong>د ویر داشتویت:</strong> ای بلگه سی یه که فقط کاریاریا ثوت نام کرده تونستون دش ویرایشت بکه ن پر و پیم بیه.\nآخرین پهرستنومه دئه بیه سی سرچشمه هار نها اماییه بیه:",
        "export": "وه صحرا ديئن بلگيا",
+       "exportall": "وه صحرا ديئن همه بلگيا",
+       "export-submit": "وه در ديئن",
        "export-addcat": "اضاف کو",
        "export-addns": "اضاف كو",
        "export-download": "ذخیره کردن جانیا",
        "allmessagesname": "نوم",
        "allmessagesdefault": "سفارشت متنی پيش فرض",
        "allmessages-filter-legend": "فیلتر",
+       "allmessages-filter-unmodified": "آلشت نبیه",
        "allmessages-filter-all": "همه",
        "allmessages-filter-modified": "آلشت بیه",
        "allmessages-prefix": "فیلتر بیه وا نهاون:",
        "thumbnail-more": "گپ كردن",
        "filemissing": "گم بیئن جانیا",
        "thumbnail_error": "خطا د راس بیئن بن کلئکی:$1",
+       "import": "وامین اوردن بلگه یا",
+       "import-interwiki-sourcewiki": "سرچشمه ویکی:",
+       "import-interwiki-sourcepage": "بلگه سرچشمه:",
+       "import-interwiki-templates": "همه چوئه یا",
+       "import-interwiki-submit": "وامین اوردن",
+       "import-interwiki-namespace": "نومجا مقصد:",
        "import-upload-filename": "نوم جانیا:",
        "import-comment": "ویر و باور:",
+       "importstart": "د حال و بار وامین اوردن",
+       "import-revision-count": "$1 {{جمی:$1|وانئری|وانئریا}}",
+       "importnopages": "هیچ بلگه ای وامین نیومائه.",
+       "importfailed": "وامین اوردن شکست حرده: <nowiki>$1</nowiki>",
        "importcantopen": "نبوئه جانیا دئه بیه نه وا بکید",
+       "importbadinterwiki": "هوم پیوند مینجاویکی گن",
+       "importsuccess": "وامین اوردن تموم بی!",
        "importnofile": "هیچ جانیا دئه بیه ای سوار نبیه.",
+       "import-noarticle": "هیچ بلگه ای سی وامین اوردن نئ!",
        "import-upload": "سوار کرد دونسمنیا ایکس ام ال",
        "import-token-mismatch": "کمبود د دونسمنیا نشینگه.\nلطفن هنی کوششت بکید.",
        "importlogpage": "پهرستنومه دئن",
+       "javascripttest": "ازمایشت کردن جاوا اسکریپت",
        "tooltip-pt-userpage": "بلگه كارورتو",
        "tooltip-pt-mytalk": "بلگه قسه كردن شما",
        "tooltip-pt-preferences": "اولويتيا شما",
        "tooltip-t-permalink": "چسب ون هميشئی د دوواره بينی ای بلگه",
        "tooltip-ca-nstab-main": "ديئن محتوا بلگه",
        "tooltip-ca-nstab-user": "ديئن بلگه كارور",
+       "tooltip-ca-nstab-media": "دیئن بلگه وارسگر",
        "tooltip-ca-nstab-special": "اي بلگه ويجه يه، شما نتونيت خود اي بلگه نه ويرايشت بكيد",
        "tooltip-ca-nstab-project": "ديئن بلگه پروجه",
        "tooltip-ca-nstab-image": "ديئن بلگه فايل",
+       "tooltip-ca-nstab-mediawiki": "دیئن پیغوم سامونه",
        "tooltip-ca-nstab-template": "ديئن قالو",
+       "tooltip-ca-nstab-help": "ديئن بلگه هومیاری",
        "tooltip-ca-nstab-category": "ديئن بلگه دسه بنی",
        "tooltip-minoredit": "یه نه د عنوان حیرده ویرایشت ثوت کو",
        "tooltip-save": "آلشتياتونه اماییه بكيد",
        "tooltip-diff": "آلشتیا نه که شما د ای متن راس کردیته نشو بیئه",
        "tooltip-compareselectedversions": "فرخیا مینجا دو تا د دو بار دیئن ای بلگه نه بوینیت",
        "tooltip-watch": "ای بلگه نه د سیل برگتو اضاف بکید",
+       "tooltip-watchlistedit-raw-submit": "وه هنگوم سازی سیل برگ",
        "tooltip-upload": "شرو د سوار کرد",
        "tooltip-rollback": "\"ورگشتن\" لرستن د حالت اول  سی ای بلگه  که سی  يه كه هومياری  نيايی اصلاح بيه وا يه پورنسن",
        "tooltip-undo": "انجوم نگرتن ای ویرایشت ورگن و همه فرمیا ویرایشت تانه که حالت پیش سیل واکو.یه اجازه میئه سی اضاف کردن یه دلیل د چکسته.",
        "tooltip-summary": "يه چكسته كؤچك وارد بكيد",
        "interlanguage-link-title": "$1-$2",
+       "interlanguage-link-title-nonlang": "$1 – $2",
        "anonymous": "ناشناس {{جمی:$1|کارور|کاروریا}}  {{سیل جا}}",
        "anonuser": "{{سیل جا}}  کارور ناشناس $1",
+       "others": "دیه رون",
        "siteusers": "{{نوم سیل جا}} {{جمی:$2|کارور|کاروریا}} $1",
+       "creditspage": "اعتوار بلگه",
+       "pageinfo-title": "دونسمنیا سی \"$1\"",
+       "pageinfo-header-basic": "دونسمنیا پایه",
+       "pageinfo-header-edits": "ویرایشت ویرگار",
+       "pageinfo-header-restrictions": "پر و پیم کردن بلگه",
+       "pageinfo-header-properties": "چیا بلگه",
+       "pageinfo-length": "انازه بلگه(وه بایت)",
+       "pageinfo-article-id": "نوم دیار کن بلگه",
        "pageinfo-language": "بلگه مینونه زون",
        "pageinfo-content-model": "شلگ مینونه بلگه",
+       "pageinfo-robot-index": "صلادار",
+       "pageinfo-robot-noindex": "بی صلا",
+       "pageinfo-views": "شماره دیئن یا",
+       "pageinfo-watchers": "شماره سیل کننه بلگه یا",
        "pageinfo-redirects-name": "شماره واگردونیا ای بلگه",
+       "pageinfo-redirects-value": "$1",
+       "pageinfo-firstuser": "بلگه راس کن",
+       "pageinfo-firsttime": "گات دروس بیین بلگه",
+       "pageinfo-lastuser": "آخری ویرایشتگر",
+       "pageinfo-lasttime": "گات آخری ویرایشت",
+       "pageinfo-edits": "شماره همه ویرایشتیا",
+       "pageinfo-toolboxlink": "دونسمنیا بلگه",
        "pageinfo-redirectsto": "واگردونی سی",
+       "pageinfo-redirectsto-info": "دونسمنیا",
+       "pageinfo-contentpage": "اشمارده بیه وه عنوان مینونه بلگه",
+       "pageinfo-contentpage-yes": "هری",
+       "pageinfo-protect-cascading": "پر و پیم بیین تافنمایی د ایچه",
+       "pageinfo-protect-cascading-yes": "هری",
+       "pageinfo-protect-cascading-from": "پر و پیم بیین تافنمایی د",
+       "pageinfo-category-info": "دونسمنیا دسه ای",
+       "pageinfo-category-pages": "شماره بلگيا",
+       "pageinfo-category-subcats": "شماره زیر دسه یا",
        "pageinfo-category-files": "شماره جانیایا",
        "patrol-log-page": "پهرستنومه گشتن",
        "filedeleteerror-short": "خطا پاک نبیئن جانیا:$1",
        "previousdiff": "← ويرايشت كۈهنه تر",
        "nextdiff": "ويرايشت تازه تر",
+       "widthheight": "$1 × $2",
+       "widthheightpage": "$1 × $2, $3 {{PLURAL:$3|بلگه|بلگه یا}}",
+       "file-info": "انازه جانیا: $1, MIME type: $2",
        "file-info-size": "$1 × $2 پیکسل, انازه فایل: $3, MIME نوع: $4",
+       "file-info-size-pages": "$1 × $2 pixels, انازه جانیا: $3, MIME type: $4, $5 {{PLURAL:$5|بلگه|بلگه یا}}",
        "file-nohires": "عسك ون بالاتري دش ني",
        "svg-long-desc": "اس وی جی فايل.نومنا $1 $2 پيكسل",
        "show-big-image": "فایل اصلی",
+       "show-big-image-size": "$1 × $2 pixels",
+       "file-info-gif-looped": "حلقه دار",
+       "file-info-png-looped": "حلقه دار",
        "file-info-png-repeat": "$1 بازی کرده{{جمی:$1|وخت|وختیا}}",
        "newimages": "عسگدونی جانیایا تازه",
        "newimages-summary": "ای بلگه یا ویجه همه جانیایا سوار بیه نه نشو می ئین.",
+       "newimages-legend": "فیلتر",
        "newimages-label": "نوم جانیا(یا بشقی د وه):",
+       "noimages": "هیچی سی دیئن نئ",
        "ilsubmit": "پی جوری",
+       "bydate": "وا گات",
        "sp-newimages-showfrom": "جانیایا تازه نه که $2 ، $2 شرو بینه نشو بیه",
+       "video-dims": "$1, $2 × $3",
+       "seconds-abbrev": "$1 s",
+       "minutes-abbrev": "$1 دیقه",
+       "hours-abbrev": "$1 ساعت",
+       "days-abbrev": "$1 گات",
+       "seconds": "{{PLURAL:$1|$1 ثانیه|$1 ثانیه یا}}",
+       "minutes": "{{PLURAL:$1|$1 دیقه|$1 دیقه یا}}",
+       "hours": "{{PLURAL:$1|$1 ساعت|$1 ساعت یا}}",
        "days": "{{جمی:$1|1$ روز|$1 روز}}",
+       "weeks": "{{PLURAL:$1|$1 هفته|$1 هفته یا}}",
        "months": "{{جمی:$1|$1 ما|$1 مایا}}",
        "years": "{{جمی:$1|$1 سال|$1 سال}}",
+       "ago": "$1 دماتر",
+       "just-now": "فقط ایسه",
+       "hours-ago": "$1 {{PLURAL:$1|ساعت |ساعتیا}} دماتر",
+       "minutes-ago": "$1 {{PLURAL:$1|دیقه|دیقه یا}} دماتر",
+       "seconds-ago": "$1 {{PLURAL:$1|ثانیه|ثانیه یا}} دماتر",
        "monday-at": "دوشمه د $1",
        "bad_image_list": "دونسمنديانه وه ای شلگ وارد بكيت:\n\nفقط سرخط يایی که وا * شرو بوئن د وير گرته بوئن. اولی چسب ون مئن هر سرخط، باید چسب ونی وه یک عسگ گن با.\nچسب ونيا نيایی د همو سرخط، وه عنوان چيا استثنادار د وير گرته بوئن",
        "metadata": "داديا  فره گپ",
        "metadata-help": "ای فایل شومل دونسمنیا هنی یه.شایت د دیربین رقم ون یا اسکنری که سی راس کردنشو استفاده بیه،وه ایچه اضاف بیه",
        "metadata-fields": "رشته یا گپ دونسمنیا که د ای پیغوم نوم ون بینه شومل بلگه عسگ ن که وختی که جدول گپ دونسمنیا وا بوئه نشون دئیه بوئن.\nچی یا هنی سی یه که پیش فرضن قام بوئن.\n*راست کو\n*مدل\n*دم وخت اصل\n*وخت آشگار\n*اف ان شماره\n*ایزو نرخ من سرعت\n*فوکالنس\n*هنرمن\n*کپی رایت\n*حالت جی پی اس \n*جی پی اس گپ حالت\n*جی پی اس همه حالت",
+       "metadata-langitem": "<strong>$2:</strong> $1",
+       "metadata-langitem-default": "$1",
+       "exif-imagewidth": "پئنا",
+       "exif-imagelength": "بلنگی",
        "exif-planarconfiguration": "سرجایک کردن رسینه",
        "exif-datetime": "آلشت دئن وخت و دمون جانیا",
        "exif-make": "سازنه دیربین",
+       "exif-artist": "نیسنه",
+       "exif-pixelydimension": "پئنا عسگ",
        "exif-usercomment": "ویر و باوریا کارور",
        "exif-relatedsoundfile": "جانیا دنگ دار مرتوط",
        "exif-datetimeoriginal": "دمون و وخت راس بیئن دونسمنیا",
+       "exif-flash": "فلش",
+       "exif-flashenergy": "آز فلش",
        "exif-filesource": "سرچشمه جانیا",
        "exif-gpstimestamp": "وخت جی پی اس (ساعت اتمی)",
+       "exif-coordinate-format": "$1° $2′ $3″ $4",
        "exif-jpegfilecomment": "ویر و باور فایل پی ان جی",
+       "exif-keywords": "کلیمه یا کلیتی",
        "exif-countrycodecreated": "رازینه سی ولاتی که عسگ د وه گرته بیه",
        "exif-citycreated": "شهری که عسگ دش گرته بیه",
        "exif-countrycodedest": "رازینه سی ولات نمائشت دئه بیه",
        "exif-citydest": "شهر دیار بیه",
+       "exif-source": "سرچشمه",
        "exif-fixtureidentifier": "نوم ثاوت",
+       "exif-writer": "نیسنه",
        "exif-languagecode": "زون",
+       "exif-iimcategory": "دسه",
        "exif-datetimeexpires": "وا نها دش استفاده نبوئه",
+       "exif-datetimereleased": "ول بیه د",
+       "exif-label": "ری دیار",
        "exif-pngfilecomment": "ویر و باور فایل جی پی ان جی",
        "exif-giffilecomment": "ویر و باور فایل جی آی اف",
+       "exif-contact-value": "$1\n\n$2\n<div class=\"adr\">\n$3\n\n$4, $5, $6 $7\n</div>\n$8",
+       "exif-orientation-1": "عادی",
        "exif-componentsconfiguration-0": "نی یش",
        "exif-exposureprogram-1": "دسی",
+       "exif-meteringmode-0": "نادیار",
+       "exif-meteringmode-1": "میانگین",
+       "exif-meteringmode-255": "هنی",
+       "exif-lightsource-0": "نادیار",
        "exif-lightsource-1": "روشنایی روز",
+       "exif-lightsource-2": "فلورسنت",
+       "exif-lightsource-4": "فلش",
+       "exif-focalplaneresolutionunit-2": "ائنج",
        "exif-scenecapturetype-3": "چی شو",
+       "exif-gaincontrol-0": "هیش کوم",
+       "exif-contrast-0": "عادی",
+       "exif-contrast-1": "نرم",
+       "exif-contrast-2": "سفت",
+       "exif-saturation-0": "عادی",
+       "exif-sharpness-0": "عادی",
+       "exif-sharpness-1": "نرم",
+       "exif-sharpness-2": "سفت",
+       "exif-subjectdistancerange-0": "نادیار",
+       "exif-subjectdistancerange-1": "گپ",
        "exif-gpsaltitude-above-sealevel": "$1 {{جمی:$1|متر|متریا}} وارؤ د ریتراز دریا",
        "exif-gpsaltitude-below-sealevel": "$1 {{جمی:$1|متر|متریا}} وارؤ د ریتراز دریا",
+       "exif-gpsdestdistance-m": "مایل",
        "exif-gpsdop-good": "خو ($1)",
+       "exif-dc-type": "نوع وارسگر",
+       "exif-rating-rejected": "رد بیه",
        "exif-iimcategory-ace": "هنریا، رهزیشت و زیستگه",
+       "exif-iimcategory-edu": "آموختاری",
+       "exif-iimcategory-evn": "زئشت گه",
+       "exif-iimcategory-lab": "کار",
        "watchlistall2": "همه شو",
        "namespacesall": "همه شو",
        "monthsall": "همه",
        "confirmemail_send": "کل کردن رازینه پشت راس کاری",
+       "recreate": "د نو راس کردن",
+       "confirm_purge_button": "خوئه",
+       "confirm-watch-button": "خوئه",
+       "confirm-watch-top": "ای بلگه نه د سیل برگتو اضاف می کید؟",
+       "confirm-unwatch-button": "خوئه",
+       "confirm-unwatch-top": "ای بلگه نه د سیل برگتو ؤرمیداریت؟",
+       "semicolon-separator": ";&#32;",
+       "comma-separator": ",&#32;",
+       "colon-separator": ":&#32;",
+       "pipe-separator": "&#32;|&#32;",
+       "word-separator": "&#32;",
+       "ellipsis": "...",
+       "percent": "$1%",
+       "parentheses": "($1)",
+       "brackets": "[$1]",
+       "quotation-marks": "\"$1\"",
+       "imgmultipageprev": "بلگه دمايی",
+       "imgmultipagenext": "بلگه نهایی",
        "imgmultigo": "رؤ!",
+       "img-lang-opt": "$2 ($1)",
        "img-lang-default": "(زون پیش زمینه)",
        "img-lang-go": "رو",
+       "table_pager_next": "بلگه نهایی",
+       "table_pager_prev": "بلگه دمايی",
+       "table_pager_first": "سرآسونه",
+       "table_pager_last": "بلگه آخری",
        "table_pager_limit_submit": "رو",
        "autosumm-replace": "مینونه وا \"َ$1\" جاگزین بی",
        "autoredircomment": "بلگه واگردونی بیه سی[[$1]]",
+       "watchlistedit-normal-title": "ویرایشت سیل برگ",
+       "watchlisttools-clear": "پاک کردن سیل برگ",
        "watchlisttools-view": "آلشتیا مرتوط نه بوینیت",
        "watchlisttools-edit": "سیل برگ بوینیتو و ویرایشت بکید",
        "watchlisttools-raw": "سیل برگ نه ردیفی ویرایشت کو",
+       "iranian-calendar-m1": "فروردین",
+       "iranian-calendar-m2": "اردیبهشت",
+       "iranian-calendar-m3": "خرداد",
+       "iranian-calendar-m4": "تیر",
+       "iranian-calendar-m5": "مرداد",
+       "iranian-calendar-m6": "شهریور",
+       "iranian-calendar-m7": "مئر",
+       "iranian-calendar-m8": "آبان",
+       "iranian-calendar-m9": "آذر",
+       "iranian-calendar-m10": "دی",
+       "iranian-calendar-m11": "بئمن",
+       "iranian-calendar-m12": "اسفند",
+       "hijri-calendar-m1": "محرم",
+       "hijri-calendar-m2": "صفر",
+       "hijri-calendar-m3": "ربیع الاول",
+       "hijri-calendar-m4": "رجو",
+       "timezone-utc": "UTC",
        "duplicate-defaultsort": "زنهار کلیت پیش فرض جور بیه $2 تازه ای یا کلید پیش فرض جوربیه $1 رد بیه.",
+       "version": "نسقه",
+       "version-specialpages": "بلگيا ويجه",
+       "version-variables": "آلشت ونا",
        "version-antispam": "نهاگرتن هرزنومه",
+       "version-other": "هنی",
        "version-ext-license": "ليسانس",
+       "version-skin-colheader-name": "پوسه",
        "version-ext-colheader-version": "نسقه",
        "version-ext-colheader-license": "ليسانس",
+       "version-ext-colheader-description": "شرح",
        "version-ext-colheader-credits": "نیسنه یا",
+       "version-poweredby-others": "دیه رون",
+       "version-software-version": "نسقه",
+       "version-entrypoints-header-url": "يو آر ال",
+       "version-entrypoints-articlepath": "[https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:$wgArticlePath Article path]",
+       "version-entrypoints-scriptpath": "[https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:$wgScriptPath Script path]",
        "redirect": "واگردونی وا جانیا،بلگه یا وانیئری نوم دیارکو",
        "redirect-submit": "رو",
+       "redirect-value": "ارزایشت:",
+       "redirect-user": "نوم دياركن کاریار:",
+       "redirect-page": "نوم دیار کن بلگه",
        "redirect-file": "نوم جانیا",
        "fileduplicatesearch-filename": "نوم جانیا:",
+       "fileduplicatesearch-submit": "پی جوری",
+       "fileduplicatesearch-info": "$1 × $2 pixel<br />انازه جانیا: $3<br />MIME type: $4",
        "specialpages": "بلگيا ويجه",
        "specialpages-group-changes": "آلشتیا تازه و پهرستنومه یا",
        "specialpages-group-media": "گزارشتیا رسانه و سوارکردیا",
        "specialpages-group-pages": "نوم گه بلگه یا",
        "specialpages-group-wiki": "رسینه و اوزاریا",
        "specialpages-group-redirects": "بلگه ویجه واگردونی بیه",
+       "blankpage": "بلگه حالی",
        "external_image_whitelist": "یه خط نه ول بکید چی وه<pre>",
        "tag-filter": "فيلتر [[Special:Tags|Tag]]:",
+       "tag-filter-submit": "فيلتر",
+       "tags-title": "سردیسیا",
+       "tags-tag": "نوم سردیس",
        "tags-display-header": "دیاری کردن د نوم گه آلشتیا",
+       "tags-active-header": "کنشتگره؟",
+       "tags-active-yes": "هری",
+       "tags-active-no": "نه",
+       "tags-edit": "ویرایشت",
+       "tags-hitcount": "$1 {{جمی:$1|آلشت|آلشتیا}}",
+       "comparepages": "کنار یک نیاین بلگه یا",
+       "compare-page1": "بلگه 1",
+       "compare-page2": "بلگه 2",
+       "compare-rev1": "دوواره ديئن1",
+       "compare-submit": "کنار یک نیاین",
        "compare-title-not-exists": "سرون مشقص بیه وجود ناره.",
        "compare-revision-not-exists": "وانئری که شما تی دیار کردیته وجود ناره.",
+       "htmlform-required": "یه دئه واس بوئه.",
+       "htmlform-submit": "دئن",
+       "htmlform-reset": "انجومشیو کردن آلشتیا",
+       "htmlform-selectorother-other": "هنی",
+       "htmlform-no": "نه",
+       "htmlform-yes": "هری",
+       "htmlform-cloner-create": "هنی اضاف بکیت",
+       "htmlform-cloner-delete": "ؤرداشتن",
        "revdelete-content-hid": "مینونه قام بیه",
        "revdelete-uname-hid": "نوم کاروری قام بیه",
        "revdelete-content-unhid": "مینونه قام نبیه",
        "revdelete-uname-unhid": "نوم کاروری قام نبیه",
+       "rightsnone": "(هيش كوم)",
+       "feedback-subject": "سرون:",
+       "feedback-message": "پيغوم:",
+       "feedback-cancel": "انجوم شیوسن",
        "feedback-submit": "کل کردن نهاهوال حون",
        "feedback-close": "انجوم بی",
        "searchsuggest-search": "پی جوری",
        "api-error-illegal-filename": "نوم جانیا اجازه دئه نئ.",
        "api-error-mustbeloggedin": "شما سی سوارکردن فایلیا با بیایت وامین",
        "duration-days": "$1{{جمی:$1|روز|روزیا}}",
+       "duration-weeks": "$1 {{جمی:$1|هفته|هفته یا}}",
        "duration-years": "$1{{جمی:$1| سال|سالیا}}",
+       "limitreport-ppvisitednodes-value": "$1/$2",
+       "limitreport-ppgeneratednodes-value": "$1/$2",
+       "limitreport-expansiondepth-value": "$1/$2",
+       "limitreport-expensivefunctioncount-value": "$1/$2",
+       "expand_templates_output": "نتیجه",
+       "expand_templates_ok": "خوئه",
        "expand_templates_remove_comments": "جا وه جا بیئن ویر و باوریا",
+       "expand_templates_preview": "پيش سيل",
        "pagelanguage": "بلگه انتخاو زون",
+       "pagelang-name": "بلگه",
        "pagelang-language": "زون",
        "pagelang-use-default": "وه کار بسن زون پیش دیه",
+       "pagelang-select-lang": "انتخاو زون",
        "right-pagelang": "آلشت دئن زون بلگه",
+       "action-pagelang": "آلشت دئن زون بلگه",
        "log-name-pagelang": "آلشت دئن زون پهرستنومه",
        "log-description-pagelang": "ای پهرستنومه در بلگه زونا آلشت گرته.",
-       "default-skin-not-found-row-disabled": "* <رازینه>$1</رازینه> / $2 ('''ناکنشتگر بیه''')"
+       "default-skin-not-found-row-enabled": "* <رازینه>$1</رازینه> / $2 ('''ناکنشتگر بیه''')",
+       "default-skin-not-found-row-disabled": "* <رازینه>$1</رازینه> / $2 ('''ناکنشتگر بیه''')",
+       "mediastatistics-table-count": "شماره جانیایا",
+       "mediastatistics-header-unknown": "نادیار",
+       "mediastatistics-header-audio": "دنگ",
+       "mediastatistics-header-video": "عسگ و فیلم",
+       "mediastatistics-header-text": "نیسسه دار"
 }
index 3b6bca6..2bba91c 100644 (file)
        "passwordreset-emailsent-capture": "Atgādinājuma e-pasta ziņojums ir nosūtīts, tas parādīts zemāk.",
        "passwordreset-emailerror-capture": "Atgādinājuma e-pasta ziņojums tika izveidots, tas parādīts zemāk, bet nosūtīšana lietotājam neizdevās: $1",
        "changeemail": "Mainīt e-pasta adresi",
-       "changeemail-header": "Mainīt konta e-pasta adresi",
        "changeemail-oldemail": "Pašreizējā e-pasta adrese:",
        "changeemail-newemail": "Jaunā e-pasta adrese:",
        "changeemail-none": "(nav)",
        "changeemail-password": "Jūsu {{SITENAME}} parole:",
        "changeemail-submit": "Mainīt e-pastu",
-       "changeemail-cancel": "Atcelt",
        "resettokens-tokens": "Žetoni:",
        "resettokens-token-label": "$1 (šībrīža vērtība: $2)",
        "bold_sample": "Teksts treknrakstā",
        "searchrelated": "saistītais",
        "searchall": "viss",
        "showingresults": "Šobrīd ir {{PLURAL:$1|redzama|redzamas}} '''$1''' {{PLURAL:$1|lapa|lapas}}, sākot ar #'''$2'''.",
-       "showingresultsheader": "{{PLURAL:$5|Šobrīd ir redzama '''$1''' lapa no '''$3'''|Šobrīd ir redzamas '''$1 — $2''' lapas no '''$3'''}}, kas satur '''$4'''",
        "search-nonefound": "Nav atrasti pieprasījumam atbilstoši rezultāti.",
        "powersearch-legend": "Izvērstā meklēšana",
        "powersearch-ns": "Meklēt šajās lapu grupās:",
        "mywatchlist": "Uzraugāmie raksti",
        "watchlistfor2": "Priekš $1 ($2)",
        "nowatchlist": "Tavā uzraugāmo rakstu sarakstā nav neviena raksta.",
-       "watchlistanontext": "Lūdzu $1, lai apskatītu vai labotu savu uzraugāmo rakstu saraksta saturu.",
+       "watchlistanontext": "Lūdzu pieslēdzies, lai apskatītu vai labotu savu uzraugāmo rakstu saraksta saturu.",
        "watchnologin": "Neesi iegājis",
        "addwatch": "Pievienot uzraugāmo lapu sarakstam",
        "addedwatchtext": "Lapa \"[[:$1]]\" ir pievienota [[Special:Watchlist|tevis uzraudzītajām lapām]], kur tiks parādītas izmaiņas, kas izdarītas šajā lapā vai šīs lapas diskusiju lapā, kā arī šī lapa tiks iezīmēta '''pustrekna''' [[Special:RecentChanges|pēdējo izmaiņu lapā]], lai to būtu vieglāk pamanīt.\n\nJa vēlāk pārdomāsi un nevēlēsies vairs uzraudzīt šo lapu, klikšķini uz saites '''neuzraudzīt''' rīku joslā.",
        "logentry-newusers-create2": "$1 {{GENDER:$2|izveidoja}} lietotāja kontu $3",
        "logentry-newusers-autocreate": "Lietotaja konts $1 tika {{GENDER:$2|izveidots}} automātiski",
        "rightsnone": "(nav)",
+       "revdelete-summary": "izmaiņu kopsavilkums",
        "feedback-subject": "Temats:",
        "feedback-message": "Ziņojums:",
        "feedback-cancel": "Atcelt",
index 8482e73..11583d5 100644 (file)
        "changeemail": "更郵址",
        "changeemail-none": "(無)",
        "changeemail-password": "汝 {{SITENAME}} 之符節",
-       "changeemail-cancel": "棄",
        "bold_sample": "粗體",
        "bold_tip": "粗體",
        "italic_sample": "斜體",
        "searchrelated": "關",
        "searchall": "全",
        "showingresults": "見'''$1'''尋,自'''$2'''始:",
-       "showingresultsheader": "見'''$4''',{{PLURAL:$5|'''$1''''''$3'''之尋|'''$1 - $2''',共'''$3'''之尋}}",
        "search-nonefound": "詢中無結。",
        "powersearch-legend": "尋",
        "powersearch-ns": "尋名集:",
        "preferences": "簿註",
        "mypreferences": "簿註",
        "prefs-edits": "數計:",
-       "prefsnologintext2": "ç\99»ç°¿ä»¥æ\94¹簿註",
+       "prefsnologintext2": "ç\99»ç°¿ä»¥æ\9b´簿註",
        "prefs-skin": "面版",
        "skin-preview": "草覽",
        "datedefault": "原註",
        "revdelete-restricted": "應限至有秩",
        "revdelete-unrestricted": "除限自有秩",
        "rightsnone": "(凡)",
+       "revdelete-summary": "摘",
        "searchsuggest-search": "尋"
 }
index ca0e8ff..b1d5f3b 100644 (file)
        "searchall": "सभटा",
        "showingresults": "नीचाँ एतऽ धरि {{PLURAL:$1|'''1''' परिणाम|'''$1''' परिणाम सभ}}  #'''$2''' सँ प्रारम्भ भऽ कऽ।",
        "showingresultsinrange": "नीचाँ एतऽ धरि {{PLURAL:$1|'''1''' परिणाम|'''$1''' परिणाम सभ}}  #'''$2''' सँ प्रारम्भ भऽ कऽ।",
-       "showingresultsheader": "{{PLURAL:$5|परिणाम '''$1''' एकर '''$3'''|परिणाम सभ '''$1 - $2''' एकर '''$3'''}} ऐ लेल '''$4'''",
        "search-nonefound": "अभ्यर्थनासँ मेल खाइत कोनो परिणाम नै भेटल।",
        "powersearch-legend": "विशेष खोज",
        "powersearch-ns": "निर्धारकमे खोज",
index 710e5f7..43756bd 100644 (file)
        "searchrelated": "voadinika",
        "searchall": "rehetra",
        "showingresults": "Omeo ny valiny{{PLURAL:$1||}} miisa hatramin'ny <b>$1</b> manomboka ny #<b>$2</b>.",
-       "showingresultsheader": "{{PLURAL:$5}}Valim-pikaronhana '''$1x–$2''' an'i '''$3''' ho an'i '''$4'''",
        "search-nonefound": "Tsy nahitana valiny ilay fanontaniana.",
        "powersearch-legend": "Fikarohana havanana",
        "powersearch-ns": "Hitady anatin'ny anaran-tsehatra :",
index da2390e..90ec18d 100644 (file)
        "newpage": "Нова страница",
        "talkpage": "Разговор",
        "talkpagelinktext": "Разговор",
-       "specialpage": "СпеÑ\86иÑ\98ална страница",
+       "specialpage": "СлÑ\83жбена страница",
        "personaltools": "Лични алатки",
        "articlepage": "Преглед на содржината",
        "talk": "Разговор",
        "nstab-main": "Страница",
        "nstab-user": "Корисник",
        "nstab-media": "Мултимедијална податотека",
-       "nstab-special": "СпеÑ\86иÑ\98ална страница",
+       "nstab-special": "СлÑ\83жбена страница",
        "nstab-project": "Проектна страница",
        "nstab-image": "Податотека",
        "nstab-mediawiki": "Порака",
        "nstab-category": "Категорија",
        "nosuchaction": "Нема такво дејство",
        "nosuchactiontext": "Дејството укажано во URL-адресата е погрешно.\nМожеби имате грешка во пишувањето на адресата, или пак имате проследено погрешна врска.\nОва може да се должи и на грешка во програмската опрема на {{SITENAME}}.",
-       "nosuchspecialpage": "Ð\9dе Ð¿Ð¾Ñ\81Ñ\82ои Ñ\82аква Ñ\81пеÑ\86иÑ\98ална страница",
-       "nospecialpagetext": "<strong>Ð\9fобаÑ\80авÑ\82е Ð½ÐµÐ¿Ð¾Ñ\81Ñ\82оеÑ\87ка Ñ\81пеÑ\86иÑ\98ална Ñ\81Ñ\82Ñ\80аниÑ\86а.</strong>\n\nСпиÑ\81окоÑ\82 Ð½Ð° Ð¿Ð¾Ñ\81Ñ\82оеÑ\87ки Ñ\81пеÑ\86иÑ\98ални страници: [[Special:SpecialPages|{{int:specialpages}}]].",
+       "nosuchspecialpage": "Ð\9dе Ð¿Ð¾Ñ\81Ñ\82ои Ñ\82аква Ñ\81лÑ\83жбена страница",
+       "nospecialpagetext": "<strong>Ð\9fобаÑ\80авÑ\82е Ð½ÐµÐ¿Ð¾Ñ\81Ñ\82оеÑ\87ка Ñ\81лÑ\83жбена Ñ\81Ñ\82Ñ\80аниÑ\86а.</strong>\n\nСпиÑ\81окоÑ\82 Ð½Ð° Ð¿Ð¾Ñ\81Ñ\82оеÑ\87ки Ñ\81лÑ\83жбени страници: [[Special:SpecialPages|{{int:specialpages}}]].",
        "error": "Грешка",
        "databaseerror": "Грешка во базата",
        "databaseerror-text": "Се појави грешка во барањето од базата.\nОва може да значи програмска грешка (бубачка).",
        "mycustomjsprotected": "Немате дозвола да ја уредувате оваа страница со JavaScript.",
        "myprivateinfoprotected": "Немате дозвола да ги уредувате вашите лични информации.",
        "mypreferencesprotected": "Немате дозвола да ги уредувате вашите нагодувања.",
-       "ns-specialprotected": "СпеÑ\86иÑ\98ални страници не може да се уредуваат.",
+       "ns-specialprotected": "СлÑ\83жбени страници не може да се уредуваат.",
        "titleprotected": "Овој наслов од страна на [[User:$1|$1]] е заштитен и не може да се создаде.\nПричината за тоа е: ''$2''.",
        "filereadonlyerror": "Не можам да ја изменам податотеката „$1“ бидејќи складиштето „$2“ е во незаписен режим.\n\t\nАдминистраторот што ја заклучи го понуди следново образложение: „''$3''“.",
        "invalidtitle-knownnamespace": "Неважечки наслов со именски простор „$2“ и текст „$3“",
        "passwordreset-emailsent-capture": "Испратено е писмо за измена на лозинката (прикажано подолу).",
        "passwordreset-emailerror-capture": "Создадено е писмо за измена на лозинката (прикажано подолу), но не успеав да го испратам на {{GENDER:$2|корисникот}}: $1",
        "changeemail": "Смени е-пошта",
-       "changeemail-header": "Промена на е-пошта за сметката",
        "changeemail-text": "Пополнете го образецов за да ја смените е-поштата. За да ја потврдите промената, ќе треба да ја внесете лозинката.",
        "changeemail-no-info": "Мора да бидете најавени ако сакате да имате директен пристап до оваа страница.",
        "changeemail-oldemail": "Тековна е-пошта:",
        "changeemail-none": "(нема)",
        "changeemail-password": "Вашата лозинка на {{SITENAME}}:",
        "changeemail-submit": "Смени е-пошта",
-       "changeemail-cancel": "Откажи",
        "changeemail-throttled": "Имате премногу обиди за најава за кратко време.\nПочекајте $1 пред да се обидете повторно.",
        "resettokens": "Врати одново шифри",
        "resettokens-text": "Можете шифрите да ги вратите одново што овозможува пристап до извесни лични податоци што се однесуваат на вашата овдешна сметка.\n\nОва треба да се направи ако по грешка сте споделиле нешто со некого или ако сметката ви е изложена на опасност.",
        "searchall": "сè",
        "showingresults": "Подолу {{PLURAL:$1|е прикажан '''1''' резултат|се прикажани '''$1''' резултати}} почнувајќи од бр. '''$2'''.",
        "showingresultsinrange": "Долу {{PLURAL:$1|е прикажан до <strong>еден</strong> резултат|се прикажани до <strong>$1</strong> резултати}} во опсег од <strong>$2</strong> до <strong>$3</strong>.",
-       "showingresultsheader": "{{PLURAL:$5|Резултат '''$1''' од '''$3'''|Резултати '''$1 - $2''' од '''$3'''}} за '''$4'''",
+       "search-showingresults": "{{PLURAL:$4|Резултат <strong>$1</strong> од <strong>$3</strong>|Резултати <strong>$1 - $2</strong> од <strong>$3</strong>}}",
        "search-nonefound": "Нема резултати што одговараат на бараното.",
        "powersearch-legend": "Напредно пребарување",
        "powersearch-ns": "Пребарај во следниве именски простори:",
        "prefs-tokenwatchlist": "Шифра",
        "prefs-diffs": "Разлики",
        "prefs-help-prefershttps": "Поставката ќе се примени следниот пат кога ќе се најавите.",
+       "prefswarning-warning": "Направивте промени во нагодувањата, но не ги зачувавте.\nИзмената нема да се изврши ако ја напуштите страницава без да стиснете на „$1“.",
        "prefs-tabs-navigation-hint": "Совет: Можете да ги користите стрелките на тастатурата за да преоѓате од едно на друго јазиче во списокот на јазичиња.",
        "email-address-validity-valid": "Исправно",
        "email-address-validity-invalid": "Се бара исправна адреса!",
        "large-file": "Се препорачува податотеките да не бидат поголеми од $1; оваа податотека е $2.",
        "largefileserver": "Големината на оваа податотека е поголема од максимално дозволената големина од серверот.",
        "emptyfile": "Податотеката што ја подигнавте е празна.\nОва може да се должи на грешка во нејзиното име.\nПроверете дали навистина сакате да ја подигнете ваквата податотека.",
-       "windows-nonascii-filename": "Опслужувачот не поддржува податотечни имиња со специјални знаци.",
+       "windows-nonascii-filename": "Опслужувачот не поддржува податотечни имиња со псоебни знаци.",
        "fileexists": "Податотека со ова име веќе постои. Проверете <strong>[[:$1]]</strong> ако не {{GENDER:|сте}} сигурни дали сакате да ја промените.\n[[$1|thumb]]",
        "filepageexists": "Описната страница на оваа податотека е веќе создадена на <strong>[[:$1]]</strong>, но не постои податотека со тоа име.\nОписот кој го внесовте нема да стои на описната страница.\nДоколку сакате описот да стои тука, ќе морате да го уредите рачно.\n[[$1|thumb]]",
        "fileexists-extension": "Податотека со слично име веќе постои: [[$2|thumb]]\n* Име на податотека која се подигнува: <strong>[[:$1]]</strong>\n* Име на постоечката податотека: <strong>[[:$2]]</strong>\nДали можеби би сакале да користите покарактеристично име.",
        "upload_source_url": "(податотеката што се ја одбрале од важечка, јавно достапна URL-адреса)",
        "upload_source_file": "(податотеката што се ја одбрале од  вашиот сметач)",
        "listfiles-delete": "избриши",
-       "listfiles-summary": "Ð\9eваа Ñ\81пеÑ\86иÑ\98ална страница ги прикажува сите подигнати податотеки.",
+       "listfiles-summary": "Ð\9eваа Ñ\81лÑ\83жбена страница ги прикажува сите подигнати податотеки.",
        "listfiles_search_for": "Побарај име на податотека:",
        "imgfile": "податотека",
        "listfiles": "Список на податотеки",
        "statistics-edits": "Број на уредувања од започнувањето на {{SITENAME}}",
        "statistics-edits-average": "Просечен број на уредувања по страница",
        "statistics-views-total": "Вкупно посети",
-       "statistics-views-total-desc": "Ð\9dе Ñ\81е Ð²ÐºÐ»Ñ\83Ñ\87ени Ð¿Ñ\80егледÑ\83ваÑ\9aа Ð½Ð° Ð½ÐµÐ¿Ð¾Ñ\81Ñ\82оеÑ\87ки Ð¸ Ñ\81пеÑ\86иÑ\98ални страници",
+       "statistics-views-total-desc": "Ð\9dе Ñ\81е Ð²ÐºÐ»Ñ\83Ñ\87ени Ð¿Ñ\80егледÑ\83ваÑ\9aа Ð½Ð° Ð½ÐµÐ¿Ð¾Ñ\81Ñ\82оеÑ\87ки Ð¸ Ñ\81лÑ\83жбени страници",
        "statistics-views-peredit": "Посети по уредување",
        "statistics-users": "Регистрирани [[Special:ListUsers|корисници]]",
        "statistics-users-active": "Активни корисници",
        "pager-newer-n": "{{PLURAL:$1|понова 1|понови $1}}",
        "pager-older-n": "{{PLURAL:$1|постара 1|постари $1}}",
        "suppress": "Скривање",
-       "querypage-disabled": "Ð\9eваа Ñ\81пеÑ\86иÑ\98ална страница е оневозможена за да не попречува на делотворноста.",
+       "querypage-disabled": "Ð\9eваа Ñ\81лÑ\83жбена страница е оневозможена за да не попречува на делотворноста.",
        "booksources": "Печатени извори",
        "booksources-search-legend": "Пребарување на извори за книга",
        "booksources-isbn": "ISBN:",
        "allpagesbadtitle": "Дадениот наслов е неважечки или има меѓујазичен или меѓувики-претставка. Може да содржи повеќе знаци кои не смеат да се користат во наслови.",
        "allpages-bad-ns": "Википедија не содржи именски простор „$1“.",
        "allpages-hide-redirects": "Скриј пренасочувања",
-       "cachedspecial-viewing-cached-ttl": "Ð\93ледаÑ\82е ÐºÐµÑ\88ирана верзија на оваа страница, која може да е стара $1.",
-       "cachedspecial-viewing-cached-ts": "Ð\93ледаÑ\82е ÐºÐµÑ\88ирана верзија на оваа страница, која може да се разликува од тековната.",
+       "cachedspecial-viewing-cached-ttl": "Ð\93ледаÑ\82е Ð¼ÐµÑ\93Ñ\83Ñ\81кладирана верзија на оваа страница, која може да е стара $1.",
+       "cachedspecial-viewing-cached-ts": "Ð\93ледаÑ\82е Ð¼ÐµÑ\93Ñ\83Ñ\81кладирана верзија на оваа страница, која може да се разликува од тековната.",
        "cachedspecial-refresh-now": "Погл. најновата.",
        "categories": "Категории",
        "categoriespagetext": "{{PLURAL:$1|Следната категорија содржи|Следните категории содржат}} страници или мултимедијални податотеки.\n[[Special:UnusedCategories|Неискористените категории]] не се прикажани овде.\nПогледајте ги и [[Special:WantedCategories|потребните категории]].",
        "protect-othertime": "Друго време:",
        "protect-othertime-op": "друго време",
        "protect-existing-expiry": "Постоечки рок на истекување: $3, $2",
+       "protect-existing-expiry-infinity": "Постоечки рок: бесконечен",
        "protect-otherreason": "Друга/дополнителна причина:",
        "protect-otherreason-op": "Друга причина",
        "protect-dropdown": "*Вообичаени причини за заштита\n** Зачестен вандализам\n** Зачестен спам\n** Непродуктивна уредувачка војна\n** Страница со зачестена посета\n** Сеприсутност на шаблонот/превметнувањето\n** Административна постапка",
        "unblocked": "[[User:$1|$1]] беше деблокиран",
        "unblocked-range": "корисникот $1 е одблокиран",
        "unblocked-id": "Блокирањето $1 беше отстрането",
+       "unblocked-ip": "[[Special:Contributions/$1|$1]] е одблокирана.",
        "blocklist": "Блокирани корисници",
        "ipblocklist": "Блокирани корисници",
        "ipblocklist-legend": "Најди блокиран корисник",
        "tooltip-t-contributions": "Список на придонеси на овој корисник",
        "tooltip-t-emailuser": "Испрати е-пошта на овој корисник",
        "tooltip-t-upload": "Подигни податотеки",
-       "tooltip-t-specialpages": "СпиÑ\81ок Ð½Ð° Ñ\81иÑ\82е Ñ\81пеÑ\86иÑ\98ални страници",
+       "tooltip-t-specialpages": "СпиÑ\81ок Ð½Ð° Ñ\81иÑ\82е Ñ\81лÑ\83жбени страници",
        "tooltip-t-print": "Верзија за печатење на оваа страница",
        "tooltip-t-permalink": "Постојана врска до оваа верзија на страницата",
        "tooltip-ca-nstab-main": "Преглед на содржината",
        "tooltip-ca-nstab-user": "Преглед на корисничката страница",
        "tooltip-ca-nstab-media": "Преглед на мултимедијалната податотека",
-       "tooltip-ca-nstab-special": "Ð\9eва Ðµ Ñ\81пеÑ\86иÑ\98ална Ñ\81Ñ\82Ñ\80аниÑ\86а, не можете да ја уредувате",
+       "tooltip-ca-nstab-special": "Ð\9eва Ðµ Ñ\81лÑ\83жбена Ñ\81Ñ\82Ñ\80аниÑ\86а Ð¸ Ð·Ð°Ñ\82оа не можете да ја уредувате",
        "tooltip-ca-nstab-project": "Преглед на проектната страница",
        "tooltip-ca-nstab-image": "Преглед на страницата на податотеката",
        "tooltip-ca-nstab-mediawiki": "Преглед на системската порака",
        "file-no-thumb-animation-gif": "'''Напомена: Поради технички ограничувања, минијатурите на GIF-слики со висока разложеност како оваа нема да се анимираат.'''",
        "newimages": "Галерија на нови податотеки",
        "imagelisttext": "Следи список на '''$1''' {{PLURAL:$1|податотека|податотеки}} подредени $2.",
-       "newimages-summary": "Ð\9eваа Ñ\81пеÑ\86иÑ\98ална страница ги покажува скоро подигнатите податотеки.",
+       "newimages-summary": "Ð\9eваа Ñ\81лÑ\83жбена страница ги покажува скоро подигнатите податотеки.",
        "newimages-legend": "Филтрирај",
        "newimages-label": "Име на податотека (или дел од името):",
        "newimages-showbots": "Прикажувај подигања од ботови",
        "version": "Верзија",
        "version-extensions": "Воспоставени додатоци",
        "version-skins": "Воспоставени рува",
-       "version-specialpages": "СпеÑ\86иÑ\98ални страници",
+       "version-specialpages": "СлÑ\83жбени страници",
        "version-parserhooks": "Расчленувачки куки",
        "version-variables": "Променливи",
        "version-antispam": "Спречување на спам",
        "version-entrypoints-scriptpath": "[https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:$wgScriptPath?uselang=mk Скрипта]",
        "redirect": "Пренасочување по податотеки, корисник или назнака на преработка",
        "redirect-legend": "Пренасочување кон податотека или страница",
-       "redirect-summary": "Ð\9eваа Ñ\81пеÑ\86иÑ\98ална страница пренасочува кон податотека (се задава името), страница (се задава назнаката на преработката или страницата) или корисничка странца (се задава бројчената назнака на корисникот). Употреба: [[{{#Special:Redirect}}/file/Example.jpg]], [[{{#Special:Redirect}}/revision/328429]] или [[{{#Special:Redirect}}/user/101]].",
+       "redirect-summary": "Ð\9eваа Ñ\81лÑ\83жбена страница пренасочува кон податотека (се задава името), страница (се задава назнаката на преработката или страницата) или корисничка странца (се задава бројчената назнака на корисникот). Употреба: [[{{#Special:Redirect}}/file/Example.jpg]], [[{{#Special:Redirect}}/revision/328429]] или [[{{#Special:Redirect}}/user/101]].",
        "redirect-submit": "Оди",
        "redirect-lookup": "Пребарај:",
        "redirect-value": "Вредност:",
        "fileduplicatesearch-result-1": "Податотеката „$1“ нема истоветни дупликати.",
        "fileduplicatesearch-result-n": "Податотеката „$1“ има {{PLURAL:$2|еден истоветен дупликат|$2 истоветни дупликати}}.",
        "fileduplicatesearch-noresults": "Не пронајдов податотека со име „$1“.",
-       "specialpages": "СпеÑ\86иÑ\98ални страници",
+       "specialpages": "СлÑ\83жбени страници",
        "specialpages-note-top": "Легенда",
-       "specialpages-note": "* Ð\9dоÑ\80мални Ñ\81пеÑ\86иÑ\98ални Ñ\81Ñ\82Ñ\80аниÑ\86и.\n* <span class=\"mw-specialpagerestricted\">Ð\9eгÑ\80аниÑ\87ени Ñ\81пеÑ\86иÑ\98ални страници.</span>",
+       "specialpages-note": "* Ð\9dоÑ\80мални Ñ\81лÑ\83жбени Ñ\81Ñ\82Ñ\80аниÑ\86и.\n* <span class=\"mw-specialpagerestricted\">Ð\9eгÑ\80аниÑ\87ени Ñ\81лÑ\83жбени страници.</span>",
        "specialpages-group-maintenance": "Извештаи за одржување",
-       "specialpages-group-other": "Ð\94Ñ\80Ñ\83ги Ñ\81пеÑ\86иÑ\98ални страници",
+       "specialpages-group-other": "Ð\94Ñ\80Ñ\83ги Ñ\81лÑ\83жбени страници",
        "specialpages-group-login": "Најава / регистрација",
        "specialpages-group-changes": "Скорешни промени и дневници",
        "specialpages-group-media": "Извештаи за мултимедијални содржини и подигања",
        "specialpages-group-pages": "Списоци на страници",
        "specialpages-group-pagetools": "Алатки за страници",
        "specialpages-group-wiki": "Податоци и алатки",
-       "specialpages-group-redirects": "Ð\9fÑ\80енаÑ\81оÑ\87Ñ\83ваÑ\9aе Ð½Ð° Ñ\81пеÑ\86иÑ\98ални страници",
+       "specialpages-group-redirects": "Ð\9fÑ\80енаÑ\81оÑ\87Ñ\83ваÑ\9aе Ð½Ð° Ñ\81лÑ\83жбени страници",
        "specialpages-group-spam": "Алатки против спам",
        "blankpage": "Празна страница",
        "intentionallyblankpage": "Оваа страница намерно е оставена празна",
        "dberr-info-hidden": "(Не може да се добие опслужувачот на базата на податоци)",
        "dberr-usegoogle": "Во меѓувреме можете да се обидете да пребарувате со Google.",
        "dberr-outofdate": "Да напоменеме дека нивните индекси на нашата содржина можат да бидат застарени.",
-       "dberr-cachederror": "Следнава Ñ\81одÑ\80жина Ðµ ÐºÐµÑ\88иÑ\80ана ÐºÐ¾Ð¿Ð¸Ñ\98а Ð½Ð° Ð±Ð°Ñ\80анаÑ\82а Ñ\81Ñ\82Ñ\80аниÑ\86а, ÐºÐ¾Ñ\98а Ð¼Ð¾Ð¶Ðµ Ð´Ð° Ðµ Ð·Ð°Ñ\81Ñ\82аÑ\80ена.",
+       "dberr-cachederror": "Следнава Ñ\81одÑ\80жина Ðµ Ð¼ÐµÑ\93Ñ\83Ñ\81кладиÑ\80ан Ð¿Ñ\80имеÑ\80ок Ð½Ð° Ð±Ð°Ñ\80анаÑ\82а Ñ\81Ñ\82Ñ\80аниÑ\86а, ÐºÐ¾Ñ\98 Ð¼Ð¾Ð¶Ðµ Ð´Ð° Ðµ Ð·Ð°Ñ\81Ñ\82аÑ\80ен.",
        "htmlform-invalid-input": "Има проблеми со дел од вашиот внос",
        "htmlform-select-badoption": "Укажаната вредност е неважечка како можност.",
        "htmlform-int-invalid": "Вредноста која ја наведовте не е цел број.",
        "logentry-upload-overwrite": "$1 {{GENDER:$2|подигна}} нова верзија на $3",
        "logentry-upload-revert": "$1 {{GENDER:$2|ја подигна}} $3",
        "rightsnone": "(нема)",
+       "revdelete-summary": "опис на уредување",
        "feedback-bugornote": "Ако сте спремни подробно да го опишете техничкиот проблем, тогаш [$1 пријавете грешка]. \nВо спротивно, послужете се со едноставниот образец подолу. Вашиот коментар ќе стои на страницата „[$3 $2]“, заедно со корисничкото име и прелистувачот што го користите.",
        "feedback-subject": "Наслов:",
        "feedback-message": "Порака:",
        "limitreport-expansiondepth": "Најголема длабочина на проширувањето",
        "limitreport-expensivefunctioncount": "Бр. на сложени расчленувачки функции",
        "expandtemplates": "Прошири шаблони",
-       "expand_templates_intro": "Ð\9eваа Ñ\81пеÑ\86иÑ\98ална страница зема еден текст и рекурзивно ги проширува сите шаблони во него.\nИсто така проширува и расчленувачки функции како\n<code><nowiki>{{</nowiki>#language:…}}</code> и променливи како\n<code><nowiki>{{</nowiki>CURRENTDAY}}</code>.\nВсушност, го проширува сето она што стои во двојни аглести загради.",
+       "expand_templates_intro": "Ð\9eваа Ñ\81лÑ\83жбена страница зема еден текст и рекурзивно ги проширува сите шаблони во него.\nИсто така проширува и расчленувачки функции како\n<code><nowiki>{{</nowiki>#language:…}}</code> и променливи како\n<code><nowiki>{{</nowiki>CURRENTDAY}}</code>.\nВсушност, го проширува сето она што стои во двојни аглести загради.",
        "expand_templates_title": "Наслов на контекстот, за {{FULLPAGENAME}} и тн.:",
        "expand_templates_input": "Влезен текст:",
        "expand_templates_output": "Извод",
        "log-name-pagelang": "Дневник на менување на јазикот",
        "log-description-pagelang": "Ова е дневник на менувања на јазикот на страницата.",
        "logentry-pagelang-pagelang": "$1 {{GENDER:$2|го смени}} јазикот на страницата $3 од $4 на $5.",
-       "default-skin-not-found": "За жал, основното руво на вашето вики (<code>$wgDefaultSkin</code>) — <code>$1</code> —  не е достапно.\n\nВашата воспоставка ги опфаќа следниве рува. Погледајте [https://www.mediawiki.org/wiki/Manual:Skin_configuration Прирачник: Поставување на рува] за да дознаете како да ги вклучите и како да го изберете основното.\n\n$2\n\n; Ако штотуку го имате воспоставено МедијаВики:\n: Веројатно сте го воспоставиле од git, или пак непосредно од изворниот код на некој друг начин. Ова е очекувано. Пробајте да воспоставите некои рува од [https://www.mediawiki.org/wiki/Category:All_skins mediawiki.org's именикот на рува] вака:\n* Со преземање на [https://www.mediawiki.org/wiki/Download tarball-воспоставувачот], кој самиот содржи неколку рува и додатоци. Можете да ја прекопирате папката <code>skins/</code> од него.\n* Клонирајќи едно од складиштата <code>mediawiki/skins/*</code> преку git во папката <code>skins/</code> на вашата воспоставка на МедијаВики.\n: Ова не би требало да прави пречки на вашето git-складиште ако сте програмер на МедијаВики.\n\n; Ако штотуку го имате надградено МедијаВики:\n: МедијаВики 1.24 и поновите верзии повеќе не ги вклучуваат воспоставените рува автоматски (погл. [https://www.mediawiki.org/wiki/Manual:Skin_autodiscovery Прирачник: Самооткривање на рува]). Можете да ги прекопирате следниве редови во <code>LocalSettings.php</code> за да ги вклучите сите моментално воспоставени рува:\n\n<pre>$3</pre>\n\n; Ако штотуку го имате изменето <code>LocalSettings.php</code>:\n: Проверете дали правилно се напишани називите на рувата.",
-       "default-skin-not-found-no-skins": "За жал, основното руво на вашето вики (<code>$wgDefaultSkin</code>) — <code>$1</code> —  не е достапно.\n\nНемате воспоставено ниедно руво.\n\n; Ако штотуку го имате воспоставено или надградено МедијаВики:\n: Веројатно сте го воспоставиле од git, или пак непосредно од изворниот код на некој друг начин. Ова е очекувано. МедијаВики 1.24 и поновите верзии немаат рува во главното складиште. Пробајте да воспоставите некои рува од [https://www.mediawiki.org/wiki/Category:All_skins mediawiki.org's именикот на рува] вака:\n:* Со преземање на [https://www.mediawiki.org/wiki/Download tarball-воспоставувачот], кој самиот содржи неколку рува и додатоци. Можете да ја прекопирате папката <code>skins/</code> од него.\n: Ова не би требало да прави пречки на вашето git-складиште ако сте програмер на МедијаВики. Погледајте [https://www.mediawiki.org/wiki/Manual:Skin_configuration Прирачник: Поставување на рува] за да дознаете како да ги вклучите и како да го изберете основното.",
+       "default-skin-not-found": "За жал, основното руво на вашето вики оопределено во <code dir=\"ltr\">$wgDefaultSkin</code> as <code>$1</code> не е достапно.\n\nВашата воспоставка ги опфаќа следниве рува. Погледајте [https://www.mediawiki.org/wiki/Manual:Skin_configuration Прирачник: Поставување на рува] за да дознаете како да ги вклучите и како да го изберете основното.\n\n$2\n\n; Ако штотуку го имате воспоставено МедијаВики:\n: Веројатно сте го воспоставиле од git, или пак непосредно од изворниот код на некој друг начин. Ова е очекувано. Пробајте да воспоставите некои рува од [https://www.mediawiki.org/wiki/Category:All_skins mediawiki.org's именикот на рува] вака:\n* Со преземање на [https://www.mediawiki.org/wiki/Download tarball-воспоставувачот], кој самиот содржи неколку рува и додатоци. Можете да ја прекопирате папката <code>skins/</code> од него.\n* Клонирајќи едно од складиштата <code>mediawiki/skins/*</code> преку git во папката <code dir=\"ltr\">skins/</code> на вашата воспоставка на МедијаВики.\n: Ова не би требало да прави пречки на вашето git-складиште ако сте програмер на МедијаВики.\n\n; Ако штотуку го имате надградено МедијаВики:\n: МедијаВики 1.24 и поновите верзии повеќе не ги вклучуваат воспоставените рува автоматски (погл. [https://www.mediawiki.org/wiki/Manual:Skin_autodiscovery Прирачник: Самооткривање на рува]). Можете да ги прекопирате следниве редови во <code>LocalSettings.php</code> за да ги вклучите сите моментално воспоставени рува:\n\n<pre dir=\"ltr\">$3</pre>\n\n; Ако штотуку го имате изменето <code>LocalSettings.php</code>:\n: Проверете дали правилно се напишани називите на рувата.",
+       "default-skin-not-found-no-skins": "За жал, основното руво на вашето вики, определено во <code>$wgDefaultSkin</code> како <code>$1</code>, не е достапно.\n\nНемате воспоставено ниедно руво.\n\n; Ако штотуку го имате воспоставено или надградено МедијаВики:\n: Веројатно сте го воспоставиле од git, или пак непосредно од изворниот код на некој друг начин. Ова е очекувано. МедијаВики 1.24 и поновите верзии немаат рува во главното складиште. Пробајте да воспоставите некои рува од [https://www.mediawiki.org/wiki/Category:All_skins mediawiki.org's именикот на рува] вака:\n:* Со преземање на [https://www.mediawiki.org/wiki/Download tarball-воспоставувачот], кој самиот содржи неколку рува и додатоци. Можете да ја прекопирате папката <code dir=\"ltr\">skins/</code> од него.\n: Ова не би требало да прави пречки на вашето git-складиште ако сте програмер на МедијаВики. Погледајте [https://www.mediawiki.org/wiki/Manual:Skin_configuration Прирачник: Поставување на рува] за да дознаете како да ги вклучите и како да го изберете основното.",
        "default-skin-not-found-row-enabled": "* <code>$1</code> / $2 (вклучено)",
-       "default-skin-not-found-row-disabled": "* <code>$1</code> / $2 ('''исклучено''')"
+       "default-skin-not-found-row-disabled": "* <code>$1</code> / $2 ('''исклучено''')",
+       "mediastatistics": "Статистики за слики и снимки",
+       "mediastatistics-summary": "Статистики за подигнати типови податотеки. Се зема предвид само последната верзија на податотеката. Старите и избришаните верзии не се бројат.",
+       "mediastatistics-nbytes": "{{PLURAL:$1|Еден бајт|$1 бајти}} ($2; $3%)",
+       "mediastatistics-table-mimetype": "MIME-тип",
+       "mediastatistics-table-extensions": "Можни додатоци",
+       "mediastatistics-table-count": "Број на податотеки",
+       "mediastatistics-table-totalbytes": "Вкупна големина",
+       "mediastatistics-header-unknown": "Непознато",
+       "mediastatistics-header-bitmap": "Bitmap-слика",
+       "mediastatistics-header-drawing": "Цртежи (векторски слики)",
+       "mediastatistics-header-audio": "Аудио",
+       "mediastatistics-header-video": "Видеа",
+       "mediastatistics-header-multimedia": "Збогатени снимки",
+       "mediastatistics-header-office": "Биротехнички",
+       "mediastatistics-header-text": "Текстуални",
+       "mediastatistics-header-executable": "Извршни",
+       "mediastatistics-header-archive": "Збиени формати"
 }
index 3de847e..39c279c 100644 (file)
        "otherlanguages": "ഇതരഭാഷകളിൽ",
        "redirectedfrom": "($1 എന്ന താളിൽ നിന്നും തിരിച്ചുവിട്ടതു പ്രകാരം)",
        "redirectpagesub": "തിരിച്ചുവിടൽ താൾ",
+       "redirectto": "തിരിച്ചുവിടുന്നു:",
        "lastmodifiedat": "ഈ താൾ അവസാനം തിരുത്തപ്പെട്ടത്: $2, $1.",
        "viewcount": "ഈ താൾ {{PLURAL:$1|ഒരു തവണ|$1 തവണ}} സന്ദർശിക്കപ്പെട്ടിട്ടുണ്ട്.",
        "protectedpage": "സംരക്ഷിത താൾ",
        "createaccount-text": "{{SITENAME}} സംരംഭത്തിൽ ($4) താങ്കളുടെ ഇമെയിൽ വിലാസത്തിൽ ആരോ ഒരു അംഗത്വം \"$2\" എന്ന ഉപയോക്തൃനാമത്തിൽ ഉണ്ടാക്കിയിരിക്കുന്നു (രഹസ്യവാക്ക്: \"$3\").  താങ്കൾ ഇപ്പോൾ ലോഗിൻ ചെയ്തു രഹസ്യവാക്ക് മാറ്റേണ്ടതാകുന്നു.\n\nഅംഗത്വം അബദ്ധവശാൽ ഉണ്ടാക്കിയതാണെങ്കിൽ താങ്കൾക്ക് ഈ സന്ദേശം നിരാകരിക്കാവുന്നതാണ്‌.",
        "login-throttled": "താങ്കൾ നിരവധി പ്രാവശ്യം ലോഗിൻ ചെയ്യാൻ ശ്രമിച്ചിരിക്കുന്നു.\nപുതിയതായി ശ്രമിക്കുന്നതിനു മുമ്പ് $1 ദയവായി കാത്തിരിക്കുക.",
        "login-abort-generic": "താങ്കളുടെ പ്രവേശിക്കൽ പരാജയപ്പെട്ടു - റദ്ദാക്കപ്പെട്ടിരിക്കുന്നു",
+       "login-migrated-generic": "താങ്കളുടെ അംഗത്വം പ്രവാസത്തിലാണ്, ഉപയോക്തൃനാമം ഈ വിക്കിയിൽ നിലവിലില്ല.",
        "loginlanguagelabel": "ഭാഷ: $1",
        "suspicious-userlogout": "ലോഗൗട്ട് ചെയ്യാനുള്ള താങ്കളുടെ അഭ്യർത്ഥന നിരസിച്ചിരിക്കുന്നു, കാരണം അത് കേടായ ബ്രൗസറിൽ നിന്നോ കാഷിങ് പ്രോക്സിയിൽ നിന്നോ ഉണ്ടായതുപോലെ അനുഭവപ്പെടുന്നു.",
        "createacct-another-realname-tip": "താങ്കളുടെ യഥാർത്ഥ പേര്‌ നൽകണമെന്നു നിർബന്ധമില്ല.\n\nഎങ്കിലും അങ്ങനെ ചെയ്താൽ, ഉപയോക്താക്കൾക്ക് അവരരവരുടെ പേരിൽ തന്നെ തങ്ങളുടെ സൃഷ്ടിക്ക് കടപ്പാട് ലഭിക്കുന്നതാണ്.",
        "passwordreset-emailsent-capture": "രഹസ്യവാക്ക് പുനർസജ്ജീകരണ ഇമെയിൽ അയച്ചിട്ടുണ്ട്, അത് താഴെക്കൊടുക്കുന്നു.",
        "passwordreset-emailerror-capture": "താഴെക്കൊടുത്തിരിക്കുന്ന, രഹസ്യവാക്ക് പുനർസജ്ജീകരണ ഇമെയിൽ സൃഷ്ടിക്കാനായെങ്കിലും, അത് {{GENDER:$2|ഉപയോക്താവിന്}} അയയ്ക്കുന്നത് പരാജയപ്പെട്ടു: $1",
        "changeemail": "ഇമെയിൽ വിലാസത്തിൽ മാറ്റംവരുത്തുക",
-       "changeemail-header": "അംഗത്വത്തിന്റെ ഇമെയിൽ വിലാസത്തിൽ മാറ്റംവരുത്തുക",
        "changeemail-text": "താങ്കളുടെ ഇമെയിൽ വിലാസത്തിൽ മാറ്റംവരുത്താൻ ഈ ഫോം പൂരിപ്പിച്ചു നൽകുക. മാറ്റം സ്ഥിരീകരിക്കാനായി താങ്കളുടെ രഹസ്യവാക്ക് കൂടെ നൽകേണ്ടതാണ്.",
        "changeemail-no-info": "ഈ താൾ നേരിട്ടു കാണുന്നതിന് താങ്കൾ ലോഗിൻ ചെയ്തിരിക്കണം.",
        "changeemail-oldemail": "ഇപ്പോഴത്തെ ഇമെയിൽ വിലാസം:",
        "changeemail-none": "(ഒന്നുമില്ല)",
        "changeemail-password": "താങ്കളുടെ {{SITENAME}} രഹസ്യവാക്ക്:",
        "changeemail-submit": "ഇമെയിലിൽ മാറ്റംവരുത്തുക",
-       "changeemail-cancel": "റദ്ദാക്കുക",
        "changeemail-throttled": "താങ്കൾ നിരവധി തവണ പ്രവേശിക്കാൻ ശ്രമിച്ചിരിക്കുന്നു.\nവീണ്ടും ശ്രമിക്കുന്നതിനു മുമ്പ് ദയവായി $1 കാത്തിരിക്കുക.",
        "resettokens": "ചീട്ടുകൾ പുനഃസജ്ജീകരിക്കുക",
        "resettokens-text": "താങ്കളുടെ അംഗത്വവുമായി ബന്ധപ്പെട്ടുള്ള ചില സ്വകാര്യവിവരങ്ങളിലേയ്ക്ക് ഇവിടെ ലഭ്യത സാദ്ധ്യമാക്കുന്ന ചീട്ടുകൾ താങ്കൾക്ക് പുനഃസജ്ജീകരിക്കാവുന്നതാണ്.\n\nതാങ്കളുടെ അംഗത്വവിവരങ്ങൾ മറ്റാർക്കെങ്കിലും അറിയാതെ കൈമാറിയിട്ടുണ്ടെങ്കിലോ താങ്കളുടെ അംഗത്വം അപഹരിക്കപ്പെട്ടുവെങ്കിലോ താങ്കളിത്  ചെയ്യേണ്ടതാണ്.",
        "searchall": "എല്ലാം",
        "showingresults": "'''$2''' മുതലുള്ള {{PLURAL:$1|'''ഒരു''' ഫലം|'''$1''' ഫലങ്ങൾ}} താഴെ പ്രദർശിപ്പിക്കുന്നു.",
        "showingresultsinrange": "#<strong>$2</strong> മുതൽ #<strong>$3</strong> വരെയുള്ള പരിധിയിലെ {{PLURAL:$1|<strong>ഒരു</strong> ഫലം|<strong>$1</strong> ഫലങ്ങൾ}} താഴെ പ്രദർശിപിക്കുന്നു.",
-       "showingresultsheader": "'''$4''' എന്ന പദത്തിനു ആകെ ലഭിച്ച {{PLURAL:$5| '''$3''' ഫലത്തിൽ '''$1''' എണ്ണം|'''$3''' ഫലത്തിൽ '''$1 മുതൽ $2''' വരെയുള്ളവ}}",
+       "search-showingresults": "{{PLURAL:$4|<strong>$3</strong> ഫലത്തിൽ<strong>$1</strong>|<strong>$3</strong> ഫലത്തിൽ <strong>$1 മുതൽ $2</strong> വരെയുള്ളവ}}",
        "search-nonefound": "താങ്കൾ തിരഞ്ഞ പദത്തിനു യോജിച്ച ഫലങ്ങളൊന്നും ലഭിച്ചില്ല.",
        "powersearch-legend": "വിപുലീകൃത തിരച്ചിൽ",
        "powersearch-ns": "തിരയേണ്ട നാമമേഖലകൾ",
        "prefs-tokenwatchlist": "ചീട്ട്",
        "prefs-diffs": "വ്യത്യാസങ്ങൾ",
        "prefs-help-prefershttps": "താങ്കൾ അടുത്ത പ്രാവശ്യം പ്രവേശിക്കുമ്പോൾ ഇവ ഫലത്തിൽ വരുന്നതാണ്.",
+       "prefswarning-warning": "താങ്കളുടെ ക്രമീകരണങ്ങളിൽ താങ്കൾ വരുത്തിയ മാറ്റങ്ങൾ ഇതുവരെ സേവ് ചെയ്തിട്ടില്ല.\n\"$1\" ഞെക്കാതെയാണ് താങ്കൾ ഈ താളിൽ നിന്നും പോകുന്നതെങ്കിൽ താങ്കളുടെ ക്രമീകരണങ്ങൾ സേവ് ചെയ്യപ്പെടുന്നതല്ല.",
        "prefs-tabs-navigation-hint": "സൂചന: ടാബുകളുടെ പട്ടികയിലെ ടാബുകളിലൂടെ നീങ്ങാൻ ഇടത്തും വലത്തും ആരോ കീകൾ ഉപയോഗിക്കാവുന്നതാണ്.",
        "email-address-validity-valid": "സാധുതയുള്ളതെന്ന് തോന്നുന്നു",
        "email-address-validity-invalid": "സാധുതയുള്ള വിലാസം ആവശ്യമാണ്!",
        "protect-othertime": "മറ്റ് കാലാവധി:",
        "protect-othertime-op": "മറ്റു കാലയളവ്",
        "protect-existing-expiry": "നിലവിലെ കാലാവധി: $3, $2",
+       "protect-existing-expiry-infinity": "നിലവിലെ കാലഹരണപ്പെടൽ കാലാവധി: അനന്തം",
        "protect-otherreason": "മറ്റ്/കൂടുതൽ കാരണം:",
        "protect-otherreason-op": "മറ്റ് കാരണം",
        "protect-dropdown": "*സംരക്ഷിക്കാനുള്ള കാരണങ്ങൾ\n** അമിതമായ നശീകരണപ്രവർത്തനങ്ങൾ\n** അമിതമായ പാഴെഴുത്ത് ഉൾപ്പെടുത്തൽ\n** സൃഷ്ടിപരമല്ലാതെ ഭവിക്കുന്ന തിരുത്തൽ യുദ്ധം\n** സന്ദർശകരുടെ എണ്ണം വളരെ കൂടുതലായ താൾ",
        "unblockiptext": "മുൻപ് തടയപ്പെട്ട ഐ.പി.യുടേയും ഉപയോക്താവിന്റേയും തിരുത്തൽ അവകാശം പുനഃസ്ഥാപിക്കാൻ താഴെയുള്ള ഫോം ഉപയോഗിക്കുക.",
        "ipusubmit": "ഈ വിലക്ക് ഒഴിവാക്കുക",
        "unblocked": "[[User:$1|$1]] എന്ന ഉപയോക്താവിനുണ്ടായിരുന്ന തടയൽ നീക്കിയിരിക്കുന്നു",
-       "unblocked-range": "$1 എന്ന പരിധിയുടെ തടയൽ നീക്കപ്പെട്ടിരിക്കുന്നു",
-       "unblocked-id": "$1 എന്ന തടയൽ നീക്കം ചെയ്തിരിക്കുന്നു",
+       "unblocked-range": "$1 എന്ന പരിധിയുടെ തടയൽ നീക്കിയിരിക്കുന്നു.",
+       "unblocked-id": "$1 എന്ന തടയൽ നീക്കിയിരിക്കുന്നു.",
+       "unblocked-ip": "[[Special:Contributions/$1|$1]] എന്ന വിലാസത്തിനുണ്ടായിരുന്ന തടയൽ നീക്കിയിരിക്കുന്നു.",
        "blocklist": "തടയപ്പെട്ട ഉപയോക്താക്കൾ",
        "ipblocklist": "തടയപ്പെട്ട ഉപയോക്താക്കൾ",
        "ipblocklist-legend": "തടഞ്ഞ ഒരു ഉപയോക്താവിനെ തിരയുക",
        "logentry-upload-overwrite": "$1 ഒരു പുതിയ പതിപ്പ് $3 {{GENDER:$2|അപ്‌ലോഡ് ചെയ്തു}}",
        "logentry-upload-revert": "$1 $3 {{GENDER:$2|അപ്‌ലോഡ് ചെയ്തു}}",
        "rightsnone": "(ഒന്നുമില്ല)",
+       "revdelete-summary": "തിരുത്തലിന്റെ ചുരുക്കം",
        "feedback-bugornote": "സാങ്കേതിക പ്രശ്നം എന്താണെന്ന് വിവരിച്ചെഴുതാൻ താങ്കൾ തയ്യാറാണെങ്കിൽ [$1 ബഗ് അറിയിക്കുക].\nഅല്ലെങ്കിൽ താങ്കൾക്ക് താഴെ എളുപ്പത്തിനായി നൽകിയിരിക്കുന്ന ഫോം ഉപയോഗിക്കാം. താങ്കളുടെ കുറിപ്പ് \"[$3 $2]\" താളിൽ, താങ്കളുടെ ഉപയോക്തൃനാമത്തിന്റെയും ഉപയോഗിക്കുന്ന ബ്രൗസറിന്റെ പേരിന്റെയും ഒപ്പം ചേർക്കുന്നതായിരിക്കും.",
        "feedback-subject": "വിഷയം:",
        "feedback-message": "സന്ദേശം:",
        "log-name-pagelang": "ഭാഷ മാറ്റലിന്റെ രേഖ",
        "log-description-pagelang": "താളുകളുടെ ഭാഷകൾ മാറ്റിയതിന്റെ രേഖകൾ ഇവിടെക്കാണാം.",
        "logentry-pagelang-pagelang": "$3 എന്ന താളിന്റെ ഭാഷയായിരുന്ന $4, $1 $5 ആയി {{GENDER:$2|മാറ്റി}}.",
-       "default-skin-not-found": "അയ്യോ! താങ്കളുടെ വിക്കിയുടെ സ്വതേയുള്ള ദൃശ്യരൂപമായ (<code>$wgDefaultSkin</code>), <code>$1</code>, ലഭ്യമല്ല.\n\nതാങ്കളുടെ ഇൻസ്റ്റലേഷനിൽ താഴെക്കൊടുക്കുന്ന ദൃശ്യരൂപങ്ങൾ ഉണ്ടാകേണ്ടതാണ്. അവ എങ്ങനെ ക്രമീകരിക്കാം എന്നും സ്വതേ വേണ്ടത് എങ്ങനെ സജ്ജമാക്കാം എന്നും [https://www.mediawiki.org/wiki/Manual:Skin_configuration ദൃശ്യരൂപം സജ്ജമാക്കൽ സഹായിയിൽ] കാണുക.\n\n$2\n\n; താങ്കൾ മീഡിയവിക്കി ഇൻസ്റ്റോൾ ചെയ്തതേ ഉള്ളുവെങ്കിൽ:\n: ഗിറ്റിൽ നിന്ന് അല്ലെങ്കിൽ മറ്റെങ്കിലും മാർഗ്ഗം ഉപയോഗിച്ച് സോഴ്സ് കോഡ് നേരിട്ട് ഉപയോഗിക്കുകയായിരിന്നെങ്കിൽ ഇത് സംഭവിച്ചേക്കാം. [https://www.mediawiki.org/wiki/Category:All_skins mediawiki.org's ദൃശ്യരൂപ ഡയറക്ടറിയിൽ നിന്ന്], ഇനിക്കൊടുക്കുന്ന മാർഗ്ഗങ്ങൾ ഉപയോഗിച്ച് ഏതാനം ദൃശ്യരൂപങ്ങൾ ഇൻസ്റ്റോൾ ചെയ്യാൻ നോക്കുക:\n:* [https://www.mediawiki.org/wiki/Download ടാർബോൾ ഇൻസ്റ്റോളർ] ഡൗൺലോഡ് ചെയ്യുക, അതിൽ നിരവധി ദൃശ്യരൂപങ്ങളും അനുബന്ധങ്ങളും ഉൾപ്പെടുത്തിയിരിക്കുന്നു. അതിൽ നിന്നും താങ്കൾക്ക് <code>skins/</code> ഡയറക്ടറി പകർത്താവുന്നതാണ്.\n:* താങ്കളുടെ മീഡിയവിക്കി ഇൻസ്റ്റലേഷന്റെ <code>skins/</code> ഡയറക്ടറിയിലേക്ക് ഗിറ്റ് ഉപയോഗിച്ച് <code>mediawiki/skins/*</code> റെപ്പോസിറ്ററികളിലൊന്ന് ക്ലോൺ ചെയ്യുക.\n: താങ്കളൊരു മീഡിയവിക്കി ഡവലപ്പറാണെങ്കിൽ ഇത് താങ്കളുടെ ഗിറ്റ് ഡെപ്പോസിറ്ററിയെ ബാധിക്കുന്നതല്ല.\n\n; മീഡിയവിക്കി താങ്കൾ അപ്ഗ്രേഡ് ചെയ്തതേ ഉള്ളുവെങ്കിൽ:\n: മീഡിയവിക്കി 1.24 ഒപ്പം അതിനു ശേഷമുള്ളവയും ഇൻസ്റ്റോൾ ചെയ്തിട്ടുള്ള ദൃശ്യരൂപങ്ങൾ സ്വതേ സജ്ജമാക്കുന്നില്ല ([https://www.mediawiki.org/wiki/Manual:Skin_autodiscovery ദൃശ്യരൂപം ഓട്ടോഡിസ്കവറി സഹായം] കാണുക). ഇൻസ്റ്റോൾ ചെയ്തിട്ടുള്ള ദൃശ്യരൂപങ്ങൾ സജ്ജമാക്കുന്നതിനായി ഇനിക്കൊടുക്കുന്ന വരികൾ <code>LocalSettings.php</code> എന്നതിലോട്ട് പകർത്തുക:\n\n<pre>$3</pre>\n\n; <code>LocalSettings.php</code> താളിൽ മാറ്റം വരുത്തിയതേയുള്ളുവെങ്കിൽ:\n: ദൃശ്യരൂപങ്ങളുടെ പേരിൽ അക്ഷരപിശകുകളുണ്ടോയെന്ന് ആവർത്തിച്ച് പരിശോധിക്കുക.",
-       "default-skin-not-found-no-skins": "അയ്യോ! താങ്കളുടെ വിക്കിയുടെ സ്വതേയുള്ള ദൃശ്യരൂപമായ (<code>$wgDefaultSkin</code>), <code>$1</code>, ലഭ്യമല്ല.\n\nതാങ്കൾ ദൃശ്യരൂപങ്ങളൊന്നും ഇൻസ്റ്റോൾ ചെയ്തിട്ടില്ല.\n\n; താങ്കൾ മീഡിയവിക്കി ഇൻസ്റ്റോൾ ചെയ്തതേ അല്ലെങ്കിൽ അപ്‌ഗ്രേഡ് ചെയ്തതേ ഉള്ളുവെങ്കിൽ:\n: ഗിറ്റിൽ നിന്ന് അല്ലെങ്കിൽ മറ്റെങ്കിലും മാർഗ്ഗം ഉപയോഗിച്ച് സോഴ്സ് കോഡ് നേരിട്ട് ഉപയോഗിക്കുകയായിരിന്നെങ്കിൽ ഇത് സംഭവിച്ചേക്കാം. [https://www.mediawiki.org/wiki/Category:All_skins mediawiki.org's ദൃശ്യരൂപ ഡയറക്ടറിയിൽ നിന്ന്], ഇനിക്കൊടുക്കുന്ന മാർഗ്ഗങ്ങൾ ഉപയോഗിച്ച് ഏതാനം ദൃശ്യരൂപങ്ങൾ ഇൻസ്റ്റോൾ ചെയ്യാൻ നോക്കുക:\n:* [https://www.mediawiki.org/wiki/Download ടാർബോൾ ഇൻസ്റ്റോളർ] ഡൗൺലോഡ് ചെയ്യുക, അതിൽ നിരവധി ദൃശ്യരൂപങ്ങളും അനുബന്ധങ്ങളും ഉൾപ്പെടുത്തിയിരിക്കുന്നു. അതിൽ നിന്നും താങ്കൾക്ക് <code>skins/</code> ഡയറക്ടറി പകർത്താവുന്നതാണ്.\n:* താങ്കളുടെ മീഡിയവിക്കി ഇൻസ്റ്റലേഷന്റെ <code>skins/</code> ഡയറക്ടറിയിലേക്ക് ഗിറ്റ് ഉപയോഗിച്ച് <code>mediawiki/skins/*</code> റെപ്പോസിറ്ററികളിലൊന്ന് ക്ലോൺ ചെയ്യുക.\n: താങ്കളൊരു മീഡിയവിക്കി ഡവലപ്പറാണെങ്കിൽ ഇത് താങ്കളുടെ ഗിറ്റ് ഡെപ്പോസിറ്ററിയെ ബാധിക്കുന്നതല്ല. ദൃശ്യരൂപങ്ങൾ എങ്ങനെ ക്രമീകരിക്കാം എന്നും സ്വതേ വേണ്ടത് എങ്ങനെ സജ്ജമാക്കാം എന്നും [https://www.mediawiki.org/wiki/Manual:Skin_configuration ദൃശ്യരൂപം സജ്ജമാക്കൽ സഹായിയിൽ] കാണുക.",
+       "default-skin-not-found": "അയ്യോ! <code dir=\"ltr\"> $wgDefaultSkin</code> നിർവചിക്കപ്പെട്ടതുപ്രകാരമുള്ള താങ്കളുടെ വിക്കിയുടെ സ്വതേയുള്ള ദൃശ്യരൂപമായ <code>$1</code>, ലഭ്യമല്ല.\n\nതാങ്കളുടെ ഇൻസ്റ്റലേഷനിൽ താഴെക്കൊടുക്കുന്ന ദൃശ്യരൂപങ്ങൾ ഉണ്ടാകേണ്ടതാണ്. അവ എങ്ങനെ ക്രമീകരിക്കാം എന്നും സ്വതേ വേണ്ടത് എങ്ങനെ സജ്ജമാക്കാം എന്നും [https://www.mediawiki.org/wiki/Manual:Skin_configuration ദൃശ്യരൂപം സജ്ജമാക്കൽ സഹായിയിൽ] കാണുക.\n\n$2\n\n; താങ്കൾ മീഡിയവിക്കി ഇൻസ്റ്റോൾ ചെയ്തതേ ഉള്ളുവെങ്കിൽ:\n: ഗിറ്റിൽ നിന്ന് അല്ലെങ്കിൽ മറ്റെങ്കിലും മാർഗ്ഗം ഉപയോഗിച്ച് സോഴ്സ് കോഡ് നേരിട്ട് ഉപയോഗിക്കുകയായിരിന്നെങ്കിൽ ഇത് സംഭവിച്ചേക്കാം. [https://www.mediawiki.org/wiki/Category:All_skins mediawiki.org's ദൃശ്യരൂപ ഡയറക്ടറിയിൽ നിന്ന്], ഇനിക്കൊടുക്കുന്ന മാർഗ്ഗങ്ങൾ ഉപയോഗിച്ച് ഏതാനം ദൃശ്യരൂപങ്ങൾ ഇൻസ്റ്റോൾ ചെയ്യാൻ നോക്കുക:\n:* [https://www.mediawiki.org/wiki/Download ടാർബോൾ ഇൻസ്റ്റോളർ] ഡൗൺലോഡ് ചെയ്യുക, അതിൽ നിരവധി ദൃശ്യരൂപങ്ങളും അനുബന്ധങ്ങളും ഉൾപ്പെടുത്തിയിരിക്കുന്നു. അതിൽ നിന്നും താങ്കൾക്ക് <code>skins/</code> ഡയറക്ടറി പകർത്താവുന്നതാണ്.\n:* താങ്കളുടെ മീഡിയവിക്കി ഇൻസ്റ്റലേഷന്റെ <code dir=\"ltr\">skins/</code> ഡയറക്ടറിയിലേക്ക് ഗിറ്റ് ഉപയോഗിച്ച് <code>mediawiki/skins/*</code> റെപ്പോസിറ്ററികളിലൊന്ന് ക്ലോൺ ചെയ്യുക.\n: താങ്കളൊരു മീഡിയവിക്കി ഡവലപ്പറാണെങ്കിൽ ഇത് താങ്കളുടെ ഗിറ്റ് ഡെപ്പോസിറ്ററിയെ ബാധിക്കുന്നതല്ല.\n\n; മീഡിയവിക്കി താങ്കൾ അപ്ഗ്രേഡ് ചെയ്തതേ ഉള്ളുവെങ്കിൽ:\n: മീഡിയവിക്കി 1.24 ഒപ്പം അതിനു ശേഷമുള്ളവയും ഇൻസ്റ്റോൾ ചെയ്തിട്ടുള്ള ദൃശ്യരൂപങ്ങൾ സ്വതേ സജ്ജമാക്കുന്നില്ല ([https://www.mediawiki.org/wiki/Manual:Skin_autodiscovery ദൃശ്യരൂപം ഓട്ടോഡിസ്കവറി സഹായം] കാണുക). ഇൻസ്റ്റോൾ ചെയ്തിട്ടുള്ള ദൃശ്യരൂപങ്ങൾ സജ്ജമാക്കുന്നതിനായി ഇനിക്കൊടുക്കുന്ന വരികൾ <code>LocalSettings.php</code> എന്നതിലോട്ട് പകർത്തുക:\n\n<pre dir=\"ltr\">$3</pre>\n\n; <code>LocalSettings.php</code> താളിൽ മാറ്റം വരുത്തിയതേയുള്ളുവെങ്കിൽ:\n: ദൃശ്യരൂപങ്ങളുടെ പേരിൽ അക്ഷരപിശകുകളുണ്ടോയെന്ന് ആവർത്തിച്ച് പരിശോധിക്കുക.",
+       "default-skin-not-found-no-skins": "അയ്യോ! <code dir=\"ltr\"> $wgDefaultSkin</code> നിർവചിക്കപ്പെട്ടതുപ്രകാരമുള്ള താങ്കളുടെ വിക്കിയുടെ സ്വതേയുള്ള ദൃശ്യരൂപമായ <code>$1</code>, ലഭ്യമല്ല.\n\nതാങ്കൾ ദൃശ്യരൂപങ്ങളൊന്നും ഇൻസ്റ്റോൾ ചെയ്തിട്ടില്ല.\n\n; താങ്കൾ മീഡിയവിക്കി ഇൻസ്റ്റോൾ ചെയ്തതേ അല്ലെങ്കിൽ അപ്‌ഗ്രേഡ് ചെയ്തതേ ഉള്ളുവെങ്കിൽ:\n: ഗിറ്റിൽ നിന്ന് അല്ലെങ്കിൽ മറ്റെങ്കിലും മാർഗ്ഗം ഉപയോഗിച്ച് സോഴ്സ് കോഡ് നേരിട്ട് ഉപയോഗിക്കുകയായിരിന്നെങ്കിൽ ഇത് സംഭവിച്ചേക്കാം. [https://www.mediawiki.org/wiki/Category:All_skins mediawiki.org's ദൃശ്യരൂപ ഡയറക്ടറിയിൽ നിന്ന്], ഇനിക്കൊടുക്കുന്ന മാർഗ്ഗങ്ങൾ ഉപയോഗിച്ച് ഏതാനം ദൃശ്യരൂപങ്ങൾ ഇൻസ്റ്റോൾ ചെയ്യാൻ നോക്കുക:\n:* [https://www.mediawiki.org/wiki/Download ടാർബോൾ ഇൻസ്റ്റോളർ] ഡൗൺലോഡ് ചെയ്യുക, അതിൽ നിരവധി ദൃശ്യരൂപങ്ങളും അനുബന്ധങ്ങളും ഉൾപ്പെടുത്തിയിരിക്കുന്നു. അതിൽ നിന്നും താങ്കൾക്ക് <code>skins/</code> ഡയറക്ടറി പകർത്താവുന്നതാണ്.\n:* താങ്കളുടെ മീഡിയവിക്കി ഇൻസ്റ്റലേഷന്റെ <code dir=\"ltr\">skins/</code> ഡയറക്ടറിയിലേക്ക് ഗിറ്റ് ഉപയോഗിച്ച് <code>mediawiki/skins/*</code> റെപ്പോസിറ്ററികളിലൊന്ന് ക്ലോൺ ചെയ്യുക.\n: താങ്കളൊരു മീഡിയവിക്കി ഡവലപ്പറാണെങ്കിൽ ഇത് താങ്കളുടെ ഗിറ്റ് ഡെപ്പോസിറ്ററിയെ ബാധിക്കുന്നതല്ല. ദൃശ്യരൂപങ്ങൾ എങ്ങനെ ക്രമീകരിക്കാം എന്നും സ്വതേ വേണ്ടത് എങ്ങനെ സജ്ജമാക്കാം എന്നും [https://www.mediawiki.org/wiki/Manual:Skin_configuration ദൃശ്യരൂപം സജ്ജമാക്കൽ സഹായിയിൽ] കാണുക.",
        "default-skin-not-found-row-enabled": "* <code>$1</code> / $2 (സജ്ജം)",
-       "default-skin-not-found-row-disabled": "* <code>$1</code> / $2 ('''സജ്ജമല്ല''')"
+       "default-skin-not-found-row-disabled": "* <code>$1</code> / $2 ('''സജ്ജമല്ല''')",
+       "mediastatistics": "മീഡിയ സ്ഥിതിവിവരക്കണക്കുകൾ",
+       "mediastatistics-summary": "അപ്‌ലോഡ് ചെയ്തിട്ടുള്ള പ്രമാണ തരങ്ങളെക്കുറിച്ചുള്ള സ്ഥിതിവിവരക്കണക്കുകൾ. ഇത് പ്രമാണത്തിന്റെ ഏറ്റവും പുതിയ പതിപ്പ് മാത്രമേ ഉൾക്കൊള്ളുന്നുള്ളു. പഴയ അഥവാ മായ്ക്കപ്പെട്ട പ്രമാണപതിപ്പുകൾ ഉൾക്കൊള്ളുന്നില്ല.",
+       "mediastatistics-nbytes": "{{PLURAL:$1|ഒരു ബൈറ്റ്|$1 ബൈറ്റ്}} ($2; $3%)",
+       "mediastatistics-table-mimetype": "മൈം(MIME) തരം",
+       "mediastatistics-table-extensions": "സാദ്ധ്യതയുള്ള എക്സ്റ്റെൻഷനുകൾ",
+       "mediastatistics-table-count": "പ്രമാണങ്ങളുടെ എണ്ണം",
+       "mediastatistics-table-totalbytes": "ആകെ വലിപ്പം",
+       "mediastatistics-header-unknown": "അജ്ഞാതം",
+       "mediastatistics-header-bitmap": "ബിറ്റ്മാപ് ചിത്രങ്ങൾ",
+       "mediastatistics-header-drawing": "വരകൾ (വെക്റ്റർ ചിത്രങ്ങൾ)",
+       "mediastatistics-header-audio": "ശബ്ദം",
+       "mediastatistics-header-video": "ചലച്ചിത്രങ്ങൾ",
+       "mediastatistics-header-multimedia": "റിച്ച് മീഡിയ",
+       "mediastatistics-header-office": "ആപ്പീസ്",
+       "mediastatistics-header-text": "എഴുത്ത്",
+       "mediastatistics-header-executable": "എക്സിക്യൂട്ടബിളുകൾ",
+       "mediastatistics-header-archive": "ചുരുക്കിയ ഫയൽതരങ്ങൾ"
 }
index 13d640d..5cf1f64 100644 (file)
        "otherlanguages": "Dalam bahasa lain",
        "redirectedfrom": "(Dilencongkan dari $1)",
        "redirectpagesub": "Laman lencongan",
+       "redirectto": "Lencong ke:",
        "lastmodifiedat": "Laman ini diubah buat kali terakhir pada $2, $1.",
        "viewcount": "Laman ini telah dilihat {{PLURAL:$1|sekali|sebanyak $1 kali}}.",
        "protectedpage": "Laman dilindungi",
        "passwordreset-emailsent-capture": "E-mel set semula kata laluan telah dihantar, seperti yang dipaparkan di bawah.",
        "passwordreset-emailerror-capture": "E-mel set semula kata laluan telah dihasilkan, seperti yang dipaparkan di bawah, tetapi tidak berjaya dihantar kepada {{GENDER:$2|pengguna}} berkenaan: $1",
        "changeemail": "Tukar alamat e-mel",
-       "changeemail-header": "Tukar alamat e-mel akaun",
        "changeemail-text": "Lengkapkan borang ini untuk menukar alamat e-mel anda. Anda akan perlu mengisikan kata laluan untuk mengesahkan perubahan ini.",
        "changeemail-no-info": "Anda hendaklah log masuk terlebih dahulu untuk mencapai laman ini secara terus.",
        "changeemail-oldemail": "Alamat e-mel sekarang:",
        "changeemail-none": "(tiada)",
        "changeemail-password": "Kata laluan anda di {{SITENAME}}:",
        "changeemail-submit": "Tukar E-mel",
-       "changeemail-cancel": "Batalkan",
        "changeemail-throttled": "Anda telah melakukan terlalu banyak cubaan log masuk.\nSila tunggu $1 dan cuba lagi.",
        "resettokens": "Set semula token",
        "resettokens-text": "Anda boleh mengeset semula token yang membolehkan akses kepada data peribadi tertentu yang berkaitan dengan akaun anda di sini.\n\nAnda harus melakukannya jika anda tanpa sengaja mengongsinya dengan sesiapa ataupun akaun anda telah dikompromi.",
        "searchall": "semua",
        "showingresults": "Yang berikut ialah '''$1''' hasil bermula daripada yang {{PLURAL:$2|pertama|ke-'''$2'''}}.",
        "showingresultsinrange": "Yang berikut adalah {{PLURAL:$1|<strong>satu</strong> hasil|sebanyak <strong>$1</strong> hasil}} dalam julat #<strong>$2</strong> hingga #<strong>$3</strong>.",
-       "showingresultsheader": "{{PLURAL:$5|Keputusan '''$1''' daripada '''$3'''|Keputusan '''$1 - $2''' daripada '''$3'''}} untuk '''$4'''",
        "search-nonefound": "Tiada hasil yang sepadan dengan pertanyaan.",
        "powersearch-legend": "Carian lanjutan",
        "powersearch-ns": "Cari dalam ruang nama:",
        "logentry-upload-overwrite": "$1 telah {{GENDER:$2|muat naik}} versi baru $3",
        "logentry-upload-revert": "$1 telah {{GENDER:$2|muat naik}} $3",
        "rightsnone": "(tiada)",
+       "revdelete-summary": "ringkasan",
        "feedback-bugornote": "Jika anda bersedia untuk menerangkan masalah teknikal secara terperinci, sila [$1 laporkan pepijat]. \nAtaupun, anda boleh menggunakan borang yang mudah di bawah. Ulasan anda akan dicatatkan pada laman \"[$3 $2]\", beserta nama pengguna anda dan pelayar yang anda gunakan.",
        "feedback-subject": "Perkara:",
        "feedback-message": "Pesanan:",
index 1f9e32a..0b217ff 100644 (file)
        "passwordreset-emailsent-capture": "Intbagħtet ittra-e għall-ssettjar mill-ġdid tal-password u l-kontenut jidher hawn taħt.",
        "passwordreset-emailerror-capture": "Ġiet ġenerata ittra-e ta' tfakkira, li l-kontenut tagħha jidher hawn taħt. Madanakollu, il-posta ma ntbagħtitx lill-utent: $1",
        "changeemail": "Biddel l-indirizz elettroniku",
-       "changeemail-header": "Biddel l-indirizz elettroniku tal-kont",
        "changeemail-text": "Kompli din il-formola sabiex tbiddel l-indirizz elettroniku. Trid iddaħħal il-password biex tikkonferma din il-bidla.",
        "changeemail-no-info": "Trid tkun dħalt fil-kont tiegħek sabiex taċċessa direttament din il-paġna.",
        "changeemail-oldemail": "Indirizz elettroniku attwali:",
        "changeemail-none": "(xejn)",
        "changeemail-password": "Il-password tiegħek fuq {{SITENAME}}:",
        "changeemail-submit": "Biddel l-indirizz elettroniku",
-       "changeemail-cancel": "Annulla",
        "changeemail-throttled": "Ippruvajt tidħol wisq drabi.\nJekk jogħġbok stenna $1 qabel ma terġa' tipprova.",
        "resettokens": "Irrisettja t-tokens",
        "bold_sample": "Tipa ħoxna",
        "searchrelated": "relatati",
        "searchall": "kollha",
        "showingresults": "Hawn taħt ġie inkluż massimu ta' {{PLURAL:$1|riżultat '''1''' li jibda|'''$1''' riżultat li jibdew}} bin-numru '''$2'''.",
-       "showingresultsheader": "{{PLURAL:$5|Riżultat '''$1''' minn '''$3'''|Riżultati '''$1 - $2''' minn '''$3'''}} għal '''$4'''",
        "search-nonefound": "It-tfittxija ma tat l-ebda riżultat.",
        "powersearch-legend": "Tfittxija avvanzata",
        "powersearch-ns": "Fittex fl-ispazju tal-isem:",
        "protect-othertime": "Ħin ieħor:",
        "protect-othertime-op": "ħin ieħor",
        "protect-existing-expiry": "Skadenza attwali: $2, $3",
+       "protect-existing-expiry-infinity": "Ħin ta' skadenza eżistenti: infinit",
        "protect-otherreason": "Raġunijiet oħra/addizzjonali:",
        "protect-otherreason-op": "Raġuni oħra",
        "protect-dropdown": "*Raġunijiet komuni għall-protezzjoni\n** Vandaliżmu eċċessiv\n** Spamming eċċessiv\n** Gwerrer tal-editjar kontinwi\n** Paġna wżata ħafna",
        "logentry-rights-rights-legacy": "$1 {{GENDER:$2|biddel|biddlet}} is-sħubija fil-gruppi ta' $3",
        "logentry-rights-autopromote": "$1 {{GENDER:$2|ġie|ġiet}} awtomatikament {{GENDER:$2|promoss|promossa}} minn $4 għal $5",
        "rightsnone": "(xejn)",
+       "revdelete-summary": "Taqsira tal-modifika",
        "feedback-bugornote": "Jekk int lest biex tiddeskrivi problema teknika fid-dettall, jekk jogħbok [$1 irraporta l-bug].\nInkella, tista' tuża l-formola sempliċi t'hawn taħt. Il-kumment tiegħek se jiżdied mal-paġna \"[$3 $2]\", flimkien ma' isem l-utent tiegħek.",
        "feedback-subject": "Suġġett:",
        "feedback-message": "Messaġġ:",
        "expand_templates_remove_comments": "Neħħi l-kummenti",
        "expand_templates_remove_nowiki": "Ħassar it-''tags'' <nowiki> fir-riżultat",
        "expand_templates_generate_xml": "Uri siġra sintattika XML",
-       "expand_templates_preview": "Dehra proviżorja"
+       "expand_templates_preview": "Dehra proviżorja",
+       "mediastatistics": "Statistika tal-midja",
+       "mediastatistics-summary": "L-istatistika dwar it-tipi ta' fajls imtellgħin. Din tinkludi biss il-verżjoni l-aktar reċenti t' fajl. Il-verżjonijiet antiki jew imħassrin tal-fajls tħallew barra.",
+       "mediastatistics-nbytes": "{{PLURAL:$1|$1 byte|$1 bytes}} ($2; $3%)",
+       "mediastatistics-table-mimetype": "Tip MIME",
+       "mediastatistics-table-extensions": "Estensjonijiet possibbli",
+       "mediastatistics-table-count": "Numru ta' fajls",
+       "mediastatistics-table-totalbytes": "Daqs totali",
+       "mediastatistics-header-unknown": "Mhux magħruf",
+       "mediastatistics-header-bitmap": "Stampi bil-Bitmap",
+       "mediastatistics-header-drawing": "Tpinġijiet (vector images)",
+       "mediastatistics-header-audio": "Awdjo",
+       "mediastatistics-header-video": "Vidjows",
+       "mediastatistics-header-multimedia": "Midja rikka",
+       "mediastatistics-header-office": "Uffiċċju",
+       "mediastatistics-header-text": "Fajls testwali",
+       "mediastatistics-header-executable": "Fajls eżegwitabbli",
+       "mediastatistics-header-archive": "Formats kompressati"
 }
index d5676fd..f0c2505 100644 (file)
        "otherlanguages": "Ate lengue",
        "redirectedfrom": "(Redirect 'a $1)",
        "redirectpagesub": "Paggena 'e redirect",
+       "redirectto": "Reindirizza a:",
        "lastmodifiedat": "Urdemo cagnamiénto pe' a paggena: $2, $1.",
        "viewcount": "Chesta paggena è stata liggiùta {{PLURAL:$1|una vòta|$1 vòte}}.",
        "protectedpage": "Paggena prutetta",
        "privacy": "'Nformazzione ppe a privacy",
        "privacypage": "Project:'Nfrummazione ncopp'â privacy",
        "badaccess": "Nun haje 'e premmesse abbastante.",
-       "badaccess-group0": "Nun t'è permesso 'a ffà l'azione richiesta.",
+       "badaccess-group0": "Nun v'è permesso 'a ffà l'azione richiesta.",
        "badaccess-groups": "L'azione ch'ê richiesto è permessa sulamente all'utente ca ce stanno dint'a {{PLURAL:$2|'o gruppo|uno d' 'e gruppe}}: $1.",
        "versionrequired": "Ce vò 'a verziona $1 'e MediaWiki",
        "versionrequiredtext": "Pe' usà sta paggena ce vò 'a verziona $1 'e MediaWiki. Vide [[Special:Version|'a paggena 'e verzione]].",
        "editinginterface": "'''Attenziò:''' 'O testo 'e sta paggena ffà parte 'e ll'interfaccia utente d' 'o sito.\nTutt' 'e cagnamiénte fatte a sta paggena cumpareno dint' 'e mmasciate 'e ll'interfaccia veduta 'a tutte ll'utente dint'a sta wiki.\nSi se buò azzeccà o cagnà traduzzione ncopp'a tutte 'e wiki, pe piacere ausate [//translatewiki.net/ translatewiki.net], 'o pruggetto Mediawiki p'a localizzaziona dint'a l'ate llengue",
        "cascadeprotected": "Sta paggena è stata prutetta 'a 'o cangamento pecché sta dint'a {{PLURAL:$1|sta paggena, che è prutetta|sti paggene, che songo prutette}} quann' 'a l'ozione \"ricurziva\" è attiva:\n$2",
        "namespaceprotected": "Nun avite permesso a cagnà 'e paggene dint'a stu namespace '''$1'''.",
-       "customcssprotected": "Nun t'è permesso 'a cagnà sta paggena CSS, pecché cuntene 'e mpustaziune perzunale 'e n'at'utente.",
-       "customjsprotected": "Nun t'è permesso 'a cagnà sta paggena JavaScript, pecché cuntene 'e mpustaziune perzunale 'e n'at'utente.",
-       "mycustomcssprotected": "Nun t'è permesso 'a cagnà sta paggena CSS.",
-       "mycustomjsprotected": "Nun t'è permesso 'a cagnà sta paggena JavaScript.",
-       "myprivateinfoprotected": "Nun t'è permesso a cagnà 'a nfurmaziona privata toja.",
-       "mypreferencesprotected": "Nun t'è permesso 'a cagnà 'e preferenze tuoje.",
+       "customcssprotected": "Nun v'è permesso 'a cagnà sta paggena CSS, pecché cuntene 'e mpustaziune perzunale 'e n'at'utente.",
+       "customjsprotected": "Nun v'è permesso 'a cagnà sta paggena JavaScript, pecché cuntene 'e mpustaziune perzunale 'e n'at'utente.",
+       "mycustomcssprotected": "Nun v'è permesso 'a cagnà sta paggena CSS.",
+       "mycustomjsprotected": "Nun v'è permesso 'a cagnà sta paggena JavaScript.",
+       "myprivateinfoprotected": "Nun v'è permesso a cagnà 'a nfurmaziona privata vuosta.",
+       "mypreferencesprotected": "Nun v'è permesso 'a cagnà 'e preferenze tuoje.",
        "ns-specialprotected": "'E paggene spiciale nun se ponno cagnà.",
        "titleprotected": "'A criazione 'e stu titolo è stata bloccata 'a ll'utente [[User:$1|$1]].\n'A ragione è chesta: ''$2''.",
        "filereadonlyerror": "Nun se può cagnà 'o file \"$1\" pecché 'o repository 'e file \"$2\" sta 'n modo sulo-lettura.\n\nL'ammenistratore che l'ha bloccato ha dato sta ragione: \"$3\".",
        "userlogin-signwithsecure": "Usa na conessione sicura",
        "yourdomainname": "Spiecà 'o dumminio",
        "password-change-forbidden": "Nun se ponno cagnà 'e password ncopp'a sta wiki.",
-       "externaldberror": "Ce sta n'errore ch' 'e server d'autenticazione esterno, o pure nun t'è permesso accedere all'aghiurnamento d' 'o cunto sterno tujo.",
+       "externaldberror": "Ce sta n'errore ch' 'e server d'autenticazione esterno, o pure nun v'è permesso accedere all'aghiurnamento d' 'o cunto sterno vuosto.",
        "login": "Tràse",
        "nav-login-createaccount": "Tràse o cria n'acciesso novo",
        "userlogin": "Tràse o cria n'acciesso novo",
        "passwordreset-emailsent-capture": "Na mmasciata e-mail pe' riabbià 'a password è stata mannata, chista mmasciata 'a putite vedé ccà abbascio.",
        "passwordreset-emailerror-capture": "Na mmasciata e-mail pe' riabbià 'a password è stata mannata, 'a putite vedé ccà abbascio, ma aita sapé ca nun s'è mannata a {{GENDER:$2|l'utente}} pecché c'è stato cocch'errore: $1",
        "changeemail": "Cagna l'indirizzo e-mail",
-       "changeemail-header": "Cagna l'indirizzo e-mail d' 'o cunto",
        "changeemail-text": "Ghienchete stu modulo pe' cangà l'indirizzo mail d' 'o vuosto. Sarrà necessario nzertà 'a password vosta pe' puté cunfermà stu cagnamiento.",
        "changeemail-no-info": "Avite 'a trasì ('o login) pe ffà l'acciesso a sta paggena direttamente.",
        "changeemail-oldemail": "Indirizzo email 'e mmò:",
        "changeemail-none": "(nisciuno)",
        "changeemail-password": "'A password vosta pe' {{SITENAME}}:",
        "changeemail-submit": "Cagna e-mail",
-       "changeemail-cancel": "Canciella",
        "changeemail-throttled": "Avite fatto troppe tentative 'a trasì.\nAspettate nu $1 apprimma 'e pruvà n'ata vota.",
        "resettokens": "Riabbìa 'e token",
        "resettokens-text": "Ccà se ponno riabbià 'e chiave ca permetessero l'acciesso a determinate date private associate a 'o cunto vuosto.\n\nL'aviste 'e ffà quanno l'avete spartuto pe' sbaglio cu cocche perzona o pure quanno 'o cunto d' 'o vuosto è stato compromesso.",
        "newarticletext": "Site ghiuto/a addò nu link 'e na paggena ca nun esiste ancora.\nP' 'a crià sta paggena, accummenciate a scrivere dint'a cascia cà abbascio (vedite 'a [$1 paggena d'aiuto] pe liegge cchiù nfurmazziune).\nSi site venuto/a ccà pe' sbaglio, vedite 'e sprémmere 'o buttòne '''Arreto''' d' 'o navigatóre.",
        "anontalkpagetext": "----\n''Chest'è 'a paggena 'e discussione 'e n'utente anonimo, ca nun ave criàt' 'ancora n'utenza o ca nun sta ausanno. Pe' l'identificà avite 'e truvà 'o nummero d' 'o ndirizzo IP d' 'o sujo. L'indirizze IP se ponno spartì però a cchiù 'e n'utente. Si sì n'utente anonimo e pienze ca 'e commente ccà dint'a sta paggena nun parlano 'e tte, allora [[Special:UserLogin/signup|crìa n'utenza nnova]] o [[Special:UserLogin|tràse cu chella ca tiene già]] pe' nun sta' mmescato mmiez'a l'ati utente anonime n futuro.''",
        "noarticletext": "Mo' mo' 'a paggena richiesta è abbacante. Se pò [[Special:Search/{{PAGENAME}}|ascià stu titolo]] dint'a l'ati paggene d' 'o sito, <span class=\"plainlinks\">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} ascià dint'e riggistre azzeccate] o pure [{{fullurl:{{FULLPAGENAME}}|action=edit}} cagnà 'a paggena mo']</span>.",
-       "noarticletext-nopermission": "Mo' mo' 'a paggena richiesta è abbacante. Se pò [[Special:Search/{{PAGENAME}}|ascià stu titolo]] dint'a l'ati paggene d' 'o sito, <span class=\"plainlinks\">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} ascià dint'e riggistre azzeccate]</span>, però nun tiene 'o permesso 'a crià sta paggena.",
+       "noarticletext-nopermission": "Mo' mo' 'a paggena richiesta è abbacante. Se pò [[Special:Search/{{PAGENAME}}|ascià stu titolo]] dint'a l'ati paggene d' 'o sito, <span class=\"plainlinks\">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} ascià dint'e riggistre azzeccate]</span>, però nun tenite 'o permesso 'a crià sta paggena.",
        "missing-revision": "'A verziona #$1 d' 'a paggena \"{{FULLPAGENAME}}\" nun esiste.\n\nChest'è causato quanno se và dint'a nu link a na paggena ch'è stata scancellata.\n'E dettaglie se ponno truvà dint'a [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} 'o riggistro 'e scancellamiente].",
        "userpage-userdoesnotexist": "'O cunto utente \"<nowiki>$1</nowiki>\" nun è riggistrato. Cuntrolla ca si buò overo crià o cagnà sta paggena.",
        "userpage-userdoesnotexist-view": "'O cunto utente \"$1\" nun è riggistrato.",
        "explainconflict": "N'at'utente ave sarvato na nova verziona d' 'a paggena pe' tramente ca stevate a fà 'e cagnamiente.\n'A cascia 'e mudifeca ncoppa cuntene 'o testo d' 'a paggena ca mò sta online, accussì comme è stato agghiurnato a l'at'utente.\n'A verziona ch' 'e cagnamiente vuoste è stata mmece riportata dint'a cascia 'e mudifeca abbascio.\nSi 'e vulite cunfermà avite 'a ripurtà 'e cagnamiente d' 'e vuoste dint'o testo ca esiste (dint'a cascia ncoppa).\nSpremmendo 'o buttón '{{int:savearticle}}', sarrà sarvato '''sulamente''' 'o testo cuntenuto dint'a cascia 'e cagnamiento ncoppa.",
        "yourtext": "'O testo vuosto",
        "storedversion": "A verziona 'n memoria",
-       "nonunicodebrowser": "'''Attenziò: staje ausanno nu navigatóre ca nun è compatibbele ch' 'e carattere Unicode. Pe' te permettere 'o cagnamiento d' 'e paggene senza crià ncunveniente, 'e carattere nun ASCII veneno viste dint' 'a cascia 'e cagnamiento sotto forma 'e codece esadecimale.'''",
+       "nonunicodebrowser": "'''Attenziò: state ausanno nu navigatóre ca nun è compatibbele ch' 'e carattere Unicode. Pe' ve permettere 'o cagnamiento d' 'e paggene senza crià ncunveniente, 'e carattere nun ASCII veneno viste dint' 'a cascia 'e cagnamiento sotto forma 'e codece esadecimale.'''",
        "editingold": "'''Attenziò: staje cagnanno na verziona nun agghiurnata d' 'a paggena. Si 'a sarve accussì, tutte 'e cagnamiente fatte aropp'a sta verziona sarranno sperdute.'''",
        "yourdiff": "Differenze",
        "copyrightwarning": "Pe' piacere tenite a mmente ca tutte 'e contribbute a {{SITENAME}} songo cunziderate pubbrecate dint'e térmene d'uso d' 'a licienza $2 (vedite $1 pe n'avé cchiù dettaglie).\nSi nun vulite ca 'e testi vuoste fossero cagnate e distribuite 'a uno qualunque senza lémmeto, nun 'e mannate ccà.<br />\nMannanno stu testo dichiarate pùre, sott'a responsabilità vuosta, ch'è stato scritto 'a vuje perzunalmente o pure ca è stato copiato 'a na fonte n pubblico dominio o similarmente libbera.\n'''Nun mannate materiale prutetto 'a copyright senz'avé autorizzaziona!'''",
        "template-protected": "(prutetto)",
        "template-semiprotected": "(semi-prutetto)",
        "hiddencategories": "Sta paggena attócca a {{PLURAL:$1|na categurìa annascunnuta|$1 categurìe annascunnute}}:",
-       "nocreatetext": "{{SITENAME}} ha limitato 'a possibilità 'e crià paggene nnove. Può turnà e cagnà na paggena ch'esiste già, o pure [[Special:UserLogin|trasì o te riggistrà]].",
-       "nocreate-loggedin": "Nun t'è permesso 'e crià paggene nnove.",
+       "nocreatetext": "{{SITENAME}} ha limitato 'a possibilità 'e crià paggene nnove. Putite turnà e cagnà na paggena ch'esiste già, o pure [[Special:UserLogin|trasì o ve riggistrà]].",
+       "nocreate-loggedin": "Nun v'è permesso 'e crià paggene nnove.",
        "sectioneditnotsupported-title": "Cagnamiento 'e sezziune nun suppurtato",
        "sectioneditnotsupported-text": "'O cagnamiento d' 'e sezziune nun è suppurtato dint'a sta paggena.",
        "permissionserrors": "Nun haje 'e premmesse abbastante.",
        "searchall": "Tutte",
        "showingresults": "Ccà abbascio {{PLURAL:$1|s'apprisentano 'o massimo '''1''' risultato|veneno apprisentate massimo '''$1''' risultate}} aropp' 'o nummero '''$2'''.",
        "showingresultsinrange": "{{PLURAL:$1|Vene mmustato|Veneno mmustate}} abbascio {{PLURAL:$1|<strong>1</strong> risultato|<strong>$1</strong> risultate}} d' 'o <strong>$2</strong> a 'o <strong>$3</strong>.",
-       "showingresultsheader": "{{PLURAL:$5|Risultato '''$1''' 'e '''$3'''|Risultate '''$1 - $2''' 'e '''$3'''}} pe' '''$4'''",
+       "search-showingresults": "{{PLURAL:$4|Risultato <strong>$1</strong> 'e <strong>$3</strong>|Risultate <strong>$1 - $2</strong> 'e <strong>$3</strong>}}",
        "search-nonefound": "'A ricerca nun ha produtto risultate.",
        "powersearch-legend": "Ricerca avanzata",
        "powersearch-ns": "Ascìa dint' 'o namespace:",
        "prefs-tokenwatchlist": "Token",
        "prefs-diffs": "Differenze",
        "prefs-help-prefershttps": "Sta preferenza averrà affetto 'a 'o prossimo acciesso vuosto.",
+       "prefswarning-warning": "Avite fatto cagnamiente a 'e preferenze d' 'e vuoste ca nun so' stat'ancora sarvate.\nSi ascite 'a sta paggena senza clickà \"$1\" 'e preferenze d' 'e vuoste nun sarranno agghiurnate.",
        "prefs-tabs-navigation-hint": "Suggerimento: se ponno ausà 'e buttòne 'e freccia a manca e a dritta pe' ve muovere nfra 'e schede dint'a l'alenco d' 'e schede.",
        "email-address-validity-valid": "L'indirizzo e-mail pare valido",
        "email-address-validity-invalid": "Nzerta n'indirizzo e-mail valido",
        "watchlist": "Paggene cuntrullate",
        "mywatchlist": "Paggene cuntrullate",
        "watchlistfor2": "Ppe $1 $2",
-       "nowatchlist": "Nun tiene paggene dint' 'a l'elenco 'e paggene cuntrullate.",
+       "nowatchlist": "Nun tenite paggene dint' 'a l'elenco 'e paggene cuntrullate.",
        "watchlistanontext": "Pe' piacere, trasite pe' vedé o cagnà l'elenco 'e paggene cuntrullate.",
        "watchnologin": "Acciesso nun affettuato",
        "addwatch": "Miette dint' 'a l'elenco 'e paggene cuntrullate",
        "protect-othertime": "N'ata durata:",
        "protect-othertime-op": "ati durate",
        "protect-existing-expiry": "'O tiempo d'ammaturamiento esistente: $3, $2",
+       "protect-existing-expiry-infinity": "Tiempo d'ammaturamiento: infinito",
        "protect-otherreason": "Ati/cchiù ragiune:",
        "protect-otherreason-op": "Ati ragiune",
        "protect-dropdown": "*Mutive 'e prutezione comune\n** Vandalisme eccessive\n** Spam eccessivo\n** 'Uerre 'e cagnamiente controproducente\n** Paggena cu troppo traffeco",
        "unblocked": "[[User:$1|$1]] è stato sbloccato.",
        "unblocked-range": "$1 è stato sbloccato",
        "unblocked-id": "'O blocco $1 è stato luvato.",
+       "unblocked-ip": "[[Special:Contributions/$1|$1]] è stato sbluccato.",
        "blocklist": "Utente bloccate",
        "ipblocklist": "Utenti bloccate",
        "ipblocklist-legend": "Ascìa n'utente bloccato",
        "emaillink": "manna e-mail",
        "autoblocker": "Autobloccate pecché l'indirizze IP vuosto è stat'ausato urdemamente 'a \"[[User:$1|$1]]\".\n'O mutivo d' 'o blocco 'e $1 è \"$2\"",
        "blocklogpage": "Blocche",
+       "blocklog-showlog": "St'utente è stato bloccato primma.\n'O riggistro d' 'e blocche se può vedé ccà abbascio pe' riferimento:",
+       "blocklog-showsuppresslog": "St'utente è stato bloccato e annascunuto primma.\n'O riggistro d' 'e luvamiente se può vedé ccà abbascio pe' riferimento:",
        "blocklogentry": "ha fermato \"[[$1]]\" pe' nu mumento 'e $2 $3",
+       "reblock-logentry": "cagnate 'e mpustaziune 'e blocco pe' [[$1]] cu na data d'ammaturamiento 'e $2 $3",
        "blocklogtext": "Chesta è 'a lista d''e azzione 'e blocco e sblocco utente.  'E nnerizze IP bloccate automaticamente nun nce so'. Addumannà 'a [[Special:BlockList|lista bloccate]] pp' 'a lista d''e nnerizze e nomme utente 'o ca blocco nce sta.",
+       "unblocklogentry": "sbluccato $1",
+       "block-log-flags-anononly": "sulamente l'utente anonime",
+       "block-log-flags-nocreate": "riggistrazione 'e cunte stutata",
+       "block-log-flags-noautoblock": "autoblocco stutato",
+       "block-log-flags-noemail": "mmasciate e-mail stutate",
+       "block-log-flags-nousertalk": "nun può cagnà 'a paggena 'e chiacchiera d' 'a toja",
+       "block-log-flags-angry-autoblock": "auto blocco avanzato appicciato",
+       "block-log-flags-hiddenname": "nomme utente annascunnuto",
+       "range_block_disabled": "'A possibbilità 'e bluccà ntervalle 'e indirizze IP nun è appicciata.",
+       "ipb_expiry_invalid": "Tiempo d'ammaturamiento invalido.",
+       "ipb_expiry_temp": "'E blocche d' 'e nomme utente annascunnute hanna essere nfinite.",
+       "ipb_hide_invalid": "Nun se può scancellà stu cunto; tène cchiù 'e {{PLURAL:$1|nu cagnamiento|$1 cagnamiente}}.",
+       "ipb_already_blocked": "\"$1\" è già bloccato.",
+       "ipb-needreblock": "$1 è già bloccato. Vulite cagnà 'e mpustaziune?",
+       "ipb-otherblocks-header": "Ati {{PLURAL:$1|blocche|blocche}}",
+       "unblock-hideuser": "Vuje nun putite sbluccà st'utente, pecché 'o nomme utente 'e chisto è stato già annascunnuto.",
+       "ipb_cant_unblock": "Errore: L'ID $1 d' 'o blocco nun se trova.\nPò essere ca 'o blocco è stato luvato già.",
+       "ipb_blocked_as_range": "Errore: l'IP $1 nun è stato bloccato direttamente e nun se può sbluccà.\n'O blocco, è mmece attivo a livello 'e l'intervallo $2, ca pò essere sbloccato.",
+       "ip_range_invalid": "L'itervallo 'e l'IP nun è valido.",
+       "ip_range_toolarge": "L'intervalle 'e blocche cchiù luonghe 'e /$1 nun songo permesse.",
+       "proxyblocker": "Bloccatore 'e proxy",
+       "proxyblockreason": "L'indirizzo IP d' 'o vuosto è stato bloccato pecché è nu proxy araputo.\nPe' piacere, cuntattate 'o provider 'e l'Internet vuosto o lu suppuorto tecnico d' 'aggenzia vuosta pe' le dà nutizia 'e stu probblema gruosso assaje.",
+       "sorbsreason": "L'indirizzo IP vuosto è elencato comm'a nu proxy araputo dint' 'a lista DNSBL ausata 'a {{SITENAME}}.",
+       "sorbs_create_account_reason": "L'indirizzo IP d' 'o vuosto è elencato comm'a nu proxy araputo dint' 'a DNSBL ausata 'a {{SITENAME}}. Nun putite crià nu cunto.",
+       "xffblockreason": "N'indirizzo IP prisente dint' 'e cap'e paggena X-Forwarded-For, o chillu d' 'o vuosto o chillu 'e n'atu server proxy ca stat'ausann, è stato bloccato. 'O mutivo origgenale 'e blocco era: $1",
+       "cant-see-hidden-user": "L'utente ca state a bluccà è stato già bluccato e annascunnuto. Si nun tenite 'o deritto ''hideuser'', nun putite veré stu blocco d'utente.",
+       "ipbblocked": "Nun putite bloccà o sbluccà utente pecche vuje stesso site bluccato.",
+       "ipbnounblockself": "Nun avite permesso a ve bluccà vuje stesso.",
+       "lockdb": "Blocca 'o database",
+       "unlockdb": "Sblocca 'o database",
+       "lockdbtext": "Bluccanno 'o database se luvarranno l'abbilità 'e tutte l'utente 'e cagnà 'e paggene, cagnà 'e preferenze lloro, cagnà 'a lista 'e paggene cuntrullate e ati cose ca richiedessero cagnamiente ô database.\nPe' piacere cunfermate ca chisto e chello ca vulite fà, e ca luvarrate 'o blocco ô database quanno sta manutenziona sarrà fernuta.",
+       "unlockdbtext": "Sbluccanno 'o database se s'arrepigliarranno l'abbilità 'e tutte l'utente 'e cagnà 'e paggene, cagnà 'e preferenze lloro, cagnà 'a lista 'e paggene cuntrullate e ati cose ca richiedessero cagnamiente ô database.\nPe' piacere cunfermate ca chisto e chello ca vulite fà.",
+       "lockconfirm": "Sì, overo vulesse bluccà 'o database.",
+       "unlockconfirm": "Sì, overo vulesse sbluccà 'o database.",
+       "lockbtn": "Blocca 'o database",
+       "unlockbtn": "Sblocca 'o database",
+       "locknoconfirm": "Nun avite scigliuto 'a casciulella 'e cunferma.",
+       "lockdbsuccesssub": "Blocco d' 'o database secutato",
+       "unlockdbsuccesssub": "'O blocco d' 'o database è stato luvato",
+       "lockdbsuccesstext": "'O database è stato bloccato.<br />\nArricuordateve 'e [[Special:UnlockDB|luvà 'o blocco]] appriesso c' 'a manutenziona sarrà fernuta.",
+       "unlockdbsuccesstext": "'O database è stato sbluccato.",
+       "lockfilenotwritable": "Nun se può scrivere ncopp' 'o file 'e blocco d' 'o database.\nPe' bluccà o sbluccà 'o database abbesuogne 'e scrivere dint' 'o server web.",
+       "databasenotlocked": "'O database nun è bluccato.",
+       "lockedbyandtime": "(pe' {{GENDER:$1|$1}} 'o $2 a 'e $3)",
+       "move-page": "Mòve $1",
+       "move-page-legend": "Mòve paggena",
+       "movepagetext": "Ausanno stu modulo ccà abbascio s'anommenarrà 'a paggena n'ata vota, movenno tutt' 'a cronologgia suja a l'atu nomme.\n'O titolo viecchio s'addeventarrà nu redirect â paggena c' 'o titolo nuovo. Putite agghiurnà 'e redirect ca puntassero ô titolo origgenale automaticamente.\nSi chesto nun facite, state sicuro 'e cuntrullà [[Special:DoubleRedirects|doppie ridirezionamiente]] o [[Special:BrokenRedirects|ridirezionamiente scassate]]. Vuje site 'o responsabbile 'e chillo ca cumbinate, assicurateve ca 'o cullegamiento cuntinua a spuntà addò avess'a spuntà.\n\nVedite bbuono ca 'a paggena <strong>nun</strong> se muoverrà si esiste n'ata paggena c' 'o titolo nuovo, a meno ca è abbacante o ca ce sta na paggena 'e ridirezionamiento senza cronologgia. Chesto significasse ca putite fà turnà 'o nomme viecchio â paggena addò ce steva apprimma si avite cumbinato nu nguacchio p'errore, e nun può sovrascrivere 'a paggena ch'esiste già. <strong>Attenzione!</strong> Chisto può essere nu cagnamiento drastico e inaspettato 'e na paggena famosa assaje; pe' piacere, avite 'a essere sicure-sicure d' 'e conseguenze apprimm' 'e cuntinuà.",
+       "movepagetext-noredirectfixer": "Ausanno stu modulo ccà abbascio s'anommenarrà 'a paggena n'ata vota, movenno tutt' 'a cronologgia suja a l'atu nomme.\n'O titolo viecchio s'addeventarrà nu redirect â paggena c' 'o titolo nuovo. State sicuro 'e cuntrullà [[Special:DoubleRedirects|doppie ridirezionamiente]] o [[Special:BrokenRedirects|ridirezionamiente scassate]]. Vuje site 'o responsabbile 'e chillo ca cumbinate, assicurateve ca 'o cullegamiento cuntinua a spuntà addò avess'a spuntà.\n\nVedite bbuono ca 'a paggena <strong>nun</strong> se muoverrà si esiste n'ata paggena c' 'o titolo nuovo, a meno ca è abbacante o ca ce sta na paggena 'e ridirezionamiento senza cronologgia. Chesto significasse ca putite fà turnà 'o nomme viecchio â paggena addò ce steva apprimma si avite cumbinato nu nguacchio p'errore, e nun può sovrascrivere 'a paggena ch'esiste già. <strong>Attenzione!</strong> Chisto può essere nu cagnamiento drastico e inaspettato 'e na paggena famosa assaje; pe' piacere, avite 'a essere sicure-sicure d' 'e conseguenze apprimm' 'e cuntinuà.",
+       "movepagetalktext": "'A paggena 'e chiacchieria suoccia a chesta sarrà spustata automaticamente cu chesta <strong>a meno che:</strong>\n*Esiste na paggena 'e chiacchieria ca nun è abbacante c' 'o nomme nuovo, o\n*Vuje sciglite accussì abbacantanno 'a casciulella ccà abbascio.\n\nInd' 'a sti case, 'a paggena nun se muoverrà, ma 'a putite sempe scagnà manualmente si vulite.",
        "movearticle": "Spusta 'a paggena",
+       "moveuserpage-warning": "<strong>Attenziò:</strong> Vuje state a muovere na paggena utente. Vedite bbuono ca sulamente 'a paggena sarrà spustata e l'utente <em>nun</em> sarrà reanummenato.",
+       "movecategorypage-warning": "<strong>Attenziò:</strong> Vuje state a muovere na categurìa. Vedite bbuono ca sulamente 'a paggena sarrà spustata e 'a categurìa viecchia <em>nun</em> sarrà cagnata â nnova.",
+       "movenologintext": "Vuje avite 'a essere n'utente riggistrato e [[Special:UserLogin|cullegato]] pe' spustà na paggena.",
+       "movenotallowed": "Nun tenite 'o permesso pe' spustà paggene.",
+       "movenotallowedfile": "Nun tenite 'o permesso pe' spustà file.",
+       "cant-move-user-page": "Nun tenite 'o permesso pe' spustà 'e paggene utente (staccannole cumme sottopàggene).",
+       "cant-move-to-user-page": "Nun tenite 'o permesso pe' spustà na paggena 'a na paggena utente (sulamente p' 'e sottopaggene utente).",
+       "cant-move-category-page": "Nun tenite 'o permesso pe' muovere paggene 'e categurìa.",
+       "cant-move-to-category-page": "Nun tenite 'o permesso pe' muovere 'a paggena ncopp' 'a na categurìa",
        "newtitle": "Titulo nuovo:",
+       "move-watch": "Cuntrolla sta paggena",
        "movepagebtn": "Spusta 'a paggena",
+       "pagemovedsub": "Spustamento fatto",
+       "movepage-moved": "<strong>\"$1\" è stata spustata int' 'a \"$2\"</strong>",
+       "movepage-moved-redirect": "Nu redirezionamiento è stato criato.",
+       "movepage-moved-noredirect": "'A criazione o lu redirezionamiento è stato luvato.",
        "articleexists": "Na paggena cu chisto nomme asiste già, o pure 'o nomme scegliuto nun è buono.  Scegliere n'ato titulo.",
+       "cantmove-titleprotected": "Nun putite spustà 'a paggena a stu pizzo pecchè 'o titolo nuovo è stato prutetto 'a criazione",
+       "movetalk": "Muove 'a paggena 'e chiacchiera suoccia a chesta",
+       "move-subpages": "Mòve 'e sottopàggene (nfin' 'a $1)",
+       "move-talk-subpages": "Mòve 'e sottopaggene 'e chiacchiera (nfin' 'a $1)",
+       "movepage-page-exists": "'A paggena $1 esiste già e nun se può scrivere ncoppa.",
+       "movepage-page-moved": "'A paggena $1 s'è spustat' 'a $2.",
+       "movepage-page-unmoved": "'A paggena $1 nun se può spustà a $2.",
+       "movepage-max-pages": "'O massimo 'e $1 {{PLURAL:$1|paggena|paggene}} è stato spustato e nun se ne ponno spustà cchiù 'n automatico.",
        "movelogpage": "Spustamente",
+       "movelogpagetext": "Ccà abbascio sta na lista d' 'e paggene spustate.",
+       "movesubpage": "{{PLURAL:$1|Sottopaggena|Sottopaggene}}",
+       "movesubpagetext": "Sta paggena tene $1 {{PLURAL:$1|sottopaggena|sottopaggene}} ccà abbascio.",
+       "movenosubpage": "Sta paggena nun tene sottopaggene.",
        "movereason": "Raggióne",
        "revertmove": "arrepiglia",
        "delete_and_move": "Scancèlla e spusta",
+       "delete_and_move_text": "== Scancellamiento richiesto ==\n'A paggena 'e destinazione \"[[:$1]]\" esiste già.\n'A vulite scancellà pe' ne putè ffà 'o spazio abbacante necessario?",
        "delete_and_move_confirm": "Sì, suprascrivi 'a paggena asistente",
+       "delete_and_move_reason": "Scancellata pe ne fà spazio abbacante e putè spustà 'a \"[[$1]]\"",
+       "selfmove": "'O titolo 'e sorgente e destinazione songh' 'e stesse;\nnun se può muovere na paggena ncopp' 'a essa stessa.",
+       "immobile-source-namespace": "Nun se ponno muovere 'e paggene dint' 'o namespace \"$1\"",
+       "immobile-target-namespace": "Nun se ponno muovere 'e paggene dint' 'o namespace \"$1\"",
+       "immobile-target-namespace-iw": "'O cullegamiento interwiki nun è na destinazione bona pe spustà na paggena.",
+       "immobile-source-page": "Sta paggena nun se può spustà.",
+       "immobile-target-page": "Nun se può spustà a chillu titolo 'e destinazione.",
+       "bad-target-model": "'A destinazione scigliuta aùsa nu mudello 'e cuntenute differénte. Nun se può cagnà 'a $1 a $2.",
+       "imagenocrossnamespace": "Nun se può muovere stu file dint' 'a nu namespace nun-file",
+       "nonfile-cannot-move-to-file": "Nun se può muovere n'oggetto ca nun è nu file a dint'o namespace d' 'e file",
+       "imagetypemismatch": "L'estenziona nova d' 'o file nun s'accucchia c' 'o tipo suojo",
+       "imageinvalidfilename": "'O nomme d' 'o file 'e destinazione nun è buono",
+       "fix-double-redirects": "Agghiuorna ogne redirezionamiento ca spuntasse ô titolo origginale",
+       "move-leave-redirect": "Lassa nu ridirezionamiento arreto",
+       "protectedpagemovewarning": "<strong>Attenziò:</strong> sta paggena è stata prutetta 'n modo tale ca sulamente l'utente ch' 'e privilegge d'ammenistratore 'a ponno muovere.\nL'urdemo elemento d' 'o riggistro è scritto ccà abbascio pe' n'avé riferimento:",
+       "semiprotectedpagemovewarning": "'''Nota:''' Sta paggena è prutetta 'n modo ca sulamente l'utente riggistrate 'a ponno mòvere.\nL'urdemo elemento d' 'o riggistro è scritto ccà abbascio pe n'avé nfurmazione:",
+       "move-over-sharedrepo": "== 'O file esiste ==\n[[:$1]] esiste ncopp'a l'archivio spartuto. Spustanno 'o file ncopp'a stu titolo sovrascreverrà 'o file spartuto.",
+       "file-exists-sharedrepo": "'O nomme d' 'o file c'avite scigliuto se sta ausanno dint'a l'archivio spartuto.\nPe' piacere, scigliete n'atu nomme.",
        "export": "Spurta 'e ppaggene",
+       "exporttext": "Vuje putite espurtà 'e teste e cagnà 'a cronologgia 'e na paggena particolare o n'inzieme 'e paggena ca stessero dint' 'a cocche XML.\nChisto po' essere 'mpurtato int'a n'ata wiki ausanno [[Special:Import|mporta pàggene]] 'e MediaWiki.\n\nPe' spurtà paggene, mettite 'o titolo dint' 'e casciulelle ccà abbascio, nu titolo pe' linea e sciglite si vulite 'a verziona 'e mò cu tutt' 'e verziun' 'assieme, o pùre sulamente 'a verziona 'e mò c' 'a nfurmaziona ncopp' 'a ll'urdemo cagnamiento.\n\nComme urtema possibbiletà, putite pure ausà nu cullegamento, p'esempio [[{{#Special:Export}}/{{MediaWiki:Mainpage}}]] p' 'a pàggena \"[[{{MediaWiki:Mainpage}}]]\".",
+       "exportall": "Spurta tutt' 'e paggene",
+       "exportcuronly": "Appenne sulamente 'a verziona 'e mo, e nun tutt' 'a cronologgia",
+       "exportnohistory": "----\n'''Vedite bbuono:''' 'A funzione 'esportazione d' 'a storia sana d' 'e paggene, ausanno stu modulo, è stata stutata pe' mutive 'e prestaziune.",
+       "exportlistauthors": "Appenne 'a lista sana 'e cuntribbutore p'ogne paggena",
+       "export-submit": "Esporta",
+       "export-addcattext": "Azzecca paggene d' 'a categurìa:",
+       "export-addcat": "Azzecca",
+       "export-addnstext": "Azzecca paggene d' 'o namespace:",
+       "export-addns": "Azzecca",
+       "export-download": "Astipa comm'a nu file",
+       "export-templates": "Include 'e template",
+       "export-pagelinks": "Include 'e paggene cullegate ca spuntassero nfin' 'a na prufunnità 'e:",
        "allmessages": "'Mmasciate d''o sistema",
        "allmessagesname": "Nomme",
+       "allmessagesdefault": "Mmasciata 'e testo predefinita",
        "allmessagescurrent": "Testo 'e mo",
+       "allmessagestext": "Chest'è na lista 'e tutt' 'e mmasciate 'e sistema ca se ponno ascià dint' 'o namespace 'e Mediawiki.\nPe' piacere vedite [https://www.mediawiki.org/wiki/Special:MyLanguage/Localisation Lucalizzazione 'e MediaWiki] e [//translatewiki.net translatewiki.net] si vulite cuntribbuì â lucalizzaziona generica 'e MediaWiki.",
+       "allmessagesnotsupportedDB": "Sta paggena nun se può ausà pecché 'a funziona <strong>$wgUseDatabaseMessages</strong> è stata stutata.",
+       "allmessages-filter-legend": "Filtro",
+       "allmessages-filter": "Filtra cu nu stato personalizzate:",
+       "allmessages-filter-unmodified": "Senza cagnamiente",
+       "allmessages-filter-all": "Tutto",
+       "allmessages-filter-modified": "Cagnate",
+       "allmessages-prefix": "Filtra pe' prefisso:",
+       "allmessages-language": "Lengua:",
+       "allmessages-filter-submit": "Vàje",
+       "allmessages-filter-translate": "Traduce",
        "thumbnail-more": "Ingrandisce",
+       "filemissing": "File perdute",
+       "thumbnail_error": "Errore crianno l'anteprimma 'e miniatura: $1",
+       "thumbnail_error_remote": "Mmasciata d'errore 'a $1:\n$2",
+       "djvu_page_error": "Pàggena DjVu fore 'e lemmeto",
+       "djvu_no_xml": "Nun se può piglià 'o XML p' 'o file DjVu",
+       "thumbnail-temp-create": "Nun se può crià na miniatura temporanea d' 'o file",
+       "thumbnail-dest-create": "Nun se può astipà 'a miniatura dint' 'a destinazione",
+       "thumbnail_invalid_params": "Parametre 'e miniatura invalide",
+       "thumbnail_dest_directory": "Nun se può crià 'a cartella 'e destinazione",
+       "thumbnail_image-type": "'O tipo d'immaggene nun è suppurtato",
+       "thumbnail_gd-library": "Configurazione d' 'a libbreria GD incompleta: funziona perza $1",
+       "thumbnail_image-missing": "'O file pare ca nun se trova: $1",
+       "thumbnail_image-failure-limit": "Se so' fatte troppe tentative senza ngarrata ($1 o cchiù) 'a generà sta miniatura. Pruvate n'ata vota cchiù tarde.",
        "import": "Mpurta paggene",
+       "importinterwiki": "Mpurtazione transkwiki",
+       "import-interwiki-text": "Scigliete na wiki e nu titolo 'e paggena 'a mpurtà.\n'E date e l'editore s'astiparranno.\nTutte l'aziune 'e mpurtaziune nfra 'e wiki songo riggistrate dint' 'e [[Special:Log/import|riggistre 'e mpurtazione]].",
+       "import-interwiki-sourcewiki": "Wiki d'origgene:",
+       "import-interwiki-sourcepage": "Paggena d'origgene:",
+       "import-interwiki-history": "Copia tutt' 'a storia d' 'e verziune 'e sta paggena",
+       "import-interwiki-templates": "Include tutt' 'e template",
        "import-interwiki-submit": "Mpurta",
+       "import-interwiki-namespace": "Namespace 'e destinazione:",
+       "import-interwiki-rootpage": "Paggena princepale 'e destinazione (opzionale):",
+       "import-upload-filename": "Nomme d' 'o file",
+       "import-comment": "Commento:",
+       "importtext": "Pe' piacere spurtate 'o file d' 'a wiki surgente ausanno l'[[Special:Export|utilità 'e sportazione]].\nScarrecatevella dint' 'o computer d' 'o vuosto e carrecate n'ata vota ccà.",
+       "importstart": "Mpurtanno 'e paggene...",
+       "import-revision-count": "$1 {{PLURAL:$1|verzione|verziune}}",
+       "importnopages": "Nisciuna pàggene 'a mpurtà.",
+       "imported-log-entries": "Mpurtate $1 {{PLURAL:$1|evento d' 'o riggistro|evente d' 'o riggistro}}.",
+       "importfailed": "Mpurtaziona fallita: <nowiki>$1</nowiki>",
+       "importunknownsource": "Nun se sape 'o tipo 'e sorgente 'e mpurtaziona",
+       "importcantopen": "Nun se può arapì 'o file 'e mpurtaziona",
+       "importbadinterwiki": "Cullegamiento interwiki errato",
+       "importsuccess": "Mpurtaziona fernuta!",
+       "importnosources": "Nisciuna fonte p' 'a mpurtaziona transwiki è stata definita; 'e carreche dirette 'e cronologgia nun songo attivate.",
+       "importnofile": "Nisciunu file 'e mpurtazione è stato carrecato.",
+       "importuploaderrorsize": "'A carreca d' 'o file 'e mpurtazione nun è riuscita.\n'O file è cchiù gruosso d' 'a dimenziona massima 'e carreca.",
+       "importuploaderrorpartial": "'A carreca d' 'o file mpurtato è fallita.\nNa parta d' 'o file file è stata carrecata ma nun a nu piezzo sano sano.",
+       "importuploaderrortemp": "'A carreca d' 'o file mpurtato nun se facette.\nNa cartella temporanea nun se truova.",
+       "import-parse-failure": "mpurtaziune XML scassata pe' n'errore d'analiso",
+       "import-noarticle": "Nisciuna paggena 'a mpurtà!",
+       "import-nonewrevisions": "Nisciuna verziona mpurtata (Tutt' 'e verziune so' state già mpurtate o pure zumpajeno pe' bbia 'e cocch'errore).",
+       "xml-error-string": "$1 a 'a linea $2, culonne $3 (byte $4): $5",
+       "import-upload": "Carreca 'e date 'e XML",
+       "import-token-mismatch": "Se so' perdut' 'e date d' 'a sessione.\nProva n'ata vota.",
+       "import-invalid-interwiki": "Nun se può mpurtà d' 'a wiki specificata.",
+       "import-error-edit": "'A paggena \"$1\" nun è stata mpurtata pecché nun avite 'o permesso p' 'a putè cagnà.",
+       "import-error-create": "'A paggena \"$1\" nun è stata mpurtata pecché nun avite 'o permesso p' 'a putè crià.",
+       "import-error-interwiki": "'A paggena \"$1\" nun è stata mpurtata pecché 'o nomme suojo stà astipato pe ne ffà 'o cullegamiento a fore (interwiki).",
+       "import-error-special": "'A paggena \"$1\" nun è stata mpurtata pecché appartene a nu namespace specifico ca nun permette sti paggene.",
+       "import-error-invalid": "'A paggena \"$1\" nun è stata mpurtata pecché 'o nomme 'e mpurtazione nun è bbuono ncopp'a sta wiki.",
+       "import-error-unserialize": "'A verzione $2 d' 'a paggena \"$1\" nun se può deserializzà. 'A virziona è stata reportata p'ausà 'o mudello 'e cuntenute $3 serializzate cumme $4.",
+       "import-error-bad-location": "'A verzione $2 aúsa nu mudello 'e cuntenuto $3 ca nun se può memorizzà ncopp'a \"$1\" 'e stu wiki, pecché 'a paggena nun supporta stu mudello.",
+       "import-options-wrong": "{{PLURAL:$2|opzione sbagliata|opziune sbagliate}}: <nowiki>$1</nowiki>",
+       "import-rootpage-invalid": "'A paggena princepale c'avite dato tène nu titolo invalido.",
+       "import-rootpage-nosubpage": "'O namespace \"$1\" d' 'a pàggena princepale nun permette 'e sottopaggene.",
+       "importlogpage": "Riggistro 'e mpurtaziune",
+       "importlogpagetext": "Mpurtaziune ammenistrative 'e paggene c' 'a storia 'e cagnamiente 'e l'ati wiki.",
        "import-logentry-upload": "ha mpurtato [[$1]] trammeto upload",
+       "import-logentry-upload-detail": "$1 {{PLURAL:$1|verzione|verziune}} mpurtate",
+       "import-logentry-interwiki": "trasferito 'a n'ata wiki 'a paggena $1",
+       "import-logentry-interwiki-detail": "$1 {{PLURAL:$1|verzione|verziune}} mpurtate 'a $2",
+       "javascripttest": "Test JavaScript",
+       "javascripttest-title": "Secutanno test pe' $1",
+       "javascripttest-pagetext-noframework": "Sta paggena è riservata pe' l'esecuziune d' 'e test 'e Javascript.",
+       "javascripttest-pagetext-unknownframework": "Ambiente 'e test scanusciuto \"$1\".",
+       "javascripttest-pagetext-frameworks": "Pe' piacere sciglite uno 'e ll'ambiente 'e test ccà abbascio: $1",
+       "javascripttest-pagetext-skins": "Sciglite nu skin pe' ne fà 'e test:",
+       "javascripttest-qunit-intro": "Vedite 'a [$1 documentaziona d' 'o test] ncopp'a mediawiki.org.",
+       "javascripttest-qunit-heading": "Ambiente 'e test MediaWiki JavaScript QUnit",
        "tooltip-pt-userpage": "A toja paggena utente",
+       "tooltip-pt-anonuserpage": "'A paggena utente pe l'IP ca vuje state cagnanno cumme",
        "tooltip-pt-mytalk": "A toja paggena 'e discussione",
+       "tooltip-pt-anontalk": "Chiacchieria ncopp' 'e cagnamiente 'a st'indirizzo IP",
        "tooltip-pt-preferences": "Preferenze d''e mmeje",
+       "tooltip-pt-watchlist": "'A lista d' 'e paggene ca state a cuntrullà",
        "tooltip-pt-mycontris": "Elenco dde tuje contributte",
        "tooltip-pt-login": "A reggistrazione è cunsigliata",
        "tooltip-pt-logout": "Jésce (logout)",
        "tooltip-ca-viewsource": "Chista paggena è prutetta, ma puo vere 'o codice sorgente",
        "tooltip-ca-history": "Vversione precedente 'e chista paggena",
        "tooltip-ca-protect": "Prutegge chesta paggena",
+       "tooltip-ca-unprotect": "Càgna 'a prutezzione 'e chesta paggena",
        "tooltip-ca-delete": "Scancèlla chista paggena",
+       "tooltip-ca-undelete": "Arrepiglia 'e cagnamiente fatte 'a sta paggena apprimma ca fuieno scancellate",
        "tooltip-ca-move": "Spusta chista paggena",
+       "tooltip-ca-watch": "Azzecca sta paggena int' 'a lista 'e paggene cuntrullate vuosta",
+       "tooltip-ca-unwatch": "Lèva sta paggena d' 'a lista 'e paggene cuntrullate vuosta",
        "tooltip-search": "Truova dint'ô {{SITENAME}}",
+       "tooltip-search-go": "Vaje â paggena cu stu nomme si esiste",
        "tooltip-search-fulltext": "Ascià 'o testo indicato dint'e paggene",
        "tooltip-p-logo": "Visita a paggena prencepale",
        "tooltip-n-mainpage": "Visita a paggena prencepale",
        "tooltip-n-mainpage-description": "Visita a paggena prencepale",
        "tooltip-n-portal": "Descrizione d&#39;'o prugietto, che po' ffa, addò truvà 'e ccose",
+       "tooltip-n-currentevents": "Ascìa 'e nfurmaziune ncopp' 'e fatte succiesse mò mò",
        "tooltip-n-recentchanges": "Ennece dde urdeme cagnamiénte ddo sito",
        "tooltip-n-randompage": "Na paggena qualsiase",
        "tooltip-n-help": "Paggena 'e ajùto",
        "tooltip-t-whatlinkshere": "'Na lista 'e tutte e paggene ca song cullegate a chista",
        "tooltip-t-recentchangeslinked": "Urdeme cagnamiénte dde paggene ca cullegano a chesta",
+       "tooltip-feed-rss": "RSS feed pe sta pàggena",
+       "tooltip-feed-atom": "Atom feed pe sta pàggena",
        "tooltip-t-contributions": "Lista dde contributte 'e chisto utente",
        "tooltip-t-emailuser": "Manna 'nu email a chisto utente",
        "tooltip-t-upload": "Careca file",
        "tooltip-t-permalink": "Jonta permanente a chista vversione dda paggena",
        "tooltip-ca-nstab-main": "Vere a paggena e contenuto",
        "tooltip-ca-nstab-user": "Vere a paggena utente",
+       "tooltip-ca-nstab-media": "Vide 'a pàggena d' 'e media",
        "tooltip-ca-nstab-special": "Chista è 'na paggena speciale, nun può essere càgnata",
        "tooltip-ca-nstab-project": "Vere a paggena 'e servizio",
        "tooltip-ca-nstab-image": "Vere a paggena ddo file",
+       "tooltip-ca-nstab-mediawiki": "Vide 'a mmasciata d' 'o sistema",
        "tooltip-ca-nstab-template": "Vere 'o modello",
+       "tooltip-ca-nstab-help": "Vide 'a paggena d'aiuto",
        "tooltip-ca-nstab-category": "Vere a paggena d\"a categurìa",
        "tooltip-minoredit": "Rénne chìsto cagnamiénto cchiù ppiccirìllo.",
        "tooltip-save": "Sàrva 'e cagnamiénte.",
        "tooltip-preview": "Primma 'e sarvà, vìre primma chille ca hê cagnàte!",
+       "tooltip-diff": "Fà vedé 'e cagnamiente c'avite fatto ô testo",
+       "tooltip-compareselectedversions": "Fà vedé 'e differenze nfra tutt' 'e dduje verziune scigliute 'e sta paggena",
+       "tooltip-watch": "Azzecca sta paggena int' 'a lista 'e paggene cuntrullate vuosta",
+       "tooltip-watchlistedit-normal-submit": "Lèva 'e titule",
+       "tooltip-watchlistedit-raw-submit": "Agghiurna l'elenco 'e paggene cuntrullate",
+       "tooltip-recreate": "Arricrèa 'e paggene pure si so state scancellate",
+       "tooltip-upload": "Accummencia 'a carreca",
        "tooltip-rollback": "\"A vascio\" annulla 'e modefeche 'e chista paggena ell'ultimo contributore cu n' uneco click",
+       "tooltip-undo": "\"Annulla\" annulla stu cagnamiento e arape 'u form 'e cagnamiento facenno vedé l'anteprimma.\nPermette azzeccà nu mutivo dint' 'o riepilego.",
+       "tooltip-preferences-save": "Riggistra 'e preferenze",
+       "tooltip-summary": "Miette nu riepilego piccerillo",
+       "anonymous": "{{PLURAL:$1|utente|utente}} anonime 'e {{SITENAME}}",
+       "siteuser": "Utente 'e {{SITENAME}} $1",
+       "anonuser": "Utente anonime 'e {{SITENAME}} $1",
+       "lastmodifiedatby": "Sta paggena è stata cagnata l'urdema vota 'e $2, d' 'o $1 da $3.",
+       "othercontribs": "Basata ncopp' 'a fatica 'e $1.",
        "others": "ate",
+       "siteusers": "{{PLURAL:$2|utente|utente}} 'e {{SITENAME}} $1",
+       "anonusers": "{{PLURAL:$2|utente|utente}} anonime 'e {{SITENAME}} $1",
+       "creditspage": "Auture d' 'a paggena",
+       "nocredits": "Nun ce stanno nfurmaziune ncopp'a l'auture 'e sta paggena.",
+       "spamprotectiontitle": "Filtro 'e prutezione anti-spam",
+       "spamprotectiontext": "'A paggena ca vulite astipà è stata bloccata p' 'o filtro anti-spam.\nChesto è succiesso pecché avite miso nu link 'e chille ca stanno dint' 'a lista nira 'e site 'e fore.",
+       "spamprotectionmatch": "'O testo ccà abbascio è stato nzignato p' 'o filtro anti-spam: $1",
+       "spambot_username": "Sistema MediaWiki 'e pulezzia anti-spam",
+       "spam_reverting": "Arrepiglianno l'urdema verziona ca nun cuntene 'e link a $1",
+       "spam_blanking": "Tutt' 'e verziune cuntenenno cullegamiente a $1, pulezzate e sbacantate",
+       "spam_deleting": "Tutt' 'e verziune cuntenenno cullegamiente a $1, scancellanno",
+       "simpleantispam-label": "Cuntrollo anti-spam.\n<strong>NUN</strong> ghienchere!",
+       "pageinfo-title": "Nfurmaziune pe' \"$1\"",
+       "pageinfo-not-current": "Scusate, nun se ponno piglià sti nfurmaziune p' 'e verziune viecchie.",
+       "pageinfo-header-basic": "Nfurmaziune bbase",
+       "pageinfo-header-edits": "Cronologgia d' 'e cagnamiente",
+       "pageinfo-header-restrictions": "Càgna prutezione",
+       "pageinfo-header-properties": "Proprietà d' 'a paggena",
+       "pageinfo-display-title": "Fà vedé 'o titolo",
+       "pageinfo-default-sort": "Chiave d'ordinamento 'e bbase",
+       "pageinfo-length": "Llonghezza d' 'a paggena ('n byte)",
+       "pageinfo-article-id": "ID d' 'a paggena",
+       "pageinfo-language": "Lengua d' 'a paggena 'e cuntenute",
+       "pageinfo-content-model": "Mudello 'e cuntenute d' 'a paggena",
+       "pageinfo-robot-policy": "Indicizzate 'a 'e robbot",
+       "pageinfo-robot-index": "Permesso",
+       "pageinfo-robot-noindex": "Nun permesso",
+       "pageinfo-views": "Nummero 'e visite",
+       "pageinfo-watchers": "Nummero 'e visite â paggena",
+       "pageinfo-few-watchers": "Meno 'e $1 {{PLURAL:$1|visita|visite}}",
+       "pageinfo-redirects-name": "Nummero 'e redirect a sta paggena",
+       "pageinfo-subpages-name": "Nummero 'e sottopaggene 'e sta paggena",
        "previousdiff": "← Càgnamiento cchiù viecchio",
        "nextdiff": "Cagnamiénte successivo →",
        "file-info-size": "$1 × $2 pixel, dimenzione ddo file: $3, tipo MIME: $4",
index 8afefa4..1867460 100644 (file)
        "searchall": "alle",
        "showingresults": "Nedenfor vises opptil {{PLURAL:$1|'''ett''' resultat|'''$1''' resultater}} fra og med nummer <b>$2</b>.",
        "showingresultsinrange": "Nedenfor vises opptil {{PLURAL:$1|<strong>1</strong> resultat|<strong>$1</strong> resulter}} i området #<strong>$2</strong> til #<strong>$3</strong>.",
-       "showingresultsheader": "{{PLURAL:$5|Resultat '''$1''' av '''$3'''|Resultat '''$1 - $2''' av '''$3'''}} for '''$4'''",
        "search-nonefound": "Ingen resultater passet til søket.",
        "powersearch-legend": "Avansert søk",
        "powersearch-ns": "Søk i navnerom:",
index f6ab918..c7a8b4b 100644 (file)
        "otherlanguages": "In andere talen",
        "redirectedfrom": "(Doorverwezen vanaf $1)",
        "redirectpagesub": "Doorverwijspagina",
+       "redirectto": "Doorverwijzen naar:",
        "lastmodifiedat": "Deze pagina is het laatst bewerkt op $1 om $2.",
        "viewcount": "Deze pagina is {{PLURAL:$1|één keer|$1 keer}} bekeken.",
        "protectedpage": "Beveiligde pagina",
        "passwordreset-emailsent-capture": "Er is een e-mail voor het opnieuw instellen van een wachtwoord verzonden. Deze wordt hieronder weergegeven.",
        "passwordreset-emailerror-capture": "Er is een e-mail voor het opnieuw instellen van een wachtwoord aangemaakt. Deze wordt hieronder weergegeven. Het verzenden naar de {{GENDER:$2|gebruiker}} is mislukt om de volgende reden: $1",
        "changeemail": "E-mailadres wijzigen",
-       "changeemail-header": "Het e-mailadres van mijn gebruiker wijzigen",
        "changeemail-text": "Vul dit formulier in om uw e-mailadres te wijzigen. U moet uw wachtwoord invoeren om deze wijziging te bevestigen.",
        "changeemail-no-info": "U moet aangemeld zijn om rechtstreeks toegang te hebben tot deze pagina.",
        "changeemail-oldemail": "Huidig e-mailadres:",
        "changeemail-none": "(geen)",
        "changeemail-password": "Uw wachtwoord voor {{SITENAME}}:",
        "changeemail-submit": "E-mailadres wijzigen",
-       "changeemail-cancel": "Annuleren",
        "changeemail-throttled": "U heeft recentelijk te veel mislukte aanmeldpogingen gedaan.\nWacht alstublieft $1 voordat u het opnieuw probeert.",
        "resettokens": "Tokens opnieuw instellen",
        "resettokens-text": "U kunt hier tokens opnieuw instellen die toegang tot bepaalde persoonlijke gegevens die zijn gekoppeld aan uw gebruiker.\n\nDoe dit als u ze per ongeluk met iemand hebt gedeeld of als uw onbevoegden toegang hebben gekregen tot uw gebruiker.",
        "searchall": "alle",
        "showingresults": "Hieronder {{PLURAL:$1|staat '''1''' resultaat|staan '''$1''' resultaten}} vanaf #'''$2'''.",
        "showingresultsinrange": "Hieronder {{PLURAL:$1|wordt|worden}} maximaal {{PLURAL:$1|<strong>1</strong> resultaat|<strong>$1 </strong>resultaten}} weergegeven in het bereik #<strong>$2</strong> tot #<strong>$3</strong>.",
-       "showingresultsheader": "{{PLURAL:$5|Resultaat '''$1''' van '''$3'''|Resultaten '''$1 - $2''' van '''$3'''}} voor '''$4'''",
        "search-nonefound": "Er zijn geen resultaten voor uw zoekopdracht.",
        "powersearch-legend": "Uitgebreid zoeken",
        "powersearch-ns": "Zoeken in naamruimten:",
index 6c57a4c..3d761c7 100644 (file)
        "searchrelated": "relatert",
        "searchall": "alle",
        "showingresults": "Nedanfor er opp til {{PLURAL:$1|'''eitt'''|'''$1'''}} resultat som byrjar med nummer '''$2''' vist{{PLURAL:$1||e}}.",
-       "showingresultsheader": "{{PLURAL:$5|Resultat '''$1''' av '''$3'''|Resultat '''$1 - $2''' av '''$3'''}} for '''$4'''",
        "search-nonefound": "Ingen resultat svarte til førespurnaden.",
        "powersearch-legend": "Avansert søk",
        "powersearch-ns": "Søk i namnerom:",
        "sp-contributions-search": "Søk etter bidrag",
        "sp-contributions-username": "IP-adresse eller brukarnamn:",
        "sp-contributions-toponly": "Vis berre endringar som er gjeldande versjonar",
+       "sp-contributions-newonly": "Berre vis endringar som oppretta ei side",
        "sp-contributions-submit": "Søk",
        "whatlinkshere": "Lenkjer hit",
        "whatlinkshere-title": "Sider som har lenkje til «$1»",
index 2df8aa0..c202f44 100644 (file)
        "passwordreset-emailsent-capture": "Wyświetlony poniżej e‐mail pozwalający na zresetowanie hasła został wysłany.",
        "passwordreset-emailerror-capture": "Poniżej wyświetlony e‐mail pozwalający na zresetowanie hasła został wygenerowany, ale nie udało się wysłać go do {{GENDER:$2|użytkownika|użytkowniczki}}: $1",
        "changeemail": "Zmiana adresu e‐mail",
-       "changeemail-header": "Zmiana adresu e‐mail",
        "changeemail-text": "Wypełnij formularz, jeśli chcesz zmienić swój adres poczty elektronicznej. Będziesz musiał wprowadzić hasło, aby potwierdzić tę zmianę.",
        "changeemail-no-info": "Musisz być zalogowany, by uzyskać bezpośredni dostęp do tej strony.",
        "changeemail-oldemail": "Obecny adres e‐mail:",
        "changeemail-none": "(brak)",
        "changeemail-password": "Twoje hasło:",
        "changeemail-submit": "Zapisz nowy",
-       "changeemail-cancel": "Anuluj",
        "changeemail-throttled": "Zbyt wiele razy próbowałeś zalogować się na to konto.\nOdczekaj $1, zanim ponowisz próbę.",
        "resettokens": "Resetowanie tokenów",
        "resettokens-text": "Na tej stronie możesz zresetować tokeny, które umożliwiają dostęp do pewnych prywatnych danych związanych z Twoim kontem.\n\nNależy to zrobić, jeśli ktoś je poznał lub zdobył hasło do Twojego konta.",
        "searchall": "wszystkie",
        "showingresults": "Poniżej znajduje się lista {{PLURAL:$1|z '''1''' wynikiem|'''$1''' wyników}}, rozpoczynając od wyniku numer '''$2'''.",
        "showingresultsinrange": "Poniżej wyświetlono co najwyżej {{PLURAL:$1|<strong>1</strong> wynik|<strong>$1</strong> wyniki|<strong>$1</strong> wyników}} w zakresie od <strong>$2</strong> do <strong>$3</strong>.",
-       "showingresultsheader": "{{PLURAL:$5|Wynik '''$1''' z '''$3'''|Wyniki '''$1 – $2''' z '''$3'''}} dla '''$4'''",
+       "search-showingresults": "{{PLURAL:$4|Wynik <strong>$1</strong> z <strong>$3</strong>|Wyniki <strong>$1 - $2</strong> z <strong>$3</strong>}}",
        "search-nonefound": "Brak wyników spełniających kryteria podane w zapytaniu.",
        "powersearch-legend": "Wyszukiwanie zaawansowane",
        "powersearch-ns": "Przeszukaj przestrzenie nazw:",
        "protect-othertime": "Inny okres",
        "protect-othertime-op": "inny okres",
        "protect-existing-expiry": "Obecny czas wygaśnięcia: $2 o $3",
+       "protect-existing-expiry-infinity": "Obecny czas wygaśnięcia: nieskończony",
        "protect-otherreason": "Inny lub dodatkowy powód",
        "protect-otherreason-op": "Inny powód",
        "protect-dropdown": "*Najczęstsze powody zabezpieczenia\n** Częste wandalizmy\n** Częste spamowanie\n** Wojna edycyjna\n** Wygłupy",
        "unblocked": "[[User:$1|$1]] {{GENDER:$1|został odblokowany|została odblokowana|został odblokowany}}.",
        "unblocked-range": "$1 został odblokowany",
        "unblocked-id": "Blokada $1 została zdjęta",
+       "unblocked-ip": "[[Special:Contributions/$1|$1]] został odblokowany.",
        "blocklist": "Zablokowani użytkownicy",
        "ipblocklist": "Zablokowani użytkownicy",
        "ipblocklist-legend": "Znajdź zablokowanego użytkownika",
        "logentry-upload-overwrite": "$1 {{GENDER:$2|przesłał|przesłała}} nową wersję $3",
        "logentry-upload-revert": "$1 {{GENDER:$2|przesłał|przesłała}} $3",
        "rightsnone": "brak",
+       "revdelete-summary": "opis zmian",
        "feedback-bugornote": "Jeśli jesteś w stanie szczegółowo opisać problem techniczny, proszę [$1 zgłoś błąd].\nW przeciwnym wypadku można użyć prostego formularza poniżej. Komentarz zostanie dodany do strony \"[$3  $2]\", wraz z nazwą użytkownika.",
        "feedback-subject": "Temat",
        "feedback-message": "Wiadomość:",
        "log-description-pagelang": "Rejestr zmian języków przypisanych do poszczególnych stron",
        "logentry-pagelang-pagelang": "$1 {{GENDER:$2|zmienił|zmieniła}} język strony $3 z „$4” na „$5”.",
        "default-skin-not-found-row-enabled": "* <code>$1</code> / $2 (włączone)",
-       "default-skin-not-found-row-disabled": "* <code>$1</code> / $2 ('''wyłączone''')"
+       "default-skin-not-found-row-disabled": "* <code>$1</code> / $2 ('''wyłączone''')",
+       "mediastatistics-summary": "Statystyki dotyczące przesłanych typów plików. Dotyczą one tylko najnowszej wersji pliku. Starsze lub usunięte wersje plików nie są uwzględniane.",
+       "mediastatistics-table-mimetype": "Typ MIME",
+       "mediastatistics-table-count": "Liczba plików",
+       "mediastatistics-table-totalbytes": "Łączny rozmiar",
+       "mediastatistics-header-unknown": "Nieznane",
+       "mediastatistics-header-bitmap": "Obrazy bitmapowe",
+       "mediastatistics-header-drawing": "Rysunki (obrazy wektorowe)",
+       "mediastatistics-header-audio": "Audio",
+       "mediastatistics-header-video": "Filmy",
+       "mediastatistics-header-executable": "Pliki wykonywalne",
+       "mediastatistics-header-archive": "Formaty skompresowane"
 }
index 244784e..aa275e1 100644 (file)
        "passwordreset-emailsent-capture": "Un mëssagi ëd riampostassion ëd la ciav a l'é stàit mandà, e a l'é mostrà sì-sota.",
        "passwordreset-emailerror-capture": "Un mëssagi ëd riampostassion ëd la ciav a l'é stàit generà, e a l'é smonù sì-sota, ma la spedission a {{GENDER:$2|l'utent}} a l'é falìa: $1",
        "changeemail": "Cangé l'adrëssa ëd pòsta eletrònica",
-       "changeemail-header": "Cangé l'adrëssa ëd pòsta eletrònica dël cont",
        "changeemail-text": "Ch'a completa 's formolari për cangé soa adrëssa eletrònica. A dev anserì soa ciav për confirmé costa modìfica.",
        "changeemail-no-info": "A dev esse intrà ant ël sistema për andé diretament a costa pàgina.",
        "changeemail-oldemail": "Adrëssa ëd pòsta eletrònica atual:",
        "changeemail-none": "(gnun-a)",
        "changeemail-password": "Soa ciav su {{SITENAME}}:",
        "changeemail-submit": "Cangé l'adrëssa ëd pòsta eletrònica",
-       "changeemail-cancel": "Anulé",
        "changeemail-throttled": "A l'ha fàit tròpi tentativ ëd rintré ant ël sistema.\nPër piasì, ch'a speta $1 prima ëd prové torna.",
        "resettokens": "Riamposté ij geton",
        "resettokens-text": "Ambelessì a peul riamposté ij geton ch'a permëtto d'acede a chèich dàit privà associà a sò cont.\n\nA dovrìa felo si për asar chiel a l'ha partagiaje con cheidun o si sò cont a l'é stàit compromëttù.",
        "searchall": "tuti",
        "showingresults": "Ambelessì-sota a treuva fin a {{PLURAL:$1|'''1'''|'''$1'''}} arzultà, a parte dal nùmer #'''$2'''.",
        "showingresultsinrange": "Smon-e sì-sota fin-a a {{PLURAL:$1|<strong>1</strong>|<strong>$1</strong>}} arzultà ant la serie da #<strong>$2</strong> a #<strong>$3</strong>.",
-       "showingresultsheader": "{{PLURAL:$5|Arzultà '''$1''' ëd '''$3'''|Arzultà '''$1 - $2''' ëd '''$3'''}} për '''$4'''",
+       "search-showingresults": "{{PLURAL:$4|Arzultà <strong>$1</strong> ëd <strong>$3</strong>|Arzultà <strong>da $1 a $2</strong> ëd <strong>$3</strong>}}",
        "search-nonefound": "A-i é gnun arzultà për l'arserca.",
        "powersearch-legend": "Arserca avansà",
        "powersearch-ns": "Sërché ant jë spassi nominaj:",
        "ipb-unblock-addr": "Dësbloché $1",
        "ipb-unblock": "Dësbloché n'utent ò n'adrëssa IP",
        "ipb-blocklist": "Vardé ij blocagi ativ",
-       "ipb-blocklist-contribs": "Contribussion për $1",
+       "ipb-blocklist-contribs": "Contribussion për {{GENDER:$1|$1}}",
        "unblockip": "Dësbloché n'utent",
        "unblockiptext": "Che a deuvra ël formolari ambelessì-sota për deje andré ël drit dë scritura a n'adrëssa IP o në stranòm che a l'era stàit blocà.",
        "ipusubmit": "Gavé ës blocagi",
        "unblocked": "[[User:$1|$1]] a l'é stait dësblocà",
        "unblocked-range": "$1 a l'é stàit dësblocà",
        "unblocked-id": "Ël blocagi $1 a l'é stait gavà via",
+       "unblocked-ip": "[[Special:Contributions/$1|$1]] a l'é stàit dësblocà.",
        "blocklist": "Utent blocà",
        "ipblocklist": "Utent blocà",
        "ipblocklist-legend": "Trové n'utent blocà",
        "movepagetalktext": "La pàgina ëd discussion tacà a costa pàgina d'artìcol, se a-i é, a sarà tramudà n'automatich ansema a l'artìcol, '''gavà costi cas-sì''':\n*quand as tramuda la pàgina tra diferent spassi nominaj,\n*quand na pàgina ëd discussion nen veujda a-i é già për ël nòm neuv, ò pura\n*a l'ha desselessionà ël quadrèt ëd conferma ambelessì-sota.\n\nAnt costi cas-sì, se a chërd dë felo, a-j farà da manca dë tramudesse la pàgina ëd discussion daspërchiel, a man.",
        "movearticle": "Cangeje nòm a l'artìcol:",
        "moveuserpage-warning": "'''Atension:''' A sta për tramudé na pàgina d'utent. Për piasì ch'a nòta che a sarà tramudà mach la pàgina e che l'utent a sarà ''pa'' arbatjà.",
+       "movecategorypage-warning": "<strong>Atension:</strong> A l'é a brus ëd tramudé na pàgina ëd categorìa. Për piasì, ch'a ten-a da ment che mach la pàgina a sarà tramudà e che tute le pàgine ant la veja categorìa a saran <em>nen</em> tramudà an cola neuva.",
        "movenologintext": "A venta esse n'Utent registrà e esse [[Special:UserLogin|rintrà ant ël sistema]]\npër podèj tramudé na pàgina.",
        "movenotallowed": "A l'ha pa ij përmess dont a fa da manca për tramudé le pàgine.",
        "movenotallowedfile": "A l'ha pa ij përmess për tramudé j'archivi.",
        "cant-move-user-page": "A l'ha pa ij përmess për tramudé le pàgine d'utent (gavà le sot-pàgine).",
        "cant-move-to-user-page": "A l'ha pa ël përmess për tramudé na pàgina a na pàgina utent (gavà a na sot-pàgina utent).",
+       "cant-move-category-page": "A l'ha nen ël përmess ëd tramudé le pàgine ëd categorìa.",
+       "cant-move-to-category-page": "A l'ha nen ël përmess ëd tramudé na pàgina a na pàgina ëd categorìa.",
        "newtitle": "Neuv tìtol ëd",
        "move-watch": "Ten-e sot-euj la pàgina sorgiss e la pàgina selessionà",
        "movepagebtn": "Tramudé la pàgina",
        "import": "Amportassion ëd pàgine",
        "importinterwiki": "Amportassion da wiki diferente",
        "import-interwiki-text": "Che a selession-a na wiki e ël tìtol dla pàgina da amporté.\nDate dle revision e stranòm dj'editor a resteran piàjit sù 'cò lor.\nTute j'amportassion antra wiki diferente a resto marcà ant ël [[Special:Log/import|Registr dj'amportassion]].",
+       "import-interwiki-sourcewiki": "Wiki sorgiss:",
+       "import-interwiki-sourcepage": "Pàgina sorgiss:",
        "import-interwiki-history": "Copié tute le revision ëd la stòria ëd costa pàgina",
        "import-interwiki-templates": "Anserì tùit jë stamp",
        "import-interwiki-submit": "Amporté",
        "import-upload": "Cariament ëd dat XML",
        "import-token-mismatch": "Pèrdita dij dat ëd session.\nPër piasì, ch'a preuva torna.",
        "import-invalid-interwiki": "As peul pa amportesse da la wiki spessificà.",
-       "import-error-edit": "La pàgina «$1» a l'é pa stàita amportà përchè chiel a peul pa modifichela.",
+       "import-error-edit": "La pàgina «$1» a l'era pa stàita amportà përchè chiel a peul pa modifichela.",
        "import-error-create": "La pàgina «$1» a l'é pa stàita amportà përchè chiel a peul pa creela.",
        "import-error-interwiki": "La pàgina «$1» a l'é pa amportà përchè sò nòm a l'é arzervà për na liura esterna (antërwiki).",
        "import-error-special": "La pàgina «$1» a l'é pa amportà përchè a ponta a në spassi nominal ch'a përmët pa dle pàgine.",
        "logentry-rights-rights-legacy": "$1 {{GENDER:$2|a l'ha modificà}} l'apartenensa a la partìa për $3",
        "logentry-rights-autopromote": "$1 a l'é {{GENDER:$2|stàit promovù}} an automàtich da $4 a $5",
        "rightsnone": "(gnun)",
+       "revdelete-summary": "resumé dla modìfica",
        "feedback-bugornote": "S'a l'é pront a descrive un problema técnich an detaj, për piasì ch'a [$1 signala un bigat]. \nDësnò, a peul dovré ël formolari semplificà sì-sota. Sò coment a sarà giontà a la pàgina «[$3 $2]», con sò stranòm.",
        "feedback-subject": "Soget:",
        "feedback-message": "Mëssagi:",
index dc00401..5b332f3 100644 (file)
        "hidetoc": "پټول",
        "collapsible-collapse": "پرځول",
        "collapsible-expand": "غځول",
+       "confirmable-yes": "هو",
+       "confirmable-no": "نه",
        "thisisdeleted": "$1 کتل او يا بيازېرمل؟",
        "viewdeleted": "$1 کتل؟",
        "restorelink": "{{PLURAL:$1|يو ړنگ شوی سمون|$1 ړنگ شوي سمونونه}}",
        "userlogin-resetlink": "د ننوتلو مالومات مو هېر شوي؟",
        "userlogin-resetpassword-link": "پټنوم مو هېر شوی؟",
        "userlogin-helplink2": "په ننوتلو کې مرسته",
-       "userlogin-createanother": "بل گڼون جوړول",
        "createacct-emailrequired": "برېښليک پته",
        "createacct-emailoptional": "برېښليک پته (اختياري)",
        "createacct-email-ph": "برېښليک پته مو وټاپۍ",
        "passwordreset-emailsent": "د پټنوم بيا پرځای کېدنې لپاره برېښليک درولېږل شو.",
        "passwordreset-emailsent-capture": "د پټنوم بياپرځای کېدنې لپار مو يو برېښليک درولېږه، برېښليک په لاندې توگه ښودل شوی.",
        "changeemail": "برېښليک پته بدلول",
-       "changeemail-header": "د گڼون برېښليک پته بدلول",
        "changeemail-text": "د برېښليک پتې بدلولو لپاره مو همدا فورمه ډکه کړۍ. د دې بدلون د تاييد لپاره بايد پټنوم مو ورکړۍ.",
        "changeemail-no-info": "دې مخ ته د لاسرسي لپاره بايد غونډال کې ورننوځۍ.",
        "changeemail-oldemail": "اوسنۍ برېښليک پته:",
        "changeemail-none": "(هېڅ)",
        "changeemail-password": "ستاسې د{{SITENAME}} پټنوم:",
        "changeemail-submit": "برېښليک بدلول",
-       "changeemail-cancel": "ناگارل",
+       "changeemail-throttled": "تاسې څو واره هڅه کړې چې غونډال ته ورننوځۍ.\nلطفاً د بيا هڅې نه مخکې $1 شېبې تم شۍ.",
        "bold_sample": "زغرد متن",
        "bold_tip": "زغرد متن",
        "italic_sample": "رېوند متن",
        "searchrelated": "اړونده",
        "searchall": "ټول",
        "showingresults": "دلته لاندې تر {{PLURAL:$1|'''1''' پايله|'''$1''' پايلې}} ښکاره شوي پيل له #'''$2''' شوی.",
-       "showingresultsheader": "د «'''$4'''» لپاره {{PLURAL:$5|له '''$1''' نه تر '''$3''' پايله|له '''$1 نه تر $2''' پايلې، ټولې پايلې '''$3''' }}",
        "search-nonefound": "ستاسې دغوښتنې اړونده پايلې و نه موندل شوې.",
        "powersearch-legend": "ژوره پلټنه",
        "powersearch-ns": "په نوم-تشيالونو کې پلټنه:",
        "randompage": "ناټاکلی مخ",
        "randompage-nopages": "په لانديني {{PLURAL:$2|نوم-تشيال|نوم-تشيالونو}} کې هېڅ کوم مخ نشته: $1.",
        "randomincategory": "په وېشنيزه کې ناټاکلی مخ",
-       "randomincategory-selectcategory": "يو ناټاکلی مخ له وېشنيزې موندل: $1 $2.",
-       "randomincategory-selectcategory-submit": "ورځه",
        "randomredirect": "ناټاکلی ورگرځېدنه",
        "statistics": "شمار",
        "statistics-header-pages": "د مخونو شمار",
        "thumbnail-more": "لويول",
        "filemissing": "دوتنه ورکه ده",
        "thumbnail_error": "د  بټنوک د جوړېدنې ستونزه: $1",
-       "import-interwiki-source": "سرچينيز ويکي/مخ:",
        "import-interwiki-history": "د دې مخ د پېښليک ټولې بڼې لمېسل",
        "import-interwiki-templates": "ټولې کينډۍ نغاړل",
        "import-interwiki-namespace": "د موخې نوم-تشيال:",
        "logentry-newusers-create": "د $1 کارن گڼون {{GENDER:$2|جوړ شو}}",
        "logentry-newusers-autocreate": "د $1 گڼون په اتوماتيک ډول {{GENDER:$2|جوړ شو}}",
        "rightsnone": "(هېڅ)",
+       "revdelete-summary": "لنډيز سمول",
        "feedback-subject": "سکالو:",
        "feedback-message": "پيغام:",
        "feedback-cancel": "ناگارل",
index f8ddf71..b0b53cc 100644 (file)
        "passwordreset-emailsent-capture": "Foi enviado um e-mail de lembrete, que é mostrado abaixo.",
        "passwordreset-emailerror-capture": "Foi gerado um e-mail de recuperação da senha, conforme mostrado abaixo, mas o envio {{GENDER:$2|ao usuário|à usuária}} falhou. $1",
        "changeemail": "Alterar o endereço de e-mail",
-       "changeemail-header": "Alterar o endereço de e-mail da conta",
        "changeemail-text": "Preencha este formulário para alterar o endereço de e-mail. Para confirmar esta alteração terá de introduzir a sua senha.",
        "changeemail-no-info": "Para acessar diretamente esta página você tem de estar autenticado.",
        "changeemail-oldemail": "Endereço de e-mail atual:",
        "changeemail-none": "(nenhum)",
        "changeemail-password": "Sua senha para o wiki {{SITENAME}}:",
        "changeemail-submit": "Alterar e-mail",
-       "changeemail-cancel": "Cancelar",
        "changeemail-throttled": "Você realizou demasiadas tentativas de se registrar.\nPor favor, aguarde $1 antes de tentar novamente.",
        "resettokens": "Reiniciar os tokens",
        "resettokens-text": "Você pode reiniciar os tokens, que permitem o acesso a certos dados privados associados à sua conta, aqui.\n\nVocê só deve reiniciá-los se compartilhou-os com alguém ou se a sua conta foi comprometida.",
        "searchrelated": "relacionados",
        "searchall": "todos",
        "showingresults": "A seguir {{PLURAL:$1|é mostrado '''um''' resultado|são mostrados até '''$1''' resultados}}, iniciando no '''$2'''º.",
-       "showingresultsheader": "{{PLURAL:$5|Resulado '''$1''' de '''$3'''|Resultados '''$1 - $2''' de '''$3'''}} para '''$4'''",
        "search-nonefound": "Não há resultados que correspondam à consulta.",
        "powersearch-legend": "Pesquisa avançada",
        "powersearch-ns": "Pesquisar nos espaços nominais:",
        "importfailed": "A importação falhou: $1",
        "importunknownsource": "Tipo de fonte de importação desconhecida",
        "importcantopen": "Não foi possível abrir o arquivo de importação",
-       "importbadinterwiki": "Ligação de interwiki incorreta",
+       "importbadinterwiki": "Link de interwiki incorreto",
        "importsuccess": "Importação completa!",
        "importnosources": "Não foram definidas fontes de importação transwiki e o carregamento direto de históricos encontra-se desativado.",
        "importnofile": "Nenhum arquivo de importação foi carregado.",
        "logentry-rights-rights-legacy": "$1 alterou os grupos de $3",
        "logentry-rights-autopromote": "$1 foi promovido automaticamente de $4 para $5",
        "rightsnone": "(nenhum)",
+       "revdelete-summary": "sumário de edição",
        "feedback-bugornote": "Se você está preparado para descrever detalhadamente um problema técnico, [$1 relate um bug].\nCaso contrário, você poderá usar o formulário simplificado a seguir. Seu comentário será adicionado à página \"[$3 $2]\", junto com o seu nome de usuário e o navegador que estiver usando neste momento.",
        "feedback-subject": "Assunto:",
        "feedback-message": "Mensagem:",
index 7c1d27b..689f32d 100644 (file)
        "passwordreset-emailsent-capture": "Foi enviado um correio eletrónico para recuperação da palavra-passe, que é mostrado abaixo.",
        "passwordreset-emailerror-capture": "Foi gerado um correio eletrónico para redefinição da palavra-passe, mostrado abaixo, mas o seu envio para {{GENDER:$2|o utilizador|a utilizadora}} falhou: $1",
        "changeemail": "Alterar o endereço de correio eletrónico",
-       "changeemail-header": "Alterar o endereço de correio eletrónico da conta",
        "changeemail-text": "Preencha este formulário para alterar o endereço de correio eletrónico. Para confirmar esta alteração terá de introduzir a sua palavra-passe.",
        "changeemail-no-info": "Precisa de iniciar sessão para aceder diretamente a esta página.",
        "changeemail-oldemail": "Correio eletrónico atual:",
        "changeemail-none": "(nenhum)",
        "changeemail-password": "A sua palavra-passe em {{SITENAME}}:",
        "changeemail-submit": "Alterar correio eletrónico",
-       "changeemail-cancel": "Cancelar",
        "changeemail-throttled": "Realizou demasiadas tentativas de início de sessão.\nAguarde $1 antes de tentar novamente, por favor.",
        "resettokens": "Redefinir chaves",
        "resettokens-text": "Pode redefinir as chaves de acesso a certos dados privados associados à sua conta aqui.\n\nDeve fazê-lo se as divulgou acidentalmente a alguém ou se a sua conta tiver sido comprometida.",
        "searchall": "todos",
        "showingresults": "{{PLURAL:$1|É apresentado '''um''' resultado|São apresentados até '''$1''' resultados}} abaixo{{PLURAL:$1||, começando pelo '''$2'''º}}.",
        "showingresultsinrange": "Apresenta-se abaixo {{PLURAL:$1|<strong>1</strong> resultado|até <strong>$1</strong> resultados}} no intervalo #<strong>$2</strong> a #<strong>$3</strong>.",
-       "showingresultsheader": "{{PLURAL:$5|Resultado '''$1''' de '''$3'''|Resultados '''$1–$2''' de '''$3'''}} para '''$4'''",
+       "search-showingresults": "{{PLURAL:$4|Resultado <strong>$1</strong> de <strong>$3</strong>|Resultados <strong>$1 - $2</strong> de <strong>$3</strong>}}",
        "search-nonefound": "A pesquisa não produziu resultados.",
        "powersearch-legend": "Pesquisa avançada",
        "powersearch-ns": "Pesquisar nos domínios:",
        "prefs-tokenwatchlist": "Chave",
        "prefs-diffs": "Diferenças",
        "prefs-help-prefershttps": "Esta preferência terá efeito no seu próximo início de sessão.",
+       "prefswarning-warning": "Fez alterações às suas preferências que não foram gravadas ainda.\nSe abandonar esta página sem clicar em \"$1\", as suas preferências não serão atualizadas.",
        "prefs-tabs-navigation-hint": "Dica: Pode usar as setas direita e esquerda do teclado para navegar entre os separadores.",
        "email-address-validity-valid": "O endereço de correio eletrónico parece válido",
        "email-address-validity-invalid": "É necessário um endereço de correio eletrónico válido!",
        "unblocked": "[[User:$1|$1]] foi desbloqueado",
        "unblocked-range": "A gama $1 foi desbloqueada",
        "unblocked-id": "O bloqueio de $1 foi removido com sucesso",
+       "unblocked-ip": "[[Special:Contributions/$1|$1]] foi desbloqueado.",
        "blocklist": "Utilizadores bloqueados",
        "ipblocklist": "Utilizadores bloqueados",
        "ipblocklist-legend": "Procurar um utilizador bloqueado",
        "logentry-upload-overwrite": "$1 {{GENDER:$2|carregou}} uma nova versão de $3",
        "logentry-upload-revert": "$1 {{GENDER:$2|carregou}} $3",
        "rightsnone": "(nenhum)",
+       "revdelete-summary": "resumo da edição",
        "feedback-bugornote": "Se está pronto para descrever um problema técnico em detalhe, por favor, [$1 comunique o defeito].\nCaso contrário, pode facilmente usar o formulário abaixo. O seu comentário será adicionado à página \"[$3 $2]\", junto com o seu nome de utilizador e o navegador que está a usar.",
        "feedback-subject": "Assunto:",
        "feedback-message": "Mensagem:",
        "log-description-pagelang": "Este é um registo de alterações aos idiomas das páginas.",
        "logentry-pagelang-pagelang": "$1 {{GENDER:$2|alterou}} o idioma da página $3 de $4 para $5.",
        "default-skin-not-found-row-enabled": "* <code>$1</code> / $2 (ativado)",
-       "default-skin-not-found-row-disabled": "* <code>$1</code> / $2 ('''desativado''')"
+       "default-skin-not-found-row-disabled": "* <code>$1</code> / $2 ('''desativado''')",
+       "mediastatistics": "Estatísticas multimédia",
+       "mediastatistics-summary": "Estatísticas sobre os tipos de ficheiros carregados. Inclui apenas a versão mais recente do ficheiro. Versões antigas ou eliminadas são excluídas.",
+       "mediastatistics-nbytes": "{{PLURAL:$1|$1 byte|$1 bytes}} ($2; $3%)",
+       "mediastatistics-table-mimetype": "Tipo MIME",
+       "mediastatistics-table-extensions": "Extensões possíveis",
+       "mediastatistics-table-count": "Número de ficheiros",
+       "mediastatistics-table-totalbytes": "Tamanho combinado",
+       "mediastatistics-header-unknown": "Desconhecido",
+       "mediastatistics-header-audio": "Áudio",
+       "mediastatistics-header-video": "Vídeo",
+       "mediastatistics-header-executable": "Executáveis",
+       "mediastatistics-header-archive": "Formatos compactados"
 }
index 7973339..0bbcde1 100644 (file)
        "otherlanguages": "This message is shown under the toolbox. It is used if there are interwiki links added to the page, like <code><nowiki>[[</nowiki>en:Interwiki article]]</code>.\n{{Identical|Otherlanguages}}",
        "redirectedfrom": "The text displayed when a certain page is redirected to another page. Parameters:\n* $1 - the name of the page user came from",
        "redirectpagesub": "Displayed under the page title of a page which is a redirect to another page, see [{{fullurl:Project:Translators|redirect=no}} Project:Translators] for example.\n\n{{Identical|Redirect page}}",
-       "redirectto": "Alt text of the arrow icon shown on redirect pages ([[commons:File:Sample redirect page.jpg]]).\n\n{{Identical|Redirect page}}",
+       "redirectto": "Alt text of the arrow icon shown on redirect pages ([[commons:File:Sample redirect page.jpg]]).\n\n{{Identical|Redirect to}}",
        "talkpageheader": "{{notranslate}}",
        "lastmodifiedat": "This message is shown below each page, in the footer with the logos and links.\n\nParameters:\n* $1 - date\n* $2 - time\nSee also:\n* {{msg-mw|Lastmodifiedatby}}",
        "viewcount": "Used as page-view counter. Parameters:\n* $1 - number of pageviews",
        "passwordreset-emailerror-capture": "Error message displayed in [[Special:PasswordReset]] when sending an email fails. Parameters:\n* $1 - error message\n* $2 - username, used for GENDER\nSee also:\n* {{msg-mw|Passwordreset-emailsent}}\n* {{msg-mw|Passwordreset-emailsent-capture}}",
        "changeemail": "Title of [[Special:ChangeEmail|special page]].",
        "changeemail-summary": "{{ignored}}",
-       "changeemail-header": "Header on [[Special:ChangeEmail]].",
        "changeemail-text": "Text of [[Special:ChangeEmail]].",
        "changeemail-no-info": "Error message for [[Special:ChangeEmail]].\n\nParameters:\n* $1 (unused) - a link to [[Special:UserLogin]] with {{msg-mw|loginreqlink}} as link description",
        "changeemail-oldemail": "Label for e-mail address field in [[Special:ChangeEmail]].",
        "changeemail-none": "Probably appears in 'Current E-mail address' field when no address held, in [[Special:ChangeEmail]].\n\n{{Identical|None}}",
        "changeemail-password": "Label for password field in [[Special:ChangeEmail]].",
        "changeemail-submit": "Submit button on [[Special:ChangeEmail]]",
-       "changeemail-cancel": "Cancel button on [[Special:ChangeEmail]]\n\n{{Identical|Cancel}}",
        "changeemail-throttled": "Error message shown at [[Special:ChangeEmail]] after the user has tried to login with incorrect password too many times.\n\nThe user has to wait a certain time before trying to log in again.\n\nParameters:\n* $1 - the time to wait before the next login attempt. Automatically formatted using the following duration messages:\n** {{msg-mw|Duration-millennia}}\n** {{msg-mw|Duration-centuries}}\n** {{msg-mw|Duration-decades}}\n** {{msg-mw|Duration-years}}\n** {{msg-mw|Duration-weeks}}\n** {{msg-mw|Duration-days}}\n** {{msg-mw|Duration-hours}}\n** {{msg-mw|Duration-minutes}}\n** {{msg-mw|Duration-seconds}}\n\nThis is a protection against robots trying to find the password by trying lots of them.\nThe number of attempts and waiting time are configured via [[mw:Manual:$wgPasswordAttemptThrottle|$wgPasswordAttemptThrottle]].\nThis message is used in html.\n\nSee also:\n* {{msg-mw|Changepassword-throttled}}",
        "resettokens": "{{doc-special|ResetTokens}}\nIn this case \"token\" may be translated as \"key\", or similar.\n{{Identical|Reset token}}",
        "resettokens-summary": "{{ignored}}",
        "showpreview": "The text of the button to preview the page you are editing. See also {{msg-mw|showdiff}} and {{msg-mw|savearticle}} for the other buttons.\n\nSee also:\n* {{msg-mw|Showpreview}}\n* {{msg-mw|Accesskey-preview}}\n* {{msg-mw|Tooltip-preview}}\n{{Identical|Show preview}}",
        "showdiff": "Button below the edit page. See also {{msg-mw|Showpreview}} and {{msg-mw|Savearticle}} for the other buttons.\n\nSee also:\n* {{msg-mw|Showdiff}}\n* {{msg-mw|Accesskey-diff}}\n* {{msg-mw|Tooltip-diff}}\n{{Identical|Show change}}",
        "blankarticle": "Notice displayed once after the user tries to save an empty page.",
-       "anoneditwarning": "Shown when editing a page anonymously.\n\nParameters:\n* $1 – A link to log in, <nowiki>{{fullurl:Special:UserLogin|returnto={{FULLPAGENAMEE}}}}</nowiki>\n* $2 – A link to sign up, <nowiki>{{fullurl:Special:UserLogin/signup|returnto={{FULLPAGENAMEE}}}}</nowiki>\n\nSee also:\n* {{msg-mw|Sf autoedit anoneditwarning}}\n* {{msg-mw|Wikibase-anonymouseditwarning-property}}\n* {{msg-mw|Wikibase-anonymouseditwarning-item}}\n* {{msg-mw|Anonpreviewwarning}}",
+       "anoneditwarning": "Shown when editing a page anonymously.\n\nParameters:\n* $1 – A link to log in, <nowiki>{{fullurl:Special:UserLogin|returnto={{FULLPAGENAMEE}}}}</nowiki>\n* $2 – A link to sign up, <nowiki>{{fullurl:Special:UserLogin/signup|returnto={{FULLPAGENAMEE}}}}</nowiki>\n\nSee also:\n* {{msg-mw|mobile-frontend-editor-anoneditwarning}}",
        "anonpreviewwarning": "See also:\n* {{msg-mw|Anoneditwarning}}",
        "missingsummary": "The text \"edit summary\" is in {{msg-mw|Summary}}.\n\nSee also:\n* {{msg-mw|Missingcommentheader}}\n* {{msg-mw|Savearticle}}",
        "missingcommenttext": "This message is shown, when the textbox by a new-section is empty.",
        "searchall": "{{Identical|All}}",
        "showingresults": "This message is used on some special pages such as [[Special:WantedCategories]]. Parameters:\n* $1 - the total number of results in the batch shown\n* $2 - the number of the first item listed\nSee also:\n* {{msg-mw|Showingresultsnum}}",
        "showingresultsinrange": "Used in pagination of [[Special:MostLinkedCategories]]. Parameters:\n* $1 - the total number of results in the batch shown\n* $2 - the number of the first item listed\n* $3 - the number of last item in the batch shown\n\nSee also {{msg-mw|Showingresults}}",
-       "showingresultsheader": "Used in search results of [[Special:Search]]. Parameters:\n* $1 - minimum offset\n* $2 - maximum offset\n* $3 - total number of results\n* $4 - the search term\n* $5 - number of results",
+       "search-showingresults": "Used in search results of [[Special:Search]]. Parameters:\n* $1 - minimum offset\n* $2 - maximum offset\n* $3 - total number of results\n* $4 - number of results",
        "search-nonefound": "Message shown when a search returned no results (when using the default MediaWiki search engine).",
        "powersearch-legend": "Advanced search\n\n{{Identical|Advanced search}}",
        "powersearch-ns": "Used in the extended search form at [[Special:Search]]",
        "prefs-tokenwatchlist": "Section heading.\nUsed in [[Special:Preferences]], tab \"Watchlist\".\n{{Identical|Token}}",
        "prefs-diffs": "Used in [[Special:Preferences]], tab \"Misc\".",
        "prefs-help-prefershttps": "Used as help text for the checkbox in [[Special:Preferences]].\n\nThe checkbox has the label {{msg-mw|Tog-prefershttps}}.\n\nSee example: [[mw:Special:Preferences]].",
+       "prefswarning-warning": "Warning shown (except in Firefox) when attempting to leave [[Special:Preferences]] with unsaved changes.\n\nParameters:\n* $1 - Text of {{msg-mw|saveprefs}}, as <nowiki>{{int:saveprefs}}</nowiki> cannot be used directly.",
        "prefs-tabs-navigation-hint": "Hint message that explains the arrow key navigation for the tabs on [[Special:Preferences]] to screenreader users.",
        "email-address-validity-valid": "Used as hint for {{msg-mw|changeemail-newemail}} field in [[Special:ChangeEmail]], when the provided E-mail address is valid.",
        "email-address-validity-invalid": "Used as warning for {{msg-mw|changeemail-newemail}} field in [[Special:ChangeEmail]], when the provided E-mail address is invalid.",
        "protect-cantedit": "Used as error message when changing the protection levels of the page.",
        "protect-othertime": "Used on the page protection form as label for the following input field (text)\n{{Identical|Other time}}",
        "protect-othertime-op": "Used on the page protection form in the drop down menu\n{{Identical|Other time}}",
-       "protect-existing-expiry": "Shows the existing expiry time in the drop down menu of the protection form ([{{canonicalurl:User:Raymond/test|action=unprotect}} example])\n\nParameters:\n* $1 - (Unused) date and time of the existing expiry time (kept for backward compatibility purposes)\n* $2 - date of the existing expiry time\n* $3 - time of the existing expiry time",
+       "protect-existing-expiry": "Shows the existing expiry time in the drop down menu of the protection form ([{{canonicalurl:User:Raymond/test|action=unprotect}} example])\n\nParameters:\n* $1 - (Unused) date and time of the existing expiry time (kept for backward compatibility purposes)\n* $2 - date of the existing expiry time\n* $3 - time of the existing expiry time\n\nSee also:\n* {{msg-mw|protect-existing-expiry-infinity}}",
+       "protect-existing-expiry-infinity": "Shows the existing expiry time in the drop down menu of the protection form, in the special case that it is infinity\n\nSee also:\n* {{msg-mw|protect-existing-expiry}}",
        "protect-otherreason": "Shown on the page protection form as label for the following input field (text)\n{{Identical|Other/additional reason}}",
        "protect-otherreason-op": "Shown on the page protection form in the drop down menu\n{{Identical|Other reason}}",
        "protect-dropdown": "Shown on the page protection form as drop down menu for protection reasons.\n\n* <code><nowiki>* Groupname</nowiki></code> - defines a new group\n* <code><nowiki>** Reason</nowiki></code> - defines a reason in this group",
        "unblockip": "Used as legend for the form in [[Special:Unblock]].",
        "unblockiptext": "Used in the {{msg-mw|Unblockip}} form on [[Special:Unblock]].",
        "ipusubmit": "Used as button text on [{{canonicalurl:Special:BlockList|action=unblock}} Special:BlockList?action=unblock]. To see the message:\n* Go to [[Special:BlockList]]\n* Click \"unblock\" for any block (but you can only see \"unblock\" if you have administrator rights)\n* It is now the button below the form",
-       "unblocked": "{{doc-important|Do not translate the namespace \"User:\".}}\nParameters:\n* $1 - the IP address or username that was unblocked\nSee also:\n* {{msg-mw|Unblocked-range}}\n* {{msg-mw|Unblocked-id}}",
-       "unblocked-range": "Shown when successfully lifting a rangeblock, so do not link to contributions. Parameters:\n* $1 - the range that was unblocked\nSee also:\n* {{msg-mw|Unblocked}}\n* {{msg-mw|Unblocked-id}}",
+       "unblocked": "{{doc-important|Do not translate the namespace \"User:\".}}\nParameters:\n* $1 - the username that was unblocked\nSee also:\n* {{msg-mw|Unblocked-range}}\n* {{msg-mw|Unblocked-id}}\n*{{msg-mw|Unblocked-ip}}",
+       "unblocked-range": "Shown when successfully lifting a rangeblock, so do not link to contributions. Parameters:\n* $1 - the range that was unblocked\nSee also:\n* {{msg-mw|Unblocked}}\n* {{msg-mw|Unblocked-id}}\n*{{msg-mw|Unblocked-ip}}",
        "unblocked-id": "Used in [[Special:Unblock]]. Parameters:\n* $1 - autoblock ID\nSee also:\n* {{msg-mw|Unblocked}}\n* {{msg-mw|Unblocked-range}}",
+       "unblocked-ip": "{{doc-important|Do not translate the title \"Special:Contributions\".}}\nParameters:\n* $1 - the IP address that was unblocked\nSee also:\n* {{msg-mw|Unblocked-range}}\n* {{msg-mw|Unblocked-id}}\n*{{msg-mw|Unblocked}}",
        "blocklist": "{{doc-special|BlockList}}",
        "ipblocklist": "Title of [[Special:Ipblocklist]].",
        "ipblocklist-legend": "Used as legend of the form in [[Special:BlockList]].\n\nSee also:\n* {{msg-mw|Ipblocklist-legend}}\n* {{msg-mw|Ipblocklist-submit}}",
        "default-skin-not-found": "Message shown when the default skin for this MediaWiki installation can not be found.\n\nParameters:\n* $1: skin identifier for the default skin\n* $2: list of installed skins, composed using {{msg-mw|default-skin-not-found-row-enabled}} and {{msg-mw|default-skin-not-found-row-disabled}}\n* $3: code snippet to use to enable installed skins",
        "default-skin-not-found-no-skins": "Message shown when the default skin for this MediaWiki installation can not be found and the installation has no skins at all.\n\nParameters:\n* $1: name of the default skin",
        "default-skin-not-found-row-enabled": "One row of the list of installed skins shown as a part of the following message (for an enabled skin):\n* {{msg-mw|default-skin-not-found}}\n----\nParameters:\n* $1 - skin identifier\n* $2 - human-readable skin name\nSee also:\n* {{msg-mw|Default-skin-not-found-row-disabled}}",
-       "default-skin-not-found-row-disabled": "One row of the list of installed skins shown as a part of the following message (for a disabled skin):\n* {{msg-mw|default-skin-not-found}}\n----\nParameters:\n* $1 - skin identifier\n* $2 - human-readable skin name\nSee also:\n* {{msg-mw|Default-skin-not-found-row-enabled}}"
+       "default-skin-not-found-row-disabled": "One row of the list of installed skins shown as a part of the following message (for a disabled skin):\n* {{msg-mw|default-skin-not-found}}\n----\nParameters:\n* $1 - skin identifier\n* $2 - human-readable skin name\nSee also:\n* {{msg-mw|Default-skin-not-found-row-enabled}}",
+       "mediastatistics": "{{doc-special|MediaStatistics}}",
+       "mediastatistics-summary": "Used to explain that this page only does statistics over current versions of files. \"Old\" versions of files and deleted files are not counted.",
+       "mediastatistics-nfiles": "{{optional}}\nEntry in table on [[Special:MediaStatistics]] that gives total number of files. $1 - number of files. $2 - percentage of total files that is this type (percent will be formatted to have about 3 interesting digits. e.g. 0.121 or 10.2)",
+       "mediastatistics-nbytes": "Combined space of this type of file. Bytes and \"human units\" are shown so that users can better get a sense of magnitude when making comparisons.\n*$1 - total space in bytes.\n*$2 - total space in \"human units\" (i.e. KB, MB, GB, etc)\n*$3 - What percentage of the space all uploads take up does this file take up.",
+       "mediastatistics-table-mimetype": "Header for table on Special:MediaStatistics. Column that lists MIME types (The values in this column will look like 'image/jpeg', and be linked to Special:MIMESearch).",
+       "mediastatistics-table-extensions": "Header for column in tables on [[Special:MediaStatistics]] that lists possible extensions for a given file type. (The values in this column will be a comma separated list of file extensions, such as '.webm' or '.png, .apng').",
+       "mediastatistics-table-count": "Column header on Special:MediaStatistics for the number of files column. The headers in this column use {{msg-mw|mediastatistics-nfiles}}.",
+       "mediastatistics-table-totalbytes": "Column header on Special:MediaStatistics for the number of bytes that this file type takes up. Values for this column use {{msg-mw|mediastatistics-nbytes}}",
+       "mediastatistics-header-unknown": "Header on Special:MediaStatistics for file types that are in the unknown category\n{{Identical|Unknown}}",
+       "mediastatistics-header-bitmap": "Header on [[Special:MediaStatistics]] for file types that are in the bitmap category. This includes raster graphics like PNG, JPEG, XCF, GIF etc. Vector graphics like SVG are considered \"drawings\" ({{msg-mw|mediastatistics-header-drawing}})",
+       "mediastatistics-header-drawing": "Header on [[Special:MediaStatistics]] for file types that are in the drawing category. This includes vector images like SVGs. Some chemical markup formats may also be included here.",
+       "mediastatistics-header-audio": "Header on [[Special:MediaStatistics]] for file types that are in the audio category\n{{Identical|Audio}}",
+       "mediastatistics-header-video": "Header on [[Special:MediaStatistics]] for file types that are in the video category\n{{Identical|Video}}",
+       "mediastatistics-header-multimedia": "Header on [[Special:MediaStatistics]] for file types that are in the multimedia category. This does not include plain audio or video files, but more complex multimedia such as flash or vrml. This especially includes scripted multimedia. Ogg files in which MediaWiki cannot determine if it is an audio or video file (or something else) are included here.",
+       "mediastatistics-header-office": "Header on [[Special:MediaStatistics]] for file types that are in the Office category. This includes PDFs, OpenDocument files, Microsoft Word files, etc.",
+       "mediastatistics-header-text": "Header on [[Special:MediaStatistics]] for file types that are in the text category. This includes simple text formats, including plain text formats, json, csv, and xml. Source code of compiled programming languages may be included here in the future, but isn't currently.",
+       "mediastatistics-header-executable": "Header on [[Special:MediaStatistics]] for file types that are in the executable category. This includes things like source files for interpreted programming language (Shell scripts, javascript, etc).",
+       "mediastatistics-header-archive": "Header on [[Special:MediaStatistics]] for file types that are in the archive category. Includes things like tar, zip, gzip etc."
 }
index 6fedb55..ac04f9b 100644 (file)
        "passwordreset-emailsent-capture": "Un mesaj de resetare a parolei a fost trimis, fiind afișat mai jos.",
        "passwordreset-emailerror-capture": "Un mesaj de resetare a parolei a fost generat (fiind afișat mai jos), dar trimiterea sa către {{GENDER:$2|utilizator}} a eșuat: $1",
        "changeemail": "Modificare adresă de e-mail",
-       "changeemail-header": "Modificare adresă de e-mail asociată contului",
        "changeemail-text": "Completați acest formular pentru a vă modifica adresa de e-mail. Va trebui să introduceți și parola pentru a confirma această modificare.",
        "changeemail-no-info": "Trebuie să fiți autentificat pentru a accesa această pagină direct.",
        "changeemail-oldemail": "Adresa de e-mail actuală:",
        "changeemail-none": "(niciuna)",
        "changeemail-password": "Parola dumneavoastră la {{SITENAME}}:",
        "changeemail-submit": "Modifică adresa de e-mail",
-       "changeemail-cancel": "Revocare",
        "changeemail-throttled": "Ați avut prea multe încercări de a vă autentifica.\nVă rugăm să așteptați $1 până să reîncercați.",
        "resettokens": "Resetare jetoane",
        "resettokens-text": "Puteți reseta, aici, jetoanele care permit accesul la anumite date asociate contului dumneavoastră.\n\nAr trebui să faceți acest lucru numai dacă le-ați partajat accidental cu altcineva ori contul dumneavoastră a fost compromis.",
        "searchall": "toate",
        "showingresults": "Mai jos {{PLURAL:$1|apare '''1''' rezultat|apar '''$1''' rezultate|apar '''$1''' de rezultate}} începând cu nr. <b>$2</b>.",
        "showingresultsinrange": "Mai jos se afișează un număr de până la {{PLURAL:$1|<strong>1</strong> rezultat|<strong>$1</strong> rezultate|<strong>$1</strong> de rezultate}} din intervalul #<strong>$2</strong> la #<strong>$3</strong>.",
-       "showingresultsheader": "{{PLURAL:$5|Rezultatul '''$1''' din '''$3'''|Rezultatele '''$1 - $2''' din '''$3'''}} pentru '''$4'''",
+       "search-showingresults": "{{PLURAL:$4|Rezultatul <strong>$1</strong> din <strong>$3</strong>|Rezultatele <strong>$1 - $2</strong> din <strong>$3</strong>}}",
        "search-nonefound": "Nu sunt rezultate conforme interogării.",
        "powersearch-legend": "Căutare avansată",
        "powersearch-ns": "Căutare în spațiile de nume:",
        "prefs-tokenwatchlist": "Jeton",
        "prefs-diffs": "Diferențe",
        "prefs-help-prefershttps": "Această preferință va avea efect la următoarea autentificare.",
+       "prefswarning-warning": "Ați efectuat modificări asupra preferințelor dumneavoastră, care nu au fost încă salvate.\nDacă părăsiți această pagină fără a apăsa butonul „$1”, preferințele dumnevoastră nu se vor actualiza.",
        "prefs-tabs-navigation-hint": "Sfat: Puteți folosi tastele săgeată stânga și dreapta pentru a naviga între filele din cadrul listei de file.",
        "email-address-validity-valid": "Adresa de e-mail pare validă",
        "email-address-validity-invalid": "Introduceți o adresă de e-mail validă",
        "protect-othertime": "Alt termen:",
        "protect-othertime-op": "alt termen",
        "protect-existing-expiry": "Data expirării: $3, $2",
+       "protect-existing-expiry-infinity": "Data expirării: nelimitat",
        "protect-otherreason": "Motiv diferit/adițional:",
        "protect-otherreason-op": "Alt motiv",
        "protect-dropdown": "*Motive uzuale de protejare\n** Vandalism excesiv\n** SPAM excesiv\n** Modificări neproductive\n** Pagină cu trafic mare",
        "unblocked": "[[User:$1|$1]] a fost deblocat",
        "unblocked-range": "$1 a fost deblocat",
        "unblocked-id": "Blocarea $1 a fost eliminată",
+       "unblocked-ip": "[[Special:Contributions/$1|$1]] a fost deblocat.",
        "blocklist": "Utilizatori blocați",
        "ipblocklist": "Utilizatori blocați",
        "ipblocklist-legend": "Găsire utilizator blocat",
        "logentry-upload-overwrite": "$1 {{GENDER:$2|a încărcat}} o nouă versiune pentru $3",
        "logentry-upload-revert": "$1 {{GENDER:$2|a încărcat}} $3",
        "rightsnone": "(niciunul)",
+       "revdelete-summary": "descrierea modificărilor",
        "feedback-bugornote": "Dacă sunteți pregătit să descrieți o problemă tehnică în detaliu vă rugăm să [$1 raportați un bug].\nÎn caz contrar, puteți utiliza formularul de mai jos. Comentariul dumneavoastră va fi adăugat pe pagina „[$3 $2]”, împreună cu numele de utilizator și numele navigatorului pe care îl folosiți.",
        "feedback-subject": "Subiect:",
        "feedback-message": "Mesaj:",
        "log-description-pagelang": "Acesta este un jurnal cu modificări ale limbii paginilor.",
        "logentry-pagelang-pagelang": "$1 {{GENDER:$2|a modificat}} limba paginii pentru $3 din $4 în $5.",
        "default-skin-not-found-row-enabled": "* <code>$1</code> / $2 (activat)",
-       "default-skin-not-found-row-disabled": "* <code>$1</code> / $2 ('''dezactivat''')"
+       "default-skin-not-found-row-disabled": "* <code>$1</code> / $2 ('''dezactivat''')",
+       "mediastatistics": "Statistici multimedia",
+       "mediastatistics-summary": "Statistici despre tipurile fișierelor încărcate. Sunt incluse doar cele mai recente versiuni ale fișierelor. Versiunile mai vechi sau șterse ale fișierelor sunt excluse.",
+       "mediastatistics-nbytes": "{{PLURAL:$1|$1 octet|$1 octeți|$1 de octeți}} ($2; $3%)",
+       "mediastatistics-table-mimetype": "Tip MIME",
+       "mediastatistics-table-extensions": "Extensii posibile",
+       "mediastatistics-table-count": "Număr de fișiere",
+       "mediastatistics-table-totalbytes": "Dimensiune combinată",
+       "mediastatistics-header-unknown": "Necunoscut",
+       "mediastatistics-header-bitmap": "Imagini bitmap",
+       "mediastatistics-header-drawing": "Desene (imagini vectoriale)",
+       "mediastatistics-header-audio": "Audio",
+       "mediastatistics-header-video": "Videoclipuri",
+       "mediastatistics-header-multimedia": "Multimedia complexe",
+       "mediastatistics-header-office": "Documente",
+       "mediastatistics-header-text": "Text",
+       "mediastatistics-header-executable": "Executabile",
+       "mediastatistics-header-archive": "Formate comprimate"
 }
index 6899d0b..493c273 100644 (file)
        "searchrelated": "colleghete",
        "searchall": "tutte",
        "showingresults": "Stoche a fazze vedè aqquà sotte {{PLURAL:$1|'''1''' resultete|'''$1''' resultete}} ca accumenzene cu #'''$2'''.",
-       "showingresultsheader": "{{PLURAL:$5|Resultate '''$1''' de '''$3'''|Resultate '''$1 - $2''' de '''$3'''}} pe '''$4'''",
        "search-nonefound": "Non ge stonne resultete ca soddisfecene l'inderrogazione.",
        "powersearch-legend": "Ricerche avanzete",
        "powersearch-ns": "Cirche jndr'à le namespace:",
index bf16ca1..be1305f 100644 (file)
        "passwordreset-emailsent-capture": "Отправлено электронное письмо с информацией о сбросе пароля, текст которого можно увидеть ниже.",
        "passwordreset-emailerror-capture": "Было создано электронное письмо с информацией о сбросе пароля, текст которого можно увидеть ниже, однако его не удалось отправить {{GENDER:$2|участнику|участнице}} по следующей причине: $1",
        "changeemail": "Изменить адрес электронной почты",
-       "changeemail-header": "Изменение адреса электронной почты",
        "changeemail-text": "Заполните эту форму, чтобы изменить свой адрес электронной почты. Вам нужно будет ввести пароль, чтобы подтвердить изменение.",
        "changeemail-no-info": "Чтобы обращаться непосредственно к этой странице, вам следует представиться системе.",
        "changeemail-oldemail": "Текущий адрес электронной почты:",
        "changeemail-none": "(нет)",
        "changeemail-password": "Ваш пароль для проекта «{{SITENAME}}»:",
        "changeemail-submit": "Изменить адрес",
-       "changeemail-cancel": "Отмена",
        "changeemail-throttled": "Вы сделали слишком много попыток представиться системе.\nПожалуйста, подождите $1 перед тем, как попробовать снова.",
        "resettokens": "Сбросить токены",
        "resettokens-text": "Вы можете сбросить токены, позволяющие получить доступ к некоторым личным данным, связанным с вашей учётной записью на этом сайте.\n\nВам необходимо сделать это, если вы случайно поделились ими с кем-то, или если ваша учётная запись была взломана.",
        "searchall": "все",
        "showingresults": "Ниже {{PLURAL:$1|1=показан результат|показаны  результаты}} с № '''$2''' и вплоть до № '''$1'''.",
        "showingresultsinrange": "Ниже показано до {{PLURAL:$1|<strong>1</strong> результата|<strong>$1</strong> результатов|<strong>$1</strong> результата}} в диапазоне от <strong>$2</strong> до <strong>$3</strong>.",
-       "showingresultsheader": "{{PLURAL:$5|1=Результат '''$1''' из '''$3'''|Результаты '''$1—$2''' из '''$3'''}} для «'''$4'''»",
+       "search-showingresults": "{{PLURAL:$4|Результат <strong>$1</strong> из <strong>$3</strong>|Результаты <strong>$1 — $2</strong> из <strong>$3</strong>}}",
        "search-nonefound": "Соответствий запросу не найдено.",
        "powersearch-legend": "Расширенный поиск",
        "powersearch-ns": "Поиск в пространствах имён:",
        "prefs-tokenwatchlist": "Токен",
        "prefs-diffs": "Разница версий",
        "prefs-help-prefershttps": "Эта настройка будет применена после следующего представления системе.",
+       "prefswarning-warning": "Вы внесли в свои настройки изменения, которые ещё не были сохранены.\nЕсли вы покинете эту страницу, не нажав «$1», настройки не будут обновлены.",
        "prefs-tabs-navigation-hint": "Совет: Вы можете использовать клавиши стрелок влево и вправо для перехода между вкладками в списке вкладок.",
        "email-address-validity-valid": "Выглядит корректно",
        "email-address-validity-invalid": "Введите корректный адрес электронной почты!",
        "right-deletedtext": "просмотр удалённого текста и изменений между удалёнными версиями страниц",
        "right-browsearchive": "поиск удалённых страниц",
        "right-undelete": "восстановление страниц",
-       "right-suppressrevision": "Ð\9fÑ\80оÑ\81моÑ\82Ñ\80, Ñ\81крытие и восстановление скрытых версий страниц",
+       "right-suppressrevision": "пÑ\80оÑ\81моÑ\82Ñ\80, Ñ\81окрытие и восстановление скрытых версий страниц",
        "right-viewsuppressed": "Просмотр версий, скрытых от всех участников",
        "right-suppressionlog": "просмотр частных журналов",
        "right-block": "установка ограничений на редактирование для других участников",
        "protect-othertime": "Другое время:",
        "protect-othertime-op": "другое время",
        "protect-existing-expiry": "Текущее время окончания: $2, $3",
+       "protect-existing-expiry-infinity": "Текущее время окончания: бесконечно",
        "protect-otherreason": "Другая причина/дополнение:",
        "protect-otherreason-op": "Другая причина",
        "protect-dropdown": "* Типовые причины защиты\n** частый вандализм\n** чрезмерный спам\n** непродуктивная война правок\n** популярная страница",
        "unblocked": "[[User:$1|$1]] {{GENDER:$1|разблокирован|разблокирована}}",
        "unblocked-range": "$1 был разблокирован",
        "unblocked-id": "Блокировка $1 была снята",
+       "unblocked-ip": "[[Special:Contributions/$1|$1]] был разблокирован.",
        "blocklist": "Заблокированные участники",
        "ipblocklist": "Заблокированные участники",
        "ipblocklist-legend": "Поиск заблокированного участника",
        "logentry-upload-overwrite": "$1 загрузил{{GENDER:$2||а}} новую версию $3",
        "logentry-upload-revert": "$1 загрузил{{GENDER:$2||а}} $3",
        "rightsnone": "(нет)",
+       "revdelete-summary": "описание изменений",
        "feedback-bugornote": "Если вы готовы подробно описать техническую проблему, пожалуйста, [$1 сообщите об ошибке].\nВ противном случае вы можете использовать данную простую форму. Ваш комментарий будет добавлен на страницу «[$3 $2]» вместе с вашим именем участника и используемым браузером.",
        "feedback-subject": "Тема:",
        "feedback-message": "Сообщение:",
        "log-name-pagelang": "Журнал изменения языка",
        "log-description-pagelang": "Это журнал изменений в языках страницы.",
        "logentry-pagelang-pagelang": "$1 изменил{{GENDER:$2||а}} язык страницы для $3 с $4 на $5.",
-       "default-skin-not-found": "Упс! Тема оформления по умолчанию для вашей вики (<code>$wgDefaultSkin</code>), <code>$1</code> недоступна.\n\nВаша установка, похоже, содержит следующие темы оформления. См. [https://www.mediawiki.org/wiki/Manual:Skin_configuration Manual:Skin configuration] для получения информации о том, как включить темы оформления и выбрать тему по умолчанию.\n\n\n$ 2\n\n\n; Если вы только что установили MediaWiki:\n: Вы, видимо, сделали это с Git или непосредственно из исходного кода с использованием другого способа. Тогда такое возможно. Попробуйте установить некоторые темы из [https://www.mediawiki.org/wiki/Category:All_skins каталога тем оформления сайта mediawiki.org]:\n:* Скачав [https://www.mediawiki.org/wiki/Download архив установочных файлов], который содержит несколько тем оформления и расширений. Вы можете скопировать папку <code>skins/</code> из него.\n:* Склонировав один из репозиториев <code>mediawiki/skins/*</code> через git в подпапку <code>skins/</code> папки, куда установлена MediaWiki.\n: Это не должно навредить вашему репозиторию, если вы MediaWiki-разработчик. См. [https://www.mediawiki.org/wiki/Manual:Skin_configuration Manual:Skin configuration] для получения информации о том, как включить темы оформления и выбрать тему по умолчанию.\n; Если вы только что обновили MediaWiki:\n: MediaWiki версии 1.24 и более новых больше не включает автоматически установленные темы (see [https://www.mediawiki.org/wiki/Manual:Skin_autodiscovery Manual: Skin autodiscovery]).\nВы можете вставить следующие строчки в <code>LocalSettings.php</code>, чтобы включить все установленные темы оформления: \n\n\n<pre>$3</pre>\n\n\n; Если вы только что изменили <code>LocalSettings.php</code>:\n: Перепроверьте названия тем на наличие опечаток.",
-       "default-skin-not-found-no-skins": "Упс! Тема оформления по умолчанию для вашей вики (<code>$wgDefaultSkin</code>), <code>$1</code> недоступна.\n\n\nУ вас нет установленных тем оформления.\n\n\n; Если вы только что установили или обновили MediaWiki:\n: Вы, видимо, сделали это с Git или непосредственно из исходного кода с использованием другого способа. Тогда такое возможно. MediaWiki версии 1.24 или более поздней не содержат темы оформления в основном репозитории. Попробуйте установить некоторые темы из [https://www.mediawiki.org/wiki/Category:All_skins каталога тем оформления сайта mediawiki.org]:\n:* Скачав [https://www.mediawiki.org/wiki/Download архив установочных файлов], который содержит несколько тем оформления и расширений. Вы можете скопировать папку <code>skins/</code> из него.\n:* Склонировав один из репозиториев <code>mediawiki/skins/*</code> через git в подпапку <code>skins/</code> папки, куда установлена MediaWiki.\n: Это не должно навредить вашему репозиторию, если вы MediaWiki-разработчик. См. [https://www.mediawiki.org/wiki/Manual:Skin_configuration Manual:Skin configuration] для получения информации о том, как включить темы оформления и выбрать тему по умолчанию.",
+       "default-skin-not-found": "Упс! Тема оформления по умолчанию для вашей вики <code>$wgDefaultSkin</code>, <code>$1</code> недоступна.\n\nВаша установка, похоже, содержит следующие темы оформления. См. [https://www.mediawiki.org/wiki/Manual:Skin_configuration Manual:Skin configuration] для получения информации о том, как включить темы оформления и выбрать тему по умолчанию.\n\n\n$ 2\n\n\n; Если вы только что установили MediaWiki:\n: Вы, видимо, сделали это с Git или непосредственно из исходного кода с использованием другого способа. Тогда такое возможно. Попробуйте установить некоторые темы из [https://www.mediawiki.org/wiki/Category:All_skins каталога тем оформления сайта mediawiki.org]:\n:* Скачав [https://www.mediawiki.org/wiki/Download архив установочных файлов], который содержит несколько тем оформления и расширений. Вы можете скопировать папку <code>skins/</code> из него.\n:* Склонировав один из репозиториев <code>mediawiki/skins/*</code> через git в подпапку <code  dir=\"ltr\">skins/</code> папки, куда установлена MediaWiki.\n: Это не должно навредить вашему репозиторию, если вы MediaWiki-разработчик. См. [https://www.mediawiki.org/wiki/Manual:Skin_configuration Manual:Skin configuration] для получения информации о том, как включить темы оформления и выбрать тему по умолчанию.\n; Если вы только что обновили MediaWiki:\n: MediaWiki версии 1.24 и более новых больше не включает автоматически установленные темы (see [https://www.mediawiki.org/wiki/Manual:Skin_autodiscovery Manual: Skin autodiscovery]).\nВы можете вставить следующие строчки в <code>LocalSettings.php</code>, чтобы включить все установленные темы оформления: \n\n\n<pre dir=\"ltr\">$3</pre>\n\n\n; Если вы только что изменили <code>LocalSettings.php</code>:\n: Перепроверьте названия тем на наличие опечаток.",
+       "default-skin-not-found-no-skins": "Упс! Тема оформления по умолчанию для вашей вики <code>$wgDefaultSkin</code>, <code>$1</code> недоступна.\n\n\nУ вас нет установленных тем оформления.\n\n\n; Если вы только что установили или обновили MediaWiki:\n: Вы, видимо, сделали это с Git или непосредственно из исходного кода с использованием другого способа. Тогда такое возможно. MediaWiki версии 1.24 или более поздней не содержат темы оформления в основном репозитории. Попробуйте установить некоторые темы из [https://www.mediawiki.org/wiki/Category:All_skins каталога тем оформления сайта mediawiki.org]:\n:* Скачав [https://www.mediawiki.org/wiki/Download архив установочных файлов], который содержит несколько тем оформления и расширений. Вы можете скопировать папку <code>skins/</code> из него.\n:* Склонировав один из репозиториев <code>mediawiki/skins/*</code> через git в подпапку <code dir=\"ltr\">skins/</code> папки, куда установлена MediaWiki.\n: Это не должно навредить вашему репозиторию, если вы MediaWiki-разработчик. См. [https://www.mediawiki.org/wiki/Manual:Skin_configuration Manual:Skin configuration] для получения информации о том, как включить темы оформления и выбрать тему по умолчанию.",
        "default-skin-not-found-row-enabled": "* <code>$1</code> / $2 (включено)",
        "default-skin-not-found-row-disabled": "* <code>$1</code> / $2 ('''отключено''')"
 }
index b1d88c0..81d974c 100644 (file)
@@ -36,7 +36,7 @@
        "tog-enotifrevealaddr": "Faghe ischire s'indiritzu de sa post.el. mea in sas notìficas de sa post.els",
        "tog-shownumberswatching": "Ammustra su nùmeru de is impitadores chi ant annotadu sa pàgina",
        "tog-oldsig": "Firma atuale:",
-       "tog-fancysig": "Trata sa firma comente unu testu wiki (sena ligàmenes automàticos)",
+       "tog-fancysig": "Trata sa firma comente unu testu wiki (sena ligòngios automàticos)",
        "tog-uselivepreview": "Imprea sa funtzione \"anteprima bia\" (isperimentale)",
        "tog-forceeditsummary": "Averte·mi si su campu ogetu est bòidu",
        "tog-watchlisthideown": "Cua sas mudas meas dae sa watclist",
@@ -49,7 +49,7 @@
        "tog-diffonly": "No ammustras su cuntènnidu de sa pàgina a pustis de sa bisura de is diferèntzias",
        "tog-showhiddencats": "Ammustra sas categorias cuadas",
        "tog-norollbackdiff": "Cua sa bisura de is diferèntzias a pustis de su rollback",
-       "tog-useeditwarning": "Amonestamì si lassu una pagina cun mudantzias chena de sarvai.",
+       "tog-useeditwarning": "Averte·mi si lassu una pàgina cun càmbios sena de sarbare",
        "tog-prefershttps": "Imprea semper una lìnia segura candu fatzo s'intrada.",
        "underline-always": "Semper",
        "underline-never": "Mai",
        "december-date": "Nadale $1",
        "pagecategories": "{{PLURAL:$1|Categoria|Categorias}}",
        "category_header": "Pàginas in sa categoria \"$1\"",
-       "subcategories": "Subcategorias",
+       "subcategories": "Sutacategorias",
        "category-media-header": "Mèdios in sa categoria \"$1\"",
        "category-empty": "''In custa categoria non ddu at peruna pàgina o documentu multimediale.''",
        "hidden-categories": "{{PLURAL:$1|Categoria cuada|Categorias cuadas}}",
        "hidden-category-category": "Categorias cuadas",
-       "category-subcat-count": "{{PLURAL:$2|Custa categoria cuntenet un'ùnica subcategoria ammustrada in suta.|Custa categoria cuntenet {{PLURAL:$1|sa subcategoria indicada|$1 subcategorias indicadas}} in suta, dae $2 totales.}}",
-       "category-subcat-count-limited": "Custa categoria tenet {{PLURAL:$1|una subcategoria, ammustrada|$1 subcategorias, ammustradas}} in suta.",
+       "category-subcat-count": "{{PLURAL:$2|Custa categoria cuntennet un'ùnica sutacategoria ammustrada in suta.|Custa categoria cuntenet {{PLURAL:$1|sa sutacategoria indicada|$1 sutacategorias indicadas}} in suta, dae $2 in totu.}}",
+       "category-subcat-count-limited": "Custa categoria tenet {{PLURAL:$1|una sutacategoria, ammustrada|$1 sutacategorias, ammustradas}} in suta.",
        "category-article-count": "{{PLURAL:$2|Custa categoria cuntenet feti sa pàgina chi sighit.|Custa categoria cuntenet {{PLURAL:$1|sa pàgina indicada|is $1 pàginas indicadas}} in suta, dae unu totale de $2.}}",
        "category-article-count-limited": "{{PLURAL:$1|Sa pàgina chi sighit est|Is $1 pàginas chi sighint sunt}} in custa categoria.",
        "category-file-count": "{{PLURAL:$2|Custa categoria cuntenet feti su documentu chi sighit.|{{PLURAL:$1|Su documentu chi sighit est|Is $1 documentos chi sighint sunt}} in custa categoria, dae $2 totales.}}",
        "listingcontinuesabbrev": "sighit",
        "index-category": "Pàginas inditzizadas",
        "noindex-category": "Pàginas no inditzitzadas",
-       "broken-file-category": "Pàginas cun ligàmenes a sos documentos non funtzionantes",
+       "broken-file-category": "Pàginas chi ligant a documentos chi no esistint",
        "about": "A propòsitu de",
        "article": "Artìculu",
        "newwindow": "(aberret in una bentana noa)",
        "portal": "Portale comunidade",
        "portal-url": "Project:Portale comunidade",
        "privacy": "Polìtica pro is datos privados",
-       "privacypage": "Project:Polìtica pro sos datos privados",
+       "privacypage": "Project:Polìtica pro is datos privados",
        "badaccess": "Permissu non bastante",
        "badaccess-group0": "Non ses autorizadu a fàghere s'atzione chi boles",
        "badaccess-groups": "S'atzione chi as rechestu est limitada a impitadores in {{PLURAL:$2|su grupu|unu de is grupos}}: $1.",
        "viewdeleted": "Vista $1?",
        "restorelink": "{{PLURAL:$1|unu càmbiu burradu|$1 càmbios burrados}}",
        "feedlinks": "Alimentatzione:",
+       "feed-invalid": "Tipu de canale de sutiscritzione invàlida.",
+       "feed-unavailable": "Non sunt disponìbiles feeds",
        "site-rss-feed": "Feed Atom de $1",
        "site-atom-feed": "Feed Atom de $1",
        "page-rss-feed": "Feed RSS pro \"$1\"",
        "nstab-help": "Agiudu",
        "nstab-category": "Categoria",
        "nosuchaction": "No esistit custa atzione",
-       "nosuchactiontext": "S'atzione ispetzificada in sa URL no est vàlida.\nEst possìbile chi sa URL siat istada carcada male, o si siat sighidu unu ligàmene non vàlidu.\nCustu diat pòdere èssere unu \"bug\" de {{SITENAME}}.",
+       "nosuchactiontext": "S'atzione ispetzificada in sa URL no est vàlida.\nEst possìbile chi sa URL siat istada carcada male, o si siat sighidu unu ligòngiu non vàlidu.\nCustu diat pòdere èssere unu \"bug\" de {{SITENAME}}.",
        "nosuchspecialpage": "Custa pàgina ispetziale no esistit",
        "nospecialpagetext": "<strong>As pedidu una pàgina ispetziale non vàlida.</strong>\n\nUna lista de pàginas ispetziales vàlidas dd'agatas in [[Special:SpecialPages|{{int:specialpages}}]].",
        "error": "Faddina",
        "databaseerror": "Faddina de su database",
+       "databaseerror-text": "B'est istadu un'errore cun una rechesta a sa base de sos datos.\nCustu podet indicare unu problema in su programma.",
+       "databaseerror-textcl": "B'est istadu un'errore cun una rechesta a sa base de sos datos.",
        "databaseerror-query": "Rechesta: $1",
        "databaseerror-function": "Funtzione: $1",
        "databaseerror-error": "Faddina: $1",
+       "laggedslavemode": "<strong>Atentzione:</strong> Sa pàgina podet non cuntènnere sos agiornamentos prus novos.",
        "readonly": "Database bloccadu",
        "enterlockreason": "Inserta su motivu de su blocu, ispetzifichende su momentu probàbile chi su blocu at a acabbare",
        "readonlytext": "In custu momentu su database est bloccadu dae aciunturas e àteras modificas, probabilmente pro ordinaria manutentzione a su database, a pustis de custas at a èssere normale torra.\n\nS'aministradore chi dd'at bloccadu at donadu custa ispiegatzione: $1",
-       "missing-article": "Su database no at agatadu su testu de una pàgina ki diat àer agatadu a suta de su nùmene \"$1\" $2.\n\nCustu a su sòlitu si verìficat cando bi est unu ligàmine in sa stòria o in unu cunfrontu intre revisiones de una pàgina ki est stada fuliada.\n\nSi no est custu su casu, s'est agatada una faddina de su software.\nPro praxere signa s'acuntèssidu a unu [[Special:ListUsers/sysop|amministradore]] spetzifichende su URL de sa faddina.",
+       "missing-article": "Su database no at agatadu su testu de una pàgina chi diat àere agatadu a suta de su nùmene \"$1\" $2.\n\nCustu a su sòlitu si verìficat cando bi est unu ligòngiu in s'istòria o in unu cunfrontu intre revisiones de una pàgina chi est istada fuliada.\n\nSi no est custu su casu, s'est agatada una faddina de su software.\nPro praghere signa s'acontèssidu a unu [[Special:ListUsers/sysop|amministradore]] ispetzifichende su URL de sa faddina.",
        "missingarticle-rev": "(revisione nùmeru: $1)",
        "missingarticle-diff": "(Dif: $1, $2)",
+       "readonly_lag": "Sa base de sos datos (database) est istada arreada automaticamente in su mentres chi sos servidores iscraos si sincronizzana cun su printzipale.",
        "internalerror": "Faddina interna",
        "internalerror_info": "Faddina interna: $1",
        "filecopyerror": "No est stadu possìbile copiare su file \"$1\" comente \"$2\".",
        "badarticleerror": "Operatzione non cunsentida pro custa pàgina.",
        "cannotdelete": "No est stadu possìbile burrare sa pàgina o su file \"$1\".\nPodet èsser stadu burradu dae calicunu àteru.",
        "cannotdelete-title": "Impossìbile burrare sa pàgina \"$1\"",
+       "delete-hook-aborted": "Sa burradura est istada annuddada dae su hook de s'estensione.\nNo est istadu datu acrarimentu.",
        "no-null-revision": "Non si podet creare una versione lulla pro sa pàgina \"$1\"",
        "badtitle": "Tìtulu malu",
        "badtitletext": "Su tìtulu de sa pàgina chi as pregontadu est bùidu, isballiadu, o iscritu in is cullegamentus inter-wiki a manera non currègia.\nPodet cuntènnere uno o unos cantos caràteres no ammìtidos pro is tìtulos.",
+       "perfcached": "Is datos chi sighint sunt in sa memòria \"cache\" e podent èessere no agiornados. Unu màssimu de {{PLURAL:$1|unu resurtu est disponìbile|$1 resurtos sunt disponìbiles}} in sa memòria",
+       "perfcachedts": "Is datos chi sighint sunt in sa memòria \"cache\", s'ùrtimu agiornamentu est de su $2 a is $3. Unu màssimu de {{PLURAL:$4|unu resurtu est disponìbile|$4 resurtos sunt disponìbiles}} in sa memòria",
        "viewsource": "Càstia mitza",
        "viewsource-title": "Càstia sa mitza de $1",
        "actionthrottled": "Atzione rimandada",
        "passwordreset-domain": "Domìniu:",
        "passwordreset-email": "Indiritzu email:",
        "passwordreset-emailtitle": "Particulares de s'impitadore in {{SITENAME}}",
+       "passwordreset-emailelement": "Nùmene impitadore: $1\nPassword temporànea: $2",
        "changeemail": "Càmbia indiritzu email",
-       "changeemail-header": "Càmbia s'indirìtzu email de su contu",
        "changeemail-oldemail": "Indiritzu email atuale:",
        "changeemail-newemail": "Indiritzu email nou:",
        "changeemail-none": "(nudda)",
        "changeemail-password": "Sa password tua pro {{SITENAME}}:",
        "changeemail-submit": "Càmbia email",
-       "changeemail-cancel": "Annudda",
        "resettokens": "Reseta tokens",
+       "resettokens-token-label": "$1 (valore atuale: $2)",
        "bold_sample": "Testu grassu",
        "bold_tip": "Testu grassu",
        "italic_sample": "Testu cursivu",
        "preview": "Antiprima",
        "showpreview": "Ammustra s'antiprima",
        "showdiff": "Ammustra is càmbios",
-       "anoneditwarning": "<strong>Dae cara:</strong> Non ses identificadu.\nS'indiritzu IP tuo at a èssere annòtidu si faghes unos cantos càmbios. Si <strong>idendificas</strong> tibe o <strong>[$2 creas unu contu]</strong>, is càmbios tuos ant a esser marcados cun su nùmene impitadore tuo, paris a àteros giuamentos.",
+       "anoneditwarning": "<strong>Atentzione:</strong> Non ses identificadu.\nS'indiritzu IP tuo at a èssere annòtidu si faghes unos cantos càmbios. Si <strong>idendificas</strong> tibe o <strong>[$2 creas unu contu]</strong>, is càmbios tuos ant a esser marcados cun su nùmene impitadore tuo, paris a àteros giuamentos.",
        "anonpreviewwarning": "''Non ses identificadu. Sarvende s'indiritzu IP tuo at a èssere registradu in s'istòria de sa pàgina.''",
        "missingcommenttext": "Inserta unu cummentu inoghe suta.",
        "summary-preview": "Antiprima ogetu:",
        "updated": "(Atualizadu)",
        "note": "'''Nota:'''",
        "previewnote": "<strong>Regorda·ti ca custa est feti una ANTIPRIMA.</strong>\nIs mudàntzias tuas non sunt galu sarbadas!",
-       "continue-editing": "Bae a s'àrea de acontzu",
+       "continue-editing": "Bae a s'àrea de modìfica",
        "previewconflict": "Custa antiprima rapresentat su testu in s'àrea acontzu testu de susu comente at a pàrrer si dda sarbas.",
        "editing": "Cambiende $1",
        "creating": "Creande $1",
        "editingsection": "Cambiende $1 (setzione)",
-       "editingcomment": "Acontzu de $1 (setzione noa)",
+       "editingcomment": "Modìfica de $1 (setzione noa)",
        "editconflict": "Cunflitu de editzione: $1",
-       "explainconflict": "Calicunu àteru at acontzadu custa pàgina in su tempus ki dda fias acontzende tue.\nS'àrea de testu de susu cuntènnet su testu de sa pàgina in sa forma atuale.\nIs mudàntzias tuas sunt ammustradas in s'àrea de testu de bàsciu.\nAs a dèper insertare is mudàntzias tuas in su testu atuale, e pro custu a ddas scrìer in s'àrea de susu.\n'''Solu''' su testu in s'àrea de susu at a èsser sarbadu si carcas su butone \"{{int:savearticle}}\".",
+       "explainconflict": "Calicunu àteru at cambiadu custa pàgina in su tempus chi dda fias cambiende tue.\nS'àrea de testu de susu cuntènnet su testu de sa pàgina in sa forma atuale.\nIs mudàntzias tuas sunt ammustradas in s'àrea de testu in suta.\nAs a dèper insertare is mudàntzias tuas in su testu atuale, e pro custu a ddas iscrìer in s'àrea de susu.\n<strong>Solu</strong> su testu in s'àrea de susu at a èsser sarbadu si carcas su butone \"{{int:savearticle}}\".",
        "yourtext": "Su testu tuo",
        "storedversion": "Revisione in archìviu",
        "editingold": "'''ATENTZIONE: Ses acontzende una revisione non-agiornada de sa pàgina.'''\nSi dda sarbas de aici, totu is acontzos fatos a pustis de custa revisione ant a bènner pèrdidos pro semper.",
        "yourdiff": "Diferèntzias",
-       "copyrightwarning": "Abbàida, pro praxere, ki totu is contributziones a {{SITENAME}} sunt cunsideradas lassadas a suta permissu de tipu $2 (càstia $1 pro nde schire de prus). Si non keris ki su scritu tuo potzat èsser acontzadu e re-distribuidu dae kie si siat sena piedade e sena àteros lìmites, non ddu imbies a {{SITENAME}}.<br />\nCun s'imbiu de custu scritu ses garantende, a responsabilidade tua, si su scritu ddu as cumpostu tue de persona e in originale, o puru si est stadu copiadu dae una fonte de domìniu pùblicu, o una fonte de gasi, o puru si as otentu permissu craru de impreare custu scritu e si ddu podes dimustrare. '''NO IMPREARE MATERIALE COBERTU DAE DERETU DE AUTORE SENA PERMISSU CRARU!'''",
+       "copyrightwarning": "Abbàida, pro praghere, chi totu is contributos a {{SITENAME}} sunt cunsideradas lassadas a suta permissu de tipu $2 (càstia $1 pro nde ischire de prus). Si non boles chi s'iscritu tuo potzat èssere cambiadu e re-distribuidu dae chie si siat sena piedade e sena àteros lìmites, non ddu imbies a {{SITENAME}}.\nCun s'imbiu de custu iscritu ses garantende, a responsabilidade tua, si su iscritu ddu as cumpostu tue de persone e in originale, o puru si est istadu copiadu dae una fonte de domìniu pùblicu, o una fonte de gasi, o puru si as otentu permissu craru de impreare custu iscritu e si ddu podes dimustrare. '''NO IMPREARE MATERIALE COBERTU DAE DERETU DE AUTORE SENA PERMISSU CRARU!'''",
        "templatesused": "{{PLURAL:$1|Template impreadu|Templates impreados}} in custa pàgina:",
        "templatesusedpreview": "{{PLURAL:$1|Template impreadu|Templates impreados}} in custa antiprima:",
        "templatesusedsection": "{{PLURAL:$1|Template impreadu|Templates impreados}} in custa setzione:",
        "edit-conflict": "Cunflitu de editzione.",
        "postedit-confirmation-created": "Sa pàgina est stada creada",
        "postedit-confirmation-restored": "Sa pàgina est stada restaurada",
-       "postedit-confirmation-saved": "S'acontzu tuo est stadu sarbadu",
+       "postedit-confirmation-saved": "Su càmbiu tuo est istadu sarbadu.",
+       "defaultmessagetext": "Testu de su messàgiu predeterminadu",
+       "invalid-content-data": "Datos de cuntènnidu invàlidos",
        "content-model-wikitext": "wikitestu",
        "content-model-text": "testu normale",
        "content-model-javascript": "JavaScript",
        "last": "pre",
        "page_first": "prima",
        "page_last": "ùrtima",
-       "histlegend": "Cunfrontu intre versiones: Marca sa casella de sa versione chi boles e carca \"Invio\" o su butone in bàsciu.<br />\nCosas de ammentare: <strong>({{int:cur}})</strong> = diferèntzias cun sa versione atuale,\n<strong>({{int:last}})</strong> = diferèntzias cun sa versione in segus, <strong>{{int:minoreditletter}}</strong> = càmbiu minore.",
+       "histlegend": "Cunfrontu intre versiones: Marca sa casella de sa versione chi boles e carca \"Invio\" o su butone in bàsciu.<br />\nCosas de ammentare: <strong>({{int:cur}})</strong> = diferèntzias cun sa versione atuale,\n<strong>({{int:last}})</strong> = diferèntzias cun sa versione pretzedente, <strong>{{int:minoreditletter}}</strong> = càmbiu minore.",
        "history-fieldset-title": "Isfògia s'istòria",
        "history-show-deleted": "Feti is burrados",
        "histfirst": "prima",
        "rev-deleted-user": "(nùmene impitadore bogadu)",
        "rev-delundel": "ammustra/cua",
        "rev-showdeleted": "ammustra",
+       "revisiondelete": "Burra o reimprea versiones",
        "revdelete-no-file": "Su documentu ispetzuficadu no esistit",
        "revdelete-show-file-submit": "Eja",
+       "revdelete-selected-text": "{{PLURAL:$1|Versione seletzionada|Versiones seletzionadas}} de [[:$2]]:",
+       "revdelete-selected-file": "{{PLURAL:$1|Versione seletzionada|Versiones seletzionadas}} de su documentu [[:$2]]:",
+       "logdelete-selected": "{{PLURAL:$1|Acadessimentu de su registru seletzionadu|Acadessimentos de su registru seletzionadu}}:",
        "revdelete-hide-text": "Testu de sa versione",
        "revdelete-hide-image": "Cua su cuntènnidu de su documentu",
+       "revdelete-hide-comment": "Modìfica s'ogetu",
+       "revdelete-radio-same": "(non cambiare)",
        "revdelete-radio-set": "Cua",
        "revdelete-radio-unset": "Ammustra",
        "revdelete-log": "Motivu:",
        "searchmenu-new": "<strong>Crea sa pàgina \"[[:$1]]\" in custa wiki!</strong> {{PLURAL:$2|0=|Càstia fintzas sa pàgina agatada cun sa chirca tua|Càstia fintzas is resurtados de sa chirca}}",
        "searchprofile-articles": "Pàginas de càbidos",
        "searchprofile-images": "Multimèdia",
-       "searchprofile-everything": "Totu",
+       "searchprofile-everything": "Totue",
        "searchprofile-advanced": "Avantzada",
        "searchprofile-articles-tooltip": "Chirca in $1",
        "searchprofile-images-tooltip": "Chirca files",
        "searchprofile-everything-tooltip": "Chirca in totue (inclùdidas is pàginas de cuntierra)",
        "searchprofile-advanced-tooltip": "Chirca in nùmene-logos personalizados",
        "search-result-size": "$1 ({{PLURAL:$2|1 paràula|$2 paràulas}})",
-       "search-result-category-size": "{{PLURAL:$1|1 cumponente|$1 cumponentes}} ({{PLURAL:$2|1 subcategoria|$2 subcategorias}}, {{PLURAL:$3|1 file|$3 files}})",
+       "search-result-category-size": "{{PLURAL:$1|1 membru|$1 membros}} ({{PLURAL:$2|1 sutacategoria|$2 sutacategorias}}, {{PLURAL:$3|1 documentu|$3 documentos}})",
        "search-redirect": "(reindiritzadu $1)",
        "search-section": "(setzione $1)",
        "search-suggest": "Fortzis fias chirchende: $1",
        "search-interwiki-more": "(àteru)",
        "searchall": "totu",
        "showingresults": "Inoghe sighende {{PLURAL:$1|benit ammustradu '''1''' resurtadu|benint ammustrados '''$1''' resurtados}} incumentzende dae su nùmeru '''$2'''.",
-       "showingresultsheader": "{{PLURAL:$5|Resurtadu <strong>$1</strong> de <strong>$3</strong>|Resurtados <strong>$1 - $2</strong> de <strong>$3</strong>}} pro <strong>$4</strong>",
        "search-nonefound": "Sa chirca no at prodùidu resurtados.",
        "powersearch-legend": "Chirca delantada",
        "powersearch-ns": "Chirca in su nùmene-logu:",
        "prefs-personal": "Datos personales",
        "prefs-rc": "Ùrtimas mudàntzias",
        "prefs-watchlist": "Watchlist",
+       "prefs-watchlist-days-max": "Màssimu $1 {{PLURAL:$1|die|dies}}",
        "prefs-watchlist-edits-max": "Cantidade màssima: 1000",
        "prefs-misc": "Àteras preferèntzias",
        "prefs-resetpass": "Càmbia password",
+       "prefs-changeemail": "Càmbia indiritzu email",
        "prefs-email": "Sèberos pro sa email",
+       "prefs-rendering": "Aparèntzia",
        "saveprefs": "Sarva preferèntzias",
+       "restoreprefs": "Restàura totu is sèberos predefinidos (in totu is setziones)",
        "prefs-editing": "Box de acontzadura",
        "rows": "Lìnias:",
        "columns": "Colunnas:",
        "searchresultshead": "Chirca",
        "stub-threshold-disabled": "Disativadu",
+       "recentchangesdays": "Dies de ammustrare in ùrtimas mudàntzias:",
        "recentchangescount": "Nùmeru de acontzos de amostare pro definidura:",
        "savedprefs": "Is preferèntzias tuas sunt stadas sarbadas.",
        "timezonelegend": "Zona de oràriu:",
        "timezoneregion-pacific": "Otzèanu Patzìficu",
        "prefs-searchoptions": "Chirca",
        "prefs-namespaces": "Nùmene-logos",
+       "default": "predefinidu",
        "prefs-files": "Files",
        "prefs-emailconfirm-label": "Cunfirma de sa email:",
        "youremail": "Email:",
-       "username": "{{GENDER:$1|Nùmene impitadore}}:Nùmene impitadore",
+       "username": "{{GENDER:$1|Nùmene impitadore}}:",
        "prefs-registration": "Ora de registratzione:",
        "yourrealname": "Nùmene beru:",
        "yourlanguage": "Limba:",
        "prefs-diffs": "Diferèntzias",
        "userrights-user-editname": "Inserta unu nùmene impitadore:",
        "editinguser": "Cambiamentu de is deretos impitadore de s'impitadore <strong>[[User:$1|$1]]</strong> $2",
+       "userrights-groupsmember": "Membru de:",
        "userrights-reason": "Motivu:",
        "userrights-irreversible-marker": "$1*",
        "group": "Grupu:",
-       "group-user": "Usuàrios",
-       "group-autoconfirmed": "Usuàrios autocunfirmadus",
+       "group-user": "Impitadores",
+       "group-autoconfirmed": "Impitadores autocunfirmadus",
        "group-bot": "Bots",
        "group-sysop": "Amministradores",
        "group-bureaucrat": "Buròcrates",
        "group-suppress": "Tzensores",
        "group-all": "(totus)",
        "group-user-member": "{{GENDER:$1|impitadore}}",
-       "group-autoconfirmed-member": "{{GENDER:$1|usuàrios autocunfirmados}}",
+       "group-autoconfirmed-member": "{{GENDER:$1|impitadores autocunfirmados}}",
        "group-bot-member": "{{GENDER:$1|bot}}",
        "group-sysop-member": "{{GENDER:$1|aministradore}}",
        "group-bureaucrat-member": "{{GENDER:$1|buròcrate}}",
        "right-minoredit": "Marcare su càmbiu che minore",
        "right-move": "Mòver pàginas",
        "right-move-subpages": "Mòvere pàginas cun is suta-pàginas issoru",
-       "right-move-rootuserpages": "Mòvere is pàginas base de is usuàrios",
+       "right-move-rootuserpages": "Mòvere is pàginas base de is impitadores",
        "right-move-categorypages": "Mòvere pàginas de categorias",
        "right-movefile": "Mòvere files",
        "right-upload": "Carrigare files",
        "right-delete": "Fuliare pàginas",
        "right-browsearchive": "Chircare pàginas fuliadas",
        "right-undelete": "Restaurare una pàgina",
+       "right-suppressionlog": "Càstia is registros privados",
        "right-siteadmin": "Bloccare e sbloccare su database",
        "newuserlogpage": "Impitadores nous",
-       "rightslog": "Deretos de is usuàrios",
+       "rightslog": "Deretos de is impitadores",
        "action-read": "lègher custa pàgina",
        "action-edit": "cambiare custa pàgina",
        "action-createpage": "creare pàginas",
        "sourceurl": "Diretzione originària:",
        "destfilename": "Nùmene de su file de destinatzione:",
        "upload-description": "Descritzione de su file",
+       "upload-options": "Optziones de carrigamentu",
+       "watchthisupload": "Annota custu documentu",
        "upload-success-subj": "Carrigamentu acabau",
        "upload-failure-subj": "Problema de carrimentu",
+       "upload-warning-subj": "Avisu de carrigamentu",
        "upload-file-error": "Faddina a intru",
+       "backend-fail-notexists": "Su documentu $1 no esistit.",
+       "backend-fail-alreadyexists": "Su documentu \"$1\" esistit giai.",
+       "uploadstash": "Càrriga stash",
        "img-auth-nofile": "Su File \"$1\" no esistit.",
+       "img-auth-streaming": "Letura currente de \"$1\".",
        "license": "Litzèntzia:",
        "license-header": "Litzèntzia",
+       "nolicense": "Nisciuna litzèntzia indicada",
        "licenses-edit": "Càmbia su sèberu de sa licèntzia",
        "upload_source_file": "(su file seberadu in su computer tuo)",
        "listfiles-delete": "Cantzella",
+       "listfiles_search_for": "Chirca figuras pro nùmene:",
        "imgfile": "file",
        "listfiles": "Lista de is files",
+       "listfiles_thumb": "Miniatura",
        "listfiles_date": "Data",
        "listfiles_name": "Nùmene",
        "listfiles_user": "Impitadore",
        "listfiles_size": "Mannesa in byte",
        "listfiles_description": "Descritzione",
        "listfiles_count": "Versiones",
+       "listfiles-latestversion": "Versione atuale",
        "listfiles-latestversion-yes": "Eja",
        "listfiles-latestversion-no": "No",
        "file-anchor-link": "File",
        "filedelete-success": "Su file '''$1''' est istadu fuliau.",
        "filedelete-otherreason": "Motivu diversu o agiuntivu:",
        "filedelete-reason-otherlist": "Àteru motivu",
+       "filedelete-edit-reasonlist": "Càmbia is motivos de sa burradura",
        "mimesearch": "Chirca MIME",
        "mimetype": "Genia MIME:",
        "download": "scàrriga",
+       "unwatchedpages": "Pàginas no annotadas",
        "listredirects": "Lista de totu is redirects",
+       "listduplicatedfiles": "Lista de documentos dopios",
+       "unusedtemplates": "Templates no impreados",
+       "unusedtemplateswlh": "àteros ligòngios",
        "randompage": "Pàgina a sa tzurpa",
        "randomincategory-category": "Categoria:",
        "statistics": "Statìsticas",
-       "statistics-header-users": "Statìsticas subra is usuàrios",
+       "statistics-header-pages": "Statìsticas subra is pàginas",
+       "statistics-header-edits": "Càmbia is statìsticas",
+       "statistics-header-views": "Càstia is statìsticas",
+       "statistics-header-users": "Statìsticas subra is impitadores",
+       "statistics-header-hooks": "Àteras statìsticas",
+       "statistics-articles": "Pàginas de càbidos",
        "statistics-pages": "Pàginas",
+       "statistics-files": "Documentos carrigados",
        "pageswithprop-submit": "Bae",
        "doubleredirects": "Redirects dòpios",
        "doubleredirectstext": "Custa pàgina cuntenet una lista de pàginas ki re-indiritzant a àteras pàginas de re-indiritzamentu.\nOgni lìnia cuntenet ligàmines a su primu e a su de duos re-indiritzamentu, aici comente sa prima lìnia de sa de duos re-indiritzamentos, chi de sòlitu adòbiat s'artìculu \"beru\", a sa cale fintzas su primu re-indiritzamentu dia depet puntare.\nIs re-indiritzamentos <del>cantzellados</del> sunt stados curretos.",
        "withoutinterwiki-submit": "Ammustra",
        "nbytes": "$1 {{PLURAL:$1|byte|bytes}}",
        "ncategories": "$1 {{PLURAL:$1|categoria|categorias}}",
-       "nlinks": "$1 {{PLURAL:$1|ligàmene|ligàmenes}}",
+       "ninterwikis": "$1 {{PLURAL:$1|interwiki|interwikis}}",
+       "nlinks": "$1 {{PLURAL:$1|ligòngiu|ligòngios}}",
        "nmembers": "$1 {{PLURAL:$1|cumponente|cumponentes}}",
        "nrevisions": "$1 {{PLURAL:$1|revisione|revisiones}}",
        "nviews": "$1 {{PLURAL:$1|bisura|bisuras}}",
        "protectedpages-reason": "Motivu",
        "protectedpages-unknown-timestamp": "Isconnottu",
        "protectedtitles": "Tìtulus amparadus",
-       "listusers": "Lista usuàrios",
+       "listusers": "Lista impitadores",
        "usereditcount": "$1 {{PLURAL:$1|acontzu|acontzos}}",
        "usercreated": "{{GENDER:$3|Creadu}} su $1 a is $2",
        "newpages": "Pàginas noas",
        "newpages-username": "Nùmene impitadore:",
        "move": "Move",
        "movethispage": "Move custa pàgina (càmbia su tìtulu)",
-       "unusedimagestext": "Is files ki sighint sunt stados carrigados ma non sunt impreados.\nDia podent essere immàgines impreadas dae àteros giassos cun unu ligàmine diretu, e tando podent essere listados inoghe comente usu ativu.",
+       "unusedimagestext": "Is documentos chi sighint sunt istados carrigados ma non sunt impreados.\nDia podent èssere immàgines impreadas dae àteros giassos cun unu ligòngiu diretu, e tando podent èssere listados inoghe comente usu ativu.",
        "notargettitle": "Perunu obietivu",
        "notargettext": "Non as ispetzificadu una pàgina o unu impitadore pro issucutare custa funtzione.",
        "pager-newer-n": "{{PLURAL:$1|1 prus nou|$1 prus nous}}",
        "listgrouprights-rights": "Deretos",
        "listgrouprights-members": "(lista de is cumponentes)",
        "listgrouprights-namespaceprotection-namespace": "Nùmene-logu",
-       "mailnologintext": "Depes èsser [[Special:UserLogin|identificadu (login)]] e àer registradu un'indiritzu e-mail vàlidu in is [[Special:Preferences|preferèntzias tuas]] pro imbiare e-mail a àteros usuàrios.",
+       "mailnologintext": "Depes èsser [[Special:UserLogin|identificadu (login)]] e àere registradu un'indiritzu email vàlidu in is [[Special:Preferences|preferèntzias tuas]] pro imbiare email a àteros impitadores.",
        "emailuser": "Imbia una email a custu impitadore",
        "emailuser-title-notarget": "Ispedi una email a s'impitadore",
        "emailpage": "Ispedi una email a s'impitadore",
        "rollback": "Annudda is acontzos",
        "rollbacklink": "rollback",
        "rollbackfailed": "Rollback faddidu",
-       "cantrollback": "Non si podet furriare s'acontzu;\ns'ùrtimu contribuidore est s'ùnicu autore de custa pàgina.",
+       "cantrollback": "Non si podet furriare sa modìfica;\ns'ùrtimu contribuidore est s'ùnicu autore de custa pàgina.",
        "revertpage": "Burradas is mudàntzias de [[Special:Contributions/$2|$2]] ([[User talk:$2|cuntierras]]), torrada a sa versione cabudiana de [[User:$1|$1]]",
        "protectlogpage": "Bardaduras",
        "protectedarticle": "at bardadu \"[[$1]]\"",
        "protect-text": "Custu modulu serbit pro castiari e cambiari su livellu de amparadura de sa pàgina '''$1'''.",
        "protect-locked-access": "Non tenes su permissu pro cambiare is livellus de amparadura de sa pàgina.\nIs impostatziones atuales pro sa pàgina '''$1''':",
        "protect-cascadeon": "A su momentu custa pàgina est bardada pro ite est inclùdida {{PLURAL:$1|in sa pàgina indicada a suta, pro sa cale|in is pàginas indicadas a suta, pro is cales}} est ativa sa bardadura ricorsiva.\nEst possìbile cambiare su livellu de bardadura de custa pàgina, ma is efetos derivados dae sa bardadura ricorsiva non ant a èssere mudados.",
-       "protect-default": "Autoritza totu is usuàrios",
+       "protect-default": "Autoriza totus is impitadores",
        "protect-fallback": "Permìtidu feti a is impitadores cun su permissu \"$1\"",
        "protect-level-autoconfirmed": "Permìtidu feti a is impitadores autocunfimados",
        "protect-level-sysop": "Permìtidu feti a is amministradores",
        "protect-cascade": "Ampara totu is pàginas inclùdias in custa (amparadura ricorsiva)",
        "protect-cantedit": "Non podes cambiare is livellus de amparadura pro sa pàgina, pro ite non tenes su permissu de cambiare sa pàgina etotu.",
        "protect-othertime": "Àteru perìodu:",
+       "protect-othertime-op": "àteru perìodu",
+       "protect-otherreason": "Motivu diversu o agiuntivu:",
        "protect-otherreason-op": "Àteru motivu",
        "protect-expiry-options": "1 ora:1 hour,1 die:1 day,1 chida:1 week,2 chidas:2 weeks,1 mese:1 month,3 meses:3 months,6 meses:6 months,1 annu:1 year,infinidu:infinite",
        "restriction-type": "Permissu:",
        "undeletedrevisions": "{{PLURAL:$1|1 revisione restaurada|$1 revisiones restauradas}}",
        "undeletedrevisions-files": "{{PLURAL:$1|1 revisione|$1 revisiones}} e {{PLURAL:$2|1 file|$2 files}} restaurados",
        "undeletedfiles": "{{PLURAL:$1|1 file restauradu|$1 files restaurados}}",
+       "undelete-search-title": "Chirca pàginas burradas",
        "undelete-search-box": "Chirca pàginas fuliadas",
        "undelete-search-prefix": "Ammustra is pàginas ca su tìtulu cumentzat cun:",
        "undelete-search-submit": "Chirca",
        "undelete-show-file-submit": "Eja",
        "namespace": "Nùmene-logu:",
        "invert": "Fùrria sa seletzione",
+       "namespace_association": "Nùmene-logu assotziadu",
        "blanknamespace": "(Printzipale)",
        "contributions": "Contributos {{GENDER:$1|impitadore}}",
        "contributions-title": "Contributziones de $1",
        "month": "Dae su mese (e in segus):",
        "year": "Dae s'annu (e in segus):",
        "sp-contributions-newbies": "Ammustra feti is contributziones de is contos noos",
+       "sp-contributions-newbies-sub": "Pro is contos noos",
        "sp-contributions-blocklog": "registru de is bloccos",
        "sp-contributions-uploads": "carrigamentos",
        "sp-contributions-logs": "registros",
        "move-leave-redirect": "Lassa unu reindiritzamentu a palas",
        "export": "Esporta pàginas",
        "export-submit": "Esporta",
+       "export-addcat": "Annanghe",
+       "export-addns": "Annanghe",
        "export-download": "Sarba comente file",
        "allmessagesname": "Nùmene",
        "allmessagesdefault": "Testu predefinidu",
        "allmessages-filter-translate": "Tradui",
        "thumbnail-more": "Amannia",
        "thumbnail_error": "Faddina creande sa miniatura: $1",
+       "import-interwiki-sourcewiki": "Wiki de orìgine:",
+       "import-interwiki-sourcepage": "Pàgina de orìgine:",
        "import-interwiki-submit": "Importa",
        "import-interwiki-namespace": "Nùmene-logu de destinatzione:",
        "import-upload-filename": "Nùmene file:",
        "import-comment": "Cummentu:",
        "importstart": "Importande is pàginas...",
        "import-revision-count": "$1 {{PLURAL:$1|revisione|revisiones}}",
+       "importlogpage": "Importatziones",
        "tooltip-pt-userpage": "Sa pàgina impitadore tua",
        "tooltip-pt-mytalk": "Sa pàgina de is cuntierras tuas",
        "tooltip-pt-preferences": "Is preferèntzias chi podes seberare",
        "siteuser": "$1, impitadore de {{SITENAME}}",
        "anonuser": "$1, impitadore anònimu de {{SITENAME}}",
        "others": "àteros",
-       "siteusers": "$1, {{PLURAL:$2|usuàriu|usuàrios}} de {{SITENAME}}",
-       "anonusers": "$1, {{PLURAL:$2|usuàriu anònimu|usuàrios anònimos}} de {{SITENAME}}",
+       "siteusers": "$1, {{PLURAL:$2|impitadore|impitadores}} de {{SITENAME}}",
+       "anonusers": "$1, {{PLURAL:$2|impitadore anònimu|impitadores anònimos}} de {{SITENAME}}",
        "creditspage": "Autores de sa pàgina",
+       "pageinfo-header-edits": "Istòria de is mudàntzias",
        "pageinfo-article-id": "ID pàgina",
+       "pageinfo-firstuser": "Creadore de sa pàgina",
+       "pageinfo-firsttime": "Data de creatzione de sa pàgina",
+       "pageinfo-lastuser": "Ùrtimu contribudore",
+       "pageinfo-lasttime": "Data de s'ùrtimu càmbiu",
+       "pageinfo-edits": "Nùmeru totale de càmbios",
+       "pageinfo-authors": "Nùmeru totale de autores dislindados",
+       "pageinfo-redirectsto-info": "info",
        "pageinfo-contentpage-yes": "Eja",
        "pageinfo-protect-cascading-yes": "Eja",
-       "previousdiff": "← Acontzu in segus",
-       "nextdiff": "Acontzu in antis →",
+       "pageinfo-category-pages": "Nùmeru de pàginas",
+       "pageinfo-category-subcats": "Nùmeru de sutacategorias",
+       "pageinfo-category-files": "Nùmeru de documentos",
+       "markaspatrolleddiff": "Marca comente cumprobadu",
+       "markaspatrolledtext": "Marca custa pàgina comente cumprobada",
+       "markedaspatrolled": "Marcada comente cumprobada",
+       "previousdiff": "← Càmbiu in segus",
+       "nextdiff": "Càmbiu in antis →",
+       "thumbsize": "Mannesa de is miniaturas:",
        "widthheightpage": "$1 × $2, $3 {{PLURAL:$3|pàgina|pàginas}}",
+       "file-info": "mannesa de su documentu: $1, casta de MIME: $2",
        "file-info-size": "$1 × $2 pixels, mannesa de su file: $3, tipu de MIME: $4",
        "file-nohires": "Non si tenent risolutziones prus artas.",
        "svg-long-desc": "file in formadu SVG, mannesa nominale $1 × $2 pixel, mannesa de su file: $3",
        "show-big-image": "Versione a risolutzione arta",
        "imagelisttext": "Innoe sighendi du est una lista de '''$1''' {{PLURAL:$1|file|files}} ordinada $2.",
+       "newimages-legend": "Filtru",
        "ilsubmit": "Chirca",
        "bydate": "data",
        "video-dims": "$1, $2×$3",
        "seconds-abbrev": "$1s",
        "minutes-abbrev": "$1m",
        "hours-abbrev": "$1h",
+       "seconds": "{{PLURAL:$1|$1 segundu|$1 segundos}}",
+       "minutes": "{{PLURAL:$1|$1 minutu|$1 minutos}}",
+       "hours": "{{PLURAL:$1|$1 ora|$1 oras}}",
+       "days": "{{PLURAL:$1|$1 die|$1 dies}}",
+       "weeks": "{{PLURAL:$1|$1 chida|$1 chidas}}",
+       "months": "{{PLURAL:$1|$1 mese|$1 meses}}",
+       "years": "{{PLURAL:$1|$1 annu|$1 annos}}",
+       "ago": "como $1",
+       "just-now": "immoe-immoe",
+       "hours-ago": "como $1 {{PLURAL:$1|ora|oras}}",
+       "minutes-ago": "como $1 {{PLURAL:$1|minutu|minutos}}",
+       "seconds-ago": "como $1 {{PLURAL:$1|segundu|segundos}}",
+       "monday-at": "Lunis a is $1",
+       "tuesday-at": "Martis a is $1",
+       "wednesday-at": "Mèrcuris a is $1",
+       "thursday-at": "Gioja a is $1",
+       "friday-at": "Chenàbura a is $1",
+       "saturday-at": "Sàbadu a is $1",
+       "sunday-at": "Domìnigu a is $1",
+       "yesterday-at": "Eris a is $1",
        "bad_image_list": "Su formadu est su chi sighit:\n\nBenint consideradas isceti is listas punnadas (lìnias chi incumentzant cun *).\nSu primu ligòngiu in cada una lìnia depet èssere unu ligòngiu a unu documentu malu (o indesideradu).\nIs ligòngios chi sighint in sa matessi lìnia sunt cunsiderados comente etzetziones (est a nàrrere, pàginas in ue si podet usare su documentu).",
        "metadata": "Metadatos",
        "metadata-help": "Custu file cuntènnit informatziones annuntiles, probabilmente annúnghedas dae sa fotocamera o dae su scannerizadore impreadu pro ddu creare o ddu digitalizare. Si su file est istadu mudadu, unos cantos particulares podent non currispòndere a sa realidade.",
        "exif-fnumber-format": "f/$1",
        "exif-flash": "Flash",
        "exif-focallength-format": "$1 mm",
+       "exif-contrast": "Cuntrastu",
+       "exif-saturation": "Saturassione",
+       "exif-gpslatituderef": "Latitùdine nord o sud",
+       "exif-gpslatitude": "Latitùdine",
+       "exif-gpslongituderef": "Longitùdine est o ovest",
+       "exif-gpslongitude": "Longitùdine",
+       "exif-source": "Orìgine",
+       "exif-languagecode": "Limba",
+       "exif-iimcategory": "Categoria",
        "exif-compression-6": "JPEG",
        "exif-photometricinterpretation-2": "RGB",
        "exif-photometricinterpretation-6": "YCbCr",
        "exif-componentsconfiguration-1": "Y",
        "exif-componentsconfiguration-2": "Cb",
        "exif-componentsconfiguration-3": "Cr",
+       "exif-exposureprogram-1": "Ghia",
        "exif-subjectdistance-value": "$1 metros",
+       "exif-meteringmode-255": "Àteru",
+       "exif-lightsource-0": "Isconnottu",
        "exif-lightsource-4": "Lampu",
        "exif-gaincontrol-0": "Nudda",
        "exif-contrast-0": "Normale",
+       "exif-saturation-0": "Normale",
        "exif-sharpness-0": "Normale",
        "watchlistall2": "totu",
        "namespacesall": "totu",
        "monthsall": "totu",
        "confirmemail": "Cunfirma s'indiritzu e-mail",
        "confirm_purge_button": "OK",
+       "confirm-watch-button": "OK",
+       "confirm-unwatch-button": "OK",
        "semicolon-separator": ";&#32;",
        "comma-separator": ",&#32;",
        "colon-separator": ":&#32;",
        "version-version": "(Versione $1)",
        "version-license": "Licèntzia MediaWiki",
        "version-ext-license": "Licèntzia",
+       "version-ext-colheader-version": "Versione",
        "version-ext-colheader-license": "Licèntzia",
+       "version-ext-colheader-description": "Descritzione",
+       "version-ext-colheader-credits": "Autores",
+       "version-license-title": "Litzèntzia pro $1",
        "version-poweredby-others": "àteros",
        "version-software-version": "Versione",
        "version-entrypoints-header-url": "URL",
        "specialpages-group-login": "Intra / crea contu",
        "specialpages-group-pages": "Listas de is pàginas",
        "tag-filter": "Filtra pro [[Special:Tags|etichetta]]:",
+       "tag-filter-submit": "Filtru",
        "tags-active-yes": "Eja",
        "tags-active-no": "No",
        "tags-edit": "càmbia",
+       "tags-hitcount": "$1 {{PLURAL:$1|càmbiu|càmbios}}",
        "compare-page1": "Pàgina 1",
        "compare-page2": "Pàgina 2",
        "compare-rev1": "Revisione 1",
        "logentry-upload-overwrite": "$1 {{GENDER:$2|carrigadu}} una versione noa de $3",
        "logentry-upload-revert": "$1 {{GENDER:$2|carrigadu}} $3",
        "rightsnone": "(nisciunu)",
+       "revdelete-summary": "ogetu de sa modìfica",
+       "feedback-subject": "Ogetu:",
+       "feedback-message": "Messàgiu:",
+       "feedback-cancel": "Annudda",
        "feedback-close": "Fatu",
        "searchsuggest-search": "Chirca",
        "expand_templates_ok": "OK",
        "expand_templates_preview": "Antiprima",
        "pagelang-name": "Pàgina",
+       "pagelang-language": "Limba",
        "pagelang-select-lang": "Sèbera limba"
 }
index fb8237a..d11f875 100644 (file)
        "searchrelated": "currilati",
        "searchall": "tutti",
        "showingresults": "Ammustra nzinu a {{PLURAL:$1|'''1''' risurtatu|'''$1''' risurtati}} a pàrtiri dô nùmmuru '''$2'''.",
-       "showingresultsheader": "{{PLURAL:$5|Risultatu '''$1''' di '''$3'''|Risultati '''$1 - $2''' di '''$3'''}} pi '''$4'''",
        "search-nonefound": "La circata nun desi nuddu risurtatu.",
        "powersearch-legend": "Ricerca avanzata",
        "powersearch-ns": "Cerca ntê namespace:",
        "logentry-delete-delete": "$1 cancillau la pàggina $3",
        "revdelete-restricted": "ristrizzioni ai suli amministratura attivate",
        "revdelete-unrestricted": "ristrizzioni pi suli amministraturi rimossi",
-       "logentry-move-move": "$1 spustau la pàggina $3 a $4",
+       "logentry-move-move": "$1 {{GENDER:$2|spustau}} la pàggina $3 nti $4",
+       "logentry-move-move_redir": "$1 {{GENDER:$2|spustau}} la pàggina $3 nti $4 cu nu rinnirizzamentu",
        "logentry-newusers-create": "$1 criau na utenza",
        "rightsnone": "(nuddu)",
+       "revdelete-summary": "riassuntu dô canciamentu",
        "searchsuggest-search": "Risciduta",
        "api-error-nomodule": "Erruri nternu: nun fu mpustatu lu mòdulu di carricamentu",
        "api-error-ok-but-empty": "Erruri ntenru: nudda risposta dû server",
index 42520d9..c581bf6 100644 (file)
@@ -26,7 +26,8 @@
                        "Valasek",
                        "Wizzard",
                        "לערי ריינהארט",
-                       "아라"
+                       "아라",
+                       "Matthew Greg"
                ]
        },
        "tog-underline": "Podčiarkovať odkazy:",
        "searchrelated": "súvisiace",
        "searchall": "všetko",
        "showingresults": "Nižšie {{PLURAL:$1|je zobrazený jeden výsledok|sú zobrazené '''1''' výsledky|je zobrazených '''$1''' výsledkov}}, počnúc od  #<b>$2</b>.",
-       "showingresultsheader": "{{PLURAL:$5|Výsledok '''$1''' z '''$3'''|Výsledky '''$1 - $2''' z '''$3'''}} pre '''$4'''",
        "search-nonefound": "Vyhľadávanie nenašlo žiadne výsledky.",
        "powersearch-legend": "Pokročilé hľadanie",
        "powersearch-ns": "Hľadať v menných priestoroch:",
        "pagelang-language": "Jazyk",
        "pagelang-use-default": "Použiť predvolený jazyk",
        "pagelang-select-lang": "Vybrať jazyk",
-       "right-pagelang": "Zmeniť jazyk stránky"
+       "right-pagelang": "Zmeniť jazyk stránky",
+       "default-skin-not-found": "Uups! Základná tapeta pre Vašu wiki, popísanú v <code dir=\"ltr\">$wgDefaultSkin</code> ako <code>$1</code>, nie je dostupná. \n\nVaša inštalácia pravdepodobne obsahuje nasledovné tapety. Pozri [https://www.mediawiki.org/wiki/Manual:Skin_configuration Manual: Skin configuration] pre viac informácii o ich aktivácii a zvoľte základnú.\n\n$2\n\n; Ak ste MediaWiki len teraz nainštalovali\n; Zrejme ste to nainštalovali z gitu alebo priamo zo zdrojového kódu inou metódou. Je to očakávané. Skúste nainštalovať nejaké tapety z [https://www.mediawiki.org/wiki/Category:All_skins mediawiki.org's skin directory];\n:*Stiahnutím [https://www.mediawiki.org/wiki/Download tarball installer], ktorý ponúka viacero tapiet a rozšírení. Skopírovať a nalepiť možno priamo z <code>skins/</code>.\n:*Klonovanie jednej zo <code>mediawiki/skins/*</code> schránok cez git do <code dir=\"ltr\">skins/</code> priečinku Vašej Media Wiki inštalácie.\n: S existujúcou git schránkou, ak ste vývojár MediaWiki, by nemal byť konflikt.\n\n: Ak ste upgradeovali MediaWiki\n: MediaWiki 1.24 a novšie už tapety automaticky neaktivujú. (see [https://www.mediawiki.org/wiki/Manual:Skin_autodiscovery Manual: Skin autodiscovery]). Nasledovný kód môžete skopírovať do <code>LocalSettings.php</code> pre aktivovanie všetkých dostupných tapiet.\n\n<pre dir=\"ltr\">$3</pre>\n\n; Ak ste upravili <code>LocalSettings.php</code>:\n: Skontrolujte chyby."
 }
index c11d5f0..344ddd9 100644 (file)
        "otherlanguages": "V drugih jezikih",
        "redirectedfrom": "(Preusmerjeno s strani $1)",
        "redirectpagesub": "Preusmeritvena stran",
+       "redirectto": "Preusmeritev na:",
        "lastmodifiedat": "Čas zadnje spremembe: $2, $1.",
        "viewcount": "Stran je bila naložena {{PLURAL:$1|$1-krat}}.",
        "protectedpage": "Zaščitena stran",
        "passwordreset-emailsent-capture": "Poslali smo e-pošto za ponastavitev gesla, ki je prikazana spodaj.",
        "passwordreset-emailerror-capture": "Ustvarili smo e-pošto za ponastavitev gesla, ki je prikazana spodaj, vendar pa pošiljanje {{GENDER:$2|uporabniku|uporabnici}} ni uspelo: $1",
        "changeemail": "Sprememba e-poštnega naslova",
-       "changeemail-header": "Sprememba e-poštnega naslova računa",
        "changeemail-text": "Izpolnite obrazec za spremembo vašega e-poštnega naslova. Za potrditev spremembe boste morali vnesti svoje geslo.",
        "changeemail-no-info": "Za neposredni dostop do strani morate biti prijavljeni.",
        "changeemail-oldemail": "Trenutni e-poštni naslov:",
        "changeemail-none": "(noben)",
        "changeemail-password": "Vaše geslo za {{GRAMMAR:tožilnik|{{SITENAME}}}}:",
        "changeemail-submit": "Spremeni e-naslov",
-       "changeemail-cancel": "Prekliči",
        "changeemail-throttled": "Izvedli ste preveč poskusov prijave.\nProsimo, počakajte $1, preden poskusite znova.",
        "resettokens": "Ponastavitev žetonov",
        "resettokens-text": "Žetone lahko ponastavite, kar omogoča dostop do nekaterih zasebnih podatkov, povezanih z vašim računom.\n\nTo storite, če ste po nesreči žetone z nekom delili, ali če je bil vaš račun ogrožen.",
        "searchall": "vse",
        "showingresults": "Prikazujem do '''$1''' {{PLURAL:$1|zadetek|zadetka|zadetke|zadetkov}}, začenši s št. '''$2'''.",
        "showingresultsinrange": "Spodaj prikazujem {{PLURAL:$1|1=<strong>1</strong> rezultat|<strong>$1</strong> rezultata|<strong>$1</strong> rezultate|<strong>$1</strong> rezultatov}} v razponu od št. <strong>$2</strong> do št. <strong>$3</strong>.",
-       "showingresultsheader": "{{PLURAL:$5|Zadetek '''$1''' od '''$3'''|Zadetki '''$1 - $2''' od skupno '''$3'''}} za povpraševanje '''$4'''",
+       "search-showingresults": "{{PLURAL:$4|Rezultat <strong>$1</strong> od <strong>$3</strong>|Rezultati <strong>$1–$2</strong> od <strong>$3</strong>}}",
        "search-nonefound": "Ni bilo zadetkov, ki ustrezajo poizvedbi.",
        "powersearch-legend": "Napredno iskanje",
        "powersearch-ns": "Iskanje v imenskih prostorih:",
        "protect-othertime": "Drugačen čas:",
        "protect-othertime-op": "drugačen čas",
        "protect-existing-expiry": "Obstoječ čas izteka: $3, $2",
+       "protect-existing-expiry-infinity": "Obstoječ čas izteka: neskončno",
        "protect-otherreason": "Drug/dodaten razlog:",
        "protect-otherreason-op": "Drug razlog",
        "protect-dropdown": "*Pogosti razlogi za zaščito\n** Prekomeren vandalizem\n** Vztrajno dodajanje reklamnih povezav\n** Neproduktivne urejevalske vojne\n** Zelo obiskana stran",
        "unblocked": "[[User:$1|$1]] je bil odblokiran",
        "unblocked-range": "$1 so odblokirani",
        "unblocked-id": "Blokada $1 je odstranjena",
+       "unblocked-ip": "[[Special:Contributions/$1|$1]] smo odblokirali.",
        "blocklist": "Blokirani uporabniki",
        "ipblocklist": "Blokirani uporabniki",
        "ipblocklist-legend": "Poišči blokiranega uporabnika",
        "logentry-upload-overwrite": "$1 je {{GENDER:$2|naložil|naložila|naložil(-a)}} novo različico $3",
        "logentry-upload-revert": "$1 je {{GENDER:$2|naložil|naložila|naložil(-a)}} $3",
        "rightsnone": "(nobeno)",
+       "revdelete-summary": "povzetek urejanja",
        "feedback-bugornote": "Če ste pripravljeni podrobno opisati tehnično težavo, vložite [$1 poročilo o hrošču].\nV nasprotnem primeru lahko uporabite preprost obrazec spodaj. Vašo pripombo bomo dodali na stran »[$3 $2]«, skupaj z vašim uporabniškim imenom in podatkom o brskalniku, ki ga uporabljate.",
        "feedback-subject": "Zadeva:",
        "feedback-message": "Sporočilo:",
        "log-name-pagelang": "Dnevnik spreminjanja jezika",
        "log-description-pagelang": "Dnevnik sprememb jezika strani.",
        "logentry-pagelang-pagelang": "$1 je {{GENDER:$2|spremenil|spremenila|spremenil(-a)}} jezik strani $3 z jezika $4 na jezik $5.",
-       "default-skin-not-found": "Ups! Privzeta koža vašega wikija (<code>$wgDefaultSkin</code>), <code>$1</code>, ni na voljo.\n\nKot kaže, vaša namestitev vsebuje kože, navedene spodaj. Oglejte si [https://www.mediawiki.org/wiki/Manual:Skin_configuration Priročnik: Konfiguracija kož] za več informacij, kako jih omogočiti in nastaviti kot privzete.\n\n$2\n\n; Če ste MediaWiki pravkar namestili:\n: Verjetno ste ga namestili z git ali neposredno iz izvorne kode na kakšen drug način. To je pričakovano. Poskusite namestiti nekaj kož z [https://www.mediawiki.org/wiki/Category:All_skins imenika kož mediawiki.org] tako:\n:* Prenesite [https://www.mediawiki.org/wiki/Download namestitveni program tarball], ki vsebuje nekaj kož in razširitev. Iz njega lahko kopirate in prilepite mapo <code>skins/</code>.\n:* Klonirajte enega od repozitorijev <code>mediawiki/skins/*</code> z git v mapo <code>skins/</code> vaše namestitve MediaWiki.\n: Če ste razvijalec MediaWiki, to ne sme poseči v vaš repozitorij git.\n\n; Če ste MediaWiki pravkar posodobili:\n: MediaWiki 1.24 in novejši nameščenih kož več ne omogočijo samodejno (oglejte si [https://www.mediawiki.org/wiki/Manual:Skin_autodiscovery Priročnik: Samodejno odkrivanje kož]). V <code>LocalSettings.php</code> lahko prilepite naslednje vrstice, da omogočite trenutno nameščene kože:\n\n<pre>$3</pre>\n\n; Če ste pravkar spremenili <code>LocalSettings.php</code>:\n: Ponovno preverite imena kož, če ste se morda zatipkali.",
-       "default-skin-not-found-no-skins": "Ups! Privzeta koža vašega wikija (<code>$wgDefaultSkin</code>), <code>$1</code>, ni na voljo.\n\nNimate nameščenih kož.\n\n; Če ste MediaWiki pravkar namestili ali posodobili:\n: Verjetno ste ga namestili z git ali neposredno iz izvorne kode na kakšen drug način. To je pričakovano. MediaWiki 1.24 in novejši nimajo vključene nobene kože v glavnem repozitoriju. Poskusite namestiti nekaj kož z [https://www.mediawiki.org/wiki/Category:All_skins imenika kož mediawiki.org] tako:\n:* Prenesite [https://www.mediawiki.org/wiki/Download namestitveni program tarball], ki vsebuje nekaj kož in razširitev. Iz njega lahko kopirate in prilepite mapo <code>skins/</code>.\n:* Klonirajte enega od repozitorijev <code>mediawiki/skins/*</code> z git v mapo <code>skins/</code> vaše namestitve MediaWiki.\n: Če ste razvijalec MediaWiki, to ne sme poseči v vaš repozitorij git. Oglejte si [https://www.mediawiki.org/wiki/Manual:Skin_configuration Priročnik: Konfiguracija kož] za več informacij, kako jih omogočiti in nastaviti kot privzete.",
+       "default-skin-not-found": "Ups! Privzeta koža vašega wikija, določena v <code dir=\"ltr\">$wgDefaultSkin</code> kot <code>$1</code>, ni na voljo.\n\nKot kaže, vaša namestitev vsebuje kože, navedene spodaj. Oglejte si [https://www.mediawiki.org/wiki/Manual:Skin_configuration Priročnik: Konfiguracija kož] za več informacij, kako jih omogočiti in nastaviti kot privzete.\n\n$2\n\n; Če ste MediaWiki pravkar namestili:\n: Verjetno ste ga namestili z git ali neposredno iz izvorne kode na kakšen drug način. To je pričakovano. Poskusite namestiti nekaj kož z [https://www.mediawiki.org/wiki/Category:All_skins imenika kož mediawiki.org] tako:\n:* Prenesite [https://www.mediawiki.org/wiki/Download namestitveni program tarball], ki vsebuje nekaj kož in razširitev. Iz njega lahko kopirate in prilepite mapo <code>skins/</code>.\n:* Klonirajte enega od repozitorijev <code>mediawiki/skins/*</code> z git v mapo <code dir=\"ltr\">skins/</code> vaše namestitve MediaWiki.\n: Če ste razvijalec MediaWiki, to ne sme poseči v vaš repozitorij git.\n\n; Če ste MediaWiki pravkar posodobili:\n: MediaWiki 1.24 in novejši nameščenih kož več ne omogočijo samodejno (oglejte si [https://www.mediawiki.org/wiki/Manual:Skin_autodiscovery Priročnik: Samodejno odkrivanje kož]). V <code>LocalSettings.php</code> lahko prilepite naslednje vrstice, da omogočite trenutno nameščene kože:\n\n<pre dir=\"ltr\">$3</pre>\n\n; Če ste pravkar spremenili <code>LocalSettings.php</code>:\n: Ponovno preverite imena kož, če ste se morda zatipkali.",
+       "default-skin-not-found-no-skins": "Ups! Privzeta koža vašega wikija, določena v <code dir=\"ltr\">$wgDefaultSkin</code> kot <code>$1</code>, ni na voljo.\n\nNimate nameščenih kož.\n\n; Če ste MediaWiki pravkar namestili ali posodobili:\n: Verjetno ste ga namestili z git ali neposredno iz izvorne kode na kakšen drug način. To je pričakovano. MediaWiki 1.24 in novejši nimajo vključene nobene kože v glavnem repozitoriju. Poskusite namestiti nekaj kož z [https://www.mediawiki.org/wiki/Category:All_skins imenika kož mediawiki.org] tako:\n:* Prenesite [https://www.mediawiki.org/wiki/Download namestitveni program tarball], ki vsebuje nekaj kož in razširitev. Iz njega lahko kopirate in prilepite mapo <code dir=\"ltr\">skins/</code>.\n:* Klonirajte enega od repozitorijev <code>mediawiki/skins/*</code> z git v mapo <code>skins/</code> vaše namestitve MediaWiki.\n: Če ste razvijalec MediaWiki, to ne sme poseči v vaš repozitorij git. Oglejte si [https://www.mediawiki.org/wiki/Manual:Skin_configuration Priročnik: Konfiguracija kož] za več informacij, kako jih omogočiti in nastaviti kot privzete.",
        "default-skin-not-found-row-enabled": "* <code>$1</code> / $2 (omogočeno)",
        "default-skin-not-found-row-disabled": "* <code>$1</code> / $2 ('''onemogočeno''')"
 }
index a0c3874..045d794 100644 (file)
        "passwordreset-emailsent-capture": "Послат је подсетник преко е-поште (приказан доле).",
        "passwordreset-emailerror-capture": "Е-порука за ресетовање лозинке, приказана испод је послата, али слање {{GENDER:$2|кориснику|корисници}} није успело: $1",
        "changeemail": "Промена е-адресе",
-       "changeemail-header": "Промените е-адресу налога",
        "changeemail-text": "Попуните овај образац да бисте променили своју е-адресу. Мораћете да унесете лозинку да потврдите измену.",
        "changeemail-no-info": "Морате бити пријављени да бисте приступили овој страници.",
        "changeemail-oldemail": "Тренутна е-адреса:",
        "changeemail-none": "(ништа)",
        "changeemail-password": "Ваша лозинка:",
        "changeemail-submit": "Промени",
-       "changeemail-cancel": "Откажи",
        "changeemail-throttled": "Превише пута сте покушали да се пријавите.\nМолимо вас да сачекате $1 пре него што покушате поново.",
        "resettokens": "Ресетовање жетона",
        "resettokens-no-tokens": "Нема жетона за ресетовање.",
        "searchall": "све",
        "showingresults": "Испод {{PLURAL:$1|је приказан <strong>1</strong> резултат|су приказана <strong>$1</strong> резултата|је приказано <strong>$1</strong> резултата}} почев од броја <strong>$2</strong>.",
        "showingresultsinrange": "Испод {{PLURAL:$1|је приказан <strong>1</strong> резултат|су приказана <strong>$1</strong> резултата|је приказано <strong>$1</strong> резултата}}, у распону од <strong>$2</strong> до <strong>$3</strong>.",
-       "showingresultsheader": "{{PLURAL:$5|Резултат '''$1''' од '''$3'''|Резултата '''$1 – $2''' од '''$3'''}} за '''$4'''",
+       "search-showingresults": "{{PLURAL:$4|Резултат <strong>$1</strong> од <strong>$3</strong>|Резултата <strong>$1 – $2</strong> од <strong>$3</strong>}}",
        "search-nonefound": "Нема поклапања.",
        "powersearch-legend": "Напредна претрага",
        "powersearch-ns": "Тражи у следећим именским просторима:",
        "undeleteinvert": "Обрни избор",
        "undeletecomment": "Разлог:",
        "undeletedrevisions": "{{PLURAL:$1|Измена је враћена|$1 измене су враћене|$1 измена је враћено}}",
-       "undeletedrevisions-files": "$1 {{PLURAL:$1|измена|измене|измена}} и $2 {{PLURAL:$2|датотека|датотеке|датотека}} је враћено",
+       "undeletedrevisions-files": "$1 {{PLURAL:$1|1 измена|измене|измена}} и $2 {{PLURAL:$2|1 датотека је враћена|датотеке су враћене|датотека је враћено}}",
        "undeletedfiles": "{{PLURAL:$1|Датотека је враћена|$1 датотеке су враћене|$1 датотека је враћено}}",
        "cannotundelete": "Враћање није успело:\n$1",
        "undeletedpage": "'''Страница $1 је враћена'''\n\nПогледајте [[Special:Log/delete|историју брисања]] за записе о скорашњим брисањима и враћањима.",
        "unblockiptext": "Користите образац испод да бисте вратили право писања блокираној IP адреси или корисничком имену.",
        "ipusubmit": "Уклони ову блокаду",
        "unblocked": "[[User:$1|$1]] је деблокиран",
-       "unblocked-range": "$1 је {{GENDER:$1|деблокиран|деблокирана|деблокиран}}",
+       "unblocked-range": "$1 је деблокиран",
        "unblocked-id": "Блокирање $1 је уклоњено",
+       "unblocked-ip": "[[Special:Contributions/$1|$1]] је деблокиран.",
        "blocklist": "Блокирани корисници",
        "ipblocklist": "Блокирани корисници",
        "ipblocklist-legend": "Проналажење блокираног корисника",
        "table_pager_limit_submit": "Иди",
        "table_pager_empty": "Нема резултата",
        "autosumm-blank": "Уклоњен целокупан садржај странице",
-       "autosumm-replace": "Замена садржаја странице са „$1“",
+       "autosumm-replace": "Замењен садржај странице са „$1“",
        "autoredircomment": "Преусмерење на [[$1]]",
        "autosumm-new": "Нова страница: $1",
        "autosumm-newblank": "Направљена празна страница",
        "watchlistedit-clear-titles": "Наслови:",
        "watchlistedit-clear-submit": "Испразни списак надгледања (Ово је трајно!)",
        "watchlistedit-clear-done": "Ваш списак надгледања је испражњен.",
-       "watchlistedit-clear-removed": "{{PLURAL:$1|1 наслов је уклоњен|$1 наслова је уклоњено}}:",
+       "watchlistedit-clear-removed": "{{PLURAL:$1|1 наслов је уклоњен|$1 наслова су уклоњена|$1 наслова је уклоњено}}:",
+       "watchlistedit-too-many": "Има превише страница за приказ овде.",
        "watchlisttools-clear": "испразни списак надгледања",
        "watchlisttools-view": "прикажи сродне измене",
        "watchlisttools-edit": "прикажи и уреди списак надгледања",
        "sqlite-no-fts": "$1 без подршке претраге целог текста",
        "logentry-delete-delete": "$1 је {{GENDER:$2|обрисао|обрисала}} страницу $3",
        "logentry-delete-restore": "$1 је {{GENDER:$2|вратио|вратила}} страницу $3",
-       "logentry-delete-event": "$1 је {{GENDER:$2|променио|променила}} видљивост {{PLURAL:$5|догађаја|$5 догађаја}} у дневнику на $3: $4",
-       "logentry-delete-revision": "$1 је {{GENDER:$2|променио|променила}} видљивост $5 {{PLURAL:$5|измене|измене|измена}} на страници $3: $4",
+       "logentry-delete-event": "$1 је {{GENDER:$2|променио|променила}} видљивост {{PLURAL:$5|1=догађаја|$5 догађаја|$5 догађаја}} у дневнику на $3: $4",
+       "logentry-delete-revision": "$1 је {{GENDER:$2|променио|променила}} видљивост $5 {{PLURAL:$5|1=измене|измене|измена}} на страници $3: $4",
        "logentry-delete-event-legacy": "$1 је {{GENDER:$2|променио|променила}} видљивост догађаја у дневнику на $3",
        "logentry-delete-revision-legacy": "$1 је {{GENDER:$2|променио|променила}} видљивост измена на страници $3",
        "logentry-suppress-delete": "$1 је {{GENDER:$2|потиснуо|потиснула}} страницу $3",
-       "logentry-suppress-event": "$1 је тајно {{GENDER:$2|променио|променила}} видљивост {{PLURAL:$5|догађаја|$5 догађаја}} у дневнику на $3: $4",
+       "logentry-suppress-event": "$1 је тајно {{GENDER:$2|променио|променила}} видљивост {{PLURAL:$5|1=догађаја|$5 догађаја|$5 догађаја}} у дневнику на $3: $4",
        "logentry-suppress-revision": "$1 је тајно {{GENDER:$2|променио|променила}} видљивост {{PLURAL:$5|измене|$5 измена}} на страници $3: $4",
        "logentry-suppress-event-legacy": "$1 је потајно {{GENDER:$2|променио|променила}} видљивост догађаја у дневнику на $3",
        "logentry-suppress-revision-legacy": "$1 је тајно {{GENDER:$2|променио|променила}} видљивост измена на страници $3",
        "logentry-upload-overwrite": "$1 је {{GENDER:$2|послао|послала}} нову верзију $3",
        "logentry-upload-revert": "$1 је {{GENDER:$2|послао|послала}} $3",
        "rightsnone": "(нема)",
+       "revdelete-summary": "опис измене",
        "feedback-bugornote": "Ако сте спремни да детаљно опишете технички проблем, онда [$1 пријавите грешку].\nУ супротном, послужите се једноставним обрасцем испод. Ваш коментар ће стајати на страници „[$3 $2]“, заједно с корисничким именом и прегледачем који користите.",
        "feedback-subject": "Наслов:",
        "feedback-message": "Порука:",
index d515d9f..b2bf051 100644 (file)
        "otherlanguages": "Drugi jezici",
        "redirectedfrom": "(preusmereno sa $1)",
        "redirectpagesub": "Preusmerenje",
+       "redirectto": "Preusmerava na:",
        "lastmodifiedat": "Ova stranica je poslednji put izmenjena $1 u $2.",
        "viewcount": "Ova stranica je pregledana {{PLURAL:$1|jedanput|$1 puta|$1 puta}}.",
        "protectedpage": "Zaštićena stranica",
        "passwordreset-emailsent-capture": "Poslat je podsetnik preko e-pošte (prikazan dole).",
        "passwordreset-emailerror-capture": "E-poruka za resetovanje lozinke, prikazana ispod je poslata, ali slanje {{GENDER:$2|korisniku|korisnici}} nije uspelo: $1",
        "changeemail": "Promena e-adrese",
-       "changeemail-header": "Promenite e-adresu naloga",
        "changeemail-text": "Popunite ovaj obrazac da biste promenili svoju e-adresu. Moraćete da unesete lozinku da potvrdite izmenu.",
        "changeemail-no-info": "Morate biti prijavljeni da biste pristupili ovoj stranici.",
        "changeemail-oldemail": "Trenutna e-adresa:",
        "changeemail-none": "(ništa)",
        "changeemail-password": "Vaša lozinka:",
        "changeemail-submit": "Promeni",
-       "changeemail-cancel": "Otkaži",
        "changeemail-throttled": "Previše puta ste pokušali da se prijavite.\nMolimo vas da sačekate $1 pre nego što pokušate ponovo.",
        "resettokens": "Resetovanje žetona",
        "resettokens-no-tokens": "Nema žetona za resetovanje.",
        "searchall": "sve",
        "showingresults": "Ispod {{PLURAL:$1|je prikazan <strong>1</strong> rezultat|su prikazana <strong>$1</strong> rezultata|je prikazano <strong>$1</strong> rezultata}} počev od broja <strong>$2</strong>.",
        "showingresultsinrange": "Ispod {{PLURAL:$1|je prikazan <strong>1</strong> rezultat|su prikazana <strong>$1</strong> rezultata|je prikazano <strong>$1</strong> rezultata}}, u rasponu od <strong>$2</strong> do <strong>$3</strong>.",
-       "showingresultsheader": "{{PLURAL:$5|1=Rezultat '''$1''' od '''$3'''|Rezultata '''$1 – $2''' od '''$3'''}} za '''$4'''",
+       "search-showingresults": "{{PLURAL:$4|Rezultat <strong>$1</strong> od <strong>$3</strong>|Rezultata <strong>$1 – $2</strong> od <strong>$3</strong>}}",
        "search-nonefound": "Nema poklapanja.",
        "powersearch-legend": "Napredna pretraga",
        "powersearch-ns": "Traži u sledećim imenskim prostorima:",
        "undeleteinvert": "Obrni izbor",
        "undeletecomment": "Razlog:",
        "undeletedrevisions": "{{PLURAL:$1|Izmena je vraćena|$1 izmene su vraćene|$1 izmena je vraćeno}}",
-       "undeletedrevisions-files": "$1 {{PLURAL:$1|izmena|izmene|izmena}} i $2 {{PLURAL:$2|datoteka|datoteke|datoteka}} je vraćeno",
+       "undeletedrevisions-files": "$1 {{PLURAL:$1|1 izmena|izmene|izmena}} i $2 {{PLURAL:$2|1 datoteka je vraćena|datoteke su vraćene|datoteka je vraćeno}}",
        "undeletedfiles": "{{PLURAL:$1|Datoteka je vraćena|$1 datoteke su vraćene|$1 datoteka je vraćeno}}",
        "cannotundelete": "Vraćanje nije uspelo:\n$1",
        "undeletedpage": "'''Stranica $1 je vraćena'''\n\nPogledajte [[Special:Log/delete|istoriju brisanja]] za zapise o skorašnjim brisanjima i vraćanjima.",
        "unblockiptext": "Koristite obrazac ispod da biste vratili pravo pisanja blokiranoj IP adresi ili korisničkom imenu.",
        "ipusubmit": "Ukloni ovu blokadu",
        "unblocked": "[[User:$1|$1]] je deblokiran",
-       "unblocked-range": "$1 je {{GENDER:$1|deblokiran|deblokirana|deblokiran}}",
+       "unblocked-range": "$1 je deblokiran",
        "unblocked-id": "Blokiranje $1 je uklonjeno",
+       "unblocked-ip": "[[Special:Contributions/$1|$1]] je deblokiran.",
        "blocklist": "Blokirani korisnici",
        "ipblocklist": "Blokirani korisnici",
        "ipblocklist-legend": "Pronalaženje blokiranog korisnika",
        "table_pager_limit_submit": "Idi",
        "table_pager_empty": "Nema rezultata",
        "autosumm-blank": "Uklonjen celokupan sadržaj stranice",
-       "autosumm-replace": "Zamena sadržaja stranice sa „$1“",
+       "autosumm-replace": "Zamenjen sadržaj stranice sa „$1“",
        "autoredircomment": "Preusmerenje na [[$1]]",
        "autosumm-new": "Nova stranica: $1",
        "autosumm-newblank": "Napravljena prazna stranica",
        "watchlistedit-clear-titles": "Naslovi:",
        "watchlistedit-clear-submit": "Isprazni spisak nadgledanja (Ovo je trajno!)",
        "watchlistedit-clear-done": "Vaš spisak nadgledanja je ispražnjen.",
-       "watchlistedit-clear-removed": "{{PLURAL:$1|1 naslov je uklonjen|$1 naslova je uklonjeno}}:",
+       "watchlistedit-clear-removed": "{{PLURAL:$1|1 naslov je uklonjen|$1 naslova su uklonjena|$1 naslova je uklonjeno}}:",
        "watchlisttools-clear": "isprazni spisak nadgledanja",
        "watchlisttools-view": "prikaži srodne izmene",
        "watchlisttools-edit": "prikaži i uredi spisak nadgledanja",
        "sqlite-no-fts": "$1 bez podrške pretrage celog teksta",
        "logentry-delete-delete": "$1 je {{GENDER:$2|obrisao|obrisala}} stranicu $3",
        "logentry-delete-restore": "$1 je {{GENDER:$2|vratio|vratila}} stranicu $3",
-       "logentry-delete-event": "$1 je {{GENDER:$2|promenio|promenila}} vidljivost {{PLURAL:$5|događaja|$5 daogađaja}} u dnevniku na $3: $4",
-       "logentry-delete-revision": "$1 je {{GENDER:$2|promenio|promenila}} vidljivost $5 {{PLURAL:$5|izmene|izmene|izmena}} na stranici $3: $4",
+       "logentry-delete-event": "$1 je {{GENDER:$2|promenio|promenila}} vidljivost {{PLURAL:$5|1=događaja|$5 događaja|$5 događaja}} u dnevniku na $3: $4",
+       "logentry-delete-revision": "$1 je {{GENDER:$2|promenio|promenila}} vidljivost $5 {{PLURAL:$5|1=izmene|izmene|izmena}} na stranici $3: $4",
        "logentry-delete-event-legacy": "$1 je {{GENDER:$2|promenio|promenila}} vidljivost događaja u dnevniku na $3",
        "logentry-delete-revision-legacy": "$1 je {{GENDER:$2|promenio|promenila}} vidljivost izmena na stranici $3",
        "logentry-suppress-delete": "$1 je {{GENDER:$2|potisnuo|potisnula}} stranicu $3",
-       "logentry-suppress-event": "$1 je tajno {{GENDER:$2|promenio|promenila}} vidljivost {{PLURAL:$5|događaja|$5 događaja}} u dnevniku na $3: $4",
+       "logentry-suppress-event": "$1 je tajno {{GENDER:$2|promenio|promenila}} vidljivost {{PLURAL:$5|1=događaja|$5 događaja|$5 događaja}} u dnevniku na $3: $4",
        "logentry-suppress-revision": "$1 je tajno {{GENDER:$2|promenio|promenila}} vidljivost {{PLURAL:$5|izmene|$5 izmena}} na stranici $3: $4",
        "logentry-suppress-event-legacy": "$1 је tajno {{GENDER:$2|promenio|promenila}} vidljivost događaj u dnevniku na $3",
        "logentry-suppress-revision-legacy": "$1 je tajno {{GENDER:$2|promenio|promenila}} vidljivost izmena na stranici $3",
        "logentry-rights-rights-legacy": "$1 je {{GENDER:$2|promenio|promenila}} čalnstvo grupe za $3",
        "logentry-rights-autopromote": "$1 je automatski {{GENDER:$1|unapređen|unapređena}} iz $4 u $5",
        "rightsnone": "(nema)",
+       "revdelete-summary": "opis izmene",
        "feedback-bugornote": "Ako ste spremni da detaljno opišete tehnički problem, onda [$1 prijavite grešku].\nU suprotnom, poslužite se jednostavnim obrascem ispod. Vaš komentar će stajati na stranici „[$3 $2]“, zajedno s korisničkim imenom i pregledačem koji koristite.",
        "feedback-subject": "Naslov:",
        "feedback-message": "Poruka:",
index 0002de3..3d006ec 100644 (file)
@@ -20,9 +20,9 @@
        "tog-extendwatchlist": "Legaan béréndélan ngarah sakabéh parobahanana kaawaskeun",
        "tog-usenewrc": "Parobahan grup dumasar kaca dina béréndélan anyar robah jeung awaskeuneun (maké JavaScript)",
        "tog-numberheadings": "Nomeran lulugu sacara otomatis",
-       "tog-showtoolbar": "Témbongkeun ''toolbar'' édit (JavaScript)",
-       "tog-editondblclick": "Édit kaca ku klik ganda (JavaScript)",
-       "tog-editsectiononrightclick": "Fungsikeun ngédit sub-bagean kalawan klik-katuhu dina judul bagean (JavaScript)",
+       "tog-showtoolbar": "Témbongkeun tulbar édit",
+       "tog-editondblclick": "Édit kaca ku klik ganda",
+       "tog-editsectiononrightclick": "Fungsikeun ngédit sub-bagean kalawan klik-katuhu dina judul bagéan",
        "tog-watchcreations": "Tambahkeun kaca-kaca jieunan kuring jeung berkas muatan kuring kana awaskeuneun",
        "tog-watchdefault": "Tambahkeun kaca jeung berkas anu diédit ku kuring kana awaskeuneun",
        "tog-watchmoves": "Tambahkeun kaca jeung berkas anu dipindahkeun ka awaskeuneun",
@@ -37,7 +37,7 @@
        "tog-shownumberswatching": "Témbongkeun jumlah nu ngawaskeun",
        "tog-oldsig": "Paraf nu geus aya:",
        "tog-fancysig": "Témbongkeun paraf salaku wikitext (tanpa tumbu otomatis)",
-       "tog-uselivepreview": "Paké pramidang saharita (JavaScript) (ujicoba)",
+       "tog-uselivepreview": "Paké pramidang saharita (ujicoba)",
        "tog-forceeditsummary": "Mun kotak ringkesan éditan masih kosong, béjaan!",
        "tog-watchlisthideown": "Sumputkeun éditan kuring dina daptar awaskeuneun",
        "tog-watchlisthidebots": "Sumputkeun éditan bot dina daptar awaskeuneun",
@@ -50,6 +50,7 @@
        "tog-showhiddencats": "Témbongkeun kategori nyumput",
        "tog-norollbackdiff": "Liwat béda sanggeus malikkeun révisi",
        "tog-useeditwarning": "Béjaan kuring lamun ninggalkeun kaca édit anu parobahanana can disimpen",
+       "tog-prefershttps": "Salawasna paké sambungan aman nalika asup log",
        "underline-always": "Salawasna",
        "underline-never": "Ulah",
        "underline-default": "Luyu jeung buhunna panyungsi",
@@ -65,7 +66,7 @@
        "thursday": "Kemis",
        "friday": "Jumaah",
        "saturday": "Saptu",
-       "sun": "Min",
+       "sun": "Ming",
        "mon": "Sen",
        "tue": "Sal",
        "wed": "Reb",
        "oct": "Okt",
        "nov": "Nop",
        "dec": "Dés",
+       "january-date": "$1 Januari",
+       "february-date": "$1 Pébruari",
+       "march-date": "$1 Maret",
+       "april-date": "$1 April",
+       "may-date": "$1 Méi",
+       "june-date": "$1 Juni",
+       "july-date": "$1 Juli",
+       "august-date": "$1 Agustus",
+       "september-date": "$1 Séptémber",
+       "october-date": "$1 Oktober",
+       "november-date": "$1 Nopémber",
+       "december-date": "$1 Désémber",
        "pagecategories": "{{PLURAL:$1|Kategori|Kategori}}",
        "category_header": "Artikel-artikel na kategori \"$1\"",
        "subcategories": "Subkategori",
        "newwindow": "(buka na jandéla anyar)",
        "cancel": "Bolay",
        "moredotdotdot": "Deui...",
-       "mypage": "Kaca kuring",
+       "morenotlisted": "Ieu béréndélan tacan lengkep.",
+       "mypage": "Kaca",
        "mytalk": "Obrolan",
        "anontalk": "Obrolan pikeun IP ieu",
        "navigation": "Pituduh",
        "actions": "Peta",
        "namespaces": "Spasi ngaran",
        "variants": "Varian",
+       "navigation-heading": "Ménu navigasi",
        "errorpagetitle": "Kasalahan",
        "returnto": "Balik deui ka $1.",
        "tagline": "Ti {{SITENAME}}",
        "permalink": "Tutumbu permanén",
        "print": "Citak",
        "view": "Tempo",
+       "view-foreign": "Tempo di $1",
        "edit": "Édit",
+       "edit-local": "Edit déskripsi lokal",
        "create": "Jieun",
+       "create-local": "Tambah déskripsi lokal",
        "editthispage": "Édit kaca ieu",
        "create-this-page": "Jieun kaca ieu",
        "delete": "Hapus",
        "deletethispage": "Hapus kaca ieu",
+       "undeletethispage": "Bolaykeun ngahapus ieu kaca",
        "undelete_short": "Bolaykeun ngahapus {{PLURAL:$1|hiji éditan|$1 éditan}}",
        "viewdeleted_short": "Témbongkeun {{PLURAL:$1|hiji éditan nu dihapus|$1 éditan nu dihapus}}",
        "protect": "Konci",
        "articlepage": "Témbongkeun kaca eusi",
        "talk": "Sawala",
        "views": "Témbongan",
-       "toolbox": "Kotak parabot",
+       "toolbox": "Parabot",
        "userpage": "Témbongkeun kaca pamaké",
        "projectpage": "Témbongkeun kaca proyék",
        "imagepage": "Tempo kaca gambar",
        "otherlanguages": "Dina séjén basa",
        "redirectedfrom": "(dipindahkeun ti $1)",
        "redirectpagesub": "Kaca alihan",
+       "redirectto": "Alihkeun ka:",
        "lastmodifiedat": "Kaca ieu panungtungan dirobah $2, $1.",
        "viewcount": "Kaca ieu geus dibuka {{PLURAL:$1|sakali|$1 kali}}.<br />",
        "protectedpage": "Kaca nu dikonci",
        "ok": "Heug",
        "retrievedfrom": "Disalin ti \"$1\"",
        "youhavenewmessages": "Anjeun boga $1 ($2).",
+       "youhavenewmessagesfromusers": "{{PLURAL:$4|Anjeun boga}} $1 ti {{PLURAL:$3|pamaké séjén|$3 pamaké}} ($2).",
+       "youhavenewmessagesmanyusers": "Anjeun boga $1 ti pamaké lian ($2).",
+       "newmessageslinkplural": "{{PLURAL:$1|obrolan anyar|obrolan anyar}}",
+       "newmessagesdifflinkplural": "{{PLURAL:$1|parobahan|999=parobahan}} panungtung",
        "youhavenewmessagesmulti": "Anjeun boga talatah anyar di $1",
        "editsection": "édit",
        "editold": "édit",
        "hidetoc": "sumputkeun",
        "collapsible-collapse": "Tilepkeun",
        "collapsible-expand": "Amparkeun",
+       "confirmable-confirm": "{{GENDER:$1|Anjeun}} geus yakin?",
+       "confirmable-yes": "Enya",
+       "confirmable-no": "Henteu",
        "thisisdeleted": "Témbongkeun atawa simpen deui $1?",
        "viewdeleted": "Témbongkeun $1?",
        "restorelink": "$1 {{PLURAL:$1|éditan|éditan}} dihapus",
        "nospecialpagetext": "<strong>Anjeun ménta kaca husus nu teu dipikawanoh.</strong>\nKaca husus anu bener bisa ditempo béréndélanana dina [[Special:SpecialPages|{{int:specialpages}}]].",
        "error": "Kasalahan",
        "databaseerror": "Kasalahan gudang data",
+       "databaseerror-query": "Kueri: $1",
+       "databaseerror-function": "Fungsi: $1",
+       "databaseerror-error": "Eror: $1",
        "laggedslavemode": "Awas: kandungan kaca bisa baé teu mutahir.",
        "readonly": "pangkalan data dikonci",
        "enterlockreason": "Asupkeun alesan pikeun ngonci, kaasup kira-kira iraha konci ieu rék dibuka",
        "viewsource-title": "Témbongkeun sumber pikeun $1",
        "actionthrottled": "Peta diwates",
        "actionthrottledtext": "Salaku tetengger anti-spam, anjeun teu diwenangkeun loba kitu peta dina jangka waktu anu sakitu heureutna. Mangga lajengkeun deui sanggeus sababaraha menit ka payun.",
-       "protectedpagetext": "Ieu kaca dikonci ngarah teu bisa dirobah.",
+       "protectedpagetext": "Ieu kaca dijaga tina éditan atawa peta lianna.",
        "viewsourcetext": "Anjeun bisa némbongkeun sarta nyalin sumber ieu kaca:",
        "viewyourtext": "Anjeun bisa némbongkeun sarta nyalin sumber '''éditan anjeun''' ka ieu kaca:",
        "protectedinterface": "Kaca ieu eusina teks antarmuka pikeun dipaké ku pakakas beyé sarta geus dikunci pikeun ngahindar ti kasalahan.",
        "namespaceprotected": "Anjeun teu ngabogaan hak pikeun ngédit kaca di ngaranspasi '''$1'''.",
        "customcssprotected": "Anjeun teu teu diwenangkeun pikeun ngédit ieu kaca CSS, sabab ngandung setélan pribadi kontributor séjén.",
        "customjsprotected": "Anjeun teu teu diwenangkeun pikeun ngédit ieu kaca JavaScript, sabab ngandung setélan pribadi kontributor séjén.",
+       "mycustomcssprotected": "Anjeun teu boga kawenangan pikeun ngédit kaca CSS ieu.",
+       "mycustomjsprotected": "Anjeun teu boga kawenangan pikeun ngédit kaca JavaScript ieu.",
+       "myprivateinfoprotected": "Anjeun teu boga kawenangan pikeun ngédit émbaran pribadi anjeun.",
+       "mypreferencesprotected": "Anjeun teu boga kawenangan pikeun ngédit préferénsi anjeun.",
        "ns-specialprotected": "Kaca dina ngaranspasi {{ns:special}} teu bisa di édit.",
        "titleprotected": "Ieu judul dikonci ku [[User:$1|$1]] kalawan alesan ''$2''.",
+       "filereadonlyerror": "Berkas \"$1\" teu bisa dirobah kusabab répositori \"$2\" keur dina mode ukur-maca.\n\nKuncén anu ngonci méré alesan: \"$3\".",
+       "exception-nologin": "Henteu asup log",
+       "exception-nologin-text": "Mangga asup log pikeun bisa asup atawa ngarobah ieu kaca.",
        "virus-badscanner": "Kasalahan konfigurasi: panyekén virus teu dipikawanoh: ''$1''",
        "virus-scanfailed": "nyekén gagal (kode $1)",
        "virus-unknownscanner": "antivirus teu dipikawanoh:",
        "logouttext": "'''Anjeun ayeuna geus kaluar log.'''\n\nAnjeun bisa tetep migunakeun {{SITENAME}} bari anonim, atawa bisa <span class='plainlinks'>[$1 asup log deui]</span> salaku pamaké nu sarua atawa nu séjén deui.\nMangkahadé, sababaraha kaca bakal tetep némbongkeun saolah-olah anjeun asup log kénéh nepi ka anjeun ngosongkeun ''cache'' panyungsi anjeun.",
+       "welcomeuser": "Bagéa, $1!",
+       "welcomecreation-msg": "Akun anjeun geus dijieun.\nLamun minat, Anjeun bisa ngarobah [[Special:Preferences|préferénsi]] {{SITENAME}}.",
        "yourname": "Sandiasma:",
+       "userlogin-yourname": "Sandiasma",
+       "userlogin-yourname-ph": "Asupkeun sandiasma anjeun",
+       "createacct-another-username-ph": "Asupkeun sandiasma",
        "yourpassword": "Sandi anjeun",
+       "userlogin-yourpassword": "Kecap sandi",
+       "userlogin-yourpassword-ph": "Asupkeun kecap sandi anjeun",
+       "createacct-yourpassword-ph": "Asupkeun kecap sandi",
        "yourpasswordagain": "Ketik deui sandi anjeun",
+       "createacct-yourpasswordagain": "Konfirmasi kecap sandi",
+       "createacct-yourpasswordagain-ph": "Asupkeun deui kecap sandi",
        "remembermypassword": "Apalkeun login kuring dina ieu komputer (pikeun paling lila $1 {{PLURAL:$1|poé|poé}})",
+       "userlogin-signwithsecure": "Paké sambungan aman",
        "yourdomainname": "Domain anjeun",
+       "password-change-forbidden": "Anjeun teu bisa ngarobah kecap sandi dina ieu wiki.",
        "externaldberror": "Aya kasalahan dina pangkalan data oténtikasi luar, atawa anjeun mémang teu diwenangkeun pikeun ngaropéa rekening luar anjeun.",
        "login": "Asup log",
        "nav-login-createaccount": "Nyieun akun/asup log",
        "logout": "Kaluar log",
        "userlogout": "Kaluar log",
        "notloggedin": "Can asup log",
+       "userlogin-noaccount": "Teu boga akun?",
+       "userlogin-joinproject": "Ngiluan {{SITENAME}}",
        "nologin": "Teu boga akun? '''$1'''.",
        "nologinlink": "Jieun akun",
        "createaccount": "Jieun akun",
        "gotaccount": "Geus boga akun? '''$1'''.",
        "gotaccountlink": "Asup log",
        "userlogin-resetlink": "Poho akun sorangan?",
-       "createaccountmail": "ku surélék",
+       "userlogin-resetpassword-link": "Poho kecap sandi?",
+       "userlogin-helplink2": "Pitulung asup log",
+       "createacct-emailrequired": "Alamat surélék:",
+       "createacct-emailoptional": "Alamat surélék (teu wajib)",
+       "createacct-email-ph": "Asupkeun alamat surélék anjeun",
+       "createacct-another-email-ph": "Asupkeun alamat surélék",
+       "createaccountmail": "Paké kecap sandi acak sarta kirim ka alamat surélék",
+       "createacct-realname": "Ngaran asli (teu wajib)",
        "createaccountreason": "Alesan:",
+       "createacct-reason": "Alesan",
+       "createacct-reason-ph": "Naha bet nyieun akun séjén",
+       "createacct-captcha": "Pamariksaan kaamanan",
+       "createacct-imgcaptcha-ph": "Asupkeun téks anu kabaca di luhur",
+       "createacct-submit": "Jieun akun anjeun",
+       "createacct-another-submit": "Jieun akun séjén",
+       "createacct-benefit-heading": "{{SITENAME}} téh dijieun ku jalma-jalma siga anjeun.",
+       "createacct-benefit-body1": "{{PLURAL:$1|édit|édit}}",
+       "createacct-benefit-body2": "{{PLURAL:$1|kaca|kaca}}",
+       "createacct-benefit-body3": "{{PLURAL:$1|kontributor|kontributor}} panungtung",
        "badretype": "Sandi nu diasupkeun teu cocog.",
        "userexists": "Sandiasma nu diasupkeun geus aya nu maké.\nMangga pilih sandiasma nu séjén.",
        "loginerror": "Kasalahan asup log",
        "passwordtooshort": "Sandina kudu diwangun ku sahanteuna {{PLURAL:$1|1 karakter|$1 karakter}}.",
        "password-name-match": "Sandi anjeun kudu béda ti landihan.",
        "password-login-forbidden": "Sandiasma jeung sandina teu bisa dipaké.",
-       "mailmypassword": "Kirim sandi anyar ngaliwatan surélék",
+       "mailmypassword": "Setél ulang kecap sandi",
        "passwordremindertitle": "Pangéling sandi ti {{SITENAME}}",
        "passwordremindertext": "Aya (jigana anjeun ti alamat IP $1) nu ménta sangkan dikiriman sandi anyar asup log {{SITENAME}} ($4). Saheulaanan, sandi anyar keur pamaké \"$2\" ayeuna diganti jadi \"$3\". Anjeun kudu asup log sarta ngarobah sandi anjeun ayeuna. Ieu sandi bakal kadaluwarsa dina {{PLURAL:$5|sapoé|$5 poé}}.\n\nMun pamundut ieu datang ti nu séjén, atawa mun anjeun geus inget sandi anu tadina poho, sarta teu hayang ngarobah sandina, anjeun teu kudu ngawaro kana ieu surat sarta bisa tetep maké sandi anu ti heula.",
        "noemail": "Teu aya alamat surélék karékam pikeun \"$1\".",
        "noemailcreate": "Anjeun kudu nyadiakeun alamat surélék anu bener",
        "passwordsent": "Sandi anyar geus dikirim ka alamat surélék nu kadaptar pikeun \"$1\". Mangga asup log deui satutasna katarima.",
        "blocked-mailpassword": "Alamat IP anjeun dipeungpeuk, moal bisa ngédit, and so\nis not allowed to use the password recovery function to prevent abuse.",
-       "eauthentsent": "Surélék konfirmasi geus dikirim ka alamat bieu. Méméh aya surat séjén asup ka rekeningna, anjeun kudu nuturkeun pituduh na surélékna pikeun ngonfirmasi yén rekening éta téh bener nu anjeun.",
+       "eauthentsent": "Surélék konfirmasi geus dikirim ka alamat bieu.\nMéméh aya surat séjén asup ka akunna, anjeun kudu nuturkeun pituduh dina surélékna pikeun mastikeun yén akun éta téh bener boga anjeun.",
        "throttled-mailpassword": "Hiji panginget kecap sandi geus dikirimkeun dina {{PLURAL:$1|jam|$1 jam}} pamungkas.\nPikeun ngahindar disalahgunakeun, ngan hiji kecap sandi anu baris dikirimkeun saban {{PLURAL:$1|jam|$1 jam}}.",
        "mailerror": "Kasalahan ngirim surat: $1",
        "acct_creation_throttle_hit": "Punten,pamaké alamat IP anjeun geus nyieun {{PLURAL:$1|1 rekening|$1 rekening}} dina sapoé ieu. mangrupa jumlah nu di idinan dina sapoé.\nanjeun teu bisa nyieun deui samentara waktu.",
-       "emailauthenticated": "Alamat surélék anjeun geus dioténtikasi dina $3, $2.",
-       "emailnotauthenticated": "Alamat surélék anjeun <strong>can dioténtikasi</strong>. Moal aya surélék nu bakal dikirim pikeun fitur-fitur di handap ieu.",
+       "emailauthenticated": "Alamat surélék anjeun geus dikonfirmasi $2 tabuh $3.",
+       "emailnotauthenticated": "Alamat surélék anjeun can dikonfirmasi.\nMoal aya surélék nu bakal dikirim pikeun fitur-fitur di handap ieu.",
        "noemailprefs": "Teu aya alamat surélék, fitur di handap moal bisa jalan.",
        "emailconfirmlink": "Konfirmasi alamat surélék anjeun",
        "invalidemailaddress": "Alamat surélék teu bisa ditarima sabab formatna salah.\nMangga lebetkeun alamat nu formatna bener atawa kosongkeun baé.",
        "cannotchangeemail": "Alamat surat-é akun hanteu bisa dirobah di ieu wiki.",
+       "emaildisabled": "Ieu loka teu bisa ngirim surélék.",
        "accountcreated": "Rekening geus dijieun.",
        "accountcreatedtext": "Rekening pamaké pikeun $1 geus dijieun.",
        "createaccount-title": "Nyieun rekening keur {{SITENAME}}",
        "login-abort-generic": "Login gagal - Dibolaykeun",
        "loginlanguagelabel": "Basa: $1",
        "suspicious-userlogout": "Pamundut anjeun pikeun kaluar log ditolak ku sabab sigana dikirim ku pangaprak buntu atawa ''cache'' proxi.",
+       "pt-login": "Asup log",
+       "pt-login-button": "Asup log",
+       "pt-createaccount": "Jieun akun",
+       "pt-userlogout": "Kaluar log",
        "php-mail-error-unknown": "Kasalahan nu teu kanyahoan dina fungsi PHP surélék().",
        "user-mail-no-addy": "Nyobaan ngirim surélék tanpa alamat.",
        "changepassword": "Robah sandi",
        "passwordreset-emailelement": "Sandiasma: $1\nSandi saheulaanan: $2",
        "passwordreset-emailsent": "Surélék pangéling geus dikirim.",
        "changeemail": "Ganti alamat surélék",
-       "changeemail-header": "Ganti alamat surélék akun",
        "changeemail-text": "Lengkepan ieu formulir pikeun ngaganti alamat surélék. Anjeun bakal kudu ngasupkeun sandi pikeun ngonfirmasi ieu parobahan.",
        "changeemail-no-info": "Anjeun kudu asup log pikeun bisa muka ieu kaca sacara langsung.",
        "changeemail-oldemail": "Alamat surélék ayeuna:",
        "changeemail-newemail": "Alamat surélék anyar:",
        "changeemail-none": "(euweuh)",
+       "changeemail-password": "Kecap sandi {{SITENAME}} Anjeun:",
        "changeemail-submit": "Ganti surélék",
-       "changeemail-cancel": "Bolay",
+       "resettokens-tokens": "Token:",
        "bold_sample": "Téks kandel",
        "bold_tip": "Téks kandel",
        "italic_sample": "Tulisan déngdék",
        "token_suffix_mismatch": "'''Éditan anjeun ditolak sabab aplikasi klien Anjeun ngarobah karakter tanda baca dina éditan. Éditan kasebut ditolak keur nyegah kasalahan dina artikel téks. Hal ieu kadang-kadang kajadian lamun Anjeun maké proksi anonim basis web nu masalah.'''",
        "edit_form_incomplete": "'''Sawatara bagian tina wangun éditan teu nepi ka sérver; pariksa deui naha éditan Anjeun tetep gembleng sarta cobaan deui.'''",
        "editing": "Ngédit $1",
+       "creating": "Nyieun $1",
        "editingsection": "Ngédit $1 (bagian)",
        "editingcomment": "Ngédit $1 (bagian anyar)",
        "editconflict": "Konflik éditan: $1",
        "edit-gone-missing": "Kaca teu bisa dianyarkeun,\nsigana kusabab geus dihapus.",
        "edit-conflict": "Éditan bantrok",
        "edit-no-change": "Éditan anjeun teu diwaro, kusabab taya nu robah dina tulisanana.",
+       "postedit-confirmation-saved": "Éditan anjeun tos disimpen.",
        "edit-already-exists": "Teu bisa nyieun kaca anyar.\nArtikelna geus aya.",
+       "defaultmessagetext": "Téks ti dituna",
+       "invalid-content-data": "Data eusi henteu valid",
+       "content-not-allowed-here": "Eusi \"$1\" teu diijinan di kaca [[$2]]",
+       "content-model-wikitext": "wikitéks",
+       "content-model-text": "téks polos",
+       "content-model-javascript": "JavaScript",
+       "content-model-css": "CSS",
        "expensive-parserfunction-warning": "Inget!: Kaca ieu ngandung réa teuing maké fungsi ''parser''.\n\nAyeuna aya {{PLURAL:$1|$1 panggilan|$1 panggilan}}, sakuduna kurang ti $2 {{PLURAL:$2|panggilan|panggilan}}.",
        "expensive-parserfunction-category": "Kaca kalawan réa teuing maké fungsi parser",
        "post-expand-template-inclusion-warning": "Inget! : Ukuran citakan anu dipaké badag teuing.\nSawatara citakan baris teu diasupkeun.",
        "histlegend": "Pilihan béda: tandaan wadah buleud vérsina pikeun ngabandingkeun sarta pencét énter atawa tombol di handap.<br />\nKaterangan: (kiw) = bédana jeung vérsi kiwari,\n(ahir) = bédana jeung vérsi nu harita, m = éditan minor.",
        "history-fieldset-title": "Sungsi jujutan",
        "history-show-deleted": "Ukur nu dihapus",
-       "histfirst": "Pangheubeulna",
-       "histlast": "Pangahirna",
+       "histfirst": "pangheubeulna",
+       "histlast": "panganyarna",
        "historysize": "($1 {{PLURAL:$1|bit|bit}})",
        "historyempty": "(kosong)",
        "history-feed-title": "Sajarah révisi",
        "revdelete-confirm": "Mangga geura konfirmasi yen Anjeun gaduh maksad pikeun ngalakukeun hal ieu, paham kana konsekwensina, tur nu dilakukeun ieu teh luyu sareng [[{{MediaWiki:Policy-url}}|kawijakanana]]",
        "revdelete-suppress-text": "Nyumputkeun revisi '''ukur''' bisa digunakeun keur kasus-kasus di handap ieu:\n* Informasi nu boga potensi mitenah\n* Informasi pribadi nu teu pantes\n*: ''alamat imah katut nomer telepon, nomer kartu identitas, jeung lian-liana.''",
        "revdelete-legend": "Setél réstriksi révisi:",
-       "revdelete-hide-text": "Sumputkeun téks révisi",
+       "revdelete-hide-text": "Téks révisi",
        "revdelete-hide-image": "Sumputkeun eusi gambar",
        "revdelete-hide-name": "Sumputkeun lampah sarta udagan",
        "revdelete-hide-comment": "Sumputkeun koméntar ngédit",
        "revdelete-hide-user": "Sumputkeun ngaran pamaké/IP éditor",
        "revdelete-hide-restricted": "Sumputkeun data boh ti kuncén atawa nu séjénna",
        "revdelete-radio-same": "(ulah dirobah)",
-       "revdelete-radio-set": "Enya",
-       "revdelete-radio-unset": "Ulah",
+       "revdelete-radio-set": "Nyumput",
+       "revdelete-radio-unset": "Némbongan",
        "revdelete-suppress": "Sumputkeun ogé ti kuncén",
        "revdelete-unsuppress": "Hapus watesan kana révisi anu geus dipulangkeun",
        "revdelete-log": "Alesan:",
        "revdelete-submit": "Larapkeun kana {{PLURAL:$1|révisi|révisi}} nu dipilih",
-       "revdelete-success": "Pangaturan nyumpukeun révisi junun dilarapkeun.",
+       "revdelete-success": "<strong>Visibilitas révisi geus dimutahirkeun.</strong>",
        "revdelete-failure": "'''Visibilitas révisi teu bisa diapdét:'''\n$1",
        "logdelete-success": "Log pangatur nyumputkeun junun dilarapkeun.",
        "logdelete-failure": "'''Visibilitas log teu bisa disét:'''\n$1",
        "search-section": "(bagean $1)",
        "search-suggest": "Meureun maksud Anjeun nyaéta: $1",
        "search-interwiki-caption": "Proyék sawargi",
-       "search-interwiki-default": "$1 hasil:",
+       "search-interwiki-default": "Hasil ti $1:",
        "search-interwiki-more": "(saterusna)",
        "search-relatedarticle": "Patula-patali",
        "searchrelated": "patula-patali",
        "searchall": "sadayana",
        "showingresults": "Di handap ieu némbongkeun {{PLURAL:$1|'''1''' hasil|'''$1''' hasil}}, dimimitianku  #'''$2'''.",
-       "showingresultsheader": "{{PLURAL:$5|Hasil '''$1''' ti '''$3'''|Hasil '''$1 - $2''' ti '''$3'''}} pikeun '''$4'''",
        "search-nonefound": "Euweuh hasil nu cocog jeung kueri.",
        "powersearch-legend": "Panéangan tuluy",
        "powersearch-ns": "Téangan di ngaranspasi:",
        "skin-preview": "Pramidang",
        "datedefault": "Tanpa préferénsi",
        "prefs-labs": "Fitur Labs",
+       "prefs-user-pages": "Kaca pamaké",
        "prefs-personal": "Data pamaké",
        "prefs-rc": "Panémbong robahan anyar jeung tukung",
        "prefs-watchlist": "Awaskeuneun",
        "prefs-watchlist-days": "Jumlah poé anu ditémbongkeun dina daptar awaskeuneun:",
-       "prefs-watchlist-days-max": "Maximum $1 {{PLURAL:$1|day|days}}",
+       "prefs-watchlist-days-max": "Panglilana $1 {{PLURAL:$1|poé|poé}}",
        "prefs-watchlist-edits": "Jumlah parobahan maksimum nu ditémbongkeun dina daptar panjang awaskeuneun:",
        "prefs-watchlist-edits-max": "Panglobana: 1000",
        "prefs-misc": "Pangaturan rupa-rupa",
        "prefs-email": "Pilihan surélék",
        "prefs-rendering": "Pidangan",
        "saveprefs": "Simpen préferénsi",
-       "restoreprefs": "Larapkeun setélan buhun",
+       "restoreprefs": "Larapkeun setélan buhun (sakabéh bab)",
        "prefs-editing": "Ukuran kotak téks",
        "rows": "Baris",
        "columns": "Kolom",
        "timezoneregion-indian": "Samudra Indonésia",
        "timezoneregion-pacific": "Samudra Pasifik",
        "allowemail": "Buka koropak pikeun nampa surélék ti nu séjén",
-       "prefs-searchoptions": "Piliheun Panéangan",
+       "prefs-searchoptions": "Paluruh",
        "prefs-namespaces": "Ngaranspasi",
        "default": "ti dituna",
        "prefs-files": "Koropak",
        "prefs-reset-intro": "Anjeun bisa maké ieu kaca pikeun mulangkeun préferénsi anjeun ka nu baku.\nMun geus anggeus teu bisa dibolaykeun.",
        "prefs-emailconfirm-label": "Konfirmasi surélék:",
        "youremail": "Surélék:",
-       "username": "Landihan:",
-       "prefs-memberingroups": "Anggota {{PLURAL:$1|jumplukan|jumplukan}}:",
+       "username": "{{GENDER:$1|Sandiasma}}:",
+       "prefs-memberingroups": "{{GENDER:$2|Anggota}} {{PLURAL:$1|kelompok|kelompok}}:",
        "prefs-registration": "Waktu daptar:",
        "yourrealname": "Ngaran anjeun*",
        "yourlanguage": "Basa antarbeungeut",
        "badsig": "Parafna teu valid; pariksa tag HTML-na geura.",
        "badsiglength": "Tawis leungeun panjang teuing. Kuduna kurang ti $1 {{PLURAL:$1|karaktér|karaktér}}.",
        "yourgender": "Jenis kelamin:",
-       "gender-unknown": "Teu nyebutkeun",
-       "gender-male": "Lalaki",
-       "gender-female": "Awéwé",
+       "gender-unknown": "Moal béja-béja",
+       "gender-male": "Manéhna ngédit kaca wiki",
+       "gender-female": "Manéhna ngédit kaca wiki",
        "email": "Surélék",
        "prefs-help-realname": "* Ngaran asli (pilihan): mun anjeun milih ngeusian, bakal dipaké pikeun nandaan kontribusi anjeun.",
        "prefs-help-email": "Surélék sipatna pilihan, tapi diperlukeun pikeun nyetél ulang sandi lamun anjeun poho.",
        "prefs-signature": "Tandatangan",
        "prefs-dateformat": "Format titimangsa",
        "prefs-timeoffset": "Format waktu",
-       "prefs-advancedediting": "Pilihan lengkep",
+       "prefs-advancedediting": "Pilihan umum",
+       "prefs-editor": "Éditor",
+       "prefs-preview": "Pratayang",
        "prefs-advancedrc": "Pilihan lengkep",
        "prefs-advancedrendering": "Pilihan lengkep",
        "prefs-advancedsearchoptions": "Pilihan lengkep",
        "prefs-advancedwatchlist": "Pilihan lengkep",
        "prefs-displayrc": "Pilihan pidangan",
        "prefs-displaywatchlist": "Pilihan pidangan",
+       "prefs-tokenwatchlist": "Token",
        "prefs-diffs": "Béda",
        "email-address-validity-valid": "Alamat surélék sigana bener",
        "email-address-validity-invalid": "Asupkeun alamat ratron nu bener",
        "right-move": "Mindahkeun kaca",
        "right-move-subpages": "Pindahkeun kaca katut sakabéh subkacana",
        "right-move-rootuserpages": "Mindahkeun akar kaca kontributor",
+       "right-move-categorypages": "Pindahkeun kaca kategori",
        "right-movefile": "Mindahkeun berkas",
        "right-suppressredirect": "Henteu nyieun hiji alihan ti ngaran lila sabot mindahkeun kaca",
        "right-upload": "Muatkeun koropak",
        "right-browsearchive": "Sungsi kaca nu geus dihapus",
        "right-undelete": "Balikeun deui kaca",
        "right-suppressrevision": "Mariksa jeung mulangkeun révisi anu disumputkeun ti kuncén",
+       "right-viewsuppressed": "Témbongkeun révisi anu disumputkeun ti pamaké lianna",
        "right-suppressionlog": "Nempo log privat",
        "right-block": "Peungpeuk pamaké lain tina ngédit",
        "right-blockemail": "Halangan pamaké keur ngirim Surélék",
        "right-hideuser": "Peungpeuk pamaké, tong ditingalikeun ka nulain",
        "right-ipblock-exempt": "Narabas peungpeuk IP, peungpeuk-otomatis, jeung peungpeuk rentang",
        "right-proxyunbannable": "Abaikeun pengpeuk otomatis keur proxy",
-       "right-unblockself": "Muka peungpeuk ka dirina sorangan",
-       "right-protect": "Ngarobah hambalan konci jeung ngédit kaca anu dikonci",
-       "right-editprotected": "Ngédit kaca anu dikonci (tanpa ngarobah protéksi)",
+       "right-unblockself": "buka peungpeuk sorangan",
+       "right-protect": "Ngarobah hambalan protéksi jeung édit kaca anu dikonci",
+       "right-editprotected": "Edit kaca anu dikonci salaku \"{{int:protect-level-sysop}}\"",
        "right-editinterface": "Édit antarbenget pamaké",
        "right-editusercssjs": "Édit berkas CSS jeung JS pamaké séjén",
        "right-editusercss": "Édit berkas CSS pamaké séjén",
        "right-edituserjs": "Ngédit berkas JS pamaké séjén",
+       "right-viewmywatchlist": "Tempo awaskeuneun anjeun",
+       "right-viewmyprivateinfo": "Tempo data pribadi anjeun (alamat surélék, ngaran asli)",
+       "right-editmyprivateinfo": "Robah data pribadi anjeun (alamat surélék, ngaran asli)",
+       "right-editmyoptions": "Robah préferénsi anjeun",
        "right-import": "Ngimpor kaca ti wiki séjén",
        "right-importupload": "Ngimpor kaca tina hiji koropak nu dimuat",
        "right-patrol": "Nandaan éditan pamaké séjén minangka geus dipatroli",
        "action-createpage": "mitembeyan kaca anyar",
        "action-createtalk": "mitembeyan kaca obrolan",
        "action-createaccount": "nyieun rekening pamaké ieu",
+       "action-history": "tempo jujutan ieu kaca",
        "action-minoredit": "nandaan ieu éditan salaku minor",
        "action-move": "mindahkeun ieu kaca",
        "action-move-subpages": "mindahkeun ieu kaca katut bagian-bagianana",
        "action-move-rootuserpages": "mindahkeun kaca utama kontributor",
+       "action-move-categorypages": "pindahkeun kaca kategori",
        "action-movefile": "mindahkeun ieu berkas",
        "action-upload": "ngamuat ieu berkas",
        "action-reupload": "nimpah berkas nu geus aya ieu",
        "action-suppressionlog": "nempo ieu log pribadi",
        "action-block": "meungpeuk ieu pamaké tina ngédit",
        "action-protect": "ngarobah hambalan konci ieu kaca",
-       "action-import": "impor ieu kaca ti séjén wiki",
+       "action-import": "impor kaca ti wiki séjén",
        "action-patrol": "Nandaan éditan séjén minangka geus diroris",
        "action-autopatrol": "tandaan éditan anjeun salaku geus diroris",
        "action-unwatchedpages": "témbongkeun béréndélan kaca nu teu diawaskeun",
        "action-userrights-interwiki": "ngarobah hak pamaké di wiki lianna",
        "action-siteadmin": "ngonci atawa muka konci databés",
        "action-sendemail": "ngirim surélék",
+       "action-editmywatchlist": "robah awaskeuneun anjeun",
+       "action-viewmyprivateinfo": "tempo émbaran pribadi anjeun",
+       "action-editmyprivateinfo": "robah émbaran pribadi anjeun",
        "nchanges": "$1 {{PLURAL:$1|parobahan|parobahan}}",
+       "enhancedrc-history": "jujutan",
        "recentchanges": "Anyar robah",
        "recentchanges-legend": "Pilihan parobahan anyar",
        "recentchanges-summary": "Lacak parobahan ka wiki panganyarna na kaca ieu.",
        "recentchanges-label-minor": "Ieu éditan minor",
        "recentchanges-label-bot": "Ieu parobahan dijieun ku bot",
        "recentchanges-label-unpatrolled": "Ieu éditan can karoris",
+       "recentchanges-legend-heading": "'''Pedaran:'''",
        "recentchanges-legend-newpage": "$1 - kaca anyar",
        "rcnotefrom": "Di handap ieu parobahan saprak <b>$2</b> (nu ditémbongkeun nepi ka <b>$1</b>).",
        "rclistfrom": "Témbongkeun nu anyar robah nepi ka $3 $2",
        "rcshowhideminor": "$1 éditan minor",
+       "rcshowhideminor-show": "Témbongkeun",
+       "rcshowhideminor-hide": "Sumputkeun",
        "rcshowhidebots": "$1 bot",
-       "rcshowhideliu": "$1 kontributor nu asup log",
+       "rcshowhidebots-show": "Témbongkeun",
+       "rcshowhidebots-hide": "Sumputkeun",
+       "rcshowhideliu": "$1 pamaké kadaptar",
+       "rcshowhideliu-show": "Témbongkeun",
+       "rcshowhideliu-hide": "Sumputkeun",
        "rcshowhideanons": "$1 kontributor anonim",
+       "rcshowhideanons-show": "Témbongkeun",
+       "rcshowhideanons-hide": "Sumputkeun",
        "rcshowhidepatr": "$1 éditan karoris",
+       "rcshowhidepatr-show": "Témbongkeun",
+       "rcshowhidepatr-hide": "Sumputkeun",
        "rcshowhidemine": "$1 éditan kuring",
+       "rcshowhidemine-show": "Témbongkeun",
+       "rcshowhidemine-hide": "Sumputkeun",
        "rclinks": "Témbongkeun $1 parobahan ahir dina $2 poé ahir<br />$3",
        "diff": "béda",
        "hist": "juj",
        "newsectionsummary": "/* $1 */ bagean anyar",
        "rc-enhanced-expand": "Témbongkeun rincian (butuh JavaScript)",
        "rc-enhanced-hide": "Sumputkeun rincian",
+       "rc-old-title": "Mimitina dijieun salaku \"$1\"",
        "recentchangeslinked": "Parobahan nu patali",
        "recentchangeslinked-feed": "Parobahan nu patali",
        "recentchangeslinked-toolbox": "Parobahan nu patali",
        "uploadbtn": "Muatkeun koropak",
        "reuploaddesc": "Balik ka formulir muatan.",
        "uploadnologin": "Can asup log",
-       "uploadnologintext": "Anjeun kudu [[Special:UserLogin|asup log]] pikeun ngamuat koropak.",
+       "uploadnologintext": "Mangga $1 pikeun ngunggah berkas.",
        "upload_directory_read_only": "Diréktori muatan ($1) teu bisa ditulis ku server ramat.",
        "uploaderror": "Kasalahan muat",
        "upload-recreate-warning": "'''Awas: berkas nu ngaranna kitu geus kungsi dihapus atawa dipindahkeun.'''\n\nLog hahapus jeung pipindah pikeun ieu kaca dipidangkeun di handap:",
        "uploadwarning-text": "Ropéa pedaran berkas di handap terus cobaan deui.",
        "savefile": "Simpen koropak",
        "uploaddisabled": "Punten, ngamuat ayeuna ditumpurkeun.",
+       "copyuploaddisabled": "Unggahan dumasar URL ditumpurkeun.",
        "uploaddisabledtext": "Fungsi ngamuat koropak ditumpurkeun.",
        "uploadscripted": "Koropak ieu ngandung kode HTML atawa skrip nu bisa dibaca ngaco ku panyungsi ramat (''web browser'').",
        "uploadvirus": "Koropakna ngandung virus! Katrangan: $1",
        "lockmanager-fail-db-release": "Teu bisa ngaleupaskeun konci dina databés $1.",
        "lockmanager-fail-svr-release": "Teu bisa ngaleupaskeun konci dina server $1.",
        "zip-wrong-format": "Berkas anu dipilih lain berkas ZIP.",
+       "img-auth-accessdenied": "Aksés ditolak",
        "img-auth-nofile": "Berkas \"$1\" henteu aya.",
        "img-auth-noread": "Pamaké teu boga kawenangan maca \"$1\".",
        "http-invalid-url": "URL teu bener: $1",
        "license": "Lisénsi:",
        "license-header": "Lisénsi",
        "nolicense": "Taya nu dipilih",
+       "licenses-edit": "Robah pilihan lisénsi",
        "license-nopreview": "(euweuh pramidang)",
        "upload_source_url": "(URL nu sohéh sarta bisa dibuka ku umum)",
        "upload_source_file": " (koropak dina komputer salira)",
+       "listfiles-delete": "hapus",
+       "listfiles-summary": "Ieu kaca husus némbongkeun sakabéh berkas anu geus diunggah.",
        "listfiles_search_for": "Sungsi ngaran média:",
        "imgfile": "koropak",
        "listfiles": "Daptar gambar",
        "listfiles_size": "Badagna",
        "listfiles_description": "Pedaran",
        "listfiles_count": "Vérsi",
+       "listfiles-latestversion": "Vérsi ayeuna",
+       "listfiles-latestversion-yes": "Enya",
+       "listfiles-latestversion-no": "Henteu",
        "file-anchor-link": "Gambar",
        "filehist": "Sajarah gambar",
        "filehist-help": "Klik dina titimangsa pikeun nempo koropak nu aya dina mangsa éta.",
        "filedelete-reason-otherlist": "Alesan séjén",
        "filedelete-reason-dropdown": "*Alesan nu ilahar\n** Ngarumpak hak cipta\n** Koropak geus aya",
        "filedelete-edit-reasonlist": "Alesan ngahapus éditan",
+       "filedelete-maintenance-title": "Henteu bisa ngahapus berkas",
        "mimesearch": "Sungsi MIME",
        "mimesearch-summary": "Ieu kaca bisa dipaké nyaring koropak dumasar tipeu MIME-na. Asupan: contenttype/subtype, contona <code>image/jpeg</code>.",
        "mimetype": "Tipeu MIME:",
        "unusedtemplateswlh": "tumbu lianna",
        "randompage": "Kaca acak",
        "randompage-nopages": "Euweuh kaca dina ieu spasi ngaran \"$1\".",
+       "randomincategory-category": "Kategori:",
        "randomredirect": "Alihan acak",
        "randomredirect-nopages": "Euweuh alihan dina ieu spasi ngaran \"$1\".",
        "statistics": "Statistik",
        "statistics-users-active": "Pamaké getol",
        "statistics-users-active-desc": "Kontributor nu ngoprék salila {{PLURAL:$1|poé|$1 poé}} panungtung",
        "statistics-mostpopular": "Kaca nu pangmindengna dibuka",
+       "pageswithprop-submit": "Jung",
        "doubleredirects": "Alihan ganda",
        "doubleredirectstext": "Ieu kaca ngabéréndélkeun kaca-kaca alihan ka kaca alihan lianna. Unggal baris ngandung tutumbu ka alihan kahiji jeung kadua, ogé tujul alihan kadua anu biasana tujul kaca anu \"bener\", anu sakuduna dituju ku alihan kahiji. Ëntri nu <del>dicorét</del> geus diropéa.",
        "double-redirect-fixed-move": "[[$1]] geus pindah, dialihkeun ka [[$2]].",
        "fewestrevisions": "Artikel nu pangjarangna dirévisi",
        "nbytes": "$1 {{PLURAL:$1|bait|bait}}",
        "ncategories": "$1 {{PLURAL:$1|kategori|kategori}}",
+       "ninterwikis": "$1 {{PLURAL:$1|interwiki|interwiki}}",
        "nlinks": "$1 {{PLURAL:$1|tumbu|tumbu}}",
        "nmembers": "$1 {{PLURAL:$1|kontributor|kontributor}}",
+       "nmemberschanged": "$1 → $2 {{PLURAL:$2|anggota|anggota}}",
        "nrevisions": "$1 {{PLURAL:$1|révisi|révisi}}",
        "nviews": "$1 {{PLURAL:$1|témbongan|témbongan}}",
        "nimagelinks": "Dipaké di $1 {{PLURAL:$1|kaca|kaca}}",
        "protectedpages": "Kaca-kaca nu dikonci",
        "protectedpages-indef": "Ngan pikeun panangtayungan kalawan waktu nuteu kawates",
        "protectedpagesempty": "Dina danget ieu, teu aya kaca nu dikonci dumasar kana ieu paraméter.",
+       "protectedpages-timestamp": "Cap titimangsa",
+       "protectedpages-page": "Kaca",
+       "protectedpages-expiry": "Kadaluwarsa",
+       "protectedpages-params": "Paraméter protéksi",
+       "protectedpages-reason": "Alesan",
+       "protectedpages-unknown-timestamp": "Teu kanyahoan",
+       "protectedpages-unknown-performer": "Pamaké henteu dipikawanoh",
        "protectedtitles": "Judul nu dikonci",
        "protectedtitlesempty": "Dina danget ieu, euweuh judul nu keur dikonci tina paraméter-paraméter éta.",
        "listusers": "Daptar pamaké",
        "booksources-text": "Di handap ieu ngabéréndélkeun tumbu ka loka-loka nu ngical buku, boh nu anyar atawa loakan, nu sugan uninga kana buku anu nuju dipilari:",
        "booksources-invalid-isbn": "ISBN-na sigana henteu bener; pariksa deui bisi aya salah salin ti sumber aslina.",
        "specialloguserlabel": "Pamaké:",
-       "speciallogtitlelabel": "Judul:",
+       "speciallogtitlelabel": "Sasaran (judul atawa pamaké):",
        "log": "Log",
        "all-logs-page": "Sakabéh log umum",
        "alllogstext": "Béréndélan sakabéh log nu aya di {{SITENAME}}.\nBisa dipondokkeun ku cara milih tipe log, ngaran pamaké, atawa kaca nu dimaksud.",
        "emailuser": "Surélékan pamaké ieu",
        "emailpage": "Surélékan pamaké",
        "emailpagetext": "Anjeun bisa maké formulir di handap pikeun ngirim surélék ka ieu pamaké.\nAlamat surélék nu diasupkeun kana [[Special:Preferences|préferénsi pamaké anjeun]] bakal katémbong salaku alamat \"Ti\" dina surélékna, sahingga nu dituju bisa males langsung.",
-       "defemailsubject": "Surélék {{SITENAME}}",
+       "defemailsubject": "Surélék {{SITENAME}} ti pamaké \"$1\"",
        "usermaildisabled": "Surélék kontributor ditumpurkeun",
        "usermaildisabledtext": "Anjeun teu bisa ngirim surélék ka kontributor séjén di ieu wiki",
        "noemailtitle": "Teu aya alamat surélék",
        "noemailtext": "Ieu pamaké ieu teu méré alamat surélék nu sah.",
        "nowikiemailtext": "Ieu kontributor milih teu nampa surélék ti kontributor séjén.",
+       "emailnotarget": "Sandiasma panarima henteu valid atawa henteu aya.",
+       "emailtarget": "ASupkeun sandiasma panarima",
        "emailusername": "Sandiasma:",
        "emailusernamesubmit": "Kirim",
        "email-legend": "Kirim surélék ka kontributor {{SITENAME}} lianna",
        "emailsent": "Surélék geus dikirim",
        "emailsenttext": "Surélék anjeun geus dikirim.",
        "emailuserfooter": "Ieu surélék dikirim ku $1 ka $2 migunakeun fungsi \"Surélékan pamaké ieu\" di {{SITENAME}}.",
+       "usermessage-summary": "Ninggalkeun talatah sistem.",
        "watchlist": "Awaskeuneun",
        "mywatchlist": "Awaskeuneun",
        "watchlistfor2": "Pikeun $1 $2",
        "nowatchlist": "Anjeun teu boga awaskeuneun.",
-       "watchlistanontext": "Mangga $1 pikeun némbongkeun atawa ngarobah béréndélan awaskeuneun anjeun.",
+       "watchlistanontext": "Mangga asup log pikeun nempo atawa ngarobah béréndélan awaskeuneun anjeun.",
        "watchnologin": "Can asup log",
        "addedwatchtext": "Kaca \"[[:$1]]\" geus ditambahkeun ka [[Special:Watchlist|awaskeuneun]] anjeun.\nJaga, parobahan na kaca ieu katut kaca obrolanana bakal dibéréndélkeun di dinya, sarta kacana bakal katémbong '''dikandelan''' dina kaca [[Special:RecentChanges|Nu anyar robah]] sangkan leuwih gampang ngawaskeunana.\n\n<p>Mun jaga anjeun moal deui ngawaskeun parobahan na kaca éta, klik tumbu \"Eureun ngawaskeun\" na lajursisi.",
+       "removewatch": "Piceun tina béréndélan awaskeuneun",
        "removedwatchtext": "Kaca \"[[:$1]]\" geus dikaluarkeun tina [[Special:Watchlist|daptar awaskeuneun]] anjeun.",
+       "removedwatchtext-short": "Kaca \"$1\" geus dipiceun tina béréndélan awaskeuneun.",
        "watch": "awaskeun",
        "watchthispage": "Awaskeun kaca ieu",
        "unwatch": "Eureun ngawaskeun",
        "unwatchthispage": "Eureun ngawaskeun",
        "notanarticle": "Sanés kaca eusi",
        "notvisiblerev": "Révisi geus dihapus",
-       "watchlist-details": "Aya {{PLURAL:$1|$1 kaca|$1 kaca}} nu ku anjeun diawaskeun, teu kaasup kaca obrolan/sawala.",
+       "watchlist-details": "Aya {{PLURAL:$1|$1 kaca|$1 kaca}} dina béréndélan awaskeuneun, teu kaasup kaca obrolan/sawala.",
        "wlheader-enotif": "Pangémbar surélék difungsikeun.",
        "wlheader-showupdated": "Kaca nu robah ti panungtungan anjeun sindang ditémbongkeun kalawan '''kandel'''",
        "wlnote": "Di handap ieu mangrupa $1 {{PLURAL:$1|robahan|robahan}} ahir salila '''$2''' jam.",
        "unwatching": "Eureun ngawaskeun...",
        "enotif_reset": "Tandaan sadaya kaca nu geus dilongok",
        "enotif_impersonal_salutation": "Pamaké {{SITENAME}}",
+       "enotif_subject_deleted": "Kaca {{SITENAME}} $1 geus {{GENDER:$2|dihapus}} ku $2",
        "enotif_lastvisited": "Tempo $1 pikeun sadaya parobahan ti saprak anjeun ninggalkeun ieu kaca.",
        "enotif_lastdiff": "Buka $1 pikeun nempo ieu parobahan.",
        "enotif_anon_editor": "pamaké anonim $1",
        "protect-level-sysop": "Ngan bisa ku kuncén",
        "protect-summary-cascade": "ngaruntuykeun",
        "protect-expiring": "kadaluwarsa $1",
+       "protect-expiring-local": "kadaluwarsa $1",
        "protect-expiry-indefinite": "tanpa wates",
        "protect-cascade": "Konci kaca nu kawengku dina ieu kaca (pangonci ngaruntuy).",
        "protect-cantedit": "Anjeung teu wenang ngarobah hambalan ngonci ieu kaca.",
        "protect-othertime": "Séjén waktu",
+       "protect-othertime-op": "séjén waktu",
        "protect-existing-expiry": "Waktu mungkas nu aya: $3, $2",
+       "protect-existing-expiry-infinity": "Waktu kadaluwarsa nu aya: taya wates",
        "protect-otherreason": "Alesan panambah/lianna:",
        "protect-otherreason-op": "Alesan séjén",
        "protect-dropdown": "*Alesan ngonci nu ilahar\n** Vandalismeu kamalinaan\n** Spamming kamalinaan\n** Perang éditan\n** Kaca loba pisan diédit",
        "contributions": "Kontribusi ti kontributor",
        "contributions-title": "Sumbangan tulisan ti $1",
        "mycontris": "Kontribusi",
-       "contribsub2": "Pikeun $1 ($2)",
+       "contribsub2": "Pikeun {{GENDER:$3|$1}} ($2)",
+       "contributions-userdoesnotexist": "Akun pamaké \"$1\" teu aya dina daptar.",
        "nocontribs": "Taya robahan nu kapanggih cocog jeung patokan ieu.",
-       "uctop": "(pangluhurna)",
+       "uctop": "(ayeuna)",
        "month": "Ti bulan (jeung saméméhna):",
        "year": "Ti taun (jeung saméméhna):",
        "sp-contributions-newbies": "Témbongkeun kontribusi ti akun anyar wungkul",
        "unblocklink": "buka blokir",
        "change-blocklink": "Robah status blokir",
        "contribslink": "kontribusi",
+       "emaillink": "kirim surélék",
        "autoblocker": "Otomatis dipeungpeuk kusabab alamat IP anjeun dipaké ku \"[[User:$1|$1]]\".\nAlesan: \"$2\"",
        "blocklogpage": "Log_peungpeuk",
        "blocklog-showlog": "Ieu pamaké saméméhna geus kungsi dipeungpeuk.\nPikeun rujukan, logna dipidangkeun di handap ieu:",
        "import": "Impor kaca",
        "importinterwiki": "Impor transwiki",
        "import-interwiki-text": "Pilih wiki jeung judul kaca nu rék diimpor.\nTanggal révisi katut ngaran nu ngédit bakal dipertahankeun.\nSadaya aktivitas impor transwiki baris kacatet dina [[Special:Log/import|log impor]].",
-       "import-interwiki-source": "Wiki/kaca sumber:",
+       "import-interwiki-sourcewiki": "Wiki sumber:",
+       "import-interwiki-sourcepage": "Kaca sumber:",
        "import-interwiki-history": "Salin sakabéh vérsi jujutan pikeun ieu kaca",
        "import-interwiki-templates": "Kaasup sakabéh citakan",
        "import-interwiki-submit": "Impor",
        "import-logentry-upload-detail": "$1 {{PLURAL:$1|vérsi heubeul}}",
        "import-logentry-interwiki": "$1 geus ditranswikikeun",
        "import-logentry-interwiki-detail": "$1 {{PLURAL:$1|vérsi heubel}} ti $2",
+       "javascripttest": "Nguji JavaScript",
        "tooltip-pt-userpage": "Kaca kontributor Anjeun",
        "tooltip-pt-anonuserpage": "Kaca pamaké pikeun IP nu ku anjeun keur diédit",
        "tooltip-pt-mytalk": "Kaca obrolan Anjeun",
        "spamprotectiontitle": "Saringan spam",
        "spamprotectiontext": "Kaca nu rék disimpen dipeungpeuk ku saringan spam.\nSigana mah ieu téh alatan tumbu ka loka luar.",
        "pageinfo-title": "Émbaran pikeun \"$1\"",
-       "pageinfo-header-edits": "Éditan",
+       "pageinfo-header-basic": "Émbaran dasar",
+       "pageinfo-header-edits": "Jujutan édit",
+       "pageinfo-header-restrictions": "Protéksi kaca",
        "pageinfo-watchers": "Jumlah nu ngawaskeun",
        "pageinfo-edits": "Jumlah éditan",
        "pageinfo-authors": "Jumlah kontributor nu béda",
+       "pageinfo-contentpage-yes": "Enya",
+       "pageinfo-protect-cascading-yes": "Enya",
        "markaspatrolleddiff": "Tandaan salaku geus diriksa",
        "markaspatrolledtext": "Tandaan artikel ieu salaku geus diriksa",
        "markedaspatrolled": "Tandaan salaku geus diriksa",
        "revdelete-restricted": "akses geus dibatesan ukur keur kuncén",
        "revdelete-unrestricted": "Watesan akses kuncén dihapuskeun",
        "rightsnone": "(euweuh)",
+       "revdelete-summary": "ringkesan ngédit",
        "feedback-subject": "Ngeunaan:",
        "feedback-message": "Surat:",
        "feedback-cancel": "Bolay",
index 23af322..cac1880 100644 (file)
                        "WikiPhoenix",
                        "לערי ריינהארט",
                        "아라",
-                       "Abbedabb"
+                       "Abbedabb",
+                       "Platinawolf"
                ]
        },
        "tog-underline": "Stryk under länkar:",
-       "tog-hideminor": "Visa inte mindre redigeringar i senaste ändringar",
+       "tog-hideminor": "Dölj mindre redigeringar i senaste ändringar",
        "tog-hidepatrolled": "Dölj patrullerade redigeringar i senaste ändringar",
-       "tog-newpageshidepatrolled": "Göm patrullerade sidor från listan över nya sidor",
+       "tog-newpageshidepatrolled": "Dölj patrullerade sidor från listan över nya sidor",
        "tog-extendwatchlist": "Utöka bevakningslistan till att visa alla ändringar, inte bara den senaste",
        "tog-usenewrc": "Gruppera ändringar efter sida i senaste ändringar och bevakningslistan",
        "tog-numberheadings": "Automatisk numrerade rubriker",
        "tog-enotifrevealaddr": "Visa min e-postadress i e-postmeddelanden om ändringar som skickas till andra",
        "tog-shownumberswatching": "Visa antalet användare som bevakar",
        "tog-oldsig": "Nuvarande signatur:",
-       "tog-fancysig": " signatur som wikitext (utan en automatisk länk)",
+       "tog-fancysig": "Behandla signatur som wikitext (utan en automatisk länk)",
        "tog-uselivepreview": "Använd direktuppdaterad förhandsgranskning (experimentell)",
        "tog-forceeditsummary": "Påminn mig om jag inte fyller i en redigeringskommentar",
-       "tog-watchlisthideown": "Visa inte mina redigeringar i bevakningslistan",
+       "tog-watchlisthideown": "Dölj mina redigeringar från bevakningslistan",
        "tog-watchlisthidebots": "Visa inte robotredigeringar i bevakningslistan",
-       "tog-watchlisthideminor": "Visa inte mindre ändringar i bevakningslistan",
+       "tog-watchlisthideminor": "Dölj mindre ändringar från bevakningslistan",
        "tog-watchlisthideliu": "Visa inte redigeringar av inloggade användare i bevakningslistan",
-       "tog-watchlisthideanons": "Visa inte redigeringar av anonyma användare i bevakningslistan",
-       "tog-watchlisthidepatrolled": "Göm patrullerade redigeringar från bevakningslistan",
+       "tog-watchlisthideanons": "Dölj redigeringar av anonyma användare från bevakningslistan",
+       "tog-watchlisthidepatrolled": "Dölj patrullerade redigeringar från bevakningslistan",
        "tog-ccmeonemails": "Skicka kopior till mig av e-post jag skickar till andra användare",
        "tog-diffonly": "Visa inte sidinnehåll under diffar",
        "tog-showhiddencats": "Visa dolda kategorier",
        "editfont-style": "Typsnitt i redigeringsrutan:",
        "editfont-default": "Webbläsarens standard",
        "editfont-monospace": "Fast bredd",
-       "editfont-sansserif": "Sans-serif",
-       "editfont-serif": "Serif",
+       "editfont-sansserif": "Sans-serif-teckensnitt",
+       "editfont-serif": "Serif-teckensnitt",
        "sunday": "söndag",
        "monday": "måndag",
        "tuesday": "tisdag",
        "cancel": "Avbryt",
        "moredotdotdot": "Mer...",
        "morenotlisted": "Denna lista är inte fullständig.",
-       "mypage": "Min sida",
+       "mypage": "Sida",
        "mytalk": "Diskussion",
        "anontalk": "Diskussionssida för denna IP-adress",
        "navigation": "Navigering",
        "editsectionhint": "Redigera avsnitt: $1",
        "toc": "Innehåll",
        "showtoc": "visa",
-       "hidetoc": "göm",
+       "hidetoc": "dölj",
        "collapsible-collapse": "Dölj",
        "collapsible-expand": "Visa",
        "confirmable-confirm": "Är {{GENDER:$1|du}} säker?",
        "passwordreset-emailsent-capture": "En lösenordsåterställning via e-post har skickats, som visas nedan.",
        "passwordreset-emailerror-capture": "En lösenordsåterställning via e-post har skapats, som visas nedan, men det gick inte att skicka den till {{GENDER:$2|användaren}}: $1",
        "changeemail": "Ändra e-postadress",
-       "changeemail-header": "Ändra kontots e-postadress",
        "changeemail-text": "Fyll i detta formulär för att ändra din e-postadress. Du måste ange ditt lösenord för att bekräfta ändringen.",
        "changeemail-no-info": "Du måste vara inloggad för att komma åt den här sidan direkt.",
        "changeemail-oldemail": "Nuvarande e-postadress:",
        "changeemail-none": "(ingen)",
        "changeemail-password": "Ditt lösenord till {{SITENAME}}:",
        "changeemail-submit": "Ändra e-post",
-       "changeemail-cancel": "Avbryt",
        "changeemail-throttled": "Du har gjort för många inloggningsförsök.\nVänta $1 innan du försöker igen.",
        "resettokens": "Återställ nycklar",
        "resettokens-text": "Du kan återställa nycklar som tillåter åtkomst till vissa privata uppgifter som är associerade till ditt konto här.\n\nDu bör återställa om du av misstag delade dem med någon eller om ditt konto har äventyrats.",
        "rev-suppressed-unhide-diff": "En av versionerna för denna diff har blivit '''undanhållen'''.\nDet kan finnas detaljer i [{{fullurl:{{#Special:Log}}/suppress|page={{FULLPAGENAMEE}}}} undanhållandeloggen].\nDu kan fortfarande [$1 se denna diff] om du önskar fortsätta.",
        "rev-deleted-diff-view": "En av sidversionerna i denna diff har '''raderats'''.\nDu kan se denna diff; mer information kan finnas i [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} raderingsloggen].",
        "rev-suppressed-diff-view": "En av versionerna för denna diff har blivit '''undanhållen'''.\nDu kan se denna diff; detaljer kan finnas i [{{fullurl:{{#Special:Log}}/suppress|page={{FULLPAGENAMEE}}}} undanhållandeloggen].",
-       "rev-delundel": "visa/göm",
+       "rev-delundel": "ändra synlighet",
        "rev-showdeleted": "visa",
        "revisiondelete": "Ta bort/återställ versioner",
        "revdelete-nooldid-title": "Ogiltig målversion",
-       "revdelete-nooldid-text": "Antingen har du inte angivit någon sidversion att utföra funktionen på,\neller så finns inte den version du angav,\neller så försöker du gömma den senaste versionen av sidan.",
+       "revdelete-nooldid-text": "Antingen har du inte angivit någon sidversion att utföra funktionen på, eller så finns inte den version du angav,\neller så försöker du dölja den senaste versionen av sidan.",
        "revdelete-no-file": "Den specificerade filen finns inte.",
        "revdelete-show-file-confirm": "Är du säker på att du vill visa en raderad version av filen \"<nowiki>$1</nowiki>\" från den $2 klockan $3?",
        "revdelete-show-file-submit": "Ja",
        "searchall": "alla",
        "showingresults": "Nedan visas upp till {{PLURAL:$1|'''1''' post|'''$1''' poster}} från och med nummer '''$2'''.",
        "showingresultsinrange": "Nedan visas upp till {{PLURAL:$3|<strong>1</strong> resultat|<strong>$1</strong> resultat}} mellan nummer <strong>$2</strong> och nummer <strong>$3</strong>.",
-       "showingresultsheader": "{{PLURAL:$5|Resultat '''$1''' av '''$3'''|Resultat '''$1 - $2''' av '''$3'''}} för '''$4'''",
+       "search-showingresults": "{{PLURAL:$4|Resultat <strong>$1</strong> av <strong>$3</strong>|Resultat <strong>$1 – $2</strong> av <strong>$3</strong>}}",
        "search-nonefound": "Inga resultat matchade frågan.",
        "powersearch-legend": "Avancerad sökning",
        "powersearch-ns": "Sök i namnrymderna:",
        "prefs-tokenwatchlist": "Nyckel",
        "prefs-diffs": "Skillnader",
        "prefs-help-prefershttps": "Ändringar av denna inställning börjar gälla nästa gång du loggar in",
+       "prefswarning-warning": "Du har gjort ändringar i dina inställningarna som inte har sparats ännu.\nOm du lämnar denna sida utan att klicka på \"$1\" kommer dina inställningar inte att uppdateras.",
        "prefs-tabs-navigation-hint": "Tips: Du kan använda vänster och höger piltangenterna för att navigera mellan flikarna i listan flikar.",
        "email-address-validity-valid": "E-postadress ser giltig ut",
        "email-address-validity-invalid": "Ange en giltig e-postadress",
        "right-suppressionlog": "Se privata loggar",
        "right-block": "Blockera andra användare från att redigera",
        "right-blockemail": "Blockera användare från att skicka e-post",
-       "right-hideuser": "Blockera användarnamn och dölja det från blockeringsloggen",
+       "right-hideuser": "Blockera ett användarnamn och dölja det från allmänheten",
        "right-ipblock-exempt": "Kan redigera från blockerade IP-adresser",
        "right-proxyunbannable": "Kan redigera från blockerade proxyer",
        "right-unblockself": "Avblockera sig själv",
        "rclinks": "Visa senaste $1 ändringar under de senaste $2 dygnen<br />$3",
        "diff": "skillnad",
        "hist": "historik",
-       "hide": "Göm",
+       "hide": "Dölj",
        "show": "Visa",
        "minoreditletter": "m",
        "newpageletter": "N",
        "rc-change-size-new": "$1 {{PLURAL:$1|byte}} efter ändring",
        "newsectionsummary": "/* $1 */ nytt avsnitt",
        "rc-enhanced-expand": "Visa detaljer",
-       "rc-enhanced-hide": "Göm detaljer",
+       "rc-enhanced-hide": "Dölj detaljer",
        "rc-old-title": "skapades ursprungligen som \"$1\"",
        "recentchangeslinked": "Relaterade ändringar",
        "recentchangeslinked-feed": "Relaterade ändringar",
        "protectedpages-timestamp": "Tidsstämpel",
        "protectedpages-page": "Sida",
        "protectedpages-expiry": "Upphör",
-       "protectedpages-performer": "Skyddar användare",
+       "protectedpages-performer": "Skyddande användare",
        "protectedpages-params": "Skyddsparametrar",
        "protectedpages-reason": "Anledning",
        "protectedpages-unknown-timestamp": "Okänd",
        "allpagesprefix": "Visa sidor med prefixet:",
        "allpagesbadtitle": "Den angivna sidtiteln var ogiltig eller innehöll ett prefix för annan språkversion eller ett interwiki-prefix.\nDen kan innehålla en eller fler tecken som inte är tillåtna i titlar.",
        "allpages-bad-ns": "Namnrymden \"$1\" finns inte på {{SITENAME}}.",
-       "allpages-hide-redirects": "Göm omdirigeringar",
+       "allpages-hide-redirects": "Dölj omdirigeringar",
        "cachedspecial-viewing-cached-ttl": "Du visar en cachad version av denna sida, som kan vara upp till $1 gammal.",
        "cachedspecial-viewing-cached-ts": "Du visar en cachad version av denna sida, som kanske inte är helt aktuell.",
        "cachedspecial-refresh-now": "Visa senaste.",
        "protect-othertime": "Annan tidsperiod:",
        "protect-othertime-op": "annan tidsperiod",
        "protect-existing-expiry": "Gällande varaktighet: $2, kl. $3",
+       "protect-existing-expiry-infinity": "Gällande varaktighet: oändlig",
        "protect-otherreason": "Annan/ytterligare anledning:",
        "protect-otherreason-op": "Annan anledning",
        "protect-dropdown": "*Vanliga anledningar för skrivskydd\n** Upprepad vandalisering\n** Upprepad spam\n** Redigeringskrig\n** Sida med många besökare",
        "blockipsuccesssub": "Blockeringen är utförd",
        "blockipsuccesstext": "[[Special:Contributions/$1|$1]] har blockerats.<br />\nFör att se alla aktuella blockeringar, gå till [[Special:BlockList|listan över blockeringar]].",
        "ipb-blockingself": "Du håller på att blockera dig själv! Är du säker på att du vill göra det?",
-       "ipb-confirmhideuser": "Du är på väg att blockera en användare med \"göm användare\" aktiverat. Detta kommer upphäva användarens namn i alla listor och loggar. Är du säker på att du vill göra det?",
+       "ipb-confirmhideuser": "Du är på väg att blockera en användare med \"dölj användare\" aktiverat. Detta kommer upphäva användarens namn i alla listor och loggar. Är du säker på att du vill göra det?",
        "ipb-confirmaction": "Markera fältet \"{{int:ipb-confirm}}\" längst ned om du är säker på att du verkligen vill göra det.",
        "ipb-edit-dropdown": "Redigera blockeringsanledningar",
        "ipb-unblock-addr": "Ta bort blockering av $1",
        "unblocked": "Blockeringen av [[User:$1|$1]] har hävts",
        "unblocked-range": "$1 har avblockerats",
        "unblocked-id": "Blockeringen $1 har hävts",
+       "unblocked-ip": "[[Special:Contributions/$1|$1]] har avblockerats.",
        "blocklist": "Blockerade användare",
        "ipblocklist": "Blockerade användare",
        "ipblocklist-legend": "Sök efter en blockerad användare",
-       "blocklist-userblocks": "Göm kontoblockeringar",
+       "blocklist-userblocks": "Dölj kontoblockeringar",
        "blocklist-tempblocks": "Dölj tillfälliga blockeringar",
-       "blocklist-addressblocks": "Göm enskilda IP-blockeringar",
-       "blocklist-rangeblocks": "Göm intervallblockeringar",
+       "blocklist-addressblocks": "Dölj enskilda IP-blockeringar",
+       "blocklist-rangeblocks": "Dölj intervallblockeringar",
        "blocklist-timestamp": "Tidsstämpel",
        "blocklist-target": "Mål",
        "blocklist-expiry": "Upphör",
        "autoblocker": "Automatisk blockerad eftersom din IP-adress nyligen använts av \"[[User:$1|$1]]\".\nMotiveringen som angavs för blockeringen av $1 var: \"$2\".",
        "blocklogpage": "Blockeringslogg",
        "blocklog-showlog": "Denna användare har blivit blockerad tidigare.\nBlockeringsloggen är tillgänglig nedan som referens:",
-       "blocklog-showsuppresslog": "Denna användare har tidigare blivit blockerad och gömd.\nUndanhållandeloggen visas nedan för referens:",
+       "blocklog-showsuppresslog": "Denna användare har tidigare blivit blockerad och dold.\nUndanhållandeloggen visas nedan för referens:",
        "blocklogentry": "blockerade [[$1]] med blockeringstid på $2 $3",
        "reblock-logentry": "ändrade blockeringsinställningar för [[$1]] med en varaktighet på $2 $3",
        "blocklogtext": "Detta är en logg över blockeringar och avblockeringar.\nAutomatiskt blockerade IP-adresser listas ej.\nSe [[Special:BlockList|blockeringslistan]] för en översikt av gällande blockeringar.",
        "block-log-flags-noemail": "e-post blockerad",
        "block-log-flags-nousertalk": "kan inte redigera sin diskussionssida",
        "block-log-flags-angry-autoblock": "utökad automatblockering aktiverad",
-       "block-log-flags-hiddenname": "användarnamn gömt",
+       "block-log-flags-hiddenname": "användarnamn dolt",
        "range_block_disabled": "Möjligheten för administratörer att blockera intervall av IP-adresser har stängts av.",
        "ipb_expiry_invalid": "Ogiltig varaktighetstid.",
        "ipb_expiry_temp": "För att dölja användarnamnet måste blockeringen vara permanent.",
        "sorbsreason": "Din IP-adress är listad som öppen proxy i den DNSBL {{SITENAME}} använder.",
        "sorbs_create_account_reason": "Din IP-adress är listad som en öppen proxy i den DNSBL som används av {{SITENAME}}.\nDu får inte skapa ett användarkonto",
        "xffblockreason": "En IP-adress i sidhuvudet X-Forwarded-For, antingen din adress eller en proxyserver som du använder, har blockerats. Den ursprungliga anledningen till blockeringen var: $1",
-       "cant-see-hidden-user": "Användaren du försöker blockera är redan blockerad och gömd. Eftersom du inte har hideuser-rättigheter, kan du inte se eller redigera användarens blockering.",
+       "cant-see-hidden-user": "Användaren du försöker blockera är redan blockerad och dold. Eftersom du inte har hideuser-rättigheter, kan du inte se eller redigera användarens blockering.",
        "ipbblocked": "Du kan inte blockera eller avblockera andra användare, eftersom du själv är blockerad",
        "ipbnounblockself": "Du har inte tillåtelse att avblockera dig själv",
        "lockdb": "Lås databas",
        "metadata-help": "Den här filen innehåller extrainformation som troligen lades till av en digitalkamera eller skanner när filen skapades. Om filen har modifierats kan det hända att vissa detaljer inte överensstämmer med den modifierade filen.",
        "metadata-expand": "Visa utökade detaljer",
        "metadata-collapse": "Dölj utökade detaljer",
-       "metadata-fields": "Bildens metadata-fält som är listad i detta meddelande kommer att finnas på bildsidan när metadata-tabellen är hopfälld.\nAndra kommer att gömmas som standard\n* make\n* model\n* datetimeoriginal\n* exposuretime\n* fnumber\n* isospeedratings\n* focallength\n* artist\n* copyright\n* imagedescription\n* gpslatitude\n* gpslongitude\n* gpsaltitude",
+       "metadata-fields": "Bildens metadata-fält som är listad i detta meddelande kommer att finnas på bildsidan när metadata-tabellen är hopfälld.\nAndra kommer att döljas som standard\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": "Bredd",
        "exif-imagelength": "Höjd",
        "exif-bitspersample": "Bitar per komponent",
        "logentry-delete-revision": "$1 {{GENDER:$2|ändrade}} synligheten för {{PLURAL:$5|en version|$5 versioner}} på sidan $3: $4",
        "logentry-delete-event-legacy": "$1 {{GENDER:$2|ändrade}} synligheten för logghändelser på $3",
        "logentry-delete-revision-legacy": "$1 {{GENDER:$2|ändrade}} synligheten för versioner på sidan $3",
-       "logentry-suppress-delete": "$1 {{GENDER:$2|gömde}} sidan $3",
+       "logentry-suppress-delete": "$1 {{GENDER:$2|dolde}} sidan $3",
        "logentry-suppress-event": "$1 {{GENDER:$2|ändrade}} i hemlighet synligheten för {{PLURAL:$5|en logghändelse|$5 logghändelser}} på $3: $4",
        "logentry-suppress-revision": "$1 {{GENDER:$2|ändrade}} synligheten i hemlighet för {{PLURAL:$5|en version|$5 versioner}} på sidan $3: $4",
        "logentry-suppress-event-legacy": "$1 {{GENDER:$2|ändrade}} synligheten i hemlighet för logghändelser på $3",
        "logentry-upload-overwrite": "$1 {{GENDER:$2|laddade upp}} en ny version av $3",
        "logentry-upload-revert": "$1 {{GENDER:$2|laddade upp}} $3",
        "rightsnone": "(inga)",
+       "revdelete-summary": "sammanfattning",
        "feedback-bugornote": "Om du är redo att beskriva ett tekniskt problem detaljerat, var god [$1 rapporterar en bugg].\nAnnars kan du använda det enkla formuläret nedan. Din kommentar kommer att läggas till på sidan \"[$3 $2]\", tillsammans med ditt användarnamn och vilken webbläsare du använder.",
        "feedback-subject": "Ämne:",
        "feedback-message": "Meddelande:",
        "log-name-pagelang": "Språkändringslogg",
        "log-description-pagelang": "Detta är en logg över ändringar i sidspråken.",
        "logentry-pagelang-pagelang": "$1 {{GENDER:$2|ändrade}} sidspråket för $3 från $4 till $5.",
-       "default-skin-not-found": "Ojsan! Standardutseendet för din wiki (<code>$wgDefaultSkin</code>), <code>$1</code>, är inte tillgängligt.\n\nDin installation verkar innehålla följande utseenden. Se [https://www.mediawiki.org/wiki/Manual:Skin_configuration Manualen: Utseendeinställningar] för information om hur dessa aktiveras och hur standard väljs.\n\n$2\n\n; Om du precis installerat MediaWiki:\n: Du installerade troligen från git, eller direkt från källkoden via någon annan metod. Detta är att förvänta. Försök att installera några utseenden från [https://www.mediawiki.org/wiki/Category:All_skins mediawiki.org:s utseendekatalog], genom att:\n:* Ladda ner [https://www.mediawiki.org/wiki/Download tarball-installeraren], som kommer med flera utseenden och tillägg. Du kan klipp-och-klistra in <code>skins/</code>-katalogen från den.\n:* Klona ett av <code>mediawiki/skins/*</code>-centralförvaren in i <code>skins/</code>-katalogen i din MediaWiki-installation.\n: Att göra detta borde inte påverka ditt git-centralförvar om du är en MediaWiki-utvecklare.\n\n; Om du precis har uppgraderat MediaWiki:\n: MediaWiki 1.24 och nyare aktiverar ej längre automatiskt utseenden (se [https://www.mediawiki.org/wiki/Manual:Skin_autodiscovery Manual: Automatisk identifiering av utseenden]). Du kan klistra in följande rader i <code>LocalSettings.php</code> för att aktivera alla för närvarande installerade utseenden:\n\n<pre>$3</pre>\n\n; Om du precis har ändrat i <code>LocalSettings.php</code>:\n: Dubbelkolla namnen för utseendena för att identifiera stavfel.",
-       "default-skin-not-found-no-skins": "Ojsan! Standardutseendet för din wiki (<code>$wgDefaultSkin</code>), <code>$1</code>, är inte tillgängligt.\n\nDu har inga installerade utseenden.\n\n; Om du precis installerat eller uppdaterat MediaWiki:\n: Du installerade troligen från git, eller direkt från källkoden via någon annan metod. Detta är att förvänta. MediaWiki 1.24 och nyare inkluderar inte några utseenden i det huvudsakliga centralförvaret. Försök att installera några utseenden från [https://www.mediawiki.org/wiki/Category:All_skins mediawiki.org:s utseendekatalog], genom att:\n:* Ladda ner [https://www.mediawiki.org/wiki/Download tarball-installeraren], som kommer med flera utseenden och tillägg. Du kan klipp-och-klistra in <code>skins/</code>-katalogen från den.\n* Klona ett av <code>mediawiki/skins/*</code>-centralförvaren in i <code>skins/</code>-katalogen i din MediaWiki-installation.\n: Att göra detta borde inte påverka ditt git-centralförvar om du är en MediaWiki-utvecklare. Se [https://www.mediawiki.org/wiki/Manual:Skin_configuration Manualen: Utseendeinställningar] för information om hur utseenden aktiveras och hur standardutseendet väljs.",
+       "default-skin-not-found": "Ojsan! Standardutseendet för din wiki, definierad i <code dir=\"ltr\">$wgDefaultSkin</code> som <code>$1</code>, är inte tillgängligt.\n\nDin installation verkar innehålla följande utseenden. Se [https://www.mediawiki.org/wiki/Manual:Skin_configuration Manualen: Utseendeinställningar] för information om hur dessa aktiveras och hur standard väljs.\n\n$2\n\n; Om du precis installerat MediaWiki:\n: Du installerade troligen från git, eller direkt från källkoden via någon annan metod. Detta är att förvänta. Försök att installera några utseenden från [https://www.mediawiki.org/wiki/Category:All_skins mediawiki.org:s utseendekatalog], genom att:\n:* Ladda ner [https://www.mediawiki.org/wiki/Download tarball-installeraren], som kommer med flera utseenden och tillägg. Du kan klipp-och-klistra in <code>skins/</code>-katalogen från den.\n:* Klona ett av <code>mediawiki/skins/*</code>-centralförvaren in i <code dir=\"ltr\">skins/</code>-katalogen i din MediaWiki-installation.\n: Att göra detta borde inte påverka ditt git-centralförvar om du är en MediaWiki-utvecklare.\n\n; Om du precis har uppgraderat MediaWiki:\n: MediaWiki 1.24 och nyare aktiverar ej längre automatiskt utseenden (se [https://www.mediawiki.org/wiki/Manual:Skin_autodiscovery Manual: Automatisk identifiering av utseenden]). Du kan klistra in följande rader i <code>LocalSettings.php</code> för att aktivera alla för närvarande installerade utseenden:\n\n<pre dir=\"ltr\">$3</pre>\n\n; Om du precis har ändrat i <code>LocalSettings.php</code>:\n: Dubbelkolla namnen för utseendena för att identifiera stavfel.",
+       "default-skin-not-found-no-skins": "Ojsan! Standardutseendet för din wiki, definierad i <code>$wgDefaultSkin</code> som <code>$1</code>, är inte tillgängligt.\n\nDu har inga installerade utseenden.\n\n; Om du precis installerat eller uppdaterat MediaWiki:\n: Du installerade troligen från git, eller direkt från källkoden via någon annan metod. Detta är att förvänta. MediaWiki 1.24 och nyare inkluderar inte några utseenden i det huvudsakliga centralförvaret. Försök att installera några utseenden från [https://www.mediawiki.org/wiki/Category:All_skins mediawiki.org:s utseendekatalog], genom att:\n:* Ladda ner [https://www.mediawiki.org/wiki/Download tarball-installeraren], som kommer med flera utseenden och tillägg. Du kan klipp-och-klistra in <code dir=\"ltr\">skins/</code>-katalogen från den.\n* Klona ett av <code>mediawiki/skins/*</code>-centralförvaren in i <code>skins/</code>-katalogen i din MediaWiki-installation.\n: Att göra detta borde inte påverka ditt git-centralförvar om du är en MediaWiki-utvecklare. Se [https://www.mediawiki.org/wiki/Manual:Skin_configuration Manualen: Utseendeinställningar] för information om hur utseenden aktiveras och hur standardutseendet väljs.",
        "default-skin-not-found-row-enabled": "* <code>$1</code> / $2 (aktiverad)",
        "default-skin-not-found-row-disabled": "* <code>$1</code> / $2 ('''inaktiverad''')"
 }
index 03f1657..2b96e5d 100644 (file)
        "createacct-yourpasswordagain": "Тасдиқи гузарвожа",
        "createacct-yourpasswordagain-ph": "Гузарвожаро бори дигар ворид кунед",
        "remembermypassword": "Вуруди манро дар ин мурургар дар хотир нигоҳ дор (то ҳадди аксар $1 {{PLURAL:$1|рӯз|рӯз}})",
-       "userlogin-remembermypassword": "Вурудшударо манро нигоҳ дор",
+       "userlogin-remembermypassword": "Вурудшуда манро нигоҳ дор",
        "userlogin-signwithsecure": "Истифодаи пайвастшавии амн",
        "yourdomainname": "Домейни Шумо",
        "password-change-forbidden": "Шумо гузарвожаро дар ин вики тағийр дода наметавонед.",
        "changeemail-none": "(ҳеҷ)",
        "changeemail-password": "Гузарвожаи Шумо дар {{SITENAME}}:",
        "changeemail-submit": "Ивази email",
-       "changeemail-cancel": "Лағв",
        "resettokens-no-tokens": "Ягон нишона барои танзими муҷадад вуҷуд надорад.",
        "resettokens-legend": "Танзими муҷадади нишона",
        "resettokens-tokens": "Нишонаҳо:",
        "searchrelated": "алоқаманд",
        "searchall": "ҳама",
        "showingresults": "Намоиши {{PLURAL:$1|'''1''' натиҷа|'''$1''' натоиҷ}} дар зер оғоз аз #'''$2'''.",
-       "showingresultsheader": "{{PLURAL:$5|Натиҷаи <strong>$1</strong> <strong>$3</strong>|Натоиҷи <strong>$1 - $2</strong> <strong>$3</strong>}} барои <strong>$4</strong>",
        "search-nonefound": "Натиҷаи муносиб бо дархост пайдо нашуд.",
        "powersearch-legend": "Ҷустуҷӯи пешрафта",
        "powersearch-ns": "Ҷустуҷӯ дар фазоҳои ном:",
        "revdelete-restricted": "маҳдудиятҳо ба мудирон амалӣ шуданд",
        "revdelete-unrestricted": "маҳдудиятҳо аз мудирон бардошта шуданд",
        "rightsnone": "(ҳеҷ)",
+       "revdelete-summary": "вироиши хулоса",
        "feedback-subject": "Мавзӯъ:",
        "feedback-message": "Пайём:",
        "feedback-cancel": "Лағв",
index 8ba938a..5ec1fe7 100644 (file)
        "mypage": "หน้า",
        "mytalk": "พูดคุย",
        "anontalk": "พูดคุยกับเลขที่อยู่ไอพีนี้",
-       "navigation": "à¸\9bà¹\89ายà¸\9aอà¸\81ทาง",
+       "navigation": "à¸\81ารà¸\99ำทาง",
        "and": "&#32;และ",
        "qbfind": "ค้นหา",
        "qbbrowse": "สืบค้น",
        "actions": "ปฏิบัติการ",
        "namespaces": "เนมสเปซ",
        "variants": "สิ่งที่แตกต่าง",
-       "navigation-heading": "รายà¸\81ารà¹\80ลือà¸\81à¸\9bà¹\89ายà¸\9aอà¸\81ทาง",
+       "navigation-heading": "รายà¸\81ารà¹\80ลือà¸\81à¸\81ารà¸\99ำทาง",
        "errorpagetitle": "มีข้อผิดพลาด",
-       "returnto": "กลับไปที่ $1",
+       "returnto": "กลับไป $1",
        "tagline": "จาก {{SITENAME}}",
-       "help": "à¸\84ำอà¸\98ิà¸\9aาย",
+       "help": "วิà¸\98ีà¹\83à¸\8aà¹\89",
        "search": "ค้นหา",
        "searchbutton": "ค้นหา",
        "go": "ไป",
        "otherlanguages": "ในภาษาอื่น",
        "redirectedfrom": "(เปลี่ยนทางจาก $1)",
        "redirectpagesub": "หน้าเปลี่ยนทาง",
-       "lastmodifiedat": "หน้านี้แก้ไขล่าสุดเมื่อวันที่ $1 เวลา $2",
-       "viewcount": "หน้านี้มีการเข้าชม $1 ครั้ง",
+       "redirectto": "เปลี่ยนทางไป:",
+       "lastmodifiedat": "ดัดแปรหน้านี้ล่าสุดเมื่อวันที่ $1 เวลา $2",
+       "viewcount": "หน้านี้มีการเข้าถึง $1 ครั้ง",
        "protectedpage": "หน้าถูกล็อก",
        "jumpto": "ข้ามไปยัง:",
-       "jumptonavigation": "à¸\9aอà¸\81ทาง",
+       "jumptonavigation": "à¸\81ารà¸\99ำทาง",
        "jumptosearch": "ค้นหา",
        "view-pool-error": "ขออภัย ขณะนี้เซิร์ฟเวอร์มีภาระเกิน\nผู้ใช้พยายามดูหน้านี้มากเกินไป\nกรุณารอสักครู่ก่อนเข้าหน้านี้อีกครั้ง\n\n$1",
        "generic-pool-error": "ขออภัย ขณะนี้เซิร์ฟเวอร์โหลดเกิน\nมีผู้ใช้พยายามดูทรัพยากรนี้มากเกินไป\nโปรดรอสักครู่ก่อนลองเข้าถึงทรัพยากรนี้อีกครั้ง",
        "passwordreset-emailsent-capture": "อีเมลตั้งรหัสผ่านใหม่ถูกส่งไปแล้ว ซึ่งแสดงด้านล่าง",
        "passwordreset-emailerror-capture": "อีเมลตั้งรหัสผ่านใหม่ถูกสร้างขึ้นแล้ว ซึ่งแสดงด้านล่าง แต่ไม่สามารถส่งไปยัง{{GENDER:$2|ผู้ใช้}}: $1",
        "changeemail": "เปลี่ยนที่อยู่อีเมล",
-       "changeemail-header": "เปลี่ยนที่อยู่อีเมลของบัญชี",
        "changeemail-text": "กรอกแบบนี้เพื่อเปลี่ยนที่อยู่อีเมลของคุณ คุณต้องกรอกรหัสผ่านเพื่อยืนยันการเปลี่ยนแปลงนี้",
        "changeemail-no-info": "คุณจำต้องล็อกอินเพื่อเข้าถึงหน้านี้โดยตรง",
        "changeemail-oldemail": "ที่อยู่อีเมลปัจจุบัน:",
        "changeemail-none": "(ไม่มี)",
        "changeemail-password": "รหัสผ่าน {{SITENAME}} ของคุณ:",
        "changeemail-submit": "เปลี่ยนอีเมล",
-       "changeemail-cancel": "ยกเลิก",
        "changeemail-throttled": "คุณได้พยายามล็อกอินหลายครั้งเกินไป\nกรุณารอ $1 ก่อนลองอีกครั้ง",
        "resettokens": "ตั้งโทเค็นใหม่",
        "resettokens-text": "คุณสามารถตั้งโทเค็นใหม่ ซึ่งให้การเข้าถึงข้อมูลส่วนตัวบางอย่างที่เกี่ยวข้องกับบัญชีของคุณที่นี่\n\nคุณควรตั้งโทเค็นใหม่ หากคุณบอกผู้อื่นโดยมิได้ตั้งใจหรือบัญชีของคุณถูกเจาะ",
        "watchthis": "เฝ้าดูหน้านี้",
        "savearticle": "บันทึก",
        "preview": "ตัวอย่าง",
-       "showpreview": "à¸\94ูตัวอย่าง",
+       "showpreview": "à¹\81สà¸\94à¸\87ตัวอย่าง",
        "showdiff": "แสดงความเปลี่ยนแปลง",
        "blankarticle": "<strong>คำเตือน:</strong> หน้าที่คุณกำลังสร้างว่าง หากคุณคลิก \"{{int:savearticle}}\" อีกครั้ง จะสร้างหน้าโดยไม่มีเนื้อหาใด",
-       "anoneditwarning": "'''คำเตือน:''' คุณมิได้ล็อกอิน เลขที่อยู่ไอพีของคุณจะถูกบันทึกไว้ในประวัติการแก้ไขของหน้านี้",
-       "anonpreviewwarning": "'''คุณมิได้ล็อกอิน การบันทึกจะเก็บเลขที่อยู่ไอพีของคุณในประวัติการแก้ไขของหน้านี้'''",
+       "anoneditwarning": "<strong>คำเตือน:</strong> คุณมิได้ล็อกอิน สาธารณะจะเห็นเลขที่อยู่ไอพีของคุณหากคุณแก้ไข หากคุณ<strong>[$1 ล็อกอิน]</strong>หรือ<strong>[$2 สร้างบัญชี]</strong> การแก้ไขของคุณจะถือว่าเป็นของชื่อผู้ใช้ของคุณ ร่วมกับประโยชน์อื่น",
+       "anonpreviewwarning": "<em>คุณมิได้ล็อกอิน การบันทึกจะเก็บเลขที่อยู่ไอพีของคุณในประวัติการแก้ไขของหน้านี้</em>",
        "missingsummary": "'''อย่าลืม:''' คุณยังไม่ได้ระบุคำอธิบายการแก้ไข ถ้าคุณกด \"บันทึก\" อีกครั้ง การแก้ไขของคุณจะถูกบันทึกโดยไม่มีคำอธิบายการแก้ไข",
        "missingcommenttext": "กรุณาใส่ความเห็นด้านล่าง",
        "missingcommentheader": "'''ประกาศเตือน:''' คุณยังไม่ได้ใส่หัวข้อ/จ่าหัวสำหรับความเห็นนี้ ถ้าคุณกด \"{{int:savearticle}}\" อีกครั้ง การแก้ไขของคุณจะถูกบันทึกโดยไม่มีหัวข้อ",
        "mergehistory-empty": "ไม่มีรุ่นที่สามารถรวมได้",
        "mergehistory-success": "ประวัติ $3 รุ่นของ [[:$1]] ได้ถูกรวมเข้ากับ [[:$2]] แล้ว",
        "mergehistory-fail": "ไม่สามารถรวมประวัติการแก้ไขได้ โปรดตรวจสอบค่าตัวแปรหน้าและเวลาอีกครั้ง",
-       "mergehistory-no-source": "ไม่มีหน้าต้นทาง $1 อยู่ในสารบบ",
-       "mergehistory-no-destination": "ไม่มีหน้าปลายทาง $1 อยู่ในสารบบ",
+       "mergehistory-no-source": "ไม่มีหน้าต้นทาง $1 อยู่",
+       "mergehistory-no-destination": "ไม่มีหน้าปลายทาง $1 อยู่",
        "mergehistory-invalid-source": "ชื่อเรื่องหน้าต้นทางต้องสมเหตุสมผล",
        "mergehistory-invalid-destination": "ชื่อเรื่องหน้าปลายทางต้องสมเหตุสมผล",
        "mergehistory-autocomment": "รวม [[:$1]] เข้ากับ [[:$2]]",
        "searchmenu-exists": "<strong>มีหน้าชื่อ \"[[:$1]]\" บนวิกินี้</strong>\n{{PLURAL:$2|0=|ดูผลการค้นหาอื่นที่พบเพิ่มเติม}}",
        "searchmenu-new": "<strong>สร้างหน้า \"[[:$1]]\" บนวิกินี้!</strong> {{PLURAL:$2|0=|ดูหน้าที่พบด้วยการค้นหาของคุณ|ดูผลการค้นหาที่พบเพิ่มเติม}}",
        "searchprofile-articles": "หน้าเนื้อหา",
-       "searchprofile-images": "มัลà¸\95ิมีà¹\80à¸\94ีย",
+       "searchprofile-images": "สืà¹\88อà¸\9bระสม",
        "searchprofile-everything": "ทุกอย่าง",
        "searchprofile-advanced": "ชั้นสูง",
        "searchprofile-articles-tooltip": "ค้นหาใน $1",
        "searchall": "ทั้งหมด",
        "showingresults": "ด้านล่างแสดง <strong>1</strong> ผลลัพธ์ เริ่มตั้งแต่รายการที่ <strong>$2</strong>",
        "showingresultsinrange": "ด้านล่างแสดงมากสุด {{PLURAL:$1|<strong>1</strong>|<strong>$1</strong>}} ผลลัพธ์ ในพิสัย #<strong>$2</strong> ถึง #<strong>$3</strong>",
-       "showingresultsheader": "{{PLURAL:$5|ผลการค้นหา <strong>$1</strong> จาก <strong>$3</strong>|ผลการค้นหา <strong>$1 - $2</strong> จาก <strong>$3</strong>}} สำหรับ <strong>$4</strong>",
+       "search-showingresults": "{{PLURAL:$4|ผลลัพธ์ <strong>$1</strong> จากทั้งหมด <strong>$3</strong>|ผลลัพธ์ <strong>$1 - $2</strong> จากทั้งหมด <strong>$3</strong>}}",
        "search-nonefound": "ไม่มีผลลัพธ์ตรงกับคำค้น",
-       "powersearch-legend": "à¸\84à¹\89à¸\99หาระà¸\94ัà¸\9aสูง",
+       "powersearch-legend": "à¸\84à¹\89à¸\99หาà¸\82ัà¹\89à¸\99สูง",
        "powersearch-ns": "ค้นหาในเนมสเปซ:",
        "powersearch-togglelabel": "เลือก:",
        "powersearch-toggleall": "ทั้งหมด",
        "search-external": "ค้นหาภายนอก",
        "searchdisabled": "การค้นหา {{SITENAME}} ปิดใช้งาน คุณสามารถค้นหาผ่านกูเกิลหรือเซิร์ชเอนจินอื่นในเวลาไม่นาน โปรดทราบว่าดัชนีเนื้อหาของ {{SITENAME}} บนเซิร์ชเอนจินอาจเป็นข้อมูลเก่า",
        "search-error": "เกิดข้อผิดพลาดขณะกำลังค้นหา: $1",
-       "preferences": "à¸\95ัà¹\89à¸\87à¸\84à¹\88าสà¹\88วà¸\99à¸\95ัว",
+       "preferences": "à¸\81ารà¸\95ัà¹\89à¸\87à¸\84à¹\88า",
        "mypreferences": "การตั้งค่า",
        "prefs-edits": "จำนวนการแก้ไข:",
        "prefsnologintext2": "โปรดล็อกอินเพื่อเปลี่ยนการตั้งค่าของคุณ",
        "rows": "แถว:",
        "columns": "คอลัมน์:",
        "searchresultshead": "ค้นหา",
-       "stub-threshold": "ขีดแบ่งสำหรับ <a href=\"#\" class=\"stub\">ลิงก์โครง</a> (ไบต์):",
+       "stub-threshold": "ขีดแบ่งสำหรับการจัดรูปแบบ <a href=\"#\" class=\"stub\">ลิงก์โครง</a> (ไบต์):",
        "stub-threshold-disabled": "ปิดใช้งาน",
        "recentchangesdays": "จำนวนวันที่แสดงในปรับปรุงล่าสุด:",
        "recentchangesdays-max": "มากสุด $1 วัน",
        "prefs-help-signature": "ความเห็นในหน้าพูดคุยควรลงลายเซ็นด้วย \"<nowiki>~~~~</nowiki>\" ซึ่งจะถูกแปลงเป็นลายเซ็นของคุณและตราเวลา",
        "badsig": "ลายเซ็นดิบไม่ถูกต้อง ให้ตรวจสอบแท็กเอชทีเอ็มแอล",
        "badsiglength": "ลายเซ็นของคุณยาวเกินไป ต้องยาวไม่เกิน $1 ตัวอักษร",
-       "yourgender": "à¹\80à¸\9eศ:",
-       "gender-unknown": "ไม่ระบุ",
+       "yourgender": "à¸\95à¹\89อà¸\87à¸\81ารà¹\83หà¹\89ระà¸\9aุà¹\80à¸\9bà¹\87à¸\99à¹\80à¸\9eศà¹\83à¸\94",
+       "gender-unknown": "à¸\82อà¹\84มà¹\88ระà¸\9aุ",
        "gender-male": "ชาย",
        "gender-female": "หญิง",
        "prefs-help-gender": "เลือกตั้งค่านี้หรือไม่ก็ได้\nซอฟต์แวร์ใช้ค่านี้เพื่อติดต่อคุณและกล่าวถึงคุณโดยใช้เพศทางไวยากรณ์ที่เหมาะสมเมื่อติดต่อผู้อื่น\nข้อมูลนี้เปิดเผยต่อสาธารณะ",
        "editusergroup": "แก้ไขกลุ่มผู้ใช้",
        "editinguser": "กำลังเปลี่ยนสิทธิผู้ใช้ของผู้ใช้ '''[[User:$1|$1]]''' $2",
        "userrights-editusergroup": "แก้ไขกลุ่มผู้ใช้",
-       "saveusergroups": "à¸\95à¸\81ลà¸\87",
-       "userrights-groupsmember": "สมาà¸\8aิà¸\81à¹\83à¸\99à¸\81ลุà¹\88ม:",
+       "saveusergroups": "à¸\9aัà¸\99à¸\97ึà¸\81à¸\81ลุà¹\88มà¸\9cูà¹\89à¹\83à¸\8aà¹\89",
+       "userrights-groupsmember": "สมาà¸\8aิà¸\81à¸\82อà¸\87:",
        "userrights-groupsmember-auto": "สมาชิกโดยปริยายของ:",
        "userrights-groups-help": "คุณสามารถเปลี่ยนแปลงกลุ่มที่ผู้ใช้รายนี้อยู่:\n* กล่องที่มีเครื่องหมายถูก หมายความว่า ผู้ใช้อยู่ในกลุ่มนั้น\n* กล่องที่ไม่มีเครื่องหมายถูก หมายความว่า ผู้ใช้ไม่ได้อยู่ในกลุ่มนั้น\n* เครื่องหมาย * ชี้ว่าคุณไม่สามารถนำกลุ่มนั้นออกได้เมื่อคุณเพิ่มกลุ่มนั้นไปแล้ว หรือกลับกัน",
        "userrights-reason": "เหตุผล:",
        "right-reupload-shared": "เขียนทับไฟล์บนคลังเก็บสื่อส่วนกลาง",
        "right-upload_by_url": "อัปโหลดไฟล์จากยูอาร์แอล",
        "right-purge": "ล้างแคชของเว็บไซต์โดยไม่มีการยืนยัน",
-       "right-autoconfirmed": "à¹\81à¸\81à¹\89à¹\84à¸\82หà¸\99à¹\89าà¸\97ีà¹\88à¸\96ูà¸\81à¸\81ึà¹\88à¸\87ลà¹\87อà¸\81",
+       "right-autoconfirmed": "à¹\84มà¹\88à¹\84à¸\94à¹\89รัà¸\9aà¸\9cลà¸\88าà¸\81à¸\82ีà¸\94à¸\88ำà¸\81ัà¸\94อัà¸\95รายึà¸\94à¹\80ลà¸\82à¸\97ีà¹\88อยูà¹\88à¹\84อà¸\9eี",
        "right-bot": "กำหนดเป็นกระบวนการอัตโนมัติ",
        "right-nominornewtalk": "ไม่มีการแก้ไขเล็กน้อยในหน้าอภิปรายที่ทำให้การแจ้งข้อความใหม่ปรากฏ",
        "right-apihighlimits": "ใช้ข้อจำกัดที่สูงขึ้นในคำสั่งเอพีไอ",
        "right-writeapi": "ใช้การเขียนเอพีไอ",
        "right-delete": "ลบหน้า",
        "right-bigdelete": "ลบหน้าที่มีประวัติขนาดใหญ่",
-       "right-deletelogentry": "ลà¸\9aà¹\81ละà¸\81ูà¹\89à¸\84ืà¸\99หà¸\99à¹\88วยà¸\9bูมà¸\97ีà¹\88à¹\80à¸\88าะà¸\88à¸\87",
+       "right-deletelogentry": "ลà¸\9aà¹\81ละà¸\81ูà¹\89à¸\84ืà¸\99หà¸\99à¹\88วยà¸\9bูมà¸\88ำà¹\80à¸\9eาะ",
        "right-deleterevision": "ลบและกู้คืนรุ่นจำเพาะของหน้า",
        "right-deletedhistory": "ดูหน่วยประวัติที่ถูกลบ โดยไม่มีข้อความที่เกี่ยวข้อง",
        "right-deletedtext": "ดูข้อความที่ถูกลบและการเปลี่ยนแปลงระหว่างรุ่นที่ถูกลบ",
        "right-browsearchive": "ค้นหาหน้าที่ถูกลบ",
        "right-undelete": "กู้คืนหน้า",
-       "right-suppressrevision": "ดูรุ่นต่าง ๆ หรือ ซ่อน/เลิกซ่อนรุ่นที่กำหนดจากผู้ใช้ใด ๆ",
-       "right-viewsuppressed": "à¸\94ูรุà¸\99à¸\97ีà¹\88à¸\96ูà¸\81à¸\8bà¹\88อà¸\99à¸\88าà¸\81à¸\9cูà¹\89à¹\83à¸\8aà¹\89อืà¹\88น",
+       "right-suppressrevision": "ดู ซ่อนและเปิดเผยรุ่นจำเพาะของหน้าจากผู้ใช้ทุกคน",
+       "right-viewsuppressed": "à¸\94ูรุà¹\88à¸\99à¸\97ีà¹\88à¸\96ูà¸\81à¸\8bà¹\88อà¸\99à¸\88าà¸\81à¸\9cูà¹\89à¹\83à¸\8aà¹\89à¸\97ุà¸\81à¸\84น",
        "right-suppressionlog": "ดูปูมส่วนตัว",
        "right-block": "บล็อกมิให้ผู้ใช้อื่นแก้ไข",
        "right-blockemail": "บล็อกมิให้ผู้ใช้ส่งอีเมล",
        "right-hideuser": "บล็อกชื่อผู้ใช้ ซ่อนไม่ให้สาธารณะเห็น",
-       "right-ipblock-exempt": "อà¹\89อมการบล็อกเลขที่อยู่ไอพี บล็อกอัตโนมัติ และบล็อกช่วง",
+       "right-ipblock-exempt": "à¹\80ลีà¹\88ยà¸\87การบล็อกเลขที่อยู่ไอพี บล็อกอัตโนมัติ และบล็อกช่วง",
        "right-proxyunbannable": "เลี่ยงการบล็อกอัตโนมัติของพร็อกซี",
        "right-unblockself": "ปลดบล็อกตนเอง",
-       "right-protect": "เปลี่ยนระดับการล็อกและแก้ไขหน้าที่ถูกล็อก",
+       "right-protect": "เปลี่ยนระดับการล็อกและแก้ไขหน้าที่ถูกล็อกแบบถ่ายทอด",
        "right-editprotected": "แก้ไขหน้าที่ถูกล็อกซึ่ง \"{{int:protect-level-sysop}}\"",
        "right-editsemiprotected": "แก้ไขหน้าที่ถูกล็อกซึ่ง \"{{int:protect-level-autoconfirmed}}\"",
        "right-editinterface": "แก้ไขอินเตอร์เฟซผู้ใช้",
        "right-editmyprivateinfo": "แก้ไขข้อมูลส่วนตัวของคุณ (เช่น ที่อยู่อีเมล ชื่อจริง)",
        "right-editmyoptions": "แก้ไขการตั้งค่าของคุณ",
        "right-rollback": "ย้อนการแก้ไขของผู้ใช้ล่าสุดที่แก้ไขหน้าเฉพาะอย่างรวดเร็ว",
-       "right-markbotedits": "ทำเครื่องหมายการย้อนว่าเป็นการแก้ไขโดยบอต",
+       "right-markbotedits": "à¸\97ำà¹\80à¸\84รืà¹\88อà¸\87หมายà¸\81ารยà¹\89อà¸\99à¸\81ลัà¸\9aà¸\89ุà¸\81à¹\80à¸\89ิà¸\99วà¹\88าà¹\80à¸\9bà¹\87à¸\99à¸\81ารà¹\81à¸\81à¹\89à¹\84à¸\82à¹\82à¸\94ยà¸\9aอà¸\95",
        "right-noratelimit": "ไม่ได้รับผลกระทบจากขีดจำกัดอัตรา",
        "right-import": "นำเข้าหน้าจากวิกิอื่น",
        "right-importupload": "นำเข้าหน้าจากไฟล์ที่อัปโหลด",
        "right-patrol": "ทำเครื่องหมายการแก้ไขของผู้อื่นว่าตรวจสอบแล้ว",
        "right-autopatrol": "ให้ทำเครื่องหมายการแก้ไขของตนเองเป็นตรวจสอบแล้วอัตโนมัติ",
-       "right-patrolmarks": "à¸\94ูà¸\81ารà¹\80à¸\9bลีà¹\88ยà¸\99à¹\81à¸\9bลà¸\87ลà¹\88าสุà¸\94à¸\82อà¸\87à¸\81ารà¸\97ำà¹\80à¸\84รืà¹\88อà¸\87หมายà¸\95รวà¸\88สอà¸\9a",
+       "right-patrolmarks": "à¸\94ูà¸\81ารà¸\97ำà¹\80à¸\84รืà¹\88อà¸\87หมายà¸\95รวà¸\88สอà¸\9aà¹\83à¸\99à¸\81ารà¹\80à¸\9bลีà¹\88ยà¸\99à¹\81à¸\9bลà¸\87ลà¹\88าสุà¸\94",
        "right-unwatchedpages": "ดูรายการหน้าที่ไม่มีผู้เฝ้าดู",
        "right-mergehistory": "รวมประวัติหน้า",
        "right-userrights": "แก้ไขสิทธิผู้ใช้ทั้งหมด",
        "action-history": "ดูประวัติของหน้านี้",
        "action-minoredit": "ทำเครื่องหมายการแก้ไขนี้เป็นการแก้ไขเล็กน้อย",
        "action-move": "ย้ายหน้านี้",
-       "action-move-subpages": "ย้ายหน้านี้ รวมทั้งหน้าย่อย",
+       "action-move-subpages": "ย้ายหน้านี้และหน้าย่อย",
        "action-move-rootuserpages": "ย้ายหน้าผู้ใช้หลัก",
        "action-movefile": "ย้ายไฟล์นี้",
        "action-upload": "อัปโหลดไฟล์นี้",
        "action-reupload": "อัปโหลดทับไฟล์ที่มีอยู่แล้วนี้",
        "action-reupload-shared": "เขียนไฟล์นี้ทับบนคลังส่วนกลาง",
-       "action-upload_by_url": "อัà¸\9bà¹\82หลà¸\94à¹\84à¸\9fลà¹\8cà¸\99ีà¹\89à¸\88าà¸\81à¸\97ีà¹\88อยูà¹\88ยูอารà¹\8cà¹\81อล",
+       "action-upload_by_url": "อัปโหลดไฟล์นี้จากยูอาร์แอล",
        "action-writeapi": "ใช้การเขียนเอพีไอ",
        "action-delete": "ลบหน้านี้",
        "action-deleterevision": "ลบรุ่นนี้",
        "enhancedrc-history": "ประวัติ",
        "recentchanges": "ปรับปรุงล่าสุด",
        "recentchanges-legend": "ตัวเลือกการปรับปรุงล่าสุด",
-       "recentchanges-summary": "à¹\83à¸\99หà¸\99à¹\89าà¸\99ีà¹\89à¹\80à¸\9bà¹\87à¸\99รายà¸\81ารà¸\81ารà¸\9bรัà¸\9aà¸\9bรุà¸\87ลà¹\88าสุà¸\94à¸\9aà¸\99วิà¸\81ินี้",
+       "recentchanges-summary": "à¸\95ิà¸\94à¸\95ามà¸\81ารà¹\80à¸\9bลีà¹\88ยà¸\99à¹\81à¸\9bลà¸\87ลà¹\88าสุà¸\94à¸\9aà¸\99วิà¸\81ิà¸\99ีà¹\89à¹\84à¸\94à¹\89à¸\97าà¸\87หà¸\99à¹\89านี้",
        "recentchanges-noresult": "ไม่มีการเปลี่ยนแปลงในช่วงที่กำหนดซึ่งตรงกับเกณฑ์เหล่านี้",
        "recentchanges-feed-description": "ติดตามการปรับปรุงล่าสุดในวิกินี้ในฟีดนี้",
        "recentchanges-label-newpage": "การแก้ไขนี้สร้างหน้าใหม่",
        "recentchanges-label-unpatrolled": "การแก้ไขนี้ยังไม่ได้ตรวจสอบ",
        "recentchanges-label-plusminus": "ขนาดของหน้าเปลี่ยนไปด้วยจำนวนไบต์เท่านี้",
        "recentchanges-legend-heading": "'''คำอธิบายสัญลักษณ์:'''",
-       "recentchanges-legend-newpage": "{{int:recentchanges-label-newpage}} (ดูเพิ่มที่[[Special:NewPages|รายชื่อหน้าใหม่]])",
-       "rcnotefrom": "à¸\94à¹\89าà¸\99ลà¹\88าà¸\87à¹\80à¸\9bà¹\87à¸\99à¸\81ารà¹\80à¸\9bลีà¹\88ยà¸\99à¹\81à¸\9bลà¸\87à¸\95ัà¹\89à¸\87à¹\81à¸\95à¹\88 <strong>$3, $4</strong> (มาà¸\81สุà¸\94 <strong>$1</strong> à¸£à¸²à¸¢à¸\81าร)",
-       "rclistfrom": "แสดงการเปลี่ยนแปลงใหม่เริ่มตั้งแต่ $3 $2",
+       "recentchanges-legend-newpage": "{{int:recentchanges-label-newpage}} (ดูเพิ่มที่ [[Special:NewPages|รายชื่อหน้าใหม่]])",
+       "rcnotefrom": "à¸\94à¹\89าà¸\99ลà¹\88าà¸\87à¹\80à¸\9bà¹\87à¸\99à¸\81ารà¹\80à¸\9bลีà¹\88ยà¸\99à¹\81à¸\9bลà¸\87à¸\95ัà¹\89à¸\87à¹\81à¸\95à¹\88 <strong>$3, $4</strong> (à¹\81สà¸\94à¸\87มาà¸\81สุà¸\94 <strong>$1</strong>)",
+       "rclistfrom": "แสดงการเปลี่ยนแปลงใหม่เริ่มตั้งแต่ $2, $3",
        "rcshowhideminor": "$1การแก้ไขเล็กน้อย",
        "rcshowhideminor-show": "แสดง",
        "rcshowhideminor-hide": "ซ่อน",
        "newpageletter": "ม",
        "boteditletter": "บ",
        "unpatrolledletter": "!",
-       "number_of_watching_users_pageview": "[$1 à¸\84à¸\99เฝ้าดู]",
+       "number_of_watching_users_pageview": "[$1 à¸\9cูà¹\89à¹\83à¸\8aà¹\89เฝ้าดู]",
        "rc_categories": "จำกัดเฉพาะหมวดหมู่ (แยกด้วย \"|\")",
        "rc_categories_any": "ใด ๆ",
        "rc-change-size-new": "$1 ไบต์หลังปรับปรุง",
        "reuploaddesc": "ยกเลิกการอัปโหลดและกลับไปยังแบบอัปโหลด",
        "upload-tryagain": "ส่งคำอธิบายไฟล์ที่ดัดแปรแล้ว",
        "uploadnologin": "ไม่ได้ล็อกอิน",
-       "uploadnologintext": "à¸\95à¹\89อà¸\87$1à¸\81à¹\88อà¸\99à¸\88ึà¸\87à¸\88ะอัà¸\9bà¹\82หลà¸\94à¹\84à¸\9fลà¹\8cà¹\84à¸\94à¹\89",
-       "upload_directory_missing": "à¹\84à¸\94à¹\80รà¸\81à¸\97อรีสำหรัà¸\9aอัà¸\9bà¹\82หลà¸\94 ($1) à¸«à¸²à¸¢à¹\84à¸\9b และเว็บเซิร์ฟเวอร์ไม่สามารถสร้างได้",
-       "upload_directory_read_only": "à¹\80วà¹\87à¸\9aà¹\80à¸\8bิรà¹\8cà¸\9fà¹\80วอรà¹\8cà¹\84มà¹\88สามารà¸\96à¹\80à¸\81à¹\87à¸\9aà¸\82à¹\89อมูลà¹\83à¸\99à¹\84à¸\94à¹\80รà¸\81à¸\97อรี ($1)",
+       "uploadnologintext": "à¹\82à¸\9bรà¸\94$1à¹\80à¸\9eืà¹\88ออัà¸\9bà¹\82หลà¸\94à¹\84à¸\9fลà¹\8c",
+       "upload_directory_missing": "สารà¸\9aà¸\9aอัà¸\9bà¹\82หลà¸\94 ($1) à¸«à¸²à¸¢ และเว็บเซิร์ฟเวอร์ไม่สามารถสร้างได้",
+       "upload_directory_read_only": "à¹\80วà¹\87à¸\9aà¹\80à¸\8bิรà¹\8cà¸\9fà¹\80วอรà¹\8cà¹\84มà¹\88สามารà¸\96à¹\80à¸\82ียà¸\99สารà¸\9aà¸\9aอัà¸\9bà¹\82หลà¸\94 ($1)",
        "uploaderror": "การอัปโหลดผิดพลาด",
        "upload-recreate-warning": "'''คำเตือน: ไฟล์ชื่อนั้นถูกลบหรือเปลี่ยนชื่อแล้ว'''\n\nปูมการลบและปูมการย้ายของหน้านี้ถูกนำมาไว้ด้านล่างเพื่อความสะดวก:",
        "uploadtext": "กรุณาใช้แบบด้านล่างในการอัปโหลดไฟล์\nสำหรับการดูหรือการค้นหาไฟล์ที่เคยอัปโหลดก่อนหน้านี้ ให้ไปที่[[Special:FileList|รายการไฟล์ที่ถูกอัปโหลด]] การอัปโหลดและการอัปโหลดซ้ำดูได้ที่[[Special:Log/upload|ปูมการอัปโหลด]] และการลบไฟล์ดูได้ที่[[Special:Log/delete|ปูมการลบ]]\n\nถ้าต้องการแทรกไฟล์ลงในหน้าหนึ่ง ๆ ให้ใช้คำสั่งหนึ่งในรูปแบบต่อไปนี้\n* '''<code><nowiki>[[</nowiki>{{ns:file}}<nowiki>:File.jpg]]</nowiki></code>''' เพื่อใช้รูปขนาดเต็ม\n* '''<code><nowiki>[[</nowiki>{{ns:file}}<nowiki>:File.png|200px|thumb|left|ข้อความอธิบาย]]</nowiki></code>''' เพื่อใช้รูปย่อขนาดกว้าง 200 พิกเซลในกล่องที่จัดชิดซ้าย โดยมี \"ข้อความอธิบาย\" เป็นคำบรรยายใต้ภาพ\n* '''<code><nowiki>[[</nowiki>{{ns:media}}<nowiki>:File.ogg]]</nowiki></code>''' สำหรับการเชื่อมโยงไฟล์โดยตรง โดยไม่ปรากฏไฟล์นั้นออกมา",
        "sourcefilename": "ชื่อไฟล์ต้นทาง:",
        "sourceurl": "ยูอาร์แอลที่มา:",
        "destfilename": "ชื่อไฟล์ปลายทาง:",
-       "upload-maxfilesize": "à¸\82à¸\99าà¸\94à¹\84à¸\9fลà¹\8cà¸\97ีà¹\88à¹\83หà¸\8dà¹\88à¸\97ีà¹\88สุà¸\94à¸\97ีà¹\88อà¸\99ุà¸\8dาà¸\95: $1",
+       "upload-maxfilesize": "à¸\82à¸\99าà¸\94à¹\84à¸\9fลà¹\8cà¹\83หà¸\8dà¹\88สุà¸\94: $1",
        "upload-description": "คำอธิบายไฟล์",
        "upload-options": "ตัวเลือกอัปโหลด",
        "watchthisupload": "เฝ้าดูไฟล์นี้",
        "upload-proto-error-text": "การอัปโหลดโดยตรงจากเว็บต้องการยูอาร์แอลที่ขึ้นต้นด้วย <code>http://</code> หรือ <code>ftp://</code>",
        "upload-file-error": "เกิดความผิดพลาดภายใน",
        "upload-file-error-text": "เกิดความผิดพลาดภายในขณะพยายามสร้างไฟล์ชั่วคราวบนเซิร์ฟเวอร์ กรุณาติดต่อ[[Special:ListUsers/sysop|ผู้ดูแลระบบ]]",
-       "upload-misc-error": "à¹\80à¸\81ิà¸\94à¸\84วามà¸\9cิà¸\94à¸\9eลาà¸\94à¹\83à¸\99à¸\81ารอัà¸\9bà¹\82หลà¸\94à¹\82à¸\94ยไม่ทราบสาเหตุ",
-       "upload-misc-error-text": "เกิดความผิดพลาดไม่ทราบสาเหตุระหว่างอัปโหลด กรุณาตรวจสอบว่ายูอาร์แอลนั้นถูกต้องและเข้าถึงได้ และลองอีกครั้ง ถ้ายังมีปัญหา ให้ติดต่อ[[Special:ListUsers/sysop|ผู้ดูแลระบบ]]",
-       "upload-too-many-redirects": "ยูอารà¹\8cà¹\81อลà¸\97ีà¹\88ระà¸\9aุมีการเปลี่ยนทางมากเกินไป",
+       "upload-misc-error": "à¹\80à¸\81ิà¸\94à¸\84วามà¸\9cิà¸\94à¸\9eลาà¸\94à¸\81ารอัà¸\9bà¹\82หลà¸\94ไม่ทราบสาเหตุ",
+       "upload-misc-error-text": "เกิดความผิดพลาดไม่ทราบสาเหตุระหว่างอัปโหลด \nกรุณาตรวจสอบว่ายูอาร์แอลนั้นถูกต้องและเข้าถึงได้ และลองอีกครั้ง \nถ้ายังมีปัญหา ให้ติดต่อ[[Special:ListUsers/sysop|ผู้ดูแลระบบ]]",
+       "upload-too-many-redirects": "ยูอารà¹\8cà¹\81อลà¸\99ัà¹\89à¸\99มีการเปลี่ยนทางมากเกินไป",
        "upload-http-error": "เกิดข้อผิดพลาดเอชทีทีพี: $1",
        "upload-copy-upload-invalid-domain": "การอัปโหลดสำเนาไม่สามารถทำได้จากโดเมนนี้",
-       "backend-fail-backup": "à¹\84มà¹\88สามารà¸\96สำรอà¸\87à¸\82à¹\89อมูลà¹\84à¸\9fลà¹\8c $1.",
+       "backend-fail-backup": "à¹\84มà¹\88สามารà¸\96สำรอà¸\87à¹\84à¸\9fลà¹\8c \"$1\"",
        "backend-fail-notexists": "ไม่มีไฟล์ $1",
-       "backend-fail-delete": "ไม่สามารถลบไฟล์ $1 ได้",
+       "backend-fail-delete": "ไม่สามารถลบไฟล์ \"$1\"",
        "backend-fail-alreadyexists": "มีไฟล์ \"$1\" อยู่แล้ว",
        "backend-fail-store": "ไม่สามารถเก็บไฟล์ \"$1\" ที่ \"$2\" ได้",
        "backend-fail-copy": "ไม่สามารถคัดลอกไฟล์ \"$1\" ไปยัง \"$2\" ได้",
        "license": "การอนุญาตใช้สิทธิ:",
        "license-header": "การอนุญาตใช้สิทธิ",
        "nolicense": "ไม่ได้เลือก",
+       "licenses-edit": "แก้ไขตัวเลือกใบอนุญาต",
        "license-nopreview": "(ไม่สามารถแสดงตัวอย่าง)",
        "upload_source_url": "(ไฟล์ที่คุณเลือกจากยูอาร์แอลที่สมเหตุสมผลและสาธารณะเข้าถึงได้)",
        "upload_source_file": "(ไฟล์ที่คุณเลือกจากคอมพิวเตอร์ของคุณ)",
        "protect-title-notallowed": "ดูระดับการล็อกของ \"$1\"",
        "prot_1movedto2": "[[$1]] ถูกเปลี่ยนชื่อเป็น [[$2]]",
        "protect-badnamespace-title": "เนมสเปซล็อกไม่ได้",
-       "protect-badnamespace-text": "หà¸\99à¹\89าà¹\83à¸\99à¹\80à¸\99มสà¹\80à¸\9bà¸\8bà¸\99ีà¹\89à¹\84มà¹\88สามารà¸\96à¸\9bà¹\89อà¸\87à¸\81ัà¸\99ได้",
+       "protect-badnamespace-text": "ลà¹\87อà¸\81หà¸\99à¹\89าà¹\83à¸\99à¹\80à¸\99มสà¹\80à¸\9bà¸\8bà¸\99ีà¹\89à¹\84มà¹\88ได้",
        "protect-norestrictiontypes-text": "หน้านี้ไม่สามารถถูกล็อก เพราะไม่มีประเภทการจำกัดที่ใช้ได้",
        "protect-norestrictiontypes-title": "หน้าที่ล็อกไม่ได้",
        "protect-legend": "ยืนยันการล็อก",
        "sp-contributions-newbies-sub": "สำหรับบัญชีใหม่",
        "sp-contributions-newbies-title": "เรื่องที่เขียนโดยบัญชีใหม่",
        "sp-contributions-blocklog": "ปูมการบล็อก",
-       "sp-contributions-deleted": "การแก้ไขที่ถูกลบ",
+       "sp-contributions-deleted": "à¸\81ารà¹\81à¸\81à¹\89à¹\84à¸\82à¸\82อà¸\87à¸\9cูà¹\89à¹\83à¸\8aà¹\89à¸\97ีà¹\88à¸\96ูà¸\81ลà¸\9a",
        "sp-contributions-uploads": "อัปโหลด",
        "sp-contributions-logs": "ปูม",
        "sp-contributions-talk": "พูดคุย",
        "blockip": "บล็อกผู้ใช้",
        "blockip-legend": "บล็อกผู้ใช้",
        "blockiptext": "ใช้แบบด้านล่างเพื่อบล็อกสิทธิเข้าถึงการเขียนของเลขที่อยู่ไอพีหรือชื่อผู้ใช้โดยเจาะจง การบล็อกนี้ควรดำเนินการเพื่อป้องกันการก่อกวนเท่านั้น และให้สอดคล้องกับ[[{{MediaWiki:Policy-url}}|นโยบาย]]\nกรอกเหตุผลโดยเจาะจงด้านล่าง (เช่น อ้างถึงหน้าที่ถูกก่อกวน)",
-       "ipaddressorusername": "เลขที่อยู่ไอพีหรือชื่อผู้ใช้",
-       "ipbexpiry": "หมดอายุ",
+       "ipaddressorusername": "เลขที่อยู่ไอพีหรือชื่อผู้ใช้:",
+       "ipbexpiry": "หมดอายุ:",
        "ipbreason": "เหตุผล:",
        "ipbreason-dropdown": "*สาเหตุการบล็อกทั่วไป\n** ใส่ข้อมูลเท็จ\n** ลบเนื้อหาในหน้าออก\n** ใส่ลิงก์สแปม\n** ใส่ข้อความไร้สาระ/ขยะเข้ามา\n** พฤติกรรมข่มขู่/รังควาน\n** ใช้หลายบัญชีในทางที่ผิด\n** ชื่อผู้ใช้ที่ไม่อาจยอมรับได้",
        "ipb-hardblock": "ป้องกันไม่ให้ผู้ใช้ล็อกอินแก้ไขจากเลขที่อยู่ไอพีนี้",
        "ipbsubmit": "บล็อกผู้ใช้นี้",
        "ipbother": "เวลาอื่น",
        "ipboptions": "2 ชั่วโมง:2 hours,1 วัน:1 day,3 วัน:3 days,1 สัปดาห์:1 week,2 สัปดาห์:2 weeks,1 เดือน:1 month,3 เดือน:3 months,6 เดือน:6 months,1 ปี:1 year,ไม่มีกำหนด:infinite",
-       "ipbhidename": "à¸\8bà¹\88อà¸\99à¸\8aืà¹\88อà¸\9cูà¹\89à¹\83à¸\8aà¹\89à¸\88าà¸\81à¸\9bูมและรายการต่าง ๆ",
-       "ipbwatchuser": "à¹\80à¸\9dà¹\89าà¸\94ูหà¸\99à¹\89าà¸\9cูà¹\89à¹\83à¸\8aà¹\89à¹\81ละหà¸\99à¹\89าà¸\84ุยà¸\81ัà¸\9aà¸\9cูà¹\89à¹\83à¸\8aà¹\89à¸\82อà¸\87à¸\9cูà¹\89à¹\83à¸\8aà¹\89รายà¸\99ีà¹\89",
+       "ipbhidename": "à¸\8bà¹\88อà¸\99à¸\8aืà¹\88อà¸\9cูà¹\89à¹\83à¸\8aà¹\89à¸\88าà¸\81à¸\81ารà¹\81à¸\81à¹\89à¹\84à¸\82และรายการต่าง ๆ",
+       "ipbwatchuser": "เฝ้าดูหน้าผู้ใช้และหน้าคุยกับผู้ใช้ของผู้ใช้นี้",
        "ipb-disableusertalk": "ป้องกันไม่ให้ผู้ใช้นี้แก้ไขหน้าคุยกับผู้ใช้ของตัวเองขณะถูกบล็อก",
        "ipb-change-block": "บล็อกผู้ใช้อีกครั้งด้วยการตั้งค่าเหล่านี้",
        "ipb-confirm": "ยืนยันการบล็อก",
        "badipaddress": "เลขที่อยู่ไอพีไม่ถูกต้อง",
        "blockipsuccesssub": "บล็อกสำเร็จ",
-       "blockipsuccesstext": "[[Special:Contributions/$1|$1]] à¹\84à¸\94à¹\89à¸\96ูà¸\81à¸\9aลà¹\87อà¸\81à¹\81ลà¹\89ว<br />\nà¸\94ู[[Special:BlockList|รายà¸\81ารà¸\9aลà¹\87อà¸\81]]à¹\80à¸\9eืà¹\88อà¸\97à¸\9aà¸\97วà¸\99à¸\81ารà¸\9aลà¹\87อà¸\81",
+       "blockipsuccesstext": "[[Special:Contributions/$1|$1]] ถูกบล็อกแล้ว<br />\nดู[[Special:BlockList|รายการบล็อก]]เพื่อทบทวนการบล็อก",
        "ipb-blockingself": "คุณกำลังบล็อกตัวเอง! แน่ใจแล้วหรือว่าต้องการทำอย่างนั้น",
        "ipb-confirmhideuser": "คุณกำลังบล็อกผู้ใช้โดยเป็นผู้ใช้ \"ซ่อนผู้ใช้\" ซึ่งจะระงับชื่อผู้ใช้ในรายการและหน่วยปูมทั้งหมด คุณแน่ใจหรือว่าต้องการดำเนินการเช่นนั้น",
-       "ipb-confirmaction": "หากคุณแน่ใจว่าคุณต้องการดำเนินการ โปรดเลือกเขตข้อมูล \"{{int:ipb-confirm}}\"  ที่อยู่ล่างสุด",
+       "ipb-confirmaction": "หากคุณแน่ใจว่าคุณต้องการดำเนินการ โปรดเลือกเขตข้อมูล \"{{int:ipb-confirm}}\" ที่อยู่ล่างสุด",
        "ipb-edit-dropdown": "แก้ไขสาเหตุการบล็อก",
        "ipb-unblock-addr": "ปลดบล็อก $1",
        "ipb-unblock": "ปลดบล็อกผู้ใช้หรือเลขที่อยู่ไอพี",
        "ipb-blocklist": "ดูการบล็อกปัจจุบัน",
        "ipb-blocklist-contribs": "ผลงานเขียนโดย $1",
        "unblockip": "ปลดบล็อกผู้ใช้",
-       "unblockiptext": "à¹\83à¸\8aà¹\89à¹\81à¸\9aà¸\9aà¸\94à¹\89าà¸\99ลà¹\88าà¸\87à¹\80à¸\9eืà¹\88อà¸\84ืà¸\99สิà¸\97à¸\98ิà¸\81ารà¹\80à¸\82à¹\89าà¸\96ึà¸\87à¸\81ารà¹\80à¸\82ียà¸\99à¹\81à¸\81à¹\88à¹\80ลà¸\82à¸\97ีà¹\88อยูà¹\88à¹\84อà¸\9eี à¸«à¸£à¸·à¸­à¸\8aืà¹\88อà¸\9cูà¹\89à¹\83à¸\8aà¹\89à¸\97ีà¹\88à¹\80à¸\84ยà¸\96ูà¸\81à¸\9aลà¹\87อà¸\81",
+       "unblockiptext": "ใช้แบบด้านล่างเพื่อคืนการเข้าถึงการเขียนแก่เลขที่อยู่ไอพี หรือชื่อผู้ใช้ที่เคยถูกบล็อก",
        "ipusubmit": "ยกเลิกการบล็อกนี้",
        "unblocked": "[[User:$1|$1]] ถูกปลดบล็อกแล้ว",
        "unblocked-range": "$1 ถูกปลดบล็อกแล้ว",
-       "unblocked-id": "เลิกบล็อก $1",
+       "unblocked-id": "บล็อก $1 ถูกนำออกแล้ว",
+       "unblocked-ip": "[[Special:Contributions/$1|$1]] ถูกปลดบล็อก",
        "blocklist": "ผู้ใช้ที่ถูกบล็อก",
        "ipblocklist": "ผู้ใช้ที่ถูกบล็อก",
        "ipblocklist-legend": "ค้นหาผู้ใช้ที่ถูกบล็อก",
-       "blocklist-userblocks": "ซ่อนบล็อกบัญชี",
-       "blocklist-tempblocks": "ซ่อนบล็อกชั่วคราว",
-       "blocklist-addressblocks": "ซ่อนบล็อกไอพีเดียว",
+       "blocklist-userblocks": "à¸\8bà¹\88อà¸\99à¸\81ารà¸\9aลà¹\87อà¸\81à¸\9aัà¸\8dà¸\8aี",
+       "blocklist-tempblocks": "à¸\8bà¹\88อà¸\99à¸\81ารà¸\9aลà¹\87อà¸\81à¸\8aัà¹\88วà¸\84ราว",
+       "blocklist-addressblocks": "à¸\8bà¹\88อà¸\99à¸\81ารà¸\9aลà¹\87อà¸\81à¹\84อà¸\9eีà¹\80à¸\94ียว",
        "blocklist-rangeblocks": "ซ่อนการบล็อกช่วง",
        "blocklist-timestamp": "ตราเวลา",
        "blocklist-target": "เป้าหมาย",
        "expiringblock": "หมดอายุ $1 เวลา $2",
        "anononlyblock": "ไม่ล็อกอินเท่านั้น",
        "noautoblockblock": "ยกเลิกการบล็อกอัตโนมัติ",
-       "createaccountblock": "ปิดใช้งานการสร้างบัญชีผู้ใช้ใหม่",
+       "createaccountblock": "ปิดใช้งานการสร้างบัญชี",
        "emailblock": "ปิดใช้งานอีเมล",
        "blocklist-nousertalk": "ไม่สามารถแก้ไขหน้าคุยกับผู้ใช้ของตนเอง",
        "ipblocklist-empty": "รายการบล็อกว่าง",
        "ipblocklist-no-results": "เลขที่อยู่ไอพีหรือชื่อผู้ใช้ที่ต้องการไม่ได้ถูกบล็อก",
        "blocklink": "บล็อก",
-       "unblocklink": "à¹\80ลิà¸\81บล็อก",
+       "unblocklink": "à¸\9bลà¸\94บล็อก",
        "change-blocklink": "เปลี่ยนการบล็อก",
        "contribslink": "เรื่องที่เขียน",
        "emaillink": "ส่งอีเมล",
        "block-log-flags-angry-autoblock": "การบล็อกอัตโนมัติขั้นสูงเปิดใช้งาน",
        "block-log-flags-hiddenname": "ชื่อผู้ใช้ถูกซ่อน",
        "range_block_disabled": "การบล็อกช่วงไอพีของผู้ดูแลระบบถูกปิดการใช้งาน",
-       "ipb_expiry_invalid": "วัà¸\99หมดอายุไม่ถูกต้อง",
+       "ipb_expiry_invalid": "à¹\80วลาหมดอายุไม่ถูกต้อง",
        "ipb_expiry_temp": "การบล็อกชื่อผู้ใช้ที่ซ่อนต้องเป็นการบล็อกถาวร",
        "ipb_hide_invalid": "ไม่สามารถยับยั้งชื่อผู้ใช้นี้ได้ อาจเพราะมีการแก้ไขมากกว่า $1 การแก้ไข",
-       "ipb_already_blocked": "\"$1\" ถูกบล็อกไปแล้วก่อนหน้านี้",
+       "ipb_already_blocked": "\"$1\" ถูกบล็อกไปแล้ว",
        "ipb-needreblock": "$1 ถูกบล็อกแล้ว คุณต้องการเปลี่ยนการตั้งค่าหรือไม่",
-       "ipb-otherblocks-header": "{{PLURAL:$1|การบล็อก}}อื่น ๆ",
-       "unblock-hideuser": "à¸\84ุà¸\93à¹\84มà¹\88สามารà¸\96ยà¸\81à¹\80ลิà¸\81à¸\81ารà¸\9aลà¹\87อà¸\81à¸\9cูà¹\89à¹\83à¸\8aà¹\89à¸\87าà¸\99รายนี้ได้ เพราะชื่อผู้ใช้ถูกซ่อนอยู่",
-       "ipb_cant_unblock": "à¸\82à¹\89อà¸\9cิà¸\94à¸\9eลาà¸\94: à¹\84มà¹\88à¸\9eà¸\9aหมายà¹\80ลà¸\82à¸\9aลà¹\87อà¸\81 $1 à¸\81ารà¸\9aลà¹\87อà¸\81à¸\94ัà¸\87à¸\81ลà¹\88าวอาจถูกปลดบล็อกแล้ว",
-       "ipb_blocked_as_range": "à¸\82à¹\89อà¸\9cิà¸\94à¸\9eลาà¸\94: à¹\80ลà¸\82à¸\97ีà¹\88อยูà¹\88à¹\84อà¸\9eี $1 à¸¡à¸´à¹\84à¸\94à¹\89à¸\96ูà¸\81à¸\9aลà¹\87อà¸\81à¹\82à¸\94ยà¸\95รà¸\87à¹\81ละà¹\84มà¹\88สามารà¸\96à¸\9bลà¸\94à¸\9aลà¹\87อà¸\81à¹\84à¸\94à¹\89\nอยà¹\88าà¸\87à¹\84รà¸\81à¹\87à¸\95าม à¹\84อà¸\9eีà¸\99ีà¹\89à¸\96ูà¸\81ระà¸\87ัà¸\9aà¹\83à¸\99à¸\90าà¸\99ะà¸\97ีà¹\88à¹\80à¸\9bà¹\87à¸\99สà¹\88วà¸\99หà¸\99ึà¹\88à¸\87à¸\82อà¸\87à¹\80ลà¸\82à¸\97ีà¹\88อยูà¹\88à¹\84อà¸\9eีà¹\83à¸\99à¸\9eิสัย $2 ซึ่งสามารถปลดบล็อกได้",
+       "ipb-otherblocks-header": "{{PLURAL:$1|การบล็อก}}อื่น",
+       "unblock-hideuser": "à¸\84ุà¸\93à¹\84มà¹\88สามารà¸\96à¸\9bลà¸\94à¸\9aลà¹\87อà¸\81à¸\9cูà¹\89à¹\83à¸\8aà¹\89นี้ได้ เพราะชื่อผู้ใช้ถูกซ่อนอยู่",
+       "ipb_cant_unblock": "à¸\82à¹\89อà¸\9cิà¸\94à¸\9eลาà¸\94: à¹\84มà¹\88à¸\9eà¸\9aà¸\81ารà¸\9aลà¹\87อà¸\81หมายà¹\80ลà¸\82 $1 อาจถูกปลดบล็อกแล้ว",
+       "ipb_blocked_as_range": "à¸\82à¹\89อà¸\9cิà¸\94à¸\9eลาà¸\94: à¹\80ลà¸\82à¸\97ีà¹\88อยูà¹\88à¹\84อà¸\9eี $1 à¸¡à¸´à¹\84à¸\94à¹\89à¸\96ูà¸\81à¸\9aลà¹\87อà¸\81à¹\82à¸\94ยà¸\95รà¸\87à¹\81ละà¹\84มà¹\88สามารà¸\96à¸\9bลà¸\94à¸\9aลà¹\87อà¸\81à¹\84à¸\94à¹\89\nอยà¹\88าà¸\87à¹\84รà¸\81à¹\87à¸\95าม à¹\84อà¸\9eีà¸\99ีà¹\89à¸\96ูà¸\81ระà¸\87ัà¸\9aà¹\82à¸\94ยà¹\80à¸\9bà¹\87à¸\99สà¹\88วà¸\99หà¸\99ึà¹\88à¸\87à¸\82อà¸\87à¸\8aà¹\88วà¸\87 $2 ซึ่งสามารถปลดบล็อกได้",
        "ip_range_invalid": "พิสัยไอพีไม่ถูกต้อง",
        "ip_range_toolarge": "พิสัยบล็อกที่มีขนาดใหญ่กว่า /$1 จะไม่ได้รับอนุญาต",
        "proxyblocker": "ตัวบล็อกพร็อกซี",
        "logentry-upload-overwrite": "$1 อัปโหลดรุ่นใหม่ของ $3",
        "logentry-upload-revert": "$1 อัปโหลด $3",
        "rightsnone": "(ไม่มี)",
+       "revdelete-summary": "คำอธิบายโดยย่อ",
        "feedback-bugornote": "หากคุณได้อธิบายปัญหาทางเทคนิคในรายละเอียดแล้ว โปรด[$1 รายงานจุดบกพร่อง]\nมิฉะนั้น คุณสามารถแบบอย่างง่ายด้านล่าง ความเห็นของคุณจะถูกเพิ่มเข้าสู่ \"[$3 $2]\" ร่วมกับชื่อผู้ใช้ของคุณ",
        "feedback-subject": "เรื่อง:",
        "feedback-message": "ข้อความ:",
index 57d4c06..2bf38e3 100644 (file)
@@ -20,7 +20,8 @@
                        "Ильнар",
                        "Рашат Якупов",
                        "Умар",
-                       "아라"
+                       "아라",
+                       "Derslek"
                ]
        },
        "tog-underline": "Сылтамаларның астына сызу:",
        "print": "Бастыру",
        "view": "Карау",
        "edit": "Үзгәртү",
+       "edit-local": "Локаль тасвирламаны үзгәртергә",
        "create": "Төзү",
+       "create-local": "Локаль тасвирлама өстәргә",
        "editthispage": "Бу битне үзгәртү",
        "create-this-page": "Бу битне төзү",
        "delete": "Бетерү",
        "deletethispage": "Бу битне бетерү",
        "undeletethispage": "Бу битне кайтарырга",
-       "undelete_short": "$1 {{PLURAL:$1|үзгәртмәне}} торгызу",
-       "viewdeleted_short": "{{PLURAL:$1|1=1 бетерелгән үзгәртүне|$1 бетерелгән үзгәртүне}} карау",
+       "undelete_short": "$1 {{PLURAL:$1|төзәтмәне|$1 төзәтмә}} торгызу",
+       "viewdeleted_short": "{{PLURAL:$1|1=1 бетерелгән үзгәртүне|$1 бетерелгән үзгәртүне}} карау\n{{PLURAL:$1|бетерелгән төзәтмәне|$1 бетерелгән төзәтмәне}} карау",
        "protect": "Яклау",
        "protect_change": "үзгәртү",
        "protectthispage": "Бу битне яклау",
        "otherlanguages": "Башка телләрдә",
        "redirectedfrom": "($1 битеннән юнәлтелде)",
        "redirectpagesub": "Башка биткә юнәлтү бите",
+       "redirectto": "Шунда юнәлтелә:",
        "lastmodifiedat": "Бу битне соңгы үзгәртү: $2, $1.",
-       "viewcount": "Бу биткә $1 {{PLURAL:$1|тапкыр}} мөрәҗәгать иттеләр.",
+       "viewcount": "Бу биткә $1 {{PLURAL:$1|бер тапкыр|$1 тапкыр}} мөрәҗәгать иттеләр.",
        "protectedpage": "Якланган бит",
        "jumpto": "Моңа күчү:",
        "jumptonavigation": "навигация",
        "passwordreset-emailsent-capture": "Җибәрелгән хат-искәртү түбәндә китерелә",
        "passwordreset-emailerror-capture": "Түбәндә язылган хат-искәртү китерелгән, аны җибәрмәүнең сәбәбе:$1",
        "changeemail": "Электрон әрҗә адресын үзгәртү",
-       "changeemail-header": "Электрон әрҗә адресын үзгәртү",
        "changeemail-text": "Электрон әрҗә адресын үзгәртү өчен, бу кырларны тутырыгыз. Үзгәртүне раслау өчен, сезгә серсүзне җыярга кирәк булыр",
        "changeemail-no-info": "Бу сәхифәгә турыдан-туры мөрәҗәгать итәр өчен, сез системага керергә тиешсез",
        "changeemail-oldemail": "Хәзерге электрон әрҗә адресы:",
        "changeemail-none": "(юк)",
        "changeemail-password": "«{{SITENAME}}» проекты өчен серсүзегез:",
        "changeemail-submit": "E-mail адресын үзгәртү",
-       "changeemail-cancel": "Баш тарту",
        "bold_sample": "Калын язылыш",
        "bold_tip": "Калын язылыш",
        "italic_sample": "Курсив язылыш",
        "searchrelated": "бәйләнгән",
        "searchall": "барлык",
        "showingresults": "Аста № '''$2''' {{PLURAL:$1|башлап}} '''$1''' {{PLURAL:$1|результат}} күрсәтелгән.",
-       "showingresultsheader": "'''$4''' өчен {{PLURAL:$5|1=Результат '''$1''' сеннән '''$3'''|Результатлар '''$1 — $2''' сеннән  '''$3'''}}",
        "search-nonefound": "Сорауга туры килгән җаваплар табылмады.",
        "powersearch-legend": "Өстәмә эзләү",
        "powersearch-ns": "исемнәрендә эзләү",
        "import": "Битләр кертү",
        "importinterwiki": "Викиара кертү",
        "import-interwiki-text": "Викины һәм кертелүче битнең исемен языгыз.\nҮзгәртүләр вакыты һәм аның авторлары сакланачак.\nБөтен викиара күчерүләр [[Special:Log/import|махсус журналда]] сакланачак.",
-       "import-interwiki-source": "Вики-чыганак/бит:",
        "import-interwiki-history": "Бу битнең барлык үзгәртү тарихын күчермәләү",
        "import-interwiki-templates": "Барлык үрнәкләрне кертү",
        "import-interwiki-submit": "Импортлау",
        "logentry-newusers-create2": "$1 $3 кулланучы хисап язмасын төзеде",
        "logentry-newusers-autocreate": "Автоматик рәвештә $1 хисап язмасы төзелде.",
        "rightsnone": "(юк)",
+       "revdelete-summary": "үзгәртүләр тасвирламасы",
        "feedback-bugornote": "Әгәр дә сез техник проблеманы җентекләп тасвирларга әзер икәнсез, зинһар өчен, [$1 хата турында хәбәр итегез].\nБашка очракта сез түбәндәге гади форманы куллана аласыз. Сезнең шәрехләмә \"[$3 $2]\" сәхифәсенә сезнең кулланучы исеме һәм сез кулланган браузер исеме белән бергә өстәләчәк.",
        "feedback-subject": "Тема:",
        "feedback-message": "Хәбәр:",
index 0fb063a..73e2466 100644 (file)
        "accountcreatedtext": "«$1» деп ажыглакчының бүрүткел бижиини бүдүрген.",
        "login-abort-generic": "Системаже таптыг эвес кирип тур силер",
        "loginlanguagelabel": "Дыл: $1",
+       "pt-userlogout": "Үнер",
        "php-mail-error-unknown": "PHP-ниң mail() ажыл-чорудулгазында билбес алдаг бар.",
        "changepassword": "Чажыт сөстү өскертири",
        "resetpass_text": "<!-- Маңаа сөзүглелди немерелээри -->",
        "search-interwiki-more": "(артык)",
        "searchrelated": "холбаалыг",
        "searchall": "шупту",
-       "showingresultsheader": "«'''$4'''» дилээниниң {{PLURAL:$5|1='''$3''' одуругдан '''$1''' түңнели|'''$3''' одуругдан '''$1—$2''' түңнелдери}}",
        "search-nonefound": "Айыткан негелдениң түңнели чок",
        "powersearch-ns": "Аттар делгемнеринден дилээри:",
        "powersearch-toggleall": "Шупту",
index 9ed3a4d..1304076 100644 (file)
        "november-date": "$1 листопада",
        "december-date": "$1 грудня",
        "pagecategories": "{{PLURAL:$1|1=Категорія|Категорії|Категорій}}",
-       "category_header": "Сторінок в категорії «$1»",
+       "category_header": "Сторінок у категорії «$1»",
        "subcategories": "Підкатегорії",
        "category-media-header": "Файли в категорії «$1»",
        "category-empty": "''Ця категорія зараз порожня.''",
        "passwordreset-emailsent-capture": "Електронний лист скидання пароля було надіслано, як показано нижче.",
        "passwordreset-emailerror-capture": "Електронний лист для відновлення пароля мав бути надісланий, як показано нижче, але його надсилання {{GENDER:$2|користувачеві|користувачці}} $1 не вдалося.",
        "changeemail": "Змінити адресу електронної пошти",
-       "changeemail-header": "Зміна адреси електронної пошти",
        "changeemail-text": "Заповніть цю форму, щоб змінити адресу електронної пошти. Вам потрібно буде ввести пароль, щоб підтвердити ці зміни.",
        "changeemail-no-info": "Ви повинні увійти в систему, щоб отримати безпосередній доступ до цієї сторінки.",
        "changeemail-oldemail": "Поточна адреса електронної пошти:",
        "changeemail-none": "(немає)",
        "changeemail-password": "Ваш пароль проекту {{SITENAME}}:",
        "changeemail-submit": "Змінити адресу електронної пошти",
-       "changeemail-cancel": "Скасувати",
        "changeemail-throttled": "Ви зробили надто багато спроб ввійти до системи.\nБудь ласка, зачекайте $1 перед повторною спробою.",
        "resettokens": "Скидання жетонів",
        "resettokens-text": "Ви можете скинути жетони, що забезпечують доступ до певних особистих даних, пов'язаних тут із вашим обліковим записом.\nВам слід це зробити, якщо ви випадково поділились жетонами з кимось, або якщо ваш обліковий запис було зламано.",
        "searchall": "усі",
        "showingresults": "Нижче {{PLURAL:$1|показане|показані|показані}} '''$1''' {{PLURAL:$1|результат|результати|результатів}}, починаючи з №&nbsp;'''$2'''",
        "showingresultsinrange": "Нижче показано до {{PLURAL:$1|<strong>1</strong> результата|<strong>$1</strong> результатів|<strong>$1</strong> результати}} у діапазоні від #<strong>$2</strong> до #<strong>$3</strong>.",
-       "showingresultsheader": "{{PLURAL:$5|1=Результат '''$1''' з '''$3'''|Результати '''$1 — $2''' з '''$3'''}} для '''$4'''",
        "search-nonefound": "Не знайдено результатів, що відповідають запиту.",
        "powersearch-legend": "Розширений пошук",
        "powersearch-ns": "Пошук у просторах назв:",
        "logentry-upload-overwrite": "$1 {{GENDER:$2|завантажив|завантажила}} нову версію $3",
        "logentry-upload-revert": "$1 {{GENDER:$2|завантажив|завантажила}} $3",
        "rightsnone": "(нема)",
+       "revdelete-summary": "коментар до редагування",
        "feedback-bugornote": "Якщо ви готові описати технічні проблеми в деталях, будь ласка, [$1 повідомте про помилку].\nАбо можете використати форму нижче. Ваш коментар буде додано на сторінку \"[$3  $2]\", разом з іменем користувача.",
        "feedback-subject": "Тема:",
        "feedback-message": "Повідомлення:",
index a7b7d8c..1e1c309 100644 (file)
        "searchrelated": "ligà",
        "searchall": "tuti",
        "showingresults": "Qua de soto vien mostrà al massimo {{PLURAL:$1|'''1''' risultato|'''$1''' risultati}} a partir dal nùmaro '''$2'''.",
-       "showingresultsheader": "{{PLURAL:$5|Risultato '''$1''' de '''$3'''|Risultati '''$1 - $2''' de '''$3'''}} par '''$4'''",
        "search-nonefound": "La riserca no la gà catà gnente.",
        "powersearch-legend": "Riserca avansà",
        "powersearch-ns": "Serca ne i namespace:",
index e7a4a53..a7104dc 100644 (file)
        "otherlanguages": "Ngôn ngữ khác",
        "redirectedfrom": "(đổi hướng từ $1)",
        "redirectpagesub": "Trang đổi hướng",
+       "redirectto": "Đổi hướng đến:",
        "lastmodifiedat": "Trang này được sửa đổi lần cuối lúc $2 $1.",
        "viewcount": "Trang này đã được đọc {{PLURAL:$1|một|$1}} lần.",
        "protectedpage": "Trang bị khóa",
        "hidetoc": "ẩn",
        "collapsible-collapse": "Thu gọn",
        "collapsible-expand": "Mở rộng",
+       "confirmable-confirm": "{{GENDER:$1}}Bạn chắc chứ?",
+       "confirmable-yes": "Có",
+       "confirmable-no": "Không",
        "thisisdeleted": "Xem hay phục hồi $1 ?",
        "viewdeleted": "Xem $1?",
        "restorelink": "{{PLURAL:$1|một|$1}} sửa đổi đã xóa",
        "invalidtitle-knownnamespace": "Tựa trang không hợp lệ có không gian tên “$2” và văn bản “$3”",
        "invalidtitle-unknownnamespace": "Tựa trang không hợp lệ có không gian tên số $1 không rõ và văn bản “$2”",
        "exception-nologin": "Chưa đăng nhập",
-       "exception-nologin-text": "Xin vui lòng [[Special:Userlogin|đăng nhập]] để truy cập trang hoặc thực hiện tác vụ này.",
+       "exception-nologin-text": "Xin vui lòng đăng nhập để truy cập trang hoặc thực hiện tác vụ này.",
        "exception-nologin-text-manual": "Xin vui lòng $1 để truy cập trang hoặc tác vụ này.",
        "virus-badscanner": "Cấu hình sau: không nhận ra bộ quét virus: ''$1''",
        "virus-scanfailed": "quét thất bại (mã $1)",
        "userlogin-resetlink": "Quên mất thông tin đăng nhập?",
        "userlogin-resetpassword-link": "Quên mật khẩu?",
        "userlogin-helplink2": "Trợ giúp đăng nhập",
-       "userlogin-loggedin": "Bạn đã đăng nhập với tên {{GENDER:$1}}$1.\nHãy sử dụng biểu mẫu ở dưới để đăng nhập với tài khoản người dùng khác.",
-       "userlogin-createanother": "Mở thêm tài khoản",
        "createacct-emailrequired": "Địa chỉ thư điện tử",
        "createacct-emailoptional": "Địa chỉ thư điện tử (tùy chọn)",
        "createacct-email-ph": "Nhập địa chỉ thư điện tử của bạn",
        "createaccount-text": "Ai đó đã tạo một tài khoản với tên $2 tại {{SITENAME}} ($4). Mật khẩu của \"$2\" là \"$3\". Bạn nên đăng nhập và đổi mật khẩu ngay bây giờ.\n\nXin hãy bỏ qua thông điệp này nếu tài khoản này không phải do bạn tạo ra.",
        "login-throttled": "Bạn đã hết quyền thử mật khẩu tài khoản này vì bạn đã nhập sai quá nhiều. Xin hãy đợi $1 rồi hãy thử lại.",
        "login-abort-generic": "Thất bại khi đăng nhập",
+       "login-migrated-generic": "Tài khoản của bạn đã được hợp nhất, và tên đăng nhập của bạn không còn tồn tại trên wiki này.",
        "loginlanguagelabel": "Ngôn ngữ: $1",
        "suspicious-userlogout": "Đã bỏ qua yêu cầu đăng xuất bạn, hình như được gửi từ trình duyệt hoặc máy proxy nhớ đệm hư.",
        "createacct-another-realname-tip": "Tên thật là không bắt buộc. \n\nNếu bạn đồng ý cung cấp, nó sẽ dùng để ghi nhận công lao của bạn.",
        "passwordreset-emailsent-capture": "Thư điện tử để tái tạo mật khẩu đã được gửi, nội dung như sau.",
        "passwordreset-emailerror-capture": "Chúng tôi đã tạo thư tái tạo mật khẩu dưới đây, nhưng không thể gửi đến {{GENDER:$2}}người dùng: $1",
        "changeemail": "Đổi địa chỉ thư điện tử",
-       "changeemail-header": "Đổi địa chỉ thư điện tử của tài khoản",
        "changeemail-text": "Điền biểu mẫu này để đổi địa chỉ thư điện tử. Bạn sẽ cần phải nhập mật khẩu để xác nhận thay đổi này.",
        "changeemail-no-info": "Bạn phải đăng nhập mới có thể truy cập trực tiếp trang này.",
        "changeemail-oldemail": "Địa chỉ thư điện tử hiện tại:",
        "changeemail-none": "(không có)",
        "changeemail-password": "Mật khẩu của bạn tại {{SITENAME}}:",
        "changeemail-submit": "Đổi địa chỉ",
-       "changeemail-cancel": "Hủy bỏ",
        "changeemail-throttled": "Bạn đã thử đăng nhập nhiều lần quá. Xin chờ $1 trước khi bạn thử lần nữa.",
        "resettokens": "Đặt lại dấu hiệu",
        "resettokens-text": "Bạn có thể đặt lại các dấu hiệu cho phép truy cập những dữ liệu cá nhân của tài khoản của bạn tại đây.\n\nBạn nên sử dụng chức năng này nếu bạn đã vô tình chia sẻ các dấu hiệu với người khác hoặc tài khoản của bạn đã bị xâm phạm.",
        "showpreview": "Xem trước",
        "showdiff": "Xem thay đổi",
        "blankarticle": "<strong>Cảnh báo:</strong> Bạn sẽ tạo ra một trang trống.\nNếu bấm “{{int:savearticle}}” lần nữa, một trang không có nội dung sẽ được tạo ra.",
-       "anoneditwarning": "'''Cảnh báo:''' Bạn chưa đăng nhập. Địa chỉ IP của bạn sẽ được ghi lại trong lịch sử sửa đổi của trang.",
+       "anoneditwarning": "<strong>Cảnh báo:</strong> Bạn chưa đăng nhập. Địa chỉ IP của bạn sẽ bị hiển thị công khai nếu bạn thực hiện bất kỳ sửa đổi nào. Nếu bạn <strong>[$1 đăng nhập]</strong> hoặc <strong>[$2 mở tài khoản]</strong>, sửa đổi của bạn sẽ được gán bởi tên đăng nhập của bạn, cùng nhiều lợi ích khác.",
        "anonpreviewwarning": "''Bạn chưa đăng nhập. Khi lưu trang này, địa chỉ IP của bạn sẽ được ghi vào lịch sử trang.''",
        "missingsummary": "'''Nhắc nhở:''' Bạn đã không ghi lại tóm lược sửa đổi. Nếu bạn nhấn Lưu trang một lần nữa, sửa đổi của bạn sẽ được lưu mà không có tóm lược.",
        "missingcommenttext": "Xin hãy gõ vào lời bàn luận ở dưới.",
        "parser-template-recursion-depth-warning": "Bản mẫu đã vượt quá giới hạn về độ sâu đệ quy ($1)",
        "language-converter-depth-warning": "Đã vượt quá giới hạn độ sâu của bộ chuyển đổi ngôn ngữ ($1)",
        "node-count-exceeded-category": "Trang có số nốt vượt quá giới hạn cho phép",
-       "node-count-exceeded-category-desc": "Thể loại chứa các trang có số nốt vượt quá giới hạn cho phép.",
-       "node-count-exceeded-warning": "Trang có nhiều nốt quá",
+       "node-count-exceeded-category-desc": "Trang có số nốt vượt quá giới hạn cho phép.",
+       "node-count-exceeded-warning": "Trang có quá nhiều nốt",
        "expansion-depth-exceeded-category": "Trang có độ sâu bung bản mẫu vượt quá giới hạn cho phép",
-       "expansion-depth-exceeded-category-desc": "Thể loại này chứa các trang có độ sâu bung bản mẫu vượt quá giới hạn cho phép.",
+       "expansion-depth-exceeded-category-desc": "Trang có độ sâu bung bản mẫu vượt quá giới hạn cho phép.",
        "expansion-depth-exceeded-warning": "Trang bung bản mẫu sâu quá",
        "parser-unstrip-loop-warning": "Vòng lặp unstrip",
        "parser-unstrip-recursion-limit": "Đã vượt quá giới hạn về độ sâu đệ quy unstrip ($1)",
        "searchall": "tất cả",
        "showingresults": "Dưới đây là {{PLURAL:$1|'''1'''|'''$1'''}} kết quả bắt đầu từ #'''$2'''.",
        "showingresultsinrange": "Dưới đây là cho tới <strong>$1</strong> kết quả từ #<strong>$2</strong> đến #<strong>$3</strong>.",
-       "showingresultsheader": "{{PLURAL:$5|Kết quả thứ '''$1''' trong tổng số '''$3''' kết quả|Các kết quả '''$1–$2''' trong tổng số '''$3''' kết quả}} cho '''$4'''",
+       "search-showingresults": "{{PLURAL:$4|Kết quả thứ <strong>$1</strong> trong tổng số <strong>$3</strong>|Các kết quả <strong>$1–$2</strong> trong tổng số <strong>$3</strong>}}",
        "search-nonefound": "Không có kết quả nào khớp với câu truy vấn.",
        "powersearch-legend": "Tìm kiếm nâng cao",
        "powersearch-ns": "Tìm trong không gian tên:",
        "preferences": "Tùy chọn",
        "mypreferences": "Tùy chọn",
        "prefs-edits": "Số lần sửa đổi:",
-       "prefsnologintext2": "Xin vui lòng $1 để thay đổi tùy chọn.",
+       "prefsnologintext2": "Xin vui lòng đăng nhập để thay đổi tùy chọn.",
        "prefs-skin": "Giao diện",
        "skin-preview": "Xem trước",
        "datedefault": "Không quan tâm",
        "randomincategory": "Trang ngẫu nhiên trong thể loại",
        "randomincategory-invalidcategory": "“$1” không phải tên thể loại hợp lệ.",
        "randomincategory-nopages": "Không có trang nào trong [[:Category:$1]].",
-       "randomincategory-selectcategory": "Xem trang ngẫu nhiên trong thể loại: $1 $2.",
-       "randomincategory-selectcategory-submit": "Xem",
+       "randomincategory-category": "Thể loại:",
+       "randomincategory-legend": "Trang ngẫu nhiên trong thể loại",
        "randomredirect": "Trang đổi hướng ngẫu nhiên",
        "randomredirect-nopages": "Không có trang đổi hướng nào trong không gian tên “$1”.",
        "statistics": "Thống kê",
        "trackingcategories-desc": "Tiêu chuẩn xếp thể loại",
        "noindex-category-desc": "Trang này không được các robot đánh chỉ mục vì trang có từ thần chú <code><nowiki>__NOINDEX__</nowiki></code> và nằm trong không gian tên cho phép từ thần chú này.",
        "index-category-desc": "Trang này có từ thần chú <code><nowiki>__INDEX__</nowiki></code> và nằm trong một không gian tên cho phép từ thần chú này, nên được các robot đánh chỉ mục, trong khi bình thường nó không được đánh chỉ mục.",
-       "post-expand-template-inclusion-category-desc": "Nếu bung tất cả các bản mẫu, kích thước trang sẽ vượt quá <code>$wgMaxArticleSize</code>, nên một số bản mẫu không được bung.",
-       "post-expand-template-argument-category-desc": "Nếu bung một tham số bản mẫu (tức định danh có mỗi bên ba dấu ngoặc móc, thí dụ <code>{{{Thí dụ}}}</code>), trang này sẽ vượt quá <code>$wgMaxArticleSize</code>.",
-       "expensive-parserfunction-category-desc": "Trang có quá nhiều hàm cú pháp cần mức độ xử lý cao (chẳng hạn như <code>#ifexist</code>). Xem [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:$wgExpensiveParserFunctionLimit?uselang=vi Manual:$wgExpensiveParserFunctionLimit].",
-       "broken-file-category-desc": "Trang này muốn nhúng một tập tin không tồn tại.",
-       "hidden-category-category-desc": "Thể loại này có <code><nowiki>__HIDDENCAT__</nowiki></code>, nên, theo mặc định, thể loại không xuất hiện trong hộp thể loại trên các trang được xếp vào thể loại.",
+       "post-expand-template-inclusion-category-desc": "Kích thước trang sẽ vượt quá <code>$wgMaxArticleSize</code> nếu bung hết toàn bộ bản mẫu, nên một số bản mẫu không được bung.",
+       "post-expand-template-argument-category-desc": "Trang này sẽ vượt quá <code>$wgMaxArticleSize</code> nếu bung một tham số bản mẫu (tức định danh có mỗi bên ba dấu ngoặc móc, thí dụ <code>{{{Thí dụ}}}</code>).",
+       "expensive-parserfunction-category-desc": "Trang có quá nhiều hàm cú pháp cần mức độ xử lý cao (chẳng hạn như <code>#ifexist</code>). Xem [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:$wgExpensiveParserFunctionLimit Manual:$wgExpensiveParserFunctionLimit].",
+       "broken-file-category-desc": "Trang này có một liên kết tập tin hỏng (liên kết nhúng tập tin không tồn tại).",
+       "hidden-category-category-desc": "Nội dung của trang thể loại này chứa <code><nowiki>__HIDDENCAT__</nowiki></code>, nên theo mặc định thì thể loại không xuất hiện trong thanh thể loại trên các trang được xếp vào thể loại.",
        "trackingcategories-nodesc": "Không có miêu tả.",
        "trackingcategories-disabled": "Thể loại bị tắt",
        "mailnologin": "Không có địa chỉ gửi thư",
        "mywatchlist": "Trang theo dõi",
        "watchlistfor2": "Của $1 $2",
        "nowatchlist": "Danh sách theo dõi của bạn không có gì.",
-       "watchlistanontext": "Xin hãy $1 để xem hay sửa đổi các trang được theo dõi.",
+       "watchlistanontext": "Xin hãy đăng nhập để xem hay sửa đổi các trang trong danh sách theo dõi của bạn.",
        "watchnologin": "Chưa đăng nhập",
        "addwatch": "Thêm vào danh sách theo dõi",
        "addedwatchtext": "Trang “[[:$1]]” đã vào [[Special:Watchlist|danh sách theo dõi]] của bạn.\nNhững sửa đổi đối với trang này và trang thảo luận của nó sẽ được liệt kê ở đấy.",
        "exbeforeblank": "nội dung trước khi tẩy trống: “$1”",
        "delete-confirm": "Xóa “$1”",
        "delete-legend": "Xóa",
-       "historywarning": "'''Cảnh báo:''' Trang bạn sắp xóa đã có lịch sử khoảng $1 {{PLURAL:$1|phiên bản|phiên bản}}:",
+       "historywarning": "<strong>Cảnh báo:</strong> Trang bạn sắp xóa đã có lịch sử $1 phiên bản:",
        "confirmdeletetext": "Bạn sắp xóa hẳn một trang cùng với tất cả lịch sử của nó.\nXin xác nhận việc bạn định làm, và hiểu rõ những hệ lụy của nó, và bạn thực hiện nó theo đúng đúng [[{{MediaWiki:Policy-url}}|quy định]].",
        "actioncomplete": "Đã thực hiện xong",
        "actionfailed": "Tác động bị thất bại",
        "delete-edit-reasonlist": "Sửa lý do xóa",
        "delete-toobig": "Trang này có lịch sử sửa đổi lớn, đến hơn {{PLURAL:$1|lần|lần}} sửa đổi.\nViệc xóa các trang như vậy bị hạn chế để ngăn ngừa phá hoại do vô ý cho {{SITENAME}}.",
        "delete-warning-toobig": "Trang này có lịch sử sửa đổi lớn, đến hơn {{PLURAL:$1|lần|lần}} sửa đổi.\nViệc xóa các trang có thể làm tổn hại đến hoạt động của cơ sở dữ liệu {{SITENAME}};\nhãy cẩn trọng khi thực hiện.",
+       "deleteprotected": "Bạn không thể xóa trang này vì nó đã được khóa lại.",
        "deleting-backlinks-warning": "'''Cảnh báo:''' Có [[Special:WhatLinksHere/{{FULLPAGENAME}}|trang khác]] liên kết đến hoặc nhúng trang mà bạn sắp xóa.",
        "rollback": "Lùi tất cả sửa đổi",
        "rollback_short": "Lùi tất cả",
        "protect-othertime": "Thời hạn khác:",
        "protect-othertime-op": "thời hạn khác",
        "protect-existing-expiry": "Thời hạn hiện thời: $3, $2",
+       "protect-existing-expiry-infinity": "Thời gian hết hạn hiện thời: vô hạn",
        "protect-otherreason": "Lý do khác/bổ sung:",
        "protect-otherreason-op": "Lý do khác",
        "protect-dropdown": "*Các lý do thường dùng khi khóa\n** Bị phá hoại quá mức\n** Bị spam quá mức\n** Bút chiến thiếu tính xây dựng\n** Trang nhiều người xem",
        "autoblockid": "Cấm tự động #$1",
        "block": "Cấm người dùng",
        "unblock": "Bỏ cấm người dùng",
-       "blockip": "Cấm người dùng",
+       "blockip": "Cấm {{GENDER:$1}}người dùng",
        "blockip-legend": "Cấm người dùng",
        "blockiptext": "Dùng mẫu dưới để cấm một địa chỉ IP hoặc thành viên không được viết trang.\nĐiều này chỉ nên làm để tránh phá hoại, và phải theo [[{{MediaWiki:Policy-url}}|quy định]].\nĐiền vào lý do cụ thể ở dưới (ví dụ, chỉ ra trang nào bị phá hoại).",
        "ipaddressorusername": "Địa chỉ IP hay tên thành viên:",
        "unblocked": "[[User:$1|$1]] đã hết bị cấm",
        "unblocked-range": "$1 đã được bỏ cấm",
        "unblocked-id": "$1 đã hết bị cấm",
+       "unblocked-ip": "[[Special:Contributions/$1|$1]] đã được bỏ cấm.",
        "blocklist": "Người dùng bị cấm",
        "ipblocklist": "Người dùng bị cấm",
        "ipblocklist-legend": "Tìm một thành viên bị cấm",
        "import": "Nhập các trang",
        "importinterwiki": "Nhập giữa các wiki",
        "import-interwiki-text": "Chọn tên trang và wiki để nhập trang vào.\nNgày của phiên bản và tên người viết trang sẽ được giữ nguyên.\nTất cả những lần nhập trang từ wiki khác được ghi lại ở [[Special:Log/import|nhật trình nhập trang]].",
-       "import-interwiki-source": "Wiki/trang mã nguồn:",
+       "import-interwiki-sourcewiki": "Wiki nguồn:",
+       "import-interwiki-sourcepage": "Trang nguồn:",
        "import-interwiki-history": "Sao chép tất cả các phiên bản cũ của trang này",
        "import-interwiki-templates": "Gồm tất cả các bản mẫu",
        "import-interwiki-submit": "Nhập",
        "logentry-rights-rights": "$1 {{GENDER:$2}}đã đổi các nhóm bao gồm $3 từ $4 đến $5",
        "logentry-rights-rights-legacy": "{{GENDER:$2}}$1 đã đổi các nhóm bao gồm $3",
        "logentry-rights-autopromote": "$1 {{GENDER:$2}}đã được tự động phong cấp từ $4 đến $5",
+       "logentry-upload-upload": "$1 {{GENDER:$2}}đã tải lên $3",
+       "logentry-upload-overwrite": "$1 {{GENDER:$2}}đã tải lên một phiên bản mới của $3",
+       "logentry-upload-revert": "$1 {{GENDER:$2}}đã tải lên $3",
        "rightsnone": "(không có)",
+       "revdelete-summary": "tóm lược sửa đổi",
        "feedback-bugornote": "Nếu bạn đã sẵn sàng để miêu tả các chi tiết của một vấn đề kỹ thuật, xin vui lòng [$1 báo cáo lỗi].\nNếu không thì bạn có thể điền biểu mẫu đơn giản ở dưới. Lời ghi của bạn sẽ được đăng lên trang “[$3 $2]”, cùng với tên người dùng và trình duyệt của bạn.",
        "feedback-subject": "Tiêu đề:",
        "feedback-message": "Thông điệp:",
        "action-pagelang": "thay đổi ngôn ngữ của trang",
        "log-name-pagelang": "Nhật trình thay đổi ngôn ngữ",
        "log-description-pagelang": "Nhật trình này ghi các thay đổi ngôn ngữ của các trang.",
-       "logentry-pagelang-pagelang": "$1 {{GENDER:$2}}đã đổi ngôn ngữ của trang $3 từ $4 thành $5."
+       "logentry-pagelang-pagelang": "$1 {{GENDER:$2}}đã đổi ngôn ngữ của trang $3 từ $4 thành $5.",
+       "default-skin-not-found": "Đã xảy ra lỗi! Giao diện mặc định của wiki này được định nghĩa trong <code dir=\"ltr\">$wgDefaultSkin</code> là <code>$1</code> nhưng không tồn tại.\n\nViệc cài đặt của bạn dường như bao gồm những giao diện sau đây. Xin xem [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Skin_configuration Hướng dẫn: Cấu hình giao diện] để biết thông tin về cách kích hoạt hoặc chọn một trong số chúng làm giao diện mặc định.\n\n$2\n\n; Nếu bạn vừa mới cài đặt MediaWiki:\n: Có lẽ bạn đã cài đặt nó từ git, hoặc trực tiếp từ mã nguồn bằng cách sử dụng một số phương thức khác. Điều này đã nằm trong tính toán của chúng tôi. Hãy thử cài đặt một số giao diện từ [https://www.mediawiki.org/wiki/Category:All_skins thư mục giao diện của mediawiki.org] bằng cách:\n:* Tải về [https://www.mediawiki.org/wiki/Special:MyLanguage/Download trình cài đặt dưới dạng gói tar], trong đó có kèm theo một số giao diện và phần mở rộng. Bạn có thể chép nó và dán vào thư mục <code>skins/</code>.\n:*Sao chép một trong những kho <code>mediawiki/skins/*</code> thông qua git vào trong thư mục <code dir=\"ltr\">skins/</code> của cài đặt MediaWiki của bạn.\n: Cách này sẽ không có ảnh hưởng đến kho git của bạn dù bạn là một nhà phát triển MediaWiki.\n\n; Nếu bạn vừa mới nâng cấp MediaWiki:\n: Phiên bản MediaWiki 1.24 trở lên không còn tự động kích hoạt giao diện đã cài đặt (xem [https://www.mediawiki.org/wiki/Manual:Skin_autodiscovery Hướng dẫn: Tự động dò giao diện]). Bạn có thể dán những dòng lệnh vào <code>LocalSettings.php</code> để kích hoạt tất cả giao diện hiện đã được cài dặt:\n\n<pre dir=\"ltr\">$3</pre>\n\n; Nếu bạn vừa mới chỉnh sửa <code>LocalSettings.php</code>:\n: Kiểm tra lại tên các giao diện xem có lỗi đánh máy nào không.",
+       "default-skin-not-found-no-skins": "Đã xảy ra lỗi! Giao diện mặc định của wiki này được định nghĩa trong <code dir=\"ltr\">$wgDefaultSkin</code> là <code>$1</code> nhưng không tồn tại.\n\nKhông có giao diện nào của bạn được kích hoạt.\n\n; Nếu bạn vừa mới cài đặt MediaWiki:\n: Bạn có thể cài đặt nó từ git, hoặc trực tiếp từ mã nguồn bằng cách sử dụng một số phương thức khác. Điều này nằm trong dự kiến. Hãy thử cài đặt một số giao diện từ [https://www.mediawiki.org/wiki/Category:All_skins thư mục giao diện của mediawiki.org], bằng cách:\n:* Tải về [https://www.mediawiki.org/wiki/Special:MyLanguage/Download trình cài đặt dưới dạng gói tar], trong đó có kèm theo một số giao diện và phần mở rộng. Bạn có thể chép nó và dán vào thư mục <code>skins/</code>.\n:*Sao chép một trong những kho <code>mediawiki/skins/*</code> thông qua git vào trong thư mục <code dir=\"ltr\">skins/</code> của cài đặt MediaWiki của bạn.\n: Cách này sẽ không có ảnh hưởng đến kho git của bạn dù bạn là một nhà phát triển MediaWiki. Xin xem [https://www.mediawiki.org/wiki/Manual:Skin_configuration Hướng dẫn: Cấu hình giao diện] để biết thông tin về cách kích hoạt hoặc chọn một trong số chúng làm giao diện mặc định.",
+       "default-skin-not-found-row-enabled": "* <code>$1</code> / $2 (kích hoạt)",
+       "default-skin-not-found-row-disabled": "* <code>$1</code> / $2 ('''vô hiệu hóa''')"
 }
index 49957ca..b01f36e 100644 (file)
        "userlogin-resetlink": "Avoz rovyî vos detays d' elodjaedje?",
        "createaccountmail": "pa emile",
        "createaccountreason": "Råjhon:",
+       "createacct-another-submit": "Ahiver èn ôte conte",
        "badretype": "Vos avoz dné deus screts diferins.",
        "userexists": "Li no d' uzeu ki vs avoz tchoezi est ddja eployî.\nTchoezixhoz è èn ôte s' i vs plait.",
        "loginerror": "Aroke d' elodjaedje",
        "accountcreated": "Conte ahivé",
        "accountcreatedtext": "Li conte d' uzeu «$1» a stî ahivé.",
        "loginlanguagelabel": "Lingaedje: $1",
+       "pt-login": "S' elodjî",
+       "pt-login-button": "S' elodjî",
+       "pt-createaccount": "Ahiver on novea conte",
+       "pt-userlogout": "\nSi dislodjî",
        "changepassword": "Candjî l' sicret",
        "resetpass_announce": "Vos vs avoz elodjî avou on scret timporaire ki vos a stî emilé.\nPor vos fini l' elodjaedje, vos dvoz defini on novea scret:",
        "resetpass_header": "Candjî l' sicret do conte",
        "passwordreset-email": "Adresse emile:",
        "passwordreset-emailtitle": "Detays do contre so {{SITENAME}}",
        "changeemail": "Candjî l' emile",
-       "changeemail-header": "Candjî l' adresse emile do conte",
        "changeemail-text": "Rimplixhoz l' formulrece po candjî voste adresse emile. Vos dvroz dner vosse sicret po-z acertiner l' candjmint.",
        "changeemail-no-info": "Vos dvoz esse elodjî po pleur aveur accès a cisse pådje ci.",
        "changeemail-oldemail": "Adresse emile pol moumint:",
        "changeemail-newemail": "Novele adresse emile:",
        "changeemail-none": "(nole)",
        "changeemail-submit": "Candjî l' emile",
-       "changeemail-cancel": "Rinoncî",
        "bold_sample": "Cråssès letes",
        "bold_tip": "Tecse e cråssès letes",
        "italic_sample": "Clintcheyès letes",
        "search-interwiki-more": "(dipus)",
        "searchall": "totafwait",
        "showingresults": "Chal pa dzo {{PLURAL:$1|'''1''' rizultat|'''$1''' rizultats}} a pårti do limero '''$2'''.",
-       "showingresultsheader": "{{PLURAL:$5|Rizultat '''$1'''|Rizultats '''$1 - $2'''}} foû di '''$3'' po '''$4'''",
        "search-nonefound": "N' a rén di çou ki vs cweroz après",
        "powersearch-legend": "Pus spepieus rcweraedjes",
        "powersearch-ns": "Cweri ezès espåces di lomaedje:",
        "pageinfo-watchers": "Nombe di shuveus",
        "pageinfo-edits": "Nombe di candjmints",
        "pageinfo-authors": "Nombe d' oteurs diferins",
-       "markaspatrolleddiff": "Marké come patrouyî",
+       "markaspatrolleddiff": "Marké come ricoridjî",
        "markaspatrolledtext": "Marker cisse pådje ci come dedja patrouyeye",
        "patrol-log-page": "Djournå des patrouyaedjes",
        "patrol-log-header": "Çouchal c' est on djournå des modêyes k' ont stî patrouyeyes.",
index f07949a..612aada 100644 (file)
        "passwordreset-emailsent-capture": "מען האט געשיקט א פאסווארט צוריקשטעלן בליצבריוו, וואס ווערט געוויזן אונטן.",
        "passwordreset-emailerror-capture": "מען האט געשאפן א פאסווארט צוריקשטעלן בליצבריוו, וואס ווערט געוויזן אונטן, אבער שיקן צום {{GENDER:$2|באניצער}}איז דורכגעפאלן: $1",
        "changeemail": "ענדערן ע-פּאָסט אַדרעס",
-       "changeemail-header": "ענדערן קאנטע ע-פּאָסט אַדרעס",
        "changeemail-text": "דערגאַנצט די פֿאָרעם צו ענדערן אייער ע-פּאָסט אַדרעס. איר וועט דאַרפֿן אַרײַנגעבן אײַער פּאַראָל צו באַשטעטיקן די ענדערונג.",
        "changeemail-no-info": "איר דאַרפֿט זיין אַרײַנלאגירט צוצוקומען גלײַך צו דעם דאָזיגן בלאַט.",
        "changeemail-oldemail": "קראַנטער ע-פּאָסט אַדרעס:",
        "changeemail-none": "(קיין)",
        "changeemail-password": "אייער {{SITENAME}} פאסווארט:",
        "changeemail-submit": "ענדערן ע־פאסט אדרעס",
-       "changeemail-cancel": "אַנולירן",
        "changeemail-throttled": "איר האט געפרוווט צופֿיל מאל אריינלאגירן.\nזייט אזוי גוט און וואַרט $1 איידער איר פרוווט נאכאמאל.",
        "resettokens": "צוריקזעצן טאקנס",
        "resettokens-text": "דא קענט איר צוריקשטעלן טאקנס וואס דערלויבן צוטריט צו געוויסע פריוואטע דאטן שייך צו אײַער קאנטע.\n\nYou should do it if you accidentally shared them with someone or if your account has been compromised.",
        "searchall": "אלץ",
        "showingresults": "ווייזן ביז {{PLURAL:$1|רעזולטאט '''איינס'''|'''$1''' רעזולטאטן}} אנגעפאנגן פון נומער #'''$2''':",
        "showingresultsinrange": "ווײַזן אונטן ביז {{PLURAL:$1|<strong>1</strong> רעזולטאט|<strong>$1</strong> רעזולטאטן}} אין גרייך #<strong>$2</strong> ביז #<strong>$3</strong>.",
-       "showingresultsheader": "{{PLURAL:$5|רעזולטאַט '''$1''' פֿון '''$3'''| רעזולטאַטן '''$1 - $2''' פֿון '''$3'''}} פֿאַר '''$4'''",
        "search-nonefound": "נישטא קיין רעזולטאטן פֿאַר דער שאלה.",
        "powersearch-legend": "ווײַטהאלטן זוכן",
        "powersearch-ns": "זוכן אין נאמענטיילן:",
        "movepagetalktext": "דער רעדן בלאט וועט ווערן באַוועגט אויטאמאֵטיש מיט אים, '''אחוץ:'''\n* ס'איז שוין דא א נישט-ליידיגער בלאט מיטן נייעם נאמען, אדער.\n* איר נעמט  אראפ דעם צייכן פונעם קעסטל אונטן.\n\nאין די פֿעלער, וועט איר דארפֿן באַוועגן אדער צונויפֿגיסן דעם בלאט האַנטלעך, ווען איר ווילט.",
        "movearticle": "באוועג בלאט:",
        "moveuserpage-warning": "'''ווארענונג:''' איר האלט ביי באוועגן א באניצער בלאט. ביטע באמערקט אז נאר דער בלאט ווערט באוועגט אבער דער באניצער נאמען ווערט ''נישט'' געענדערט.",
+       "movecategorypage-warning": "<strong>ווארענונג:</strong> איר האלט ביי באוועגן א קאטעגאריע בלאט. גיט אכט אז נאר דער בלאט וועט ווערן באוועגט, אבער די בלעטער אין דער אלטער קאטעגאריע וועט מען <em>נישט</em> be ארײַנשטעלן אין דער נייער קאטעגאריע.",
        "movenologintext": "איר דארפֿט זיך אײַנשרײַבן און זײַן  [[Special:UserLogin|אַרײַנלאגירט]] צו באַוועגן א בלאַט.",
        "movenotallowed": "איר זענט נישט דערלויבט צו באוועגן בלעטער.",
        "movenotallowedfile": "איר האט נישט קיין רשות צו באוועגן טעקעס.",
        "logentry-rights-rights-legacy": "$1 {{GENDER:$2|האט געביטן}} גרופע מיטגלידערשאפט פאר $3",
        "logentry-rights-autopromote": "$1 אויטאמאטיש  {{GENDER:$2|פראמאווירט}} פון $4 צו $5",
        "rightsnone": "(גארנישט)",
+       "revdelete-summary": "רעדאקטירונג קיצור",
        "feedback-bugornote": "ווען איר זענט גרייט צו באשרייבן א טעכנישן פראבלעם ביטע [$1 מעלדט א פעלער].\nאנדערש, קענט איר ניצן די גרינגע פארעם אונטן. מען וועט צולייגן אייער הערה צום בלאט \"[$3 $2]\", צוזאמען מיט אייער באניצער נאמען און וועלכן בלעטערער איר ניצט.",
        "feedback-subject": "טעמע:",
        "feedback-message": "מעלדונג:",
index 337efcc..ba4dacb 100644 (file)
        "october-date": "10月$1日",
        "november-date": "11月$1日",
        "december-date": "12月$1日",
-       "pagecategories": "{{PLURAL:$1|分类|$1个分类}}",
+       "pagecategories": "{{PLURAL:$1|分类}}",
        "category_header": "分类“$1”中的页面",
        "subcategories": "子分类",
        "category-media-header": "分类“$1”中的媒体文件",
        "category-empty": "<em>本分类目前没有包含页面或媒体文件。</em>",
-       "hidden-categories": "{{PLURAL:$1|隐藏分类}}",
+       "hidden-categories": "{{PLURAL:$1|隐藏分类|$1个隐藏分类}}",
        "hidden-category-category": "隐藏分类",
        "category-subcat-count": "{{PLURAL:$2|本分类只有以下子分类。|本分类有以下$1个子分类,共有$2个子分类。}}",
        "category-subcat-count-limited": "本分类有以下{{PLURAL:$1|子分类|$1个子分类}}。",
        "policy-url": "Project:方针",
        "portal": "社区主页",
        "portal-url": "Project:社区专页",
-       "privacy": "é\9a\90ç§\81æ\9d\83æ\94¿ç­\96",
+       "privacy": "隐私政策",
        "privacypage": "Project:隐私权政策",
        "badaccess": "权限错误",
        "badaccess-group0": "你被禁止执行你刚才请求的操作。",
        "hidetoc": "隐藏",
        "collapsible-collapse": "折叠",
        "collapsible-expand": "展开",
-       "confirmable-confirm": "{{GENDER:$1|}}确定么?",
+       "confirmable-confirm": "{{GENDER:$1|}}确定么?",
        "confirmable-yes": "是",
        "confirmable-no": "否",
        "thisisdeleted": "查看或还原$1?",
        "passwordreset-emailsent-capture": "密码重设电子邮件已发送,并在下面显示。",
        "passwordreset-emailerror-capture": "重置密码邮件已生成,但是无法向{{GENDER:$2|下列用户}} 发送:$1",
        "changeemail": "更改电子邮件地址",
-       "changeemail-header": "更改账户电子邮件地址",
        "changeemail-text": "完成该表格以更改你的电子邮件地址。你需要输入你的密码以确认该更改。",
        "changeemail-no-info": "\n您必须登录以直接访问本页。",
        "changeemail-oldemail": "当前电子邮件地址:",
        "changeemail-none": "(无)",
        "changeemail-password": "你的{{SITENAME}}密码:",
        "changeemail-submit": "更改电子邮件地址",
-       "changeemail-cancel": "取消",
        "changeemail-throttled": "您最近尝试了太多次登录。请等待$1后再试。",
        "resettokens": "重置密钥",
        "resettokens-text": "你可以在这里重置允许访问与你的账户有关的特定私人数据的密钥。\n\n如果你意外将它们分享给他人,或是你的账户已经被入侵,你应该重置它们。",
        "searchall": "所有",
        "showingresults": "下面显示从第'''$2'''条结果开始的'''$1'''条结果。",
        "showingresultsinrange": "下面显示区间#<strong>$2</strong>至#<strong>$3</strong>的<strong>$1</strong>条结果。",
-       "showingresultsheader": "关于<strong>$4</strong>的{{PLURAL:$5|第<strong>$1</strong>条结果,共<strong>$3</strong>条结果|第<strong>$1 - $2</strong>条结果,共<strong>$3</strong>条结果}}",
+       "search-showingresults": "{{PLURAL:$4|<strong>$3</strong>条结果中的<strong>$1</strong>条|<strong>$3</strong>条结果中的<strong>$1~$2</strong>条}}",
        "search-nonefound": "找不到和查询相匹配的结果。",
        "powersearch-legend": "高级搜索",
        "powersearch-ns": "搜索名字空间:",
        "prefs-tokenwatchlist": "密钥",
        "prefs-diffs": "差异对比",
        "prefs-help-prefershttps": "该设置将在下次登录时生效。",
+       "prefswarning-warning": "您对您的参数设置的更改尚未保存。如果您不点击“$1”就离开,您的设置就不会更新。",
        "prefs-tabs-navigation-hint": "提示:您可以通过左、右箭头键在选项卡之间切换。",
        "email-address-validity-valid": "电子邮件地址有效",
        "email-address-validity-invalid": "请输入有效的电子邮件地址",
        "protect-othertime": "其它时间:",
        "protect-othertime-op": "其它时间",
        "protect-existing-expiry": "现有的终止时间:$2 $3",
+       "protect-existing-expiry-infinity": "当前到期时间:无限期",
        "protect-otherreason": "其他/附加原因:",
        "protect-otherreason-op": "其他原因",
        "protect-dropdown": "*常见保护原因\n** 过度破坏\n** 过多垃圾信息\n** 负面的编辑战\n** 高流量页面",
        "unblocked": "[[User:$1|$1]]已经被解封",
        "unblocked-range": "$1已被解封",
        "unblocked-id": "封禁$1已被解除",
+       "unblocked-ip": "[[Special:Contributions/$1|$1]]已解封。",
        "blocklist": "被封禁用户",
        "ipblocklist": "被封禁用户",
        "ipblocklist-legend": "查找被封禁用户",
        "thumbnail-more": "放大",
        "filemissing": "无法找到文件",
        "thumbnail_error": "生成缩略图出错:$1",
-       "thumbnail_error_remote": "来自$1的错误消息从:\n$2",
+       "thumbnail_error_remote": "来自$1的错误消息$2",
        "djvu_page_error": "DjVu页面超出范围",
        "djvu_no_xml": "无法在DjVu文件中获取XML",
        "thumbnail-temp-create": "无法创建临时缩略图文件",
        "logentry-upload-overwrite": "$1{{GENDER:$2|上传了}}$3的新版本",
        "logentry-upload-revert": "$1{{GENDER:$2|上传了}}$3",
        "rightsnone": "(无)",
+       "revdelete-summary": "编辑摘要",
        "feedback-bugornote": "如果你准备好详细描述一个技术问题,请[$1 报告bug]。或者你可以使用下面的简单表格。你的评论将被添加至页面“[$3 $2]”,附有你的用户名。",
        "feedback-subject": "主题:",
        "feedback-message": "信息:",
        "log-name-pagelang": "更改语言日志",
        "log-description-pagelang": "这是页面语言更改的日志。",
        "logentry-pagelang-pagelang": "$1{{GENDER:$2|更改}}$3的页面语言:从$4改为$5。",
-       "default-skin-not-found": "天哪!您wiki的默认皮肤(<code>$wgDefaultSkin</code>)<code>$1</code>不可用。您的安装版本看起来需要包含以下皮肤。参见MediaWiki官网手册[https://www.mediawiki.org/wiki/Manual:Skin_configuration “皮肤配置”]获取如何启用他们并设置为默认。\n\n$2\n\n; 如果您刚刚安装完了MediaWiki的话:\n: 您可能是从git库安装的,或者使用其他方法直接从源代码安装的。希望如此。尝试通过以下方法从[https://www.mediawiki.org/wiki/Category:All_skins mediawiki.org的皮肤存储库]安装一些皮肤:\n:* 下载[https://www.mediawiki.org/wiki/Download/zh-hans 打包安装器],这会预装一些皮肤和扩展。您可在此处复制粘贴<code>skins/</code>。\n:* 通过git直接克隆<code>mediawiki/skins/*</code>存储库中的一个至您的MediaWiki副本的<code>skins/</code>。\n: 做这些事应该不会打扰您的git存储库如果你是MediaWiki开发人员的话。\n\n; 如果您升级了您的MediaWiki的话:\n: MediaWiki 1.24版本起不再自动启用已安装皮肤(参见[https://www.mediawiki.org/wiki/Manual:Skin_autodiscovery 此手册])。您可复制粘贴以下文本至您wiki的<code>LocalSettings.php</code>以启用安装的皮肤:\n\n<pre>$3</pre>\n\n; 如果您已经修改了<code>LocalSettings.php</code>:\n: 请再次检查皮肤名以确保不存在错误拼写。",
-       "default-skin-not-found-no-skins": "天哪!您wiki的默认皮肤(<code>$wgDefaultSkin</code>)<code>$1</code>不可用。而且您没有安装任何皮肤。\n\n; 如果您刚刚安装完了MediaWiki的话:\n: 您可能是从git库安装的,或者使用其他方法直接从源代码安装的。希望如此。尝试通过以下方法从[https://www.mediawiki.org/wiki/Category:All_skins mediawiki.org的皮肤存储库]安装一些皮肤:\n:* 下载[https://www.mediawiki.org/wiki/Download/zh-hans 打包安装器],这会预装一些皮肤和扩展。您可在此处复制粘贴<code>skins/</code>。\n:* 通过git直接克隆<code>mediawiki/skins/*</code>存储库中的一个至您的MediaWiki副本的<code>skins/</code>。\n: 做这些事应该不会打扰您的git存储库如果你是MediaWiki开发人员的话。参见MediaWiki官网手册[https://www.mediawiki.org/wiki/Manual:Skin_configuration “皮肤配置”]获取如何启用他们并设置为默认。",
+       "default-skin-not-found": "天哪!您在<code dir=\"ltr\">$wgDefaultSkin</code>定义的wiki默认皮肤<code>$1</code>不可用。您的安装版本看起来需要包含以下皮肤。参见MediaWiki官网手册[https://www.mediawiki.org/wiki/Manual:Skin_configuration “皮肤配置”]获取如何启用他们并设置为默认。\n\n$2\n\n; 如果您刚刚安装完了MediaWiki的话:\n: 您可能是从git库安装的,或者使用其他方法直接从源代码安装的。希望如此。尝试通过以下方法从[https://www.mediawiki.org/wiki/Category:All_skins mediawiki.org的皮肤存储库]安装一些皮肤:\n:* 下载[https://www.mediawiki.org/wiki/Download/zh-hans 打包安装器],这会预装一些皮肤和扩展。您可在此处复制粘贴<code>skins/</code>。\n:* 通过git直接克隆<code>mediawiki/skins/*</code>存储库中的一个至您的MediaWiki副本的<code dir=\"ltr\">skins/</code>。\n: 做这些事应该不会打扰您的git存储库如果你是MediaWiki开发人员的话。\n\n; 如果您升级了您的MediaWiki的话:\n: MediaWiki 1.24版本起不再自动启用已安装皮肤(参见[https://www.mediawiki.org/wiki/Manual:Skin_autodiscovery 此手册])。您可复制粘贴以下文本至您wiki的<code>LocalSettings.php</code>以启用安装的皮肤:\n\n<pre dir=\"ltr\">$3</pre>\n\n; 如果您已经修改了<code>LocalSettings.php</code>:\n: 请再次检查皮肤名以确保不存在错误拼写。",
+       "default-skin-not-found-no-skins": "天哪!您在<code>$wgDefaultSkin</code>定义的wiki默认皮肤<code>$1</code>不可用。而且您没有安装任何皮肤。\n\n; 如果您刚刚安装完了MediaWiki的话:\n: 您可能是从git库安装的,或者使用其他方法直接从源代码安装的。希望如此。尝试通过以下方法从[https://www.mediawiki.org/wiki/Category:All_skins mediawiki.org的皮肤存储库]安装一些皮肤:\n:* 下载[https://www.mediawiki.org/wiki/Download/zh-hans 打包安装器],这会预装一些皮肤和扩展。您可在此处复制粘贴<code>skins/</code>。\n:* 通过git直接克隆<code>mediawiki/skins/*</code>存储库中的一个至您的MediaWiki副本的<code dir=\"ltr\">skins/</code>。\n: 做这些事应该不会打扰您的git存储库如果你是MediaWiki开发人员的话。参见MediaWiki官网手册[https://www.mediawiki.org/wiki/Manual:Skin_configuration “皮肤配置”]获取如何启用他们并设置为默认。",
        "default-skin-not-found-row-enabled": "* <code>$1</code> / $2(已启用)",
-       "default-skin-not-found-row-disabled": "* <code>$1</code> / $2('''已禁用''')"
+       "default-skin-not-found-row-disabled": "* <code>$1</code> / $2('''已禁用''')",
+       "mediastatistics": "媒体统计",
+       "mediastatistics-summary": "有关上传文件类型的统计。这只包含文件的最新版本,旧版本或删除版本则不会包括。",
+       "mediastatistics-nbytes": "{{PLURAL:$1|$1字节}}($2;$3%)",
+       "mediastatistics-table-mimetype": "MIME类型",
+       "mediastatistics-table-extensions": "可能的扩展",
+       "mediastatistics-table-count": "文件数",
+       "mediastatistics-table-totalbytes": "组合尺寸",
+       "mediastatistics-header-unknown": "未知",
+       "mediastatistics-header-bitmap": "位图图像",
+       "mediastatistics-header-drawing": "图纸(矢量图像)",
+       "mediastatistics-header-audio": "音频",
+       "mediastatistics-header-video": "视频",
+       "mediastatistics-header-multimedia": "富媒体",
+       "mediastatistics-header-office": "办公文件",
+       "mediastatistics-header-text": "文本",
+       "mediastatistics-header-executable": "可执行文件",
+       "mediastatistics-header-archive": "压缩格式"
 }
index d3ea390..b1af745 100644 (file)
@@ -61,7 +61,7 @@
                ]
        },
        "tog-underline": "連結顯示底線:",
-       "tog-hideminor": "é\9a±è\97\8fæ\9c\80è¿\91è®\8aæ\9b´ä¸­ç\9a\84å°\8fä¿®è¨\82",
+       "tog-hideminor": "é\9a±è\97\8fæ\9c\80è¿\91è®\8aæ\9b´ä»¥ä¾\86ç\9a\84å°\8f編輯",
        "tog-hidepatrolled": "隱藏最近變更中巡查過的編輯",
        "tog-newpageshidepatrolled": "隱藏新頁面清單中巡查過的頁面",
        "tog-extendwatchlist": "展開監視清單顯示包含最近以外的所有變更",
        "otherlanguages": "其他語言",
        "redirectedfrom": "(已重新導向自 $1)",
        "redirectpagesub": "重新導向頁面",
+       "redirectto": "重新導向至:",
        "lastmodifiedat": "此頁面最後修訂於 $1 $2。",
        "viewcount": "此頁面已被檢視過 $1 次。",
        "protectedpage": "受保護頁面",
        "throttled-mailpassword": "密碼重設的電子郵件已經在最近 $1 小時內寄出。\n為防止濫用,$1 小時內只能寄出一次密碼重設信件。",
        "mailerror": "傳送電子郵件錯誤:$1",
        "acct_creation_throttle_hit": "使用您目前的 IP 位址的訪客在最近一天建立了 {{PLURAL:$1|1 個帳號|$1 個帳號}},已超出系統允許的上限。\n因此,目前無法讓使用此 IP 位址的訪客建立帳號。",
-       "emailauthenticated": "您的電子郵件位址已確認於 $2 的 $3。",
+       "emailauthenticated": "您的電子郵件位址已於 $2 $3 確認。",
        "emailnotauthenticated": "您的電子郵件位址尚未確認,\n尚不會寄出以下功能的電子郵件給您。",
        "noemailprefs": "在您的偏好設定中設定電子郵件位址,讓您可以使用這些功能。",
        "emailconfirmlink": "確認您的電子郵件位址",
        "createaccount-text": "不明人士使用您的電子郵件位址在 {{SITENAME}} ($4) 建立了一個帳號名稱為 \"$2\",密碼為 \"$3\"。\n您應該立即登入並更改密碼。\n\n如果該帳號是建立錯誤的話,您可以忽略此訊息。",
        "login-throttled": "您已經嘗試太多次的登入動作。\n請稍等 $1 後再試。",
        "login-abort-generic": "您登入失敗 - 已中止",
+       "login-migrated-generic": "您的帳號已轉移,且此 Wiki 中您的使用者名稱已不存在。",
        "loginlanguagelabel": "語言:$1",
        "suspicious-userlogout": "您登出的請求被拒絕,可能是因您使用了有問題的瀏覽器或者快取代理伺服器。",
        "createacct-another-realname-tip": "真實姓名為選填欄位。\n若您提供真實姓名,它會用於使用者貢獻署名。",
        "passwordreset-emailsent-capture": "已寄出重設密碼的電子郵件,並於下方顯示。",
        "passwordreset-emailerror-capture": "下列為重設密碼的電子郵件內容,傳送給{{GENDER:$2|使用者}}失敗:$1",
        "changeemail": "變更電子郵件位址",
-       "changeemail-header": "變更帳號的電子郵件位址",
        "changeemail-text": "完成此表單以修改您的電子郵件位址,您需要輸入您的密碼來確認此次變更。",
        "changeemail-no-info": "您必須登入方可直接存取此頁面。",
        "changeemail-oldemail": "目前的電子郵件位址:",
        "changeemail-none": "(無)",
        "changeemail-password": "您於 {{SITENAME}} 的密碼:",
        "changeemail-submit": "變更電子郵件",
-       "changeemail-cancel": "取消",
        "changeemail-throttled": "您最近嘗試了太多次登入。\n請等待 $1 後再試。",
        "resettokens": "重設密鑰",
        "resettokens-text": "您可以在此重設用來存取您帳號相關隱私資料的密鑰。\n\n若您不小心將您的密鑰分享給其他人或您的帳號已遭到入侵、破壞,應該要重設此密鑰。",
        "headline_tip": "第 2 層標題文字",
        "nowiki_sample": "插入非格式化文字",
        "nowiki_tip": "忽略 Wiki 格式化語法",
+       "image_sample": "範例.jpg",
        "image_tip": "附加檔案",
        "media_tip": "檔案連結",
        "sig_tip": "您的簽名與日期時間",
        "search-suggest": "您指的是不是:$1",
        "search-interwiki-caption": "姐妹專案",
        "search-interwiki-default": "來自 $1 的結果:",
-       "search-interwiki-more": "(更多)",
+       "search-interwiki-more": "(更多)",
        "search-relatedarticle": "相關",
        "searchrelated": "相關",
        "searchall": "全部",
        "showingresults": "以下顯示從第 <strong>$2</strong> 筆開始,共 {{PLURAL:$1|<strong>1</strong> 筆結果|<strong>$1</strong> 筆結果}}:",
        "showingresultsinrange": "以下顯示從第 <strong>$2</strong> 筆至第 <strong>$3</strong> 筆中的 {{PLURAL:$1|<strong>1</strong> 筆結果|<strong>$1</strong> 筆結果}}:",
-       "showingresultsheader": "<strong>$4</strong> 的 {{PLURAL:$5|第 <strong>$1</strong> 筆結果,共 <strong>$3</strong> 筆|第 <strong>$1 - $2</strong>,共 <strong>$3</strong> 筆}}",
+       "search-showingresults": "{{PLURAL:$4|<strong>$3</strong> 的 <strong>$1</strong> 筆結果|<strong>$3</strong> 的 <strong>$1 - $2</strong> 筆結果}}",
        "search-nonefound": "無符合查詢條件的結果。",
        "powersearch-legend": "進階搜尋",
        "powersearch-ns": "搜尋以下命名空間:",
        "prefs-tokenwatchlist": "密鑰",
        "prefs-diffs": "差異",
        "prefs-help-prefershttps": "此偏好設定將於您下次登入時生效。",
+       "prefswarning-warning": "您對您的偏好設定所做的變更尚未儲存。\n若您未點選 \"$1\" 離開此頁面,將不會更新您的偏好設定。",
        "prefs-tabs-navigation-hint": "提示:您可使用左、右方向鍵切換頁籤。",
        "email-address-validity-valid": "電子郵件位址有效",
        "email-address-validity-invalid": "請輸入一個有效的電子郵件位址",
        "protect-othertime": "其它時間:",
        "protect-othertime-op": "其它時間",
        "protect-existing-expiry": "已設定期限:$2 $3",
+       "protect-existing-expiry-infinity": "已設定的期限:無限期",
        "protect-otherreason": "其它/額外的原因:",
        "protect-otherreason-op": "其它原因",
        "protect-dropdown": "*常見的保護原因\n** 過度的破壞\n** 過多垃圾訊息\n** 反生產性的編輯戰\n** 高流量頁面",
        "unblocked": "[[User:$1|$1]] 的封鎖已經解除。",
        "unblocked-range": "已解除封鎖 $1。",
        "unblocked-id": "已經移除 $1 的封鎖。",
+       "unblocked-ip": "[[Special:Contributions/$1|$1]] 已解除封鎖。",
        "blocklist": "已封鎖的使用者",
        "ipblocklist": "已封鎖的使用者",
        "ipblocklist-legend": "搜尋已封鎖的使用者",
        "ipb_blocked_as_range": "錯誤:IP 位址 $1 並不是直接被封鎖,因此無法直接解除封鎖。\n此 IP 位址在 $2 的封鎖範圍之中,您可以解決此範圍的封鎖。",
        "ip_range_invalid": "無效的 IP 範圍。",
        "ip_range_toolarge": "不允許封鎖範圍大於 /$1。",
-       "proxyblocker": "代理封鎖器",
+       "proxyblocker": "代理伺服器封鎖器",
        "proxyblockreason": "因您的 IP 位址是開放代理伺服器,已被封鎖。\n請聯繫您的網絡服務供應商或您所在組織的技術支援,告知他們此嚴重的安全性問題。",
        "sorbsreason": "您的 IP 位址在 {{SITENAME}} 使用的 DNSBL 列為開放代理伺服器。",
        "sorbs_create_account_reason": "您連線到 {{SITENAME}} 的 IP 位址被 DNSBL 列為開放代理伺服器。\n您不能建立帳號。",
        "compare-rev1": "修訂 1",
        "compare-rev2": "修訂 2",
        "compare-submit": "比較",
-       "compare-invalid-title": "æ\89\80æ\8c\87å®\9a標題無效。",
-       "compare-title-not-exists": "æ\89\80æ\8c\87å®\9aç\9a\84話題不存在。",
-       "compare-revision-not-exists": "所指定的修訂不存在。",
+       "compare-invalid-title": "æ\82¨æ\89\80æ\8c\87å®\9aç\9a\84標題無效。",
+       "compare-title-not-exists": "æ\82¨æ\89\80æ\8c\87å®\9aç\9a\84æ¨\99題不存在。",
+       "compare-revision-not-exists": "æ\82¨æ\89\80æ\8c\87å®\9aç\9a\84ä¿®è¨\82ä¸\8då­\98å\9c¨ã\80\82",
        "dberr-problems": "抱歉!這個網站出現了一些技術上的問題。",
        "dberr-again": "嘗試等候數分鐘後,然後再試。",
        "dberr-info": "(無法連線資料庫伺服器:$1)",
        "dberr-info-hidden": "(無法連線資料庫伺服器)",
-       "dberr-usegoogle": "在現階段您可以嘗試透過 Google 搜尋。",
-       "dberr-outofdate": "留意他們索引出來之內容可能不是最新的。",
-       "dberr-cachederror": "這個是所要求出來的快取複本,可能不是最新的。",
+       "dberr-usegoogle": "您可以嘗試在此期間使用 Google 搜尋。",
+       "dberr-outofdate": "注意,它們用來建立索引的內容可能不是最新的。",
+       "dberr-cachederror": "這是請求面頁面的快取複本,可能不是最新的。",
        "htmlform-invalid-input": "您的輸入的內容有問題。",
        "htmlform-select-badoption": "您所指定的值不是有效的選項。",
        "htmlform-int-invalid": "您所指定的值不是一個整數。",
        "logentry-upload-overwrite": "$1 {{GENDER:$2|上傳了}}新版本的 $3",
        "logentry-upload-revert": "$1 {{GENDER:$2|已上傳}} $3",
        "rightsnone": "(無)",
+       "revdelete-summary": "編輯摘要",
        "feedback-bugornote": "如果您準備要詳細描述一個技術問題,請至 [$1 回報問題]。\n或您可以使用以下的簡易表單回報問題,您的使用者名稱與評論將被新增到頁面 \"[$3 $2]\"。",
        "feedback-subject": "主旨:",
        "feedback-message": "訊息:",
        "api-error-file-too-large": "您送出的檔案太大了。",
        "api-error-filename-tooshort": "檔案名稱過短。",
        "api-error-filetype-banned": "此檔案類型已禁止使用。",
-       "api-error-filetype-banned-type": "$1{{PLURAL:$4|不是允許的檔案類型}}。  允許的{{PLURAL:$3|檔案類型是}} $2。",
+       "api-error-filetype-banned-type": "$1 {{PLURAL:$4|不是允許的檔案類型}}。 允許的{{PLURAL:$3|檔案類型有}} $2。",
        "api-error-filetype-missing": "此檔案名稱缺少副檔名。",
-       "api-error-hookaborted": "你試圖進行的修改被一個擴展鉤子終止。",
+       "api-error-hookaborted": "您嘗試進行的修改被某個擴充套件中止。",
        "api-error-http": "內部錯誤:無法連線到伺服器。",
        "api-error-illegal-filename": "不允許使用的檔案名稱。",
        "api-error-internal-error": "內部錯誤:此 Wiki 在處理你的上傳時發生錯誤。",
        "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": "不允許覆蓋已存在的檔案。",
        "limitreport-cputime-value": "$1 秒",
        "limitreport-walltime": "實際使用時間",
        "limitreport-walltime-value": "$1 秒",
-       "limitreport-ppvisitednodes": "預處理機訪問節點次數",
+       "limitreport-ppvisitednodes": "預處理器已訪問節點計數",
        "limitreport-ppgeneratednodes": "預處理器產生節點次數",
        "limitreport-postexpandincludesize": "展開後的引用大小",
        "limitreport-postexpandincludesize-value": "$1/$2 個{{PLURAL:$2|位元組}}",
        "right-pagelang": "更改頁面語言",
        "action-pagelang": "更改頁面語言",
        "log-name-pagelang": "更改語言日誌",
-       "log-description-pagelang": "這是頁面語言更改日誌。",
+       "log-description-pagelang": "此頁為頁面語言的變更日誌。",
        "logentry-pagelang-pagelang": "$1 {{GENDER:$2|已更改}}頁面 $3 的語言從 $4 到 $5。",
-       "default-skin-not-found": "哎呀!您的 Wiki 預設外觀 (<code>$wgDefaultSkin</code>),<code>$1</code> 無法使用。\n\n您的安裝程序應包含以下外觀。 請參考 [https://www.mediawiki.org/wiki/Manual:Skin_configuration 操作手冊:外觀設定] 以取得如何開啟外觀並設為預設值的資訊。\n\n$2\n\n; 若您才剛安裝完 MediaWiki:\n: 您大概是使用 git 或直接透過原始碼使用其他方法安裝,這種情況是正常的。請嘗試安裝 [https://www.mediawiki.org/wiki/Category:All_skins mediawiki.org 的外觀目錄] 中的部份外觀使用以下方式:\n:* 下載 [https://www.mediawiki.org/wiki/Special:MyLanguage/Download tarball 安裝程式],該程式包含數個外觀與擴充套件。 您可以複製並貼上至 <code>skins/</code> 目錄。\n:* 透過 git 複製 <code>mediawiki/skins/*</code> 儲存庫中其中一個外觀到您安裝的 MediaWiki <code>skins/</code> 目錄中。\n: 若您是 MediaWiki 的開發人員,這麼做應該不會影響到您的 git 儲存庫。\n\n; 若您才剛升級 MediaWiki:\n: MediaWiki 1.24 與較新的版本不再自動開啟已安裝的外觀 (請參考 [https://www.mediawiki.org/wiki/Manual:Skin_autodiscovery 操作手冊:外觀自動搜尋])。 您可以將下列行貼上至 <code>LocalSettings.php</code> 來開啟所有目前已經安裝的外觀:\n\n<pre>$3</pre>\n\n; 若您才剛修改 <code>LocalSettings.php</code>:\n: 請再次確認您輸入的外觀名稱是否有誤。",
-       "default-skin-not-found-no-skins": "哎呀!您的 Wiki 預設外觀 (<code>$wgDefaultSkin</code>),<code>$1</code> 無法使用。\n\n您未安裝任何的外觀。\n\n; 若您才剛安裝完或升級完 MediaWiki:\n: 您大概是使用 git 或直接透過原始碼使用其他方法安裝,這種情況是正常的。 MediaWiki 1.24 或較新的版本在主要儲存庫中不再包含任何的外觀。 請嘗試安裝 [https://www.mediawiki.org/wiki/Category:All_skins mediawiki.org 的外觀目錄] 中的部份外觀使用以下方式:\n:* 下載 [https://www.mediawiki.org/wiki/Download tarball 安裝程式],該程式包含數個外觀與擴充套件。 您可以複製並貼上至 <code>skins/</code> 目錄。\n:* 透過 git 複製 <code>mediawiki/skins/*</code> 儲存庫中其中一個外觀到您安裝的 MediaWiki <code>skins/</code> 目錄中。\n: 若您是 MediaWiki 的開發人員,這麼做應該不會影響到您的 git 儲存庫。 請參考 [https://www.mediawiki.org/wiki/Manual:Skin_configuration 操作手冊:外觀設定] 以取得如何開啟外觀並設為預設值的資訊。",
+       "default-skin-not-found": "哎呀!您於 <code dir=\"ltr\">$wgDefaultSkin</code> 設定的 Wiki 預設外觀 <code>$1</code> 無法使用。\n\n您的安裝程序應包含以下外觀。 請參考 [https://www.mediawiki.org/wiki/Manual:Skin_configuration 操作手冊:外觀設定] 以取得如何開啟外觀並設為預設值的資訊。\n\n$2\n\n; 若您才剛安裝完 MediaWiki:\n: 您大概是使用 git 或直接透過原始碼使用其他方法安裝,這種情況是正常的。請嘗試安裝 [https://www.mediawiki.org/wiki/Category:All_skins mediawiki.org 的外觀目錄] 中的部份外觀使用以下方式:\n:* 下載 [https://www.mediawiki.org/wiki/Special:MyLanguage/Download tarball 安裝程式],該程式包含數個外觀與擴充套件。 您可以複製並貼上至 <code>skins/</code> 目錄。\n:* 透過 git 複製 <code>mediawiki/skins/*</code> 儲存庫中其中一個外觀到您安裝的 MediaWiki <code dir=\"ltr\">skins/</code> 目錄中。\n: 若您是 MediaWiki 的開發人員,這麼做應該不會影響到您的 git 儲存庫。\n\n; 若您才剛升級 MediaWiki:\n: MediaWiki 1.24 與較新的版本不再自動開啟已安裝的外觀 (請參考 [https://www.mediawiki.org/wiki/Manual:Skin_autodiscovery 操作手冊:外觀自動搜尋])。 您可以將下列行貼上至 <code>LocalSettings.php</code> 來開啟所有目前已經安裝的外觀:\n\n<pre dir=\"ltr\">$3</pre>\n\n; 若您才剛修改 <code>LocalSettings.php</code>:\n: 請再次確認您輸入的外觀名稱是否有誤。",
+       "default-skin-not-found-no-skins": "哎呀!您於 <code>$wgDefaultSkin</code> 設定的 Wiki 預設外觀 <code>$1</code> 無法使用。\n\n您未安裝任何的外觀。\n\n; 若您才剛安裝完或升級完 MediaWiki:\n: 您大概是使用 git 或直接透過原始碼使用其他方法安裝,這種情況是正常的。 MediaWiki 1.24 或較新的版本在主要儲存庫中不再包含任何的外觀。 請嘗試安裝 [https://www.mediawiki.org/wiki/Category:All_skins mediawiki.org 的外觀目錄] 中的部份外觀使用以下方式:\n:* 下載 [https://www.mediawiki.org/wiki/Download tarball 安裝程式],該程式包含數個外觀與擴充套件。 您可以複製並貼上至 <code>skins/</code> 目錄。\n:* 透過 git 複製 <code>mediawiki/skins/*</code> 儲存庫中其中一個外觀到您安裝的 MediaWiki <code dir=\"ltr\">skins/</code> 目錄中。\n: 若您是 MediaWiki 的開發人員,這麼做應該不會影響到您的 git 儲存庫。 請參考 [https://www.mediawiki.org/wiki/Manual:Skin_configuration 操作手冊:外觀設定] 以取得如何開啟外觀並設為預設值的資訊。",
        "default-skin-not-found-row-enabled": "* <code>$1</code> / $2 (已開啟)",
-       "default-skin-not-found-row-disabled": "* <code>$1</code> / $2 ('''已停用''')"
+       "default-skin-not-found-row-disabled": "* <code>$1</code> / $2 ('''已停用''')",
+       "mediastatistics": "媒體統計資訊",
+       "mediastatistics-summary": "已上傳檔案類型的統計資訊,此報表僅統計檔案的最新版本,不包含舊的或已刪除的版本。",
+       "mediastatistics-nbytes": "{{PLURAL:$1|$1 位元組|$1 位元組}} ($2; $3%)",
+       "mediastatistics-table-mimetype": "MIME 類型",
+       "mediastatistics-table-extensions": "可用的副檔名",
+       "mediastatistics-table-count": "檔案數量",
+       "mediastatistics-table-totalbytes": "大小總計",
+       "mediastatistics-header-unknown": "不明",
+       "mediastatistics-header-bitmap": "點陣圖",
+       "mediastatistics-header-drawing": "繪圖 (向量圖)",
+       "mediastatistics-header-audio": "音訊",
+       "mediastatistics-header-video": "影片",
+       "mediastatistics-header-multimedia": "豐富多媒體",
+       "mediastatistics-header-office": "辦公",
+       "mediastatistics-header-text": "純文字",
+       "mediastatistics-header-executable": "可執行",
+       "mediastatistics-header-archive": "已壓縮格式"
 }
index ccdd310..0a10279 100644 (file)
@@ -428,6 +428,7 @@ $specialPageAliases = array(
        'Log'                       => array( 'Log', 'Logs' ),
        'Lonelypages'               => array( 'LonelyPages', 'OrphanedPages' ),
        'Longpages'                 => array( 'LongPages' ),
+       'MediaStatistics'           => array( 'MediaStatistics' ),
        'MergeHistory'              => array( 'MergeHistory' ),
        'MIMEsearch'                => array( 'MIMESearch' ),
        'Mostcategories'            => array( 'MostCategories' ),
@@ -512,16 +513,16 @@ $linkPrefixCharset = 'a-zA-Z\\x{80}-\\x{10ffff}';
  * basis if needed.
  */
 $imageFiles = array(
-       'button-bold'     => 'button_bold.png',
-       'button-italic'   => 'button_italic.png',
-       'button-link'     => 'button_link.png',
-       'button-extlink'  => 'button_extlink.png',
-       'button-headline' => 'button_headline.png',
-       'button-image'    => 'button_image.png',
-       'button-media'    => 'button_media.png',
-       'button-nowiki'   => 'button_nowiki.png',
-       'button-sig'      => 'button_sig.png',
-       'button-hr'       => 'button_hr.png',
+       'button-bold'     => 'en/button_bold.png',
+       'button-italic'   => 'en/button_italic.png',
+       'button-link'     => 'en/button_link.png',
+       'button-extlink'  => 'en/button_extlink.png',
+       'button-headline' => 'en/button_headline.png',
+       'button-image'    => 'en/button_image.png',
+       'button-media'    => 'en/button_media.png',
+       'button-nowiki'   => 'en/button_nowiki.png',
+       'button-sig'      => 'en/button_sig.png',
+       'button-hr'       => 'en/button_hr.png',
 );
 
 /**
index 2f6c650..e338b42 100644 (file)
@@ -209,6 +209,6 @@ $magicWords = array(
 );
 
 $imageFiles = array(
-       'button-italic'   => 'ksh/button_S_italic.png',
+       'button-italic'   => 'ksh/button_italic.png',
 );
 
index 9098d85..a96b766 100644 (file)
@@ -433,9 +433,9 @@ $fallback8bitEncoding = 'windows-1251';
 $linkPrefixExtension = false;
 
 $imageFiles = array(
-       'button-bold'   => 'cyrl/button_bold.png',
-       'button-italic' => 'cyrl/button_italic.png',
-       'button-link'   => 'cyrl/button_link.png',
+       'button-bold'   => 'ru/button_bold.png',
+       'button-italic' => 'ru/button_italic.png',
+       'button-link'   => 'ru/button_link.png',
 );
 
 $linkTrail = '/^([a-zабвгдеёжзийклмнопрстуфхцчшщъыьэюя]+)(.*)$/sDu';
diff --git a/maintenance/archives/patch-restructure.sql b/maintenance/archives/patch-restructure.sql
deleted file mode 100644 (file)
index a5bc3e5..0000000
+++ /dev/null
@@ -1,146 +0,0 @@
--- The Great Restructuring of October 2004
--- Creates 'page', 'revision' tables and transforms the classic
--- cur+old into a separate page+revision+text structure.
---
--- The pre-conversion 'old' table is renamed to 'text' and used
--- without internal restructuring to avoid rebuilding the entire
--- table. (This can be done separately if desired.)
---
--- The pre-conversion 'cur' table is now redundant and can be
--- discarded when done.
-
-CREATE TABLE /*$wgDBprefix*/page (
-  page_id int unsigned NOT NULL auto_increment,
-  page_namespace tinyint NOT NULL,
-  page_title varchar(255) binary NOT NULL,
-  page_restrictions tinyblob NOT NULL,
-  page_counter bigint unsigned NOT NULL default '0',
-  page_is_redirect tinyint unsigned NOT NULL default '0',
-  page_is_new tinyint unsigned NOT NULL default '0',
-  page_random real unsigned NOT NULL,
-  page_touched binary(14) NOT NULL default '',
-  page_latest int unsigned NOT NULL,
-  page_len int unsigned NOT NULL,
-
-  PRIMARY KEY page_id (page_id),
-  UNIQUE INDEX name_title (page_namespace,page_title),
-  INDEX (page_random),
-  INDEX (page_len)
-);
-
-CREATE TABLE /*$wgDBprefix*/revision (
-  rev_id int unsigned NOT NULL auto_increment,
-  rev_page int unsigned NOT NULL,
-  rev_comment tinyblob NOT NULL,
-  rev_user int unsigned NOT NULL default '0',
-  rev_user_text varchar(255) binary NOT NULL default '',
-  rev_timestamp binary(14) NOT NULL default '',
-  rev_minor_edit tinyint unsigned NOT NULL default '0',
-  rev_deleted tinyint unsigned NOT NULL default '0',
-
-  PRIMARY KEY rev_page_id (rev_page, rev_id),
-  UNIQUE INDEX rev_id (rev_id),
-  INDEX rev_timestamp (rev_timestamp),
-  INDEX page_timestamp (rev_page,rev_timestamp),
-  INDEX user_timestamp (rev_user,rev_timestamp),
-  INDEX usertext_timestamp (rev_user_text,rev_timestamp)
-);
-
--- If creating new 'text' table it would look like this:
---
--- CREATE TABLE /*$wgDBprefix*/text (
---   old_id int(8) unsigned NOT NULL auto_increment,
---   old_text mediumtext NOT NULL,
---   old_flags tinyblob NOT NULL,
---
---   PRIMARY KEY old_id (old_id)
--- );
-
-
--- Lock!
-LOCK TABLES /*$wgDBprefix*/page WRITE, /*$wgDBprefix*/revision WRITE, /*$wgDBprefix*/old WRITE, /*$wgDBprefix*/cur WRITE;
-
--- Save the last old_id value for later
-SELECT (@maxold:=MAX(old_id)) FROM /*$wgDBprefix*/old;
-
--- First, copy all current entries into the old table.
-INSERT
-  INTO /*$wgDBprefix*/old
-    (old_namespace,
-    old_title,
-    old_text,
-    old_comment,
-    old_user,
-    old_user_text,
-    old_timestamp,
-    old_minor_edit,
-    old_flags)
-  SELECT
-    cur_namespace,
-    cur_title,
-    cur_text,
-    cur_comment,
-    cur_user,
-    cur_user_text,
-    cur_timestamp,
-    cur_minor_edit,
-    ''
-  FROM /*$wgDBprefix*/cur;
-
--- Now, copy all old data except the text into revisions
-INSERT
-  INTO /*$wgDBprefix*/revision
-    (rev_id,
-    rev_page,
-    rev_comment,
-    rev_user,
-    rev_user_text,
-    rev_timestamp,
-    rev_minor_edit)
-  SELECT
-    old_id,
-    cur_id,
-    old_comment,
-    old_user,
-    old_user_text,
-    old_timestamp,
-    old_minor_edit
-  FROM /*$wgDBprefix*/old,/*$wgDBprefix*/cur
-  WHERE old_namespace=cur_namespace
-    AND old_title=cur_title;
-
--- And, copy the cur data into page
-INSERT
-  INTO /*$wgDBprefix*/page
-    (page_id,
-    page_namespace,
-    page_title,
-    page_restrictions,
-    page_counter,
-    page_is_redirect,
-    page_is_new,
-    page_random,
-    page_touched,
-    page_latest)
-  SELECT
-    cur_id,
-    cur_namespace,
-    cur_title,
-    cur_restrictions,
-    cur_counter,
-    cur_is_redirect,
-    cur_is_new,
-    cur_random,
-    cur_touched,
-    rev_id
-  FROM /*$wgDBprefix*/cur,/*$wgDBprefix*/revision
-  WHERE cur_id=rev_page
-    AND rev_timestamp=cur_timestamp
-    AND rev_id > @maxold;
-
-UNLOCK TABLES;
-
--- Keep the old table around as the text store.
--- Its extra fields will be ignored, but trimming them is slow
--- so we won't bother doing it for now.
-ALTER TABLE /*$wgDBprefix*/old RENAME TO /*$wgDBprefix*/text;
diff --git a/maintenance/cssjanus/COPYING b/maintenance/cssjanus/COPYING
deleted file mode 100644 (file)
index 3f2c895..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
-   Copyright 2008 Google Inc.
-
-   Licensed under the Apache License, Version 2.0 (the "License");
-   you may not use this file except in compliance with the License.
-   You may obtain a copy of the License at
-
-       http://www.apache.org/licenses/LICENSE-2.0
-
-   Unless required by applicable law or agreed to in writing, software
-   distributed under the License is distributed on an "AS IS" BASIS,
-   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-   See the License for the specific language governing permissions and
-   limitations under the License.
diff --git a/maintenance/cssjanus/LICENSE b/maintenance/cssjanus/LICENSE
deleted file mode 100644 (file)
index d645695..0000000
+++ /dev/null
@@ -1,202 +0,0 @@
-
-                                 Apache License
-                           Version 2.0, January 2004
-                        http://www.apache.org/licenses/
-
-   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
-
-   1. Definitions.
-
-      "License" shall mean the terms and conditions for use, reproduction,
-      and distribution as defined by Sections 1 through 9 of this document.
-
-      "Licensor" shall mean the copyright owner or entity authorized by
-      the copyright owner that is granting the License.
-
-      "Legal Entity" shall mean the union of the acting entity and all
-      other entities that control, are controlled by, or are under common
-      control with that entity. For the purposes of this definition,
-      "control" means (i) the power, direct or indirect, to cause the
-      direction or management of such entity, whether by contract or
-      otherwise, or (ii) ownership of fifty percent (50%) or more of the
-      outstanding shares, or (iii) beneficial ownership of such entity.
-
-      "You" (or "Your") shall mean an individual or Legal Entity
-      exercising permissions granted by this License.
-
-      "Source" form shall mean the preferred form for making modifications,
-      including but not limited to software source code, documentation
-      source, and configuration files.
-
-      "Object" form shall mean any form resulting from mechanical
-      transformation or translation of a Source form, including but
-      not limited to compiled object code, generated documentation,
-      and conversions to other media types.
-
-      "Work" shall mean the work of authorship, whether in Source or
-      Object form, made available under the License, as indicated by a
-      copyright notice that is included in or attached to the work
-      (an example is provided in the Appendix below).
-
-      "Derivative Works" shall mean any work, whether in Source or Object
-      form, that is based on (or derived from) the Work and for which the
-      editorial revisions, annotations, elaborations, or other modifications
-      represent, as a whole, an original work of authorship. For the purposes
-      of this License, Derivative Works shall not include works that remain
-      separable from, or merely link (or bind by name) to the interfaces of,
-      the Work and Derivative Works thereof.
-
-      "Contribution" shall mean any work of authorship, including
-      the original version of the Work and any modifications or additions
-      to that Work or Derivative Works thereof, that is intentionally
-      submitted to Licensor for inclusion in the Work by the copyright owner
-      or by an individual or Legal Entity authorized to submit on behalf of
-      the copyright owner. For the purposes of this definition, "submitted"
-      means any form of electronic, verbal, or written communication sent
-      to the Licensor or its representatives, including but not limited to
-      communication on electronic mailing lists, source code control systems,
-      and issue tracking systems that are managed by, or on behalf of, the
-      Licensor for the purpose of discussing and improving the Work, but
-      excluding communication that is conspicuously marked or otherwise
-      designated in writing by the copyright owner as "Not a Contribution."
-
-      "Contributor" shall mean Licensor and any individual or Legal Entity
-      on behalf of whom a Contribution has been received by Licensor and
-      subsequently incorporated within the Work.
-
-   2. Grant of Copyright License. Subject to the terms and conditions of
-      this License, each Contributor hereby grants to You a perpetual,
-      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
-      copyright license to reproduce, prepare Derivative Works of,
-      publicly display, publicly perform, sublicense, and distribute the
-      Work and such Derivative Works in Source or Object form.
-
-   3. Grant of Patent License. Subject to the terms and conditions of
-      this License, each Contributor hereby grants to You a perpetual,
-      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
-      (except as stated in this section) patent license to make, have made,
-      use, offer to sell, sell, import, and otherwise transfer the Work,
-      where such license applies only to those patent claims licensable
-      by such Contributor that are necessarily infringed by their
-      Contribution(s) alone or by combination of their Contribution(s)
-      with the Work to which such Contribution(s) was submitted. If You
-      institute patent litigation against any entity (including a
-      cross-claim or counterclaim in a lawsuit) alleging that the Work
-      or a Contribution incorporated within the Work constitutes direct
-      or contributory patent infringement, then any patent licenses
-      granted to You under this License for that Work shall terminate
-      as of the date such litigation is filed.
-
-   4. Redistribution. You may reproduce and distribute copies of the
-      Work or Derivative Works thereof in any medium, with or without
-      modifications, and in Source or Object form, provided that You
-      meet the following conditions:
-
-      (a) You must give any other recipients of the Work or
-          Derivative Works a copy of this License; and
-
-      (b) You must cause any modified files to carry prominent notices
-          stating that You changed the files; and
-
-      (c) You must retain, in the Source form of any Derivative Works
-          that You distribute, all copyright, patent, trademark, and
-          attribution notices from the Source form of the Work,
-          excluding those notices that do not pertain to any part of
-          the Derivative Works; and
-
-      (d) If the Work includes a "NOTICE" text file as part of its
-          distribution, then any Derivative Works that You distribute must
-          include a readable copy of the attribution notices contained
-          within such NOTICE file, excluding those notices that do not
-          pertain to any part of the Derivative Works, in at least one
-          of the following places: within a NOTICE text file distributed
-          as part of the Derivative Works; within the Source form or
-          documentation, if provided along with the Derivative Works; or,
-          within a display generated by the Derivative Works, if and
-          wherever such third-party notices normally appear. The contents
-          of the NOTICE file are for informational purposes only and
-          do not modify the License. You may add Your own attribution
-          notices within Derivative Works that You distribute, alongside
-          or as an addendum to the NOTICE text from the Work, provided
-          that such additional attribution notices cannot be construed
-          as modifying the License.
-
-      You may add Your own copyright statement to Your modifications and
-      may provide additional or different license terms and conditions
-      for use, reproduction, or distribution of Your modifications, or
-      for any such Derivative Works as a whole, provided Your use,
-      reproduction, and distribution of the Work otherwise complies with
-      the conditions stated in this License.
-
-   5. Submission of Contributions. Unless You explicitly state otherwise,
-      any Contribution intentionally submitted for inclusion in the Work
-      by You to the Licensor shall be under the terms and conditions of
-      this License, without any additional terms or conditions.
-      Notwithstanding the above, nothing herein shall supersede or modify
-      the terms of any separate license agreement you may have executed
-      with Licensor regarding such Contributions.
-
-   6. Trademarks. This License does not grant permission to use the trade
-      names, trademarks, service marks, or product names of the Licensor,
-      except as required for reasonable and customary use in describing the
-      origin of the Work and reproducing the content of the NOTICE file.
-
-   7. Disclaimer of Warranty. Unless required by applicable law or
-      agreed to in writing, Licensor provides the Work (and each
-      Contributor provides its Contributions) on an "AS IS" BASIS,
-      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
-      implied, including, without limitation, any warranties or conditions
-      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
-      PARTICULAR PURPOSE. You are solely responsible for determining the
-      appropriateness of using or redistributing the Work and assume any
-      risks associated with Your exercise of permissions under this License.
-
-   8. Limitation of Liability. In no event and under no legal theory,
-      whether in tort (including negligence), contract, or otherwise,
-      unless required by applicable law (such as deliberate and grossly
-      negligent acts) or agreed to in writing, shall any Contributor be
-      liable to You for damages, including any direct, indirect, special,
-      incidental, or consequential damages of any character arising as a
-      result of this License or out of the use or inability to use the
-      Work (including but not limited to damages for loss of goodwill,
-      work stoppage, computer failure or malfunction, or any and all
-      other commercial damages or losses), even if such Contributor
-      has been advised of the possibility of such damages.
-
-   9. Accepting Warranty or Additional Liability. While redistributing
-      the Work or Derivative Works thereof, You may choose to offer,
-      and charge a fee for, acceptance of support, warranty, indemnity,
-      or other liability obligations and/or rights consistent with this
-      License. However, in accepting such obligations, You may act only
-      on Your own behalf and on Your sole responsibility, not on behalf
-      of any other Contributor, and only if You agree to indemnify,
-      defend, and hold each Contributor harmless for any liability
-      incurred by, or claims asserted against, such Contributor by reason
-      of your accepting any such warranty or additional liability.
-
-   END OF TERMS AND CONDITIONS
-
-   APPENDIX: How to apply the Apache License to your work.
-
-      To apply the Apache License to your work, attach the following
-      boilerplate notice, with the fields enclosed by brackets "[]"
-      replaced with your own identifying information. (Don't include
-      the brackets!)  The text should be enclosed in the appropriate
-      comment syntax for the file format. We also recommend that a
-      file or class name and description of purpose be included on the
-      same "printed page" as the copyright notice for easier
-      identification within third-party archives.
-
-   Copyright [yyyy] [name of copyright owner]
-
-   Licensed under the Apache License, Version 2.0 (the "License");
-   you may not use this file except in compliance with the License.
-   You may obtain a copy of the License at
-
-       http://www.apache.org/licenses/LICENSE-2.0
-
-   Unless required by applicable law or agreed to in writing, software
-   distributed under the License is distributed on an "AS IS" BASIS,
-   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-   See the License for the specific language governing permissions and
-   limitations under the License.
diff --git a/maintenance/cssjanus/README b/maintenance/cssjanus/README
deleted file mode 100644 (file)
index 1b96d1a..0000000
+++ /dev/null
@@ -1,91 +0,0 @@
-=CSSJanus=
-
-_Flips CSS from LTR to an RTL orienation and vice-versa_
-
-Author: `Lindsey Simon <elsigh@google.com>`
-
-==Introduction==
-
-CSSJanus is CSS parser utility designed to aid the conversion of a website's
-layout from left-to-right(LTR) to right-to-left(RTL). The script was born out of
-a need to convert CSS for RTL languages when tables are not being used for layout (since tables will automatically reorder TD's in RTL).
-CSSJanus will change most of the obvious CSS property names and their values as
-well as some not-so-obvious ones (cursor, background-position %, etc...).
-The script is designed to offer flexibility to account for cases when you do
-not want to change certain rules which exist to account for bidirectional text
-display bugs, as well as situations where you may or may not want to flip annotations inside of the background url string.
-Note that you can disable CSSJanus from running on an entire class or any
-rule within a class by prepending a /* @noflip */ comment before the rule(s)
-you want CSSJanus to ignore.
-
-CSSJanus itself is not always enough to make a website that works in a LTR
-language context work in a RTL language all the way, but it is a start.
-
-==Getting the code==
-
-View the trunk at:
-
-  http://cssjanus.googlecode.com/svn/trunk/
-
-Check out the latest development version anonymously with:
-
-{{{
-  $ svn checkout http://cssjanus.googlecode.com/svn/trunk/ cssjanus
-}}}
-
-==Using==
-
-Usage:
-  ./cssjanus.py < file.css > file-rtl.css
-Flags:
-  --swap_left_right_in_url: Fixes "left"/"right" string within urls.
-  Ex: ./cssjanus.py --swap_left_right_in_url < file.css > file_rtl.css
-  --swap_ltr_rtl_in_url: Fixes "ltr"/"rtl" string within urls.
-  Ex: ./cssjanus.py --swap_ltr_rtl_in_url < file.css > file_rtl.css
-
-If you'd like to make use of the webapp version of cssjanus, you'll need to
-download the Google App Engine SDK
-  http://code.google.com/appengine/downloads.html
-and also drop a "django" directory into this directory, with the latest svn
-from django. You should be good to go with that setup. Please let me know
-otherwise.
-
-==Bugs, Patches==
-
-Patches and bug reports are welcome, just please keep the style
-consistent with the original source. If you find a bug, please include a diff
-of cssjanus_test.py with the bug included as a new unit test which fails. It
-will make understanding and fixing the bug easier.
-
-==Todo==
-
-* Include some helpers for some typical bidi text solutions?
-* Aural CSS (azimuth) swapping?
-
-==Contributors==
-
-Additional thanks to Mike Samuel for his work on csslex.py, Andy Perelson for
-his help coding and reviewing, Stephen Zabel for his help with i18n and my sanity,
-and to Eric Meyer for his thoughtful input.
-Thanks to Junyu Wang for the Chinese translation.
-Thanks to Masashi Kawashima for the Japanese translation.
-Thanks to Taaryk Taar and Tariq Al-Omaireeni for an updated Arabic translation.
-Thanks to Jens Meiert for the German translation.
-
-==License==
-
-{{{
-  Copyright 2008 Google Inc. All Rights Reserved.
-
-  Licensed under the Apache License, Version 2.0 (the 'License');
-  you may not use this file except in compliance with the License.
-  You may obtain a copy of the License at
-
-      http://www.apache.org/licenses/LICENSE-2.0
-
-  Unless required by applicable law or agreed to in writing, software
-  distributed under the License is distributed on an 'AS IS' BASIS,
-  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-  See the License for the specific language governing permissions and
-  limitations under the License.
-}}}
diff --git a/maintenance/cssjanus/cssjanus.py b/maintenance/cssjanus/cssjanus.py
deleted file mode 100644 (file)
index dd14bd5..0000000
+++ /dev/null
@@ -1,574 +0,0 @@
-#!/usr/bin/python
-#
-# Copyright 2008 Google Inc. All Rights Reserved.
-
-"""Converts a LeftToRight Cascading Style Sheet into a RightToLeft one.
-
-   This is a utility script for replacing "left" oriented things in a CSS file
-   like float, padding, margin with "right" oriented values.
-   It also does the opposite.
-   The goal is to be able to conditionally serve one large, cat'd, compiled CSS
-   file appropriate for LeftToRight oriented languages and RightToLeft ones.
-   This utility will hopefully help your structural layout done in CSS in
-   terms of its RTL compatibility. It will not help with some of the more
-   complicated bidirectional text issues.
-"""
-
-__author__ = 'elsigh@google.com (Lindsey Simon)'
-__version__ = '0.1'
-
-import logging
-import re
-import sys
-import getopt
-import os
-
-import csslex
-
-logging.getLogger().setLevel(logging.INFO)
-
-# Global for the command line flags.
-SWAP_LTR_RTL_IN_URL_DEFAULT = False
-SWAP_LEFT_RIGHT_IN_URL_DEFAULT = False
-FLAGS = {'swap_ltr_rtl_in_url': SWAP_LTR_RTL_IN_URL_DEFAULT,
-         'swap_left_right_in_url': SWAP_LEFT_RIGHT_IN_URL_DEFAULT}
-
-# Generic token delimiter character.
-TOKEN_DELIMITER = '~'
-
-# This is a temporary match token we use when swapping strings.
-TMP_TOKEN = '%sTMP%s' % (TOKEN_DELIMITER, TOKEN_DELIMITER)
-
-# Token to be used for joining lines.
-TOKEN_LINES = '%sJ%s' % (TOKEN_DELIMITER, TOKEN_DELIMITER)
-
-# Global constant text strings for CSS value matches.
-LTR = 'ltr'
-RTL = 'rtl'
-LEFT = 'left'
-RIGHT = 'right'
-
-# This is a lookbehind match to ensure that we don't replace instances
-# of our string token (left, rtl, etc...) if there's a letter in front of it.
-# Specifically, this prevents replacements like 'background: url(bright.png)'.
-LOOKBEHIND_NOT_LETTER = r'(?<![a-zA-Z])'
-
-# This is a lookahead match to make sure we don't replace left and right
-# in actual classnames, so that we don't break the HTML/CSS dependencies.
-# Read literally, it says ignore cases where the word left, for instance, is
-# directly followed by valid classname characters and a curly brace.
-# ex: .column-left {float: left} will become .column-left {float: right}
-LOOKAHEAD_NOT_OPEN_BRACE = (r'(?!(?:%s|%s|%s|#|\:|\.|\,|\+|>)*?{)' %
-                            (csslex.NMCHAR, TOKEN_LINES, csslex.SPACE))
-
-
-# These two lookaheads are to test whether or not we are within a
-# background: url(HERE) situation.
-# Ref: http://www.w3.org/TR/CSS21/syndata.html#uri
-VALID_AFTER_URI_CHARS = r'[\'\"]?%s' % csslex.WHITESPACE
-LOOKAHEAD_NOT_CLOSING_PAREN = r'(?!%s?%s\))' % (csslex.URL_CHARS,
-                                                VALID_AFTER_URI_CHARS)
-LOOKAHEAD_FOR_CLOSING_PAREN = r'(?=%s?%s\))' % (csslex.URL_CHARS,
-                                                VALID_AFTER_URI_CHARS)
-
-# Compile a regex to swap left and right values in 4 part notations.
-# We need to match negatives and decimal numeric values.
-# ex. 'margin: .25em -2px 3px 0' becomes 'margin: .25em 0 3px -2px'.
-POSSIBLY_NEGATIVE_QUANTITY = r'((?:-?%s)|(?:inherit|auto))' % csslex.QUANTITY
-POSSIBLY_NEGATIVE_QUANTITY_SPACE = r'%s%s%s' % (POSSIBLY_NEGATIVE_QUANTITY,
-                                                csslex.SPACE,
-                                                csslex.WHITESPACE)
-FOUR_NOTATION_QUANTITY_RE = re.compile(r'%s%s%s%s' %
-                                       (POSSIBLY_NEGATIVE_QUANTITY_SPACE,
-                                        POSSIBLY_NEGATIVE_QUANTITY_SPACE,
-                                        POSSIBLY_NEGATIVE_QUANTITY_SPACE,
-                                        POSSIBLY_NEGATIVE_QUANTITY),
-                                       re.I)
-COLOR = r'(%s|%s)' % (csslex.NAME, csslex.HASH)
-COLOR_SPACE = r'%s%s' % (COLOR, csslex.SPACE)
-FOUR_NOTATION_COLOR_RE = re.compile(r'(-color%s:%s)%s%s%s(%s)' %
-                                    (csslex.WHITESPACE,
-                                     csslex.WHITESPACE,
-                                     COLOR_SPACE,
-                                     COLOR_SPACE,
-                                     COLOR_SPACE,
-                                     COLOR),
-                                    re.I)
-
-# Compile the cursor resize regexes
-CURSOR_EAST_RE = re.compile(LOOKBEHIND_NOT_LETTER + '([ns]?)e-resize')
-CURSOR_WEST_RE = re.compile(LOOKBEHIND_NOT_LETTER + '([ns]?)w-resize')
-
-# Matches the condition where we need to replace the horizontal component
-# of a background-position value when expressed in horizontal percentage.
-# Had to make two regexes because in the case of position-x there is only
-# one quantity, and otherwise we don't want to match and change cases with only
-# one quantity.
-BG_HORIZONTAL_PERCENTAGE_RE = re.compile(r'background(-position)?(%s:%s)'
-                                         '([^%%]*?)(%s)%%'
-                                         '(%s(?:%s|%s))' % (csslex.WHITESPACE,
-                                                            csslex.WHITESPACE,
-                                                            csslex.NUM,
-                                                            csslex.WHITESPACE,
-                                                            csslex.QUANTITY,
-                                                            csslex.IDENT))
-
-BG_HORIZONTAL_PERCENTAGE_X_RE = re.compile(r'background-position-x(%s:%s)'
-                                           '(%s)%%' % (csslex.WHITESPACE,
-                                                       csslex.WHITESPACE,
-                                                       csslex.NUM))
-
-# Matches the opening of a body selector.
-BODY_SELECTOR = r'body%s{%s' % (csslex.WHITESPACE, csslex.WHITESPACE)
-
-# Matches anything up until the closing of a selector.
-CHARS_WITHIN_SELECTOR = r'[^\}]*?'
-
-# Matches the direction property in a selector.
-DIRECTION_RE = r'direction%s:%s' % (csslex.WHITESPACE, csslex.WHITESPACE)
-
-# These allow us to swap "ltr" with "rtl" and vice versa ONLY within the
-# body selector and on the same line.
-BODY_DIRECTION_LTR_RE = re.compile(r'(%s)(%s)(%s)(ltr)' %
-                                   (BODY_SELECTOR, CHARS_WITHIN_SELECTOR,
-                                    DIRECTION_RE),
-                                   re.I)
-BODY_DIRECTION_RTL_RE = re.compile(r'(%s)(%s)(%s)(rtl)' %
-                                   (BODY_SELECTOR, CHARS_WITHIN_SELECTOR,
-                                    DIRECTION_RE),
-                                   re.I)
-
-
-# Allows us to swap "direction:ltr" with "direction:rtl" and
-# vice versa anywhere in a line.
-DIRECTION_LTR_RE = re.compile(r'%s(ltr)' % DIRECTION_RE)
-DIRECTION_RTL_RE = re.compile(r'%s(rtl)' % DIRECTION_RE)
-
-# We want to be able to switch left with right and vice versa anywhere
-# we encounter left/right strings, EXCEPT inside the background:url(). The next
-# two regexes are for that purpose. We have alternate IN_URL versions of the
-# regexes compiled in case the user passes the flag that they do
-# actually want to have left and right swapped inside of background:urls.
-LEFT_RE = re.compile('%s(%s)%s%s' % (LOOKBEHIND_NOT_LETTER,
-                                     LEFT,
-                                     LOOKAHEAD_NOT_CLOSING_PAREN,
-                                     LOOKAHEAD_NOT_OPEN_BRACE),
-                     re.I)
-RIGHT_RE = re.compile('%s(%s)%s%s' % (LOOKBEHIND_NOT_LETTER,
-                                      RIGHT,
-                                      LOOKAHEAD_NOT_CLOSING_PAREN,
-                                      LOOKAHEAD_NOT_OPEN_BRACE),
-                      re.I)
-LEFT_IN_URL_RE = re.compile('%s(%s)%s' % (LOOKBEHIND_NOT_LETTER,
-                                          LEFT,
-                                          LOOKAHEAD_FOR_CLOSING_PAREN),
-                            re.I)
-RIGHT_IN_URL_RE = re.compile('%s(%s)%s' % (LOOKBEHIND_NOT_LETTER,
-                                           RIGHT,
-                                           LOOKAHEAD_FOR_CLOSING_PAREN),
-                             re.I)
-LTR_IN_URL_RE = re.compile('%s(%s)%s' % (LOOKBEHIND_NOT_LETTER,
-                                         LTR,
-                                         LOOKAHEAD_FOR_CLOSING_PAREN),
-                           re.I)
-RTL_IN_URL_RE = re.compile('%s(%s)%s' % (LOOKBEHIND_NOT_LETTER,
-                                         RTL,
-                                         LOOKAHEAD_FOR_CLOSING_PAREN),
-                           re.I)
-
-COMMENT_RE = re.compile('(%s)' % csslex.COMMENT, re.I)
-
-NOFLIP_TOKEN = r'\@noflip'
-# The NOFLIP_TOKEN inside of a comment. For now, this requires that comments
-# be in the input, which means users of a css compiler would have to run
-# this script first if they want this functionality.
-NOFLIP_ANNOTATION = r'/\*%s%s%s\*/' % (csslex.WHITESPACE,
-                                       NOFLIP_TOKEN,
-                                       csslex. WHITESPACE)
-
-# After a NOFLIP_ANNOTATION, and within a class selector, we want to be able
-# to set aside a single rule not to be flipped. We can do this by matching
-# our NOFLIP annotation and then using a lookahead to make sure there is not
-# an opening brace before the match.
-NOFLIP_SINGLE_RE = re.compile(r'(%s%s[^;}]+;?)' % (NOFLIP_ANNOTATION,
-                                                   LOOKAHEAD_NOT_OPEN_BRACE),
-                              re.I)
-
-# After a NOFLIP_ANNOTATION, we want to grab anything up until the next } which
-# means the entire following class block. This will prevent all of its
-# declarations from being flipped.
-NOFLIP_CLASS_RE = re.compile(r'(%s%s})' % (NOFLIP_ANNOTATION,
-                                           CHARS_WITHIN_SELECTOR),
-                             re.I)
-
-
-class Tokenizer:
-  """Replaces any CSS comments with string tokens and vice versa."""
-
-  def __init__(self, token_re, token_string):
-    """Constructor for the Tokenizer.
-
-    Args:
-      token_re: A regex for the string to be replace by a token.
-      token_string: The string to put between token delimiters when tokenizing.
-    """
-    logging.debug('Tokenizer::init token_string=%s' % token_string)
-    self.token_re = token_re
-    self.token_string = token_string
-    self.originals = []
-
-  def Tokenize(self, line):
-    """Replaces any string matching token_re in line with string tokens.
-
-    By passing a function as an argument to the re.sub line below, we bypass
-    the usual rule where re.sub will only replace the left-most occurrence of
-    a match by calling the passed in function for each occurrence.
-
-    Args:
-      line: A line to replace token_re matches in.
-
-    Returns:
-      line: A line with token_re matches tokenized.
-    """
-    line = self.token_re.sub(self.TokenizeMatches, line)
-    logging.debug('Tokenizer::Tokenize returns: %s' % line)
-    return line
-
-  def DeTokenize(self, line):
-    """Replaces tokens with the original string.
-
-    Args:
-      line: A line with tokens.
-
-    Returns:
-      line with any tokens replaced by the original string.
-    """
-
-    # Put all of the comments back in by their comment token.
-    for i, original in enumerate(self.originals):
-      token = '%s%s_%s%s' % (TOKEN_DELIMITER, self.token_string, i + 1,
-                             TOKEN_DELIMITER)
-      line = line.replace(token, original)
-      logging.debug('Tokenizer::DeTokenize i:%s w/%s' % (i, token))
-    logging.debug('Tokenizer::DeTokenize returns: %s' % line)
-    return line
-
-  def TokenizeMatches(self, m):
-    """Replaces matches with tokens and stores the originals.
-
-    Args:
-      m: A match object.
-
-    Returns:
-      A string token which replaces the CSS comment.
-    """
-    logging.debug('Tokenizer::TokenizeMatches %s' % m.group(1))
-    self.originals.append(m.group(1))
-    return '%s%s_%s%s' % (TOKEN_DELIMITER,
-                          self.token_string,
-                          len(self.originals),
-                          TOKEN_DELIMITER)
-
-
-def FixBodyDirectionLtrAndRtl(line):
-  """Replaces ltr with rtl and vice versa ONLY in the body direction.
-
-  Args:
-    line: A string to replace instances of ltr with rtl.
-  Returns:
-    line with direction: ltr and direction: rtl swapped only in body selector.
-    line = FixBodyDirectionLtrAndRtl('body { direction:ltr }')
-    line will now be 'body { direction:rtl }'.
-  """
-
-  line = BODY_DIRECTION_LTR_RE.sub('\\1\\2\\3%s' % TMP_TOKEN, line)
-  line = BODY_DIRECTION_RTL_RE.sub('\\1\\2\\3%s' % LTR, line)
-  line = line.replace(TMP_TOKEN, RTL)
-  logging.debug('FixBodyDirectionLtrAndRtl returns: %s' % line)
-  return line
-
-
-def FixLeftAndRight(line):
-  """Replaces left with right and vice versa in line.
-
-  Args:
-    line: A string in which to perform the replacement.
-
-  Returns:
-    line with left and right swapped. For example:
-    line = FixLeftAndRight('padding-left: 2px; margin-right: 1px;')
-    line will now be 'padding-right: 2px; margin-left: 1px;'.
-  """
-
-  line = LEFT_RE.sub(TMP_TOKEN, line)
-  line = RIGHT_RE.sub(LEFT, line)
-  line = line.replace(TMP_TOKEN, RIGHT)
-  logging.debug('FixLeftAndRight returns: %s' % line)
-  return line
-
-
-def FixLeftAndRightInUrl(line):
-  """Replaces left with right and vice versa ONLY within background urls.
-
-  Args:
-    line: A string in which to replace left with right and vice versa.
-
-  Returns:
-    line with left and right swapped in the url string. For example:
-    line = FixLeftAndRightInUrl('background:url(right.png)')
-    line will now be 'background:url(left.png)'.
-  """
-
-  line = LEFT_IN_URL_RE.sub(TMP_TOKEN, line)
-  line = RIGHT_IN_URL_RE.sub(LEFT, line)
-  line = line.replace(TMP_TOKEN, RIGHT)
-  logging.debug('FixLeftAndRightInUrl returns: %s' % line)
-  return line
-
-
-def FixLtrAndRtlInUrl(line):
-  """Replaces ltr with rtl and vice versa ONLY within background urls.
-
-  Args:
-    line: A string in which to replace ltr with rtl and vice versa.
-
-  Returns:
-    line with left and right swapped. For example:
-    line = FixLtrAndRtlInUrl('background:url(rtl.png)')
-    line will now be 'background:url(ltr.png)'.
-  """
-
-  line = LTR_IN_URL_RE.sub(TMP_TOKEN, line)
-  line = RTL_IN_URL_RE.sub(LTR, line)
-  line = line.replace(TMP_TOKEN, RTL)
-  logging.debug('FixLtrAndRtlInUrl returns: %s' % line)
-  return line
-
-
-def FixCursorProperties(line):
-  """Fixes directional CSS cursor properties.
-
-  Args:
-    line: A string to fix CSS cursor properties in.
-
-  Returns:
-    line reformatted with the cursor properties substituted. For example:
-    line = FixCursorProperties('cursor: ne-resize')
-    line will now be 'cursor: nw-resize'.
-  """
-
-  line = CURSOR_EAST_RE.sub('\\1' + TMP_TOKEN, line)
-  line = CURSOR_WEST_RE.sub('\\1e-resize', line)
-  line = line.replace(TMP_TOKEN, 'w-resize')
-  logging.debug('FixCursorProperties returns: %s' % line)
-  return line
-
-
-def FixFourPartNotation(line):
-  """Fixes the second and fourth positions in 4 part CSS notation.
-
-  Args:
-    line: A string to fix 4 part CSS notation in.
-
-  Returns:
-    line reformatted with the 4 part notations swapped. For example:
-    line = FixFourPartNotation('padding: 1px 2px 3px 4px')
-    line will now be 'padding: 1px 4px 3px 2px'.
-  """
-  line = FOUR_NOTATION_QUANTITY_RE.sub('\\1 \\4 \\3 \\2', line)
-  line = FOUR_NOTATION_COLOR_RE.sub('\\1\\2 \\5 \\4 \\3', line)
-  logging.debug('FixFourPartNotation returns: %s' % line)
-  return line
-
-
-def FixBackgroundPosition(line):
-  """Fixes horizontal background percentage values in line.
-
-  Args:
-    line: A string to fix horizontal background position values in.
-
-  Returns:
-    line reformatted with the 4 part notations swapped.
-  """
-  line = BG_HORIZONTAL_PERCENTAGE_RE.sub(CalculateNewBackgroundPosition, line)
-  line = BG_HORIZONTAL_PERCENTAGE_X_RE.sub(CalculateNewBackgroundPositionX,
-                                           line)
-  logging.debug('FixBackgroundPosition returns: %s' % line)
-  return line
-
-
-def CalculateNewBackgroundPosition(m):
-  """Fixes horizontal background-position percentages.
-
-  This function should be used as an argument to re.sub since it needs to
-  perform replacement specific calculations.
-
-  Args:
-    m: A match object.
-
-  Returns:
-    A string with the horizontal background position percentage fixed.
-    BG_HORIZONTAL_PERCENTAGE_RE.sub(FixBackgroundPosition,
-                                    'background-position: 75% 50%')
-    will return 'background-position: 25% 50%'.
-  """
-
-  # The flipped value is the offset from 100%
-  new_x = str(100-int(m.group(4)))
-
-  # Since m.group(1) may very well be None type and we need a string..
-  if m.group(1):
-    position_string = m.group(1)
-  else:
-    position_string = ''
-
-  return 'background%s%s%s%s%%%s' % (position_string, m.group(2), m.group(3),
-                                     new_x, m.group(5))
-
-
-def CalculateNewBackgroundPositionX(m):
-  """Fixes percent based background-position-x.
-
-  This function should be used as an argument to re.sub since it needs to
-  perform replacement specific calculations.
-
-  Args:
-    m: A match object.
-
-  Returns:
-    A string with the background-position-x percentage fixed.
-    BG_HORIZONTAL_PERCENTAGE_X_RE.sub(CalculateNewBackgroundPosition,
-                                      'background-position-x: 75%')
-    will return 'background-position-x: 25%'.
-  """
-
-  # The flipped value is the offset from 100%
-  new_x = str(100-int(m.group(2)))
-
-  return 'background-position-x%s%s%%' % (m.group(1), new_x)
-
-
-def ChangeLeftToRightToLeft(lines,
-                            swap_ltr_rtl_in_url=None,
-                            swap_left_right_in_url=None):
-  """Turns lines into a stream and runs the fixing functions against it.
-
-  Args:
-    lines: An list of CSS lines.
-    swap_ltr_rtl_in_url: Overrides this flag if param is set.
-    swap_left_right_in_url: Overrides this flag if param is set.
-
-  Returns:
-    The same lines, but with left and right fixes.
-  """
-
-  global FLAGS
-
-  # Possibly override flags with params.
-  logging.debug('ChangeLeftToRightToLeft swap_ltr_rtl_in_url=%s, '
-                'swap_left_right_in_url=%s' % (swap_ltr_rtl_in_url,
-                                               swap_left_right_in_url))
-  if swap_ltr_rtl_in_url is None:
-    swap_ltr_rtl_in_url = FLAGS['swap_ltr_rtl_in_url']
-  if swap_left_right_in_url is None:
-    swap_left_right_in_url = FLAGS['swap_left_right_in_url']
-
-  # Turns the array of lines into a single line stream.
-  logging.debug('LINES COUNT: %s' % len(lines))
-  line = TOKEN_LINES.join(lines)
-
-  # Tokenize any single line rules with the /* noflip */ annotation.
-  noflip_single_tokenizer = Tokenizer(NOFLIP_SINGLE_RE, 'NOFLIP_SINGLE')
-  line = noflip_single_tokenizer.Tokenize(line)
-
-  # Tokenize any class rules with the /* noflip */ annotation.
-  noflip_class_tokenizer = Tokenizer(NOFLIP_CLASS_RE, 'NOFLIP_CLASS')
-  line = noflip_class_tokenizer.Tokenize(line)
-
-  # Tokenize the comments so we can preserve them through the changes.
-  comment_tokenizer = Tokenizer(COMMENT_RE, 'C')
-  line = comment_tokenizer.Tokenize(line)
-
-  # Here starteth the various left/right orientation fixes.
-  line = FixBodyDirectionLtrAndRtl(line)
-
-  if swap_left_right_in_url:
-    line = FixLeftAndRightInUrl(line)
-
-  if swap_ltr_rtl_in_url:
-    line = FixLtrAndRtlInUrl(line)
-
-  line = FixLeftAndRight(line)
-  line = FixCursorProperties(line)
-  line = FixFourPartNotation(line)
-  line = FixBackgroundPosition(line)
-
-  # DeTokenize the single line noflips.
-  line = noflip_single_tokenizer.DeTokenize(line)
-
-  # DeTokenize the class-level noflips.
-  line = noflip_class_tokenizer.DeTokenize(line)
-
-  # DeTokenize the comments.
-  line = comment_tokenizer.DeTokenize(line)
-
-  # Rejoin the lines back together.
-  lines = line.split(TOKEN_LINES)
-
-  return lines
-
-def usage():
-  """Prints out usage information."""
-
-  print 'Usage:'
-  print '  ./cssjanus.py < file.css > file-rtl.css'
-  print 'Flags:'
-  print '  --swap_left_right_in_url: Fixes "left"/"right" string within urls.'
-  print '  Ex: ./cssjanus.py --swap_left_right_in_url < file.css > file_rtl.css'
-  print '  --swap_ltr_rtl_in_url: Fixes "ltr"/"rtl" string within urls.'
-  print '  Ex: ./cssjanus --swap_ltr_rtl_in_url < file.css > file_rtl.css'
-
-def setflags(opts):
-  """Parse the passed in command line arguments and set the FLAGS global.
-
-  Args:
-    opts: getopt iterable intercepted from argv.
-  """
-
-  global FLAGS
-
-  # Parse the arguments.
-  for opt, arg in opts:
-    logging.debug('opt: %s, arg: %s' % (opt, arg))
-    if opt in ("-h", "--help"):
-      usage()
-      sys.exit()
-    elif opt in ("-d", "--debug"):
-      logging.getLogger().setLevel(logging.DEBUG)
-    elif opt == '--swap_ltr_rtl_in_url':
-      FLAGS['swap_ltr_rtl_in_url'] = True
-    elif opt == '--swap_left_right_in_url':
-      FLAGS['swap_left_right_in_url'] = True
-
-
-def main(argv):
-  """Sends stdin lines to ChangeLeftToRightToLeft and writes to stdout."""
-
-  # Define the flags.
-  try:
-    opts, args = getopt.getopt(argv, 'hd', ['help', 'debug',
-                                            'swap_left_right_in_url',
-                                            'swap_ltr_rtl_in_url'])
-  except getopt.GetoptError:
-    usage()
-    sys.exit(2)
-
-  # Parse and set the flags.
-  setflags(opts)
-
-  # Call the main routine with all our functionality.
-  fixed_lines = ChangeLeftToRightToLeft(sys.stdin.readlines())
-  sys.stdout.write(''.join(fixed_lines))
-
-if __name__ == '__main__':
-  main(sys.argv[1:])
diff --git a/maintenance/cssjanus/csslex.py b/maintenance/cssjanus/csslex.py
deleted file mode 100644 (file)
index 1fc7304..0000000
+++ /dev/null
@@ -1,114 +0,0 @@
-#!/usr/bin/python
-#
-# Copyright 2007 Google Inc. All Rights Reserved.
-
-"""CSS Lexical Grammar rules.
-
-CSS lexical grammar from http://www.w3.org/TR/CSS21/grammar.html
-"""
-
-__author__ = ['elsigh@google.com (Lindsey Simon)',
-              'msamuel@google.com (Mike Samuel)']
-
-# public symbols
-__all__ = [ "NEWLINE", "HEX", "NON_ASCII", "UNICODE", "ESCAPE", "NMSTART", "NMCHAR", "STRING1", "STRING2", "IDENT", "NAME", "HASH", "NUM", "STRING", "URL", "SPACE", "WHITESPACE", "COMMENT", "QUANTITY", "PUNC" ]
-
-# The comments below are mostly copied verbatim from the grammar.
-
-# "@import"               {return IMPORT_SYM;}
-# "@page"                 {return PAGE_SYM;}
-# "@media"                {return MEDIA_SYM;}
-# "@charset"              {return CHARSET_SYM;}
-KEYWORD = r'(?:\@(?:import|page|media|charset))'
-
-# nl                      \n|\r\n|\r|\f ; a newline
-NEWLINE = r'\n|\r\n|\r|\f'
-
-# h                       [0-9a-f]      ; a hexadecimal digit
-HEX = r'[0-9a-f]'
-
-# nonascii                [\200-\377]
-NON_ASCII = r'[\200-\377]'
-
-# unicode                 \\{h}{1,6}(\r\n|[ \t\r\n\f])?
-UNICODE = r'(?:(?:\\' + HEX + r'{1,6})(?:\r\n|[ \t\r\n\f])?)'
-
-# escape                  {unicode}|\\[^\r\n\f0-9a-f]
-ESCAPE = r'(?:' + UNICODE + r'|\\[^\r\n\f0-9a-f])'
-
-# nmstart                 [_a-z]|{nonascii}|{escape}
-NMSTART = r'(?:[_a-z]|' + NON_ASCII + r'|' + ESCAPE + r')'
-
-# nmchar                  [_a-z0-9-]|{nonascii}|{escape}
-NMCHAR = r'(?:[_a-z0-9-]|' + NON_ASCII + r'|' + ESCAPE + r')'
-
-# ident                   -?{nmstart}{nmchar}*
-IDENT = r'-?' + NMSTART + NMCHAR + '*'
-
-# name                    {nmchar}+
-NAME = NMCHAR + r'+'
-
-# hash
-HASH = r'#' + NAME
-
-# string1                 \"([^\n\r\f\\"]|\\{nl}|{escape})*\"  ; "string"
-STRING1 = r'"(?:[^\"\\]|\\.)*"'
-
-# string2                 \'([^\n\r\f\\']|\\{nl}|{escape})*\'  ; 'string'
-STRING2 = r"'(?:[^\'\\]|\\.)*'"
-
-# string                  {string1}|{string2}
-STRING = '(?:' + STRING1 + r'|' + STRING2 + ')'
-
-# num                     [0-9]+|[0-9]*"."[0-9]+
-NUM = r'(?:[0-9]*\.[0-9]+|[0-9]+)'
-
-# s                       [ \t\r\n\f]
-SPACE = r'[ \t\r\n\f]'
-
-# w                       {s}*
-WHITESPACE = '(?:' + SPACE + r'*)'
-
-# url special chars
-URL_SPECIAL_CHARS = r'[!#$%&*-~]'
-
-# url chars               ({url_special_chars}|{nonascii}|{escape})*
-URL_CHARS = r'(?:%s|%s|%s)*' % (URL_SPECIAL_CHARS, NON_ASCII, ESCAPE)
-
-# url
-URL = r'url\(%s(%s|%s)%s\)' % (WHITESPACE, STRING, URL_CHARS, WHITESPACE)
-
-# comments
-# see http://www.w3.org/TR/CSS21/grammar.html
-COMMENT = r'/\*[^*]*\*+([^/*][^*]*\*+)*/'
-
-# {E}{M}             {return EMS;}
-# {E}{X}             {return EXS;}
-# {P}{X}             {return LENGTH;}
-# {C}{M}             {return LENGTH;}
-# {M}{M}             {return LENGTH;}
-# {I}{N}             {return LENGTH;}
-# {P}{T}             {return LENGTH;}
-# {P}{C}             {return LENGTH;}
-# {D}{E}{G}          {return ANGLE;}
-# {R}{A}{D}          {return ANGLE;}
-# {G}{R}{A}{D}       {return ANGLE;}
-# {M}{S}             {return TIME;}
-# {S}                {return TIME;}
-# {H}{Z}             {return FREQ;}
-# {K}{H}{Z}          {return FREQ;}
-# %                  {return PERCENTAGE;}
-UNIT = r'(?:em|ex|px|cm|mm|in|pt|pc|deg|rad|grad|ms|s|hz|khz|%)'
-
-# {num}{UNIT|IDENT}                   {return NUMBER;}
-QUANTITY = '%s(?:%s%s|%s)?' % (NUM, WHITESPACE, UNIT, IDENT)
-
-# "<!--"                  {return CDO;}
-# "-->"                   {return CDC;}
-# "~="                    {return INCLUDES;}
-# "|="                    {return DASHMATCH;}
-# {w}"{"                  {return LBRACE;}
-# {w}"+"                  {return PLUS;}
-# {w}">"                  {return GREATER;}
-# {w}","                  {return COMMA;}
-PUNC =  r'<!--|-->|~=|\|=|[\{\+>,:;]'
index d043818..df8a34c 100644 (file)
@@ -750,6 +750,7 @@ bmwschema
 bmysql
 bname
 bodycontent
+bogo
 boldening
 bolding
 booksources
@@ -861,6 +862,7 @@ categorypage
 categoryviewer
 catids
 catlinks
+catmsg
 catpage
 catrope
 cattitles
@@ -1677,6 +1679,7 @@ geocoordinate
 geodata
 geosearch
 gerrit
+geshi
 getcookie
 getenv
 getheader
@@ -1810,6 +1813,7 @@ hit
 hitcount
 hitcounter
 hits
+hlist
 hmac
 hobby
 homelink
@@ -2249,6 +2253,7 @@ loginerror
 loginfo
 loginlanguagelinks
 loginlink
+loginout
 loginprompt
 loginreqlink
 loginreqpagetext
@@ -2453,6 +2458,7 @@ moodbar
 moredotdotdot
 morelinkstoimage
 morethan
+mouseup
 move
 movedarticleprotection
 moveddeleted
@@ -2599,6 +2605,7 @@ newpos
 newquery
 newrevid
 news
+newsectionheaderdefaultlevel
 newsectionlink
 newsectionsummary
 newset
@@ -4010,6 +4017,7 @@ test
 testclean
 testdata
 testmailuser
+teston
 testpass
 testrunner
 testswarm
@@ -4156,6 +4164,7 @@ transwiki
 troff
 true
 truespeed
+truncatedtext
 trustworthy
 truteq
 truthy
@@ -4263,6 +4272,7 @@ unseed
 unserialization
 unserialize
 unserialized
+unserializes
 unserializing
 unsetting
 unstub
@@ -4437,6 +4447,7 @@ viewdeleted
 viewhelppage
 viewmyprivateinfo
 viewmywatchlist
+viewport
 viewprevnext
 viewsource
 viewsourcelink
@@ -4612,6 +4623,7 @@ xml
 xmldoublequote
 xmlfm
 xmlimport
+xmlmeta
 xmlns
 xmlselect
 xor
index 36760d7..66e8da0 100644 (file)
@@ -163,36 +163,39 @@ class FindHooks extends Maintenance {
         * @return array Array of documented hooks
         */
        private function getHooksFromOnlineDoc() {
-               // All hooks
-               $allhookdata = Http::get(
-                       'http://www.mediawiki.org/w/api.php?action=query&list=categorymembers&'
-                       . 'cmtitle=Category:MediaWiki_hooks&cmlimit=500&format=php'
+               $allhooks = $this->getHooksFromOnlineDocCategory( 'MediaWiki_hooks' );
+               $removed = $this->getHooksFromOnlineDocCategory( 'Removed_hooks' );
+               return array_diff( $allhooks, $removed );
+       }
+
+       /**
+        * @param string $title
+        * @return array
+        */
+       private function getHooksFromOnlineDocCategory( $title ) {
+               $params = array(
+                       'action' => 'query',
+                       'list' => 'categorymembers',
+                       'cmtitle' => "Category:$title",
+                       'cmlimit' => 500,
+                       'format' => 'json',
+                       'continue' => '',
                );
-               $allhookdata = unserialize( $allhookdata );
-               $allhooks = array();
-               foreach ( $allhookdata['query']['categorymembers'] as $page ) {
-                       $found = preg_match( '/Manual\:Hooks\/([a-zA-Z0-9- :]+)/', $page['title'], $matches );
-                       if ( $found ) {
-                               $hook = str_replace( ' ', '_', $matches[1] );
-                               $allhooks[] = $hook;
+
+               $retval = array();
+               while ( true ) {
+                       $json = Http::get( wfAppendQuery( 'http://www.mediawiki.org/w/api.php', $params ) );
+                       $data = FormatJson::decode( $json, true );
+                       foreach ( $data['query']['categorymembers'] as $page ) {
+                               if ( preg_match( '/Manual\:Hooks\/([a-zA-Z0-9- :]+)/', $page['title'], $m ) ) {
+                                       $retval[] = str_replace( ' ', '_', $m[1] );
+                               }
                        }
-               }
-               // Removed hooks
-               $oldhookdata = Http::get(
-                       'http://www.mediawiki.org/w/api.php?action=query&list=categorymembers&'
-                       . 'cmtitle=Category:Removed_hooks&cmlimit=500&format=php'
-               );
-               $oldhookdata = unserialize( $oldhookdata );
-               $removed = array();
-               foreach ( $oldhookdata['query']['categorymembers'] as $page ) {
-                       $found = preg_match( '/Manual\:Hooks\/([a-zA-Z0-9- :]+)/', $page['title'], $matches );
-                       if ( $found ) {
-                               $hook = str_replace( ' ', '_', $matches[1] );
-                               $removed[] = $hook;
+                       if ( !isset( $data['continue'] ) ) {
+                               return $retval;
                        }
+                       $params = array_replace( $params, $data['continue'] );
                }
-
-               return array_diff( $allhooks, $removed );
        }
 
        /**
index 7705ec9..e67d077 100644 (file)
@@ -70,33 +70,40 @@ class ImportSiteScripts extends Maintenance {
        protected function fetchScriptList() {
                $data = array(
                        'action' => 'query',
-                       'format' => 'php', //'json',
+                       'format' => 'json',
                        'list' => 'allpages',
                        'apnamespace' => '8',
                        'aplimit' => '500',
+                       'continue' => '',
                );
                $baseUrl = $this->getArg( 0 );
                $pages = array();
 
-               do {
+               while ( true ) {
                        $url = wfAppendQuery( $baseUrl, $data );
                        $strResult = Http::get( $url );
-                       //$result = FormatJson::decode( $strResult ); // Still broken
-                       $result = unserialize( $strResult );
+                       $result = FormatJson::decode( $strResult, true );
 
-                       if ( !empty( $result['query']['allpages'] ) ) {
-                               foreach ( $result['query']['allpages'] as $page ) {
-                                       if ( substr( $page['title'], -3 ) === '.js' ) {
-                                               strtok( $page['title'], ':' );
-                                               $pages[] = strtok( '' );
-                                       }
+                       $page = null;
+                       foreach ( $result['query']['allpages'] as $page ) {
+                               if ( substr( $page['title'], -3 ) === '.js' ) {
+                                       strtok( $page['title'], ':' );
+                                       $pages[] = strtok( '' );
                                }
                        }
-                       if ( !empty( $result['query-continue'] ) ) {
-                               $data['apfrom'] = $result['query-continue']['allpages']['apfrom'];
-                               $this->output( "Fetching new batch from {$data['apfrom']}\n" );
+
+                       if ( $page !== null ) {
+                               $this->output( "Fetched list up to {$page['title']}\n" );
+                       }
+
+                       if ( isset( $result['continue'] ) ) { // >= 1.21
+                               $data = array_replace( $data, $result['continue'] );
+                       } elseif ( isset( $result['query-continue']['allpages'] ) ) { // <= 1.20
+                               $data = array_replace( $data, $result['query-continue']['allpages'] );
+                       } else {
+                               break;
                        }
-               } while ( isset( $result['query-continue'] ) );
+               }
 
                return $pages;
        }
index db6c315..973cf7b 100644 (file)
@@ -48,7 +48,7 @@ class GenerateCollationData extends Maintenance {
         * Important tertiary weights from UTS #10 section 7.2
         */
        const NORMAL_UPPERCASE = 0x08;
-       const NORMAL_HIRAGANA = 0X0E;
+       const NORMAL_HIRAGANA = 0x0E;
 
        public function __construct() {
                parent::__construct();
index 1e0fa40..36be16e 100644 (file)
@@ -88,7 +88,7 @@ CREATE INDEX &mw_prefix.page_i03 ON &mw_prefix.page (page_is_redirect, page_name
 
 -- Create a dummy page to satisfy fk contraints especially with revisions
 INSERT INTO &mw_prefix.page
-  VALUES (0, 0, ' ', NULL, 0, 0, 0, 0, current_timestamp, NULL, 0, 0, NULL);
+  VALUES (0, 0, ' ', NULL, 0, 0, 0, 0, current_timestamp, NULL, 0, 0, NULL, NULL);
 
 /*$mw$*/
 CREATE TRIGGER &mw_prefix.page_set_random BEFORE INSERT ON &mw_prefix.page
index 10cfbbb..70905fb 100644 (file)
@@ -985,8 +985,10 @@ return array(
 
        'mediawiki.action.edit' => array(
                'scripts' => 'resources/src/mediawiki.action/mediawiki.action.edit.js',
+               'styles' => 'resources/src/mediawiki.action/mediawiki.action.edit.css',
                'dependencies' => array(
                        'mediawiki.action.edit.styles',
+                       'mediawiki.action.edit.toolbar',
                        'jquery.textSelection',
                        'jquery.byteLimit',
                ),
@@ -996,6 +998,10 @@ return array(
                'styles' => 'resources/src/mediawiki.action/mediawiki.action.edit.styles.css',
                'position' => 'top',
        ),
+       'mediawiki.action.edit.toolbar' => array(
+               'class' => 'ResourceLoaderEditToolbarModule',
+               'styles' => 'resources/src/mediawiki.action/mediawiki.action.edit.toolbar/mediawiki.action.edit.toolbar.less',
+       ),
        'mediawiki.action.edit.collapsibleFooter' => array(
                'scripts' => 'resources/src/mediawiki.action/mediawiki.action.edit.collapsibleFooter.js',
                'styles' => 'resources/src/mediawiki.action/mediawiki.action.edit.collapsibleFooter.css',
@@ -1170,11 +1176,11 @@ return array(
        'mediawiki.page.ready' => array(
                'scripts' => 'resources/src/mediawiki.page/mediawiki.page.ready.js',
                'dependencies' => array(
+                       'jquery.accessKeyLabel',
                        'jquery.checkboxShiftClick',
                        'jquery.makeCollapsible',
                        'jquery.placeholder',
                        'jquery.mw-jump',
-                       'mediawiki.util',
                ),
                'targets' => array( 'desktop', 'mobile' ),
        ),
@@ -1295,6 +1301,10 @@ return array(
                'dependencies' => array(
                        'mediawiki.language',
                ),
+               'messages' => array(
+                       'prefswarning-warning',
+                       'saveprefs',
+               ),
        ),
        'mediawiki.special.recentchanges' => array(
                'scripts' => 'resources/src/mediawiki.special/mediawiki.special.recentchanges.js',
@@ -1426,21 +1436,27 @@ return array(
                'position' => 'top',
        ),
        'mediawiki.legacy.commonPrint' => array(
-               'styles' => array( 'resources/src/mediawiki.legacy/commonPrint.css' => array( 'media' => 'print' ) ),
+               'styles' => array(
+                       'resources/src/mediawiki.legacy/commonPrint.css' => array( 'media' => 'print' )
+               ),
        ),
        'mediawiki.legacy.protect' => array(
                'scripts' => 'resources/src/mediawiki.legacy/protect.js',
                'dependencies' => array(
                        'jquery.byteLimit',
                ),
-               'position' => 'top',
+               'messages' => array( 'protect-unchain-permissions' )
        ),
        'mediawiki.legacy.shared' => array(
                // Used in the web installer. Test it after modifying this definition!
-               'styles' => array( 'resources/src/mediawiki.legacy/shared.css' => array( 'media' => 'screen' ) ),
+               'styles' => array(
+                       'resources/src/mediawiki.legacy/shared.css' => array( 'media' => 'screen' )
+               ),
        ),
        'mediawiki.legacy.oldshared' => array(
-               'styles' => array( 'resources/src/mediawiki.legacy/oldshared.css' => array( 'media' => 'screen' ) ),
+               'styles' => array(
+                       'resources/src/mediawiki.legacy/oldshared.css' => array( 'media' => 'screen' )
+               ),
        ),
        'mediawiki.legacy.wikibits' => array(
                'scripts' => 'resources/src/mediawiki.legacy/wikibits.js',
@@ -1453,38 +1469,48 @@ return array(
        /* MediaWiki UI */
 
        'mediawiki.ui' => array(
-               'styles' => array(
-                       'resources/src/mediawiki.ui/default.less',
+               'skinStyles' => array(
+                       'default' => array(
+                               'resources/src/mediawiki.ui/default.less',
+                       ),
                ),
                'position' => 'top',
                'targets' => array( 'desktop', 'mobile' ),
        ),
        'mediawiki.ui.checkbox' => array(
-               'styles' => array(
-                       'resources/src/mediawiki.ui/components/checkbox.less',
+               'skinStyles' => array(
+                       'default' => array(
+                               'resources/src/mediawiki.ui/components/checkbox.less',
+                       ),
                ),
                'position' => 'top',
                'targets' => array( 'desktop', 'mobile' ),
        ),
        // Lightweight module for anchor styles
        'mediawiki.ui.anchor' => array(
-               'styles' => array(
-                       'resources/src/mediawiki.ui/components/anchors.less',
+               'skinStyles' => array(
+                       'default' => array(
+                               'resources/src/mediawiki.ui/components/anchors.less',
+                       ),
                ),
                'position' => 'top',
                'targets' => array( 'desktop', 'mobile' ),
        ),
        // Lightweight module for button styles
        'mediawiki.ui.button' => array(
-               'styles' => array(
-                       'resources/src/mediawiki.ui/components/buttons.less',
+               'skinStyles' => array(
+                       'default' => array(
+                               'resources/src/mediawiki.ui/components/buttons.less',
+                       ),
                ),
                'position' => 'top',
                'targets' => array( 'desktop', 'mobile' ),
        ),
        'mediawiki.ui.input' => array(
-               'styles' => array(
-                       'resources/src/mediawiki.ui/components/inputs.less',
+               'skinStyles' => array(
+                       'default' => array(
+                               'resources/src/mediawiki.ui/components/inputs.less',
+                       ),
                ),
                'position' => 'top',
                'targets' => array( 'desktop', 'mobile' ),
diff --git a/resources/assets/file-type-icons/COPYING b/resources/assets/file-type-icons/COPYING
new file mode 100644 (file)
index 0000000..136530a
--- /dev/null
@@ -0,0 +1,43 @@
+The icons used here are derived from the crystalsvg icons in the the
+pics/crystalsvg/ directory of kdelibs-3.4.0 they were modified on 2005-05-15
+by Ævar Arnfjörð Bjarmason for use in MediaWiki.
+
+What follows is the contents of the LICENSE.crystalsvg file found in the pics/
+subdirectory of kdelibs-3.4.0:
+
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+This copyright and license notice covers all CrystalSVG images.
+Note the license notice contains an add-on.
+********************************************************************************
+KDE Crystal theme icons.
+Copyright (C) 2002 and following years KDE Artists
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation,
+version 2.1 of the License.
+This library 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
+Lesser General Public License for more details.
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+    **** NOTE THIS ADD-ON ****
+The GNU Lesser General Public License or LGPL is written for software libraries
+in the first place. We expressly want the LGPL to be valid for this artwork
+library too.
+KDE Crystal theme icons is a special kind of software library, it is an
+artwork library, it's elements can be used in a Graphical User Interface, or
+GUI.
+Source code, for this library means:
+ - for vectors svg;
+ - for pixels, if applicable, the multi-layered formats xcf or psd, or
+otherwise png.
+The LGPL in some sections obliges you to make the files carry
+notices. With images this is in some cases impossible or hardly useful.
+With this library a notice is placed at a prominent place in the directory
+containing the elements. You may follow this practice.
+The exception in section 6 of the GNU Lesser General Public License covers
+the use of elements of this art library in a GUI.
+kde-artists [at] kde.org
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
diff --git a/resources/assets/file-type-icons/fileicon-c.png b/resources/assets/file-type-icons/fileicon-c.png
new file mode 100644 (file)
index 0000000..0d603b7
Binary files /dev/null and b/resources/assets/file-type-icons/fileicon-c.png differ
diff --git a/resources/assets/file-type-icons/fileicon-cpp.png b/resources/assets/file-type-icons/fileicon-cpp.png
new file mode 100644 (file)
index 0000000..123688f
Binary files /dev/null and b/resources/assets/file-type-icons/fileicon-cpp.png differ
diff --git a/resources/assets/file-type-icons/fileicon-deb.png b/resources/assets/file-type-icons/fileicon-deb.png
new file mode 100644 (file)
index 0000000..87ca3fa
Binary files /dev/null and b/resources/assets/file-type-icons/fileicon-deb.png differ
diff --git a/resources/assets/file-type-icons/fileicon-djvu.png b/resources/assets/file-type-icons/fileicon-djvu.png
new file mode 100644 (file)
index 0000000..1da2276
Binary files /dev/null and b/resources/assets/file-type-icons/fileicon-djvu.png differ
diff --git a/resources/assets/file-type-icons/fileicon-djvu.xcf b/resources/assets/file-type-icons/fileicon-djvu.xcf
new file mode 100644 (file)
index 0000000..8043dcd
Binary files /dev/null and b/resources/assets/file-type-icons/fileicon-djvu.xcf differ
diff --git a/resources/assets/file-type-icons/fileicon-dvi.png b/resources/assets/file-type-icons/fileicon-dvi.png
new file mode 100644 (file)
index 0000000..f37878d
Binary files /dev/null and b/resources/assets/file-type-icons/fileicon-dvi.png differ
diff --git a/resources/assets/file-type-icons/fileicon-exe.png b/resources/assets/file-type-icons/fileicon-exe.png
new file mode 100644 (file)
index 0000000..dc020eb
Binary files /dev/null and b/resources/assets/file-type-icons/fileicon-exe.png differ
diff --git a/resources/assets/file-type-icons/fileicon-h.png b/resources/assets/file-type-icons/fileicon-h.png
new file mode 100644 (file)
index 0000000..339bf02
Binary files /dev/null and b/resources/assets/file-type-icons/fileicon-h.png differ
diff --git a/resources/assets/file-type-icons/fileicon-html.png b/resources/assets/file-type-icons/fileicon-html.png
new file mode 100644 (file)
index 0000000..f28f8a2
Binary files /dev/null and b/resources/assets/file-type-icons/fileicon-html.png differ
diff --git a/resources/assets/file-type-icons/fileicon-iso.png b/resources/assets/file-type-icons/fileicon-iso.png
new file mode 100644 (file)
index 0000000..c73d229
Binary files /dev/null and b/resources/assets/file-type-icons/fileicon-iso.png differ
diff --git a/resources/assets/file-type-icons/fileicon-java.png b/resources/assets/file-type-icons/fileicon-java.png
new file mode 100644 (file)
index 0000000..a1b4f22
Binary files /dev/null and b/resources/assets/file-type-icons/fileicon-java.png differ
diff --git a/resources/assets/file-type-icons/fileicon-mid.png b/resources/assets/file-type-icons/fileicon-mid.png
new file mode 100644 (file)
index 0000000..ce2bebb
Binary files /dev/null and b/resources/assets/file-type-icons/fileicon-mid.png differ
diff --git a/resources/assets/file-type-icons/fileicon-mov.png b/resources/assets/file-type-icons/fileicon-mov.png
new file mode 100644 (file)
index 0000000..952de1f
Binary files /dev/null and b/resources/assets/file-type-icons/fileicon-mov.png differ
diff --git a/resources/assets/file-type-icons/fileicon-o.png b/resources/assets/file-type-icons/fileicon-o.png
new file mode 100644 (file)
index 0000000..f3523d9
Binary files /dev/null and b/resources/assets/file-type-icons/fileicon-o.png differ
diff --git a/resources/assets/file-type-icons/fileicon-ogg.png b/resources/assets/file-type-icons/fileicon-ogg.png
new file mode 100644 (file)
index 0000000..ef4d801
Binary files /dev/null and b/resources/assets/file-type-icons/fileicon-ogg.png differ
diff --git a/resources/assets/file-type-icons/fileicon-ogg.xcf b/resources/assets/file-type-icons/fileicon-ogg.xcf
new file mode 100644 (file)
index 0000000..a91024b
Binary files /dev/null and b/resources/assets/file-type-icons/fileicon-ogg.xcf differ
diff --git a/resources/assets/file-type-icons/fileicon-pdf.png b/resources/assets/file-type-icons/fileicon-pdf.png
new file mode 100644 (file)
index 0000000..8c8da92
Binary files /dev/null and b/resources/assets/file-type-icons/fileicon-pdf.png differ
diff --git a/resources/assets/file-type-icons/fileicon-ps.png b/resources/assets/file-type-icons/fileicon-ps.png
new file mode 100644 (file)
index 0000000..e872833
Binary files /dev/null and b/resources/assets/file-type-icons/fileicon-ps.png differ
diff --git a/resources/assets/file-type-icons/fileicon-psd.png b/resources/assets/file-type-icons/fileicon-psd.png
new file mode 100644 (file)
index 0000000..598f190
Binary files /dev/null and b/resources/assets/file-type-icons/fileicon-psd.png differ
diff --git a/resources/assets/file-type-icons/fileicon-rm.png b/resources/assets/file-type-icons/fileicon-rm.png
new file mode 100644 (file)
index 0000000..81dbe0b
Binary files /dev/null and b/resources/assets/file-type-icons/fileicon-rm.png differ
diff --git a/resources/assets/file-type-icons/fileicon-rpm.png b/resources/assets/file-type-icons/fileicon-rpm.png
new file mode 100644 (file)
index 0000000..1903aac
Binary files /dev/null and b/resources/assets/file-type-icons/fileicon-rpm.png differ
diff --git a/resources/assets/file-type-icons/fileicon-svg.png b/resources/assets/file-type-icons/fileicon-svg.png
new file mode 100644 (file)
index 0000000..b782113
Binary files /dev/null and b/resources/assets/file-type-icons/fileicon-svg.png differ
diff --git a/resources/assets/file-type-icons/fileicon-tar.png b/resources/assets/file-type-icons/fileicon-tar.png
new file mode 100644 (file)
index 0000000..e5fd1b7
Binary files /dev/null and b/resources/assets/file-type-icons/fileicon-tar.png differ
diff --git a/resources/assets/file-type-icons/fileicon-tex.png b/resources/assets/file-type-icons/fileicon-tex.png
new file mode 100644 (file)
index 0000000..a437284
Binary files /dev/null and b/resources/assets/file-type-icons/fileicon-tex.png differ
diff --git a/resources/assets/file-type-icons/fileicon-ttf.png b/resources/assets/file-type-icons/fileicon-ttf.png
new file mode 100644 (file)
index 0000000..1ed4e74
Binary files /dev/null and b/resources/assets/file-type-icons/fileicon-ttf.png differ
diff --git a/resources/assets/file-type-icons/fileicon-txt.png b/resources/assets/file-type-icons/fileicon-txt.png
new file mode 100644 (file)
index 0000000..9e988e7
Binary files /dev/null and b/resources/assets/file-type-icons/fileicon-txt.png differ
diff --git a/resources/assets/file-type-icons/fileicon-xcf.png b/resources/assets/file-type-icons/fileicon-xcf.png
new file mode 100644 (file)
index 0000000..1037b50
Binary files /dev/null and b/resources/assets/file-type-icons/fileicon-xcf.png differ
diff --git a/resources/assets/file-type-icons/fileicon.png b/resources/assets/file-type-icons/fileicon.png
new file mode 100644 (file)
index 0000000..59696a3
Binary files /dev/null and b/resources/assets/file-type-icons/fileicon.png differ
diff --git a/resources/assets/licenses/cc-0.png b/resources/assets/licenses/cc-0.png
new file mode 100644 (file)
index 0000000..9d3fe5f
Binary files /dev/null and b/resources/assets/licenses/cc-0.png differ
diff --git a/resources/assets/licenses/cc-by-nc-sa.png b/resources/assets/licenses/cc-by-nc-sa.png
new file mode 100644 (file)
index 0000000..0d24a71
Binary files /dev/null and b/resources/assets/licenses/cc-by-nc-sa.png differ
diff --git a/resources/assets/licenses/cc-by-sa.png b/resources/assets/licenses/cc-by-sa.png
new file mode 100644 (file)
index 0000000..518fb64
Binary files /dev/null and b/resources/assets/licenses/cc-by-sa.png differ
diff --git a/resources/assets/licenses/cc-by.png b/resources/assets/licenses/cc-by.png
new file mode 100644 (file)
index 0000000..9cca2f9
Binary files /dev/null and b/resources/assets/licenses/cc-by.png differ
diff --git a/resources/assets/licenses/gnu-fdl.png b/resources/assets/licenses/gnu-fdl.png
new file mode 100644 (file)
index 0000000..3feaf57
Binary files /dev/null and b/resources/assets/licenses/gnu-fdl.png differ
diff --git a/resources/assets/licenses/public-domain.png b/resources/assets/licenses/public-domain.png
new file mode 100644 (file)
index 0000000..ebf0107
Binary files /dev/null and b/resources/assets/licenses/public-domain.png differ
diff --git a/resources/assets/mediawiki.png b/resources/assets/mediawiki.png
new file mode 100644 (file)
index 0000000..8c42118
Binary files /dev/null and b/resources/assets/mediawiki.png differ
diff --git a/resources/assets/poweredby_mediawiki_88x31.png b/resources/assets/poweredby_mediawiki_88x31.png
new file mode 100644 (file)
index 0000000..30e1d2e
Binary files /dev/null and b/resources/assets/poweredby_mediawiki_88x31.png differ
index a6705d0..ebb2860 100644 (file)
@@ -2,12 +2,17 @@
        "@metadata": {
                "authors": [
                        "Vacio",
-                       "Xelgen"
+                       "Xelgen",
+                       "Դավիթ Սարոյան"
                ]
        },
-       "ooui-dialog-action-close": "Փակել",
        "ooui-outline-control-move-down": "Իջեցնել կետը",
        "ooui-outline-control-move-up": "Բարձրացնել կետը",
        "ooui-outline-control-remove": "Հեռացնել տարրը",
-       "ooui-toolbar-more": "Ավելին"
+       "ooui-toolbar-more": "Ավելին",
+       "ooui-dialog-message-accept": "Լավ",
+       "ooui-dialog-message-reject": "Չեղարկել",
+       "ooui-dialog-process-error": "Ինչ-որ սխալ է տեղի ունեցել",
+       "ooui-dialog-process-dismiss": "Փակել",
+       "ooui-dialog-process-retry": "Կրկին փորձել"
 }
diff --git a/resources/lib/oojs-ui/images/icons/help-rtl.png b/resources/lib/oojs-ui/images/icons/help-rtl.png
deleted file mode 100644 (file)
index a5a0a66..0000000
Binary files a/resources/lib/oojs-ui/images/icons/help-rtl.png and /dev/null differ
index 98b378d..fdf41ae 100644 (file)
@@ -1,12 +1,12 @@
 /*!
- * OOjs UI v0.1.0-pre (f9c217dfa4)
+ * OOjs UI v0.1.0-pre (f2c3f12959)
  * https://www.mediawiki.org/wiki/OOjs_UI
  *
  * Copyright 2011–2014 OOjs Team and other contributors.
  * Released under the MIT license
  * http://oojs.mit-license.org
  *
- * Date: 2014-09-10T17:25:40Z
+ * Date: 2014-09-18T23:22:20Z
  */
 /*
  * Blank theme mixins.
  */
 /* @noflip */
 .oo-ui-rtl {
-  direction: rtl;
+       direction: rtl;
 }
 /* @noflip */
 .oo-ui-ltr {
-  direction: ltr;
+       direction: ltr;
 }
 .oo-ui-buttonElement > .oo-ui-buttonElement-button {
-  cursor: pointer;
-  display: inline-block;
-  vertical-align: middle;
-  -webkit-touch-callout: none;
-  -webkit-user-select: none;
-  -moz-user-select: none;
-  -ms-user-select: none;
-  user-select: none;
+       cursor: pointer;
+       display: inline-block;
+       vertical-align: middle;
+       -webkit-touch-callout: none;
+       -webkit-user-select: none;
+          -moz-user-select: none;
+           -ms-user-select: none;
+               user-select: none;
 }
 .oo-ui-buttonElement > .oo-ui-buttonElement-button > .oo-ui-iconElement-icon {
-  display: none;
+       display: none;
 }
 .oo-ui-buttonElement > .oo-ui-buttonElement-button > .oo-ui-indicatorElement-indicator {
-  display: none;
+       display: none;
 }
 .oo-ui-buttonElement.oo-ui-widget-disabled > .oo-ui-buttonElement-button {
-  cursor: default;
+       cursor: default;
 }
 .oo-ui-buttonElement.oo-ui-indicatorElement > .oo-ui-buttonElement-button > .oo-ui-indicatorElement-indicator,
 .oo-ui-buttonElement.oo-ui-iconElement > .oo-ui-buttonElement-button > .oo-ui-iconElement-icon {
-  display: inline-block;
-  vertical-align: middle;
-  background-position: center center;
-  background-repeat: no-repeat;
+       display: inline-block;
+       vertical-align: middle;
+       background-position: center center;
+       background-repeat: no-repeat;
 }
 .oo-ui-buttonElement-frameless {
-  display: inline-block;
-  position: relative;
+       display: inline-block;
+       position: relative;
 }
 .oo-ui-buttonElement-frameless > .oo-ui-buttonElement-button > .oo-ui-labelElement-label {
-  display: inline-block;
-  vertical-align: middle;
+       display: inline-block;
+       vertical-align: middle;
 }
 .oo-ui-buttonElement-framed > .oo-ui-buttonElement-button {
-  display: inline-block;
-  vertical-align: top;
-  text-align: center;
+       display: inline-block;
+       vertical-align: top;
+       text-align: center;
 }
 .oo-ui-buttonElement-framed > .oo-ui-buttonElement-button > .oo-ui-labelElement-label {
-  display: inline-block;
-  vertical-align: middle;
+       display: inline-block;
+       vertical-align: middle;
 }
 .oo-ui-buttonElement-framed.oo-ui-widget-disabled > .oo-ui-buttonElement-button,
 .oo-ui-buttonElement-framed.oo-ui-widget-disabled.oo-ui-buttonElement-active > .oo-ui-buttonElement-button,
 .oo-ui-buttonElement-framed.oo-ui-widget-disabled.oo-ui-buttonElement-pressed > .oo-ui-buttonElement-button {
-  cursor: default;
+       cursor: default;
 }
 .oo-ui-buttonElement > .oo-ui-buttonElement-button {
-  color: #333;
+       color: #333333;
 }
 .oo-ui-buttonElement > .oo-ui-buttonElement-button > .oo-ui-iconElement-icon {
-  margin-left: 0;
+       margin-left: 0;
 }
 .oo-ui-buttonElement > .oo-ui-buttonElement-button > .oo-ui-indicatorElement-indicator {
-  margin-right: -0.75em;
+       margin-right: -0.75em;
 }
 .oo-ui-buttonElement.oo-ui-indicatorElement > .oo-ui-buttonElement-button > .oo-ui-indicatorElement-indicator,
 .oo-ui-buttonElement.oo-ui-iconElement > .oo-ui-buttonElement-button > .oo-ui-iconElement-icon {
-  opacity: 0.8;
-  width: 1.9em;
-  height: 1.9em;
+       opacity: 0.8;
+       width: 1.9em;
+       height: 1.9em;
 }
 .oo-ui-buttonElement-frameless > .oo-ui-buttonElement-button > .oo-ui-iconElement-icon {
-  /* Don't animate opacities for now, causes wiggling in Chrome (bug 63020) */
-  /*.oo-ui-transition(opacity 200ms);*/
+       /* Don't animate opacities for now, causes wiggling in Chrome (bug 63020) */
+       /*.oo-ui-transition(opacity 200ms);*/
 }
 .oo-ui-buttonElement-frameless > .oo-ui-buttonElement-button:hover > .oo-ui-iconElement-icon,
 .oo-ui-buttonElement-frameless > .oo-ui-buttonElement-button:focus > .oo-ui-iconElement-icon {
-  opacity: 1;
+       opacity: 1;
 }
 .oo-ui-buttonElement-frameless > .oo-ui-buttonElement-button:hover > .oo-ui-labelElement-label,
 .oo-ui-buttonElement-frameless > .oo-ui-buttonElement-button:focus > .oo-ui-labelElement-label {
-  color: #000;
+       color: #000000;
 }
 .oo-ui-buttonElement-frameless > .oo-ui-buttonElement-button > .oo-ui-labelElement-label {
-  color: #333;
-  margin-left: 0.25em;
+       color: #333333;
+       margin-left: 0.25em;
 }
 .oo-ui-buttonElement-frameless.oo-ui-flaggedElement-primary > .oo-ui-buttonElement-button > .oo-ui-labelElement-label {
-  color: #087ecc;
+       color: #087ecc;
 }
 .oo-ui-buttonElement-frameless.oo-ui-flaggedElement-constructive > .oo-ui-buttonElement-button > .oo-ui-labelElement-label {
-  color: #76ab36;
+       color: #76ab36;
 }
 .oo-ui-buttonElement-frameless.oo-ui-flaggedElement-destructive > .oo-ui-buttonElement-button > .oo-ui-labelElement-label {
-  color: #d45353;
+       color: #d45353;
 }
 .oo-ui-buttonElement-frameless.oo-ui-widget-disabled > .oo-ui-buttonElement-button > .oo-ui-iconElement-icon {
-  opacity: 0.2;
+       opacity: 0.2;
 }
 .oo-ui-buttonElement-frameless.oo-ui-widget-disabled > .oo-ui-buttonElement-button > .oo-ui-labelElement-label {
-  color: #ccc;
+       color: #cccccc;
 }
 .oo-ui-buttonElement-framed > .oo-ui-buttonElement-button {
-  margin: 0.1em 0;
-  padding: 0.2em 0.8em;
-  border-radius: 0.3em;
-  text-shadow: 0 1px 1px rgba(255, 255, 255, 0.5);
-  border: 1px #c9c9c9 solid;
-  -webkit-transition: border-color 100ms ease-in-out;
-  -moz-transition: border-color 100ms ease-in-out;
-  -ms-transition: border-color 100ms ease-in-out;
-  -o-transition: border-color 100ms ease-in-out;
-  transition: border-color 100ms ease-in-out;
-  background: #eeeeee;
-  filter: progid:DXImageTransform.Microsoft.gradient(GradientType=0, startColorstr='#ffffff', endColorstr='#dddddd');
-  background-image: -webkit-gradient(linear, right top, right bottom, color-stop(0%, #ffffff), color-stop(100%, #dddddd));
-  background-image: -webkit-linear-gradient(top, #ffffff 0%, #dddddd 100%);
-  background-image: -moz-linear-gradient(top, #ffffff 0%, #dddddd 100%);
-  background-image: -ms-linear-gradient(top, #ffffff 0%, #dddddd 100%);
-  background-image: -o-linear-gradient(top, #ffffff 0%, #dddddd 100%);
-  background-image: linear-gradient(top, #ffffff 0%, #dddddd 100%);
+       margin: 0.1em 0;
+       padding: 0.2em 0.8em;
+       border-radius: 0.3em;
+       text-shadow: 0 1px 1px rgba(255, 255, 255, 0.5);
+       border: 1px #c9c9c9 solid;
+       -webkit-transition: border-color 100ms ease-in-out;
+          -moz-transition: border-color 100ms ease-in-out;
+           -ms-transition: border-color 100ms ease-in-out;
+            -o-transition: border-color 100ms ease-in-out;
+               transition: border-color 100ms ease-in-out;
+       background: #eeeeee;
+       filter: progid:DXImageTransform.Microsoft.gradient(GradientType=0, startColorstr='#ffffff', endColorstr='#dddddd');
+       background-image: -webkit-gradient(linear, right top, right bottom, color-stop(0%, #ffffff), color-stop(100%, #dddddd));
+       background-image: -webkit-linear-gradient(top, #ffffff 0%, #dddddd 100%);
+       background-image:    -moz-linear-gradient(top, #ffffff 0%, #dddddd 100%);
+       background-image:     -ms-linear-gradient(top, #ffffff 0%, #dddddd 100%);
+       background-image:      -o-linear-gradient(top, #ffffff 0%, #dddddd 100%);
+       background-image:         linear-gradient(top, #ffffff 0%, #dddddd 100%);
 }
 .oo-ui-buttonElement-framed > .oo-ui-buttonElement-button:hover,
 .oo-ui-buttonElement-framed > .oo-ui-buttonElement-button:focus {
-  border-color: #aaa;
+       border-color: #aaaaaa;
 }
 .oo-ui-buttonElement-framed > .oo-ui-buttonElement-button > .oo-ui-labelElement-label {
-  line-height: 1.9em;
+       line-height: 1.9em;
 }
 .oo-ui-buttonElement-framed.oo-ui-buttonElement-active > .oo-ui-buttonElement-button,
 .oo-ui-buttonElement-framed.oo-ui-buttonElement-pressed > .oo-ui-buttonElement-button {
-  box-shadow: inset 0 1px 4px 0 rgba(0, 0, 0, 0.07);
-  color: black;
-  border-color: #c9c9c9;
-  background: #eeeeee;
-  filter: progid:DXImageTransform.Microsoft.gradient(GradientType=0, startColorstr='#dddddd', endColorstr='#ffffff');
-  background-image: -webkit-gradient(linear, right top, right bottom, color-stop(0%, #dddddd), color-stop(100%, #ffffff));
-  background-image: -webkit-linear-gradient(top, #dddddd 0%, #ffffff 100%);
-  background-image: -moz-linear-gradient(top, #dddddd 0%, #ffffff 100%);
-  background-image: -ms-linear-gradient(top, #dddddd 0%, #ffffff 100%);
-  background-image: -o-linear-gradient(top, #dddddd 0%, #ffffff 100%);
-  background-image: linear-gradient(top, #dddddd 0%, #ffffff 100%);
+       box-shadow: inset 0 1px 4px 0 rgba(0, 0, 0, 0.07);
+       color: black;
+       border-color: #c9c9c9;
+       background: #eeeeee;
+       filter: progid:DXImageTransform.Microsoft.gradient(GradientType=0, startColorstr='#dddddd', endColorstr='#ffffff');
+       background-image: -webkit-gradient(linear, right top, right bottom, color-stop(0%, #dddddd), color-stop(100%, #ffffff));
+       background-image: -webkit-linear-gradient(top, #dddddd 0%, #ffffff 100%);
+       background-image:    -moz-linear-gradient(top, #dddddd 0%, #ffffff 100%);
+       background-image:     -ms-linear-gradient(top, #dddddd 0%, #ffffff 100%);
+       background-image:      -o-linear-gradient(top, #dddddd 0%, #ffffff 100%);
+       background-image:         linear-gradient(top, #dddddd 0%, #ffffff 100%);
 }
 .oo-ui-buttonElement-framed.oo-ui-iconElement > .oo-ui-buttonElement-button > .oo-ui-iconElement-icon {
-  margin-left: -0.5em;
-  margin-right: -0.5em;
+       margin-left: -0.5em;
+       margin-right: -0.5em;
 }
 .oo-ui-buttonElement-framed.oo-ui-iconElement.oo-ui-labelElement > .oo-ui-buttonElement-button > .oo-ui-iconElement-icon {
-  margin-left: -0.5em;
-  margin-right: 0.3em;
+       margin-left: -0.5em;
+       margin-right: 0.3em;
 }
 .oo-ui-buttonElement-framed.oo-ui-flaggedElement-primary > .oo-ui-buttonElement-button {
-  border: solid 1px #a6cee1;
-  background: #cde7f4;
-  filter: progid:DXImageTransform.Microsoft.gradient(GradientType=0, startColorstr='#eaf4fa', endColorstr='#b0d9ee');
-  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%);
-  background-image: -moz-linear-gradient(top, #eaf4fa 0%, #b0d9ee 100%);
-  background-image: -ms-linear-gradient(top, #eaf4fa 0%, #b0d9ee 100%);
-  background-image: -o-linear-gradient(top, #eaf4fa 0%, #b0d9ee 100%);
-  background-image: linear-gradient(top, #eaf4fa 0%, #b0d9ee 100%);
+       border: solid 1px #a6cee1;
+       background: #cde7f4;
+       filter: progid:DXImageTransform.Microsoft.gradient(GradientType=0, startColorstr='#eaf4fa', endColorstr='#b0d9ee');
+       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%);
+       background-image:    -moz-linear-gradient(top, #eaf4fa 0%, #b0d9ee 100%);
+       background-image:     -ms-linear-gradient(top, #eaf4fa 0%, #b0d9ee 100%);
+       background-image:      -o-linear-gradient(top, #eaf4fa 0%, #b0d9ee 100%);
+       background-image:         linear-gradient(top, #eaf4fa 0%, #b0d9ee 100%);
 }
 .oo-ui-buttonElement-framed.oo-ui-flaggedElement-primary > .oo-ui-buttonElement-button:hover,
 .oo-ui-buttonElement-framed.oo-ui-flaggedElement-primary > .oo-ui-buttonElement-button:focus {
-  border-color: #9dc2d4;
+       border-color: #9dc2d4;
 }
 .oo-ui-buttonElement-framed.oo-ui-flaggedElement-primary.oo-ui-buttonElement-active > .oo-ui-buttonElement-button,
 .oo-ui-buttonElement-framed.oo-ui-flaggedElement-primary.oo-ui-buttonElement-pressed > .oo-ui-buttonElement-button {
-  border: solid 1px #a6cee1;
-  background: #cde7f4;
-  filter: progid:DXImageTransform.Microsoft.gradient(GradientType=0, startColorstr='#b0d9ee', endColorstr='#eaf4fa');
-  background-image: -webkit-gradient(linear, right top, right bottom, color-stop(0%, #b0d9ee), color-stop(100%, #eaf4fa));
-  background-image: -webkit-linear-gradient(top, #b0d9ee 0%, #eaf4fa 100%);
-  background-image: -moz-linear-gradient(top, #b0d9ee 0%, #eaf4fa 100%);
-  background-image: -ms-linear-gradient(top, #b0d9ee 0%, #eaf4fa 100%);
-  background-image: -o-linear-gradient(top, #b0d9ee 0%, #eaf4fa 100%);
-  background-image: linear-gradient(top, #b0d9ee 0%, #eaf4fa 100%);
+       border: solid 1px #a6cee1;
+       background: #cde7f4;
+       filter: progid:DXImageTransform.Microsoft.gradient(GradientType=0, startColorstr='#b0d9ee', endColorstr='#eaf4fa');
+       background-image: -webkit-gradient(linear, right top, right bottom, color-stop(0%, #b0d9ee), color-stop(100%, #eaf4fa));
+       background-image: -webkit-linear-gradient(top, #b0d9ee 0%, #eaf4fa 100%);
+       background-image:    -moz-linear-gradient(top, #b0d9ee 0%, #eaf4fa 100%);
+       background-image:     -ms-linear-gradient(top, #b0d9ee 0%, #eaf4fa 100%);
+       background-image:      -o-linear-gradient(top, #b0d9ee 0%, #eaf4fa 100%);
+       background-image:         linear-gradient(top, #b0d9ee 0%, #eaf4fa 100%);
 }
 .oo-ui-buttonElement-framed.oo-ui-flaggedElement-constructive > .oo-ui-buttonElement-button {
-  border: solid 1px #b8d892;
-  background: #daf0be;
-  filter: progid:DXImageTransform.Microsoft.gradient(GradientType=0, startColorstr='#f0fbe1', endColorstr='#c3e59a');
-  background-image: -webkit-gradient(linear, right top, right bottom, color-stop(0%, #f0fbe1), color-stop(100%, #c3e59a));
-  background-image: -webkit-linear-gradient(top, #f0fbe1 0%, #c3e59a 100%);
-  background-image: -moz-linear-gradient(top, #f0fbe1 0%, #c3e59a 100%);
-  background-image: -ms-linear-gradient(top, #f0fbe1 0%, #c3e59a 100%);
-  background-image: -o-linear-gradient(top, #f0fbe1 0%, #c3e59a 100%);
-  background-image: linear-gradient(top, #f0fbe1 0%, #c3e59a 100%);
+       border: solid 1px #b8d892;
+       background: #daf0be;
+       filter: progid:DXImageTransform.Microsoft.gradient(GradientType=0, startColorstr='#f0fbe1', endColorstr='#c3e59a');
+       background-image: -webkit-gradient(linear, right top, right bottom, color-stop(0%, #f0fbe1), color-stop(100%, #c3e59a));
+       background-image: -webkit-linear-gradient(top, #f0fbe1 0%, #c3e59a 100%);
+       background-image:    -moz-linear-gradient(top, #f0fbe1 0%, #c3e59a 100%);
+       background-image:     -ms-linear-gradient(top, #f0fbe1 0%, #c3e59a 100%);
+       background-image:      -o-linear-gradient(top, #f0fbe1 0%, #c3e59a 100%);
+       background-image:         linear-gradient(top, #f0fbe1 0%, #c3e59a 100%);
 }
 .oo-ui-buttonElement-framed.oo-ui-flaggedElement-constructive > .oo-ui-buttonElement-button:hover,
 .oo-ui-buttonElement-framed.oo-ui-flaggedElement-constructive > .oo-ui-buttonElement-button:focus {
-  border-color: #adcb89;
+       border-color: #adcb89;
 }
 .oo-ui-buttonElement-framed.oo-ui-flaggedElement-constructive.oo-ui-buttonElement-active > .oo-ui-buttonElement-button,
 .oo-ui-buttonElement-framed.oo-ui-flaggedElement-constructive.oo-ui-buttonElement-pressed > .oo-ui-buttonElement-button {
-  border: solid 1px #b8d892;
-  background: #daf0be;
-  filter: progid:DXImageTransform.Microsoft.gradient(GradientType=0, startColorstr='#c3e59a', endColorstr='#f0fbe1');
-  background-image: -webkit-gradient(linear, right top, right bottom, color-stop(0%, #c3e59a), color-stop(100%, #f0fbe1));
-  background-image: -webkit-linear-gradient(top, #c3e59a 0%, #f0fbe1 100%);
-  background-image: -moz-linear-gradient(top, #c3e59a 0%, #f0fbe1 100%);
-  background-image: -ms-linear-gradient(top, #c3e59a 0%, #f0fbe1 100%);
-  background-image: -o-linear-gradient(top, #c3e59a 0%, #f0fbe1 100%);
-  background-image: linear-gradient(top, #c3e59a 0%, #f0fbe1 100%);
+       border: solid 1px #b8d892;
+       background: #daf0be;
+       filter: progid:DXImageTransform.Microsoft.gradient(GradientType=0, startColorstr='#c3e59a', endColorstr='#f0fbe1');
+       background-image: -webkit-gradient(linear, right top, right bottom, color-stop(0%, #c3e59a), color-stop(100%, #f0fbe1));
+       background-image: -webkit-linear-gradient(top, #c3e59a 0%, #f0fbe1 100%);
+       background-image:    -moz-linear-gradient(top, #c3e59a 0%, #f0fbe1 100%);
+       background-image:     -ms-linear-gradient(top, #c3e59a 0%, #f0fbe1 100%);
+       background-image:      -o-linear-gradient(top, #c3e59a 0%, #f0fbe1 100%);
+       background-image:         linear-gradient(top, #c3e59a 0%, #f0fbe1 100%);
 }
 .oo-ui-buttonElement-framed.oo-ui-flaggedElement-destructive > .oo-ui-buttonElement-button {
-  color: #d45353;
+       color: #d45353;
 }
 .oo-ui-buttonElement-framed.oo-ui-widget-disabled > .oo-ui-buttonElement-button,
 .oo-ui-buttonElement-framed.oo-ui-widget-disabled.oo-ui-buttonElement-active > .oo-ui-buttonElement-button,
 .oo-ui-buttonElement-framed.oo-ui-widget-disabled.oo-ui-buttonElement-pressed > .oo-ui-buttonElement-button {
-  opacity: 0.5;
-  box-shadow: none;
-  color: #333;
-  background: #eee;
-  border-color: #ccc;
+       opacity: 0.5;
+       box-shadow: none;
+       color: #333333;
+       background: #eeeeee;
+       border-color: #cccccc;
 }
 .oo-ui-buttonElement-framed.oo-ui-widget-disabled > .oo-ui-buttonElement-button:hover,
 .oo-ui-buttonElement-framed.oo-ui-widget-disabled.oo-ui-buttonElement-active > .oo-ui-buttonElement-button:hover,
 .oo-ui-buttonElement-framed.oo-ui-widget-disabled > .oo-ui-buttonElement-button:focus,
 .oo-ui-buttonElement-framed.oo-ui-widget-disabled.oo-ui-buttonElement-active > .oo-ui-buttonElement-button:focus,
 .oo-ui-buttonElement-framed.oo-ui-widget-disabled.oo-ui-buttonElement-pressed > .oo-ui-buttonElement-button:focus {
-  border-color: #ccc;
-  box-shadow: none;
+       border-color: #cccccc;
+       box-shadow: none;
 }
 .oo-ui-clippableElement-clippable {
-  -webkit-box-sizing: border-box;
-  -moz-box-sizing: border-box;
-  box-sizing: border-box;
+       -webkit-box-sizing: border-box;
+          -moz-box-sizing: border-box;
+               box-sizing: border-box;
 }
 .oo-ui-bookletLayout-stackLayout.oo-ui-stackLayout-continuous .oo-ui-panelLayout-scrollable {
-  overflow-y: hidden;
+       overflow-y: hidden;
 }
 .oo-ui-bookletLayout-stackLayout .oo-ui-panelLayout {
-  width: 100%;
-  -webkit-box-sizing: border-box;
-  -moz-box-sizing: border-box;
-  box-sizing: border-box;
+       width: 100%;
+       -webkit-box-sizing: border-box;
+          -moz-box-sizing: border-box;
+               box-sizing: border-box;
 }
 .oo-ui-bookletLayout-stackLayout .oo-ui-panelLayout-scrollable {
-  overflow-y: auto;
+       overflow-y: auto;
 }
 .oo-ui-bookletLayout-stackLayout .oo-ui-panelLayout-padded {
-  padding: 2em;
+       padding: 2em;
 }
 .oo-ui-bookletLayout-outlinePanel-editable .oo-ui-outlineWidget {
-  position: absolute;
-  top: 0;
-  left: 0;
-  right: 0;
-  bottom: 3em;
-  overflow-y: auto;
+       position: absolute;
+       top: 0;
+       left: 0;
+       right: 0;
+       bottom: 3em;
+       overflow-y: auto;
 }
 .oo-ui-bookletLayout-outlinePanel .oo-ui-outlineControlsWidget {
-  position: absolute;
-  bottom: 0;
-  left: 0;
-  right: 0;
+       position: absolute;
+       bottom: 0;
+       left: 0;
+       right: 0;
 }
 .oo-ui-bookletLayout-stackLayout .oo-ui-panelLayout {
-  padding: 1.5em;
+       padding: 1.5em;
 }
 .oo-ui-bookletLayout-outlinePanel {
-  border-right: solid 1px #ddd;
+       border-right: solid 1px #dddddd;
 }
 .oo-ui-bookletLayout-outlinePanel .oo-ui-outlineControlsWidget {
-  box-shadow: 0 0 0.25em rgba(0, 0, 0, 0.25);
+       box-shadow: 0 0 0.25em rgba(0, 0, 0, 0.25);
 }
 .oo-ui-fieldLayout {
-  margin-bottom: 1em;
+       margin-bottom: 1em;
 }
 .oo-ui-fieldLayout:before,
 .oo-ui-fieldLayout:after {
-  content: " ";
-  display: table;
+       content: " ";
+       display: table;
 }
 .oo-ui-fieldLayout:after {
-  clear: both;
+       clear: both;
 }
 .oo-ui-fieldLayout.oo-ui-fieldLayout-align-left > .oo-ui-labelElement-label,
 .oo-ui-fieldLayout.oo-ui-fieldLayout-align-right > .oo-ui-labelElement-label {
-  display: block;
-  float: left;
+       display: block;
+       float: left;
 }
 .oo-ui-fieldLayout.oo-ui-fieldLayout-align-left > .oo-ui-fieldLayout-field,
 .oo-ui-fieldLayout.oo-ui-fieldLayout-align-right > .oo-ui-fieldLayout-field {
-  display: block;
-  float: left;
+       display: block;
+       float: left;
 }
 .oo-ui-fieldLayout.oo-ui-fieldLayout-align-right > .oo-ui-labelElement-label {
-  text-align: right;
+       text-align: right;
 }
 .oo-ui-fieldLayout.oo-ui-fieldLayout-align-inline > .oo-ui-labelElement-label {
-  display: inline-block;
-  vertical-align: middle;
+       display: inline-block;
+       vertical-align: middle;
 }
 .oo-ui-fieldLayout.oo-ui-fieldLayout-align-inline > .oo-ui-fieldLayout-field {
-  display: inline-block;
-  vertical-align: middle;
+       display: inline-block;
+       vertical-align: middle;
 }
 .oo-ui-fieldLayout.oo-ui-fieldLayout-align-top > .oo-ui-labelElement-label {
-  display: inline-block;
+       display: inline-block;
 }
 .oo-ui-fieldLayout > .oo-ui-popupButtonWidget > .oo-ui-popupWidget > .oo-ui-popupWidget-popup {
-  z-index: 1;
+       z-index: 1;
+}
+.oo-ui-fieldLayout .oo-ui-fieldLayout-help {
+       float: right;
+}
+.oo-ui-fieldLayout .oo-ui-fieldLayout-help-content {
+       padding: 0.5em 0.75em;
 }
 .oo-ui-fieldLayout:last-child {
-  margin-bottom: 0;
+       margin-bottom: 0;
 }
 .oo-ui-fieldLayout.oo-ui-fieldLayout-align-left > .oo-ui-labelElement-label,
 .oo-ui-fieldLayout.oo-ui-fieldLayout-align-right > .oo-ui-labelElement-label {
-  padding-top: 0.5em;
-  margin-right: 5%;
-  width: 35%;
+       padding-top: 0.5em;
+       margin-right: 5%;
+       width: 35%;
 }
 .oo-ui-fieldLayout.oo-ui-fieldLayout-align-left > .oo-ui-fieldLayout-field,
 .oo-ui-fieldLayout.oo-ui-fieldLayout-align-right > .oo-ui-fieldLayout-field {
-  width: 60%;
+       width: 60%;
 }
 .oo-ui-fieldLayout.oo-ui-fieldLayout-align-inline > .oo-ui-labelElement-label {
-  padding: 0.75em 0.5em 0.5em 0.5em;
+       padding: 0.75em 0.5em 0.5em 0.5em;
 }
 .oo-ui-fieldLayout.oo-ui-fieldLayout-align-inline > .oo-ui-fieldLayout-field {
-  padding: 0.5em 0;
+       padding: 0.5em 0;
 }
 .oo-ui-fieldLayout.oo-ui-fieldLayout-align-top > .oo-ui-labelElement-label {
-  padding: 0.5em 0;
+       padding: 0.5em 0;
 }
 .oo-ui-fieldLayout > .oo-ui-popupButtonWidget > .oo-ui-buttonElement-button > .oo-ui-iconElement-icon {
-  margin-top: 0.25em;
+       margin-top: 0.25em;
 }
 .oo-ui-fieldLayout-disabled .oo-ui-labelElement-label {
-  color: #ccc;
+       color: #cccccc;
 }
 .oo-ui-fieldsetLayout {
-  position: relative;
-  margin: 0;
-  padding: 0;
-  border: none;
+       position: relative;
+       margin: 0;
+       padding: 0;
+       border: none;
 }
 .oo-ui-fieldsetLayout.oo-ui-iconElement > .oo-ui-iconElement-icon {
-  display: block;
-  position: absolute;
-  background-position: center center;
-  background-repeat: no-repeat;
+       display: block;
+       position: absolute;
+       background-position: center center;
+       background-repeat: no-repeat;
 }
 .oo-ui-fieldsetLayout.oo-ui-labelElement > .oo-ui-labelElement-label {
-  display: inline-block;
+       display: inline-block;
 }
 .oo-ui-fieldsetLayout + .oo-ui-fieldsetLayout {
-  margin-top: 2em;
+       margin-top: 2em;
 }
 .oo-ui-fieldsetLayout > .oo-ui-labelElement-label {
-  font-size: 1.5em;
-  margin-bottom: 0.5em;
-  padding: 0.25em 0;
+       font-size: 1.5em;
+       margin-bottom: 0.5em;
+       padding: 0.25em 0;
 }
 .oo-ui-fieldsetLayout.oo-ui-iconElement > .oo-ui-labelElement-label {
-  padding-left: 1.75em;
-  line-height: 1.33em;
+       padding-left: 1.75em;
+       line-height: 1.33em;
 }
 .oo-ui-fieldsetLayout.oo-ui-iconElement > .oo-ui-iconElement-icon {
-  left: 0;
-  top: 0.25em;
-  width: 2em;
-  height: 2em;
+       left: 0;
+       top: 0.25em;
+       width: 2em;
+       height: 2em;
 }
 .oo-ui-gridLayout {
-  position: absolute;
-  top: 0;
-  left: 0;
-  right: 0;
-  bottom: 0;
+       position: absolute;
+       top: 0;
+       left: 0;
+       right: 0;
+       bottom: 0;
 }
 .oo-ui-panelLayout {
-  position: relative;
+       position: relative;
 }
 .oo-ui-panelLayout-scrollable {
-  overflow-y: auto;
+       overflow-y: auto;
 }
 .oo-ui-panelLayout-expanded {
-  position: absolute;
-  top: 0;
-  left: 0;
-  right: 0;
-  bottom: 0;
+       position: absolute;
+       top: 0;
+       left: 0;
+       right: 0;
+       bottom: 0;
 }
 .oo-ui-panelLayout-padded {
-  padding: 1.25em;
+       padding: 1.25em;
 }
 .oo-ui-stackLayout > .oo-ui-panelLayout {
-  display: none;
+       display: none;
 }
 .oo-ui-stackLayout-continuous > .oo-ui-panelLayout {
-  display: block;
-  position: relative;
+       display: block;
+       position: relative;
 }
 .oo-ui-popupTool .oo-ui-popupWidget-popup,
 .oo-ui-popupTool .oo-ui-popupWidget-anchor {
-  z-index: 4;
+       z-index: 4;
 }
 .oo-ui-popupTool .oo-ui-popupWidget {
-  margin-left: 1.25em;
-  font-size: 0.8em;
+       margin-left: 1.25em;
+       font-size: 0.8em;
 }
 .oo-ui-toolGroup {
-  display: inline-block;
-  vertical-align: middle;
-  margin: 0.3em;
-  border-radius: 0.25em;
-  border: solid 1px transparent;
-  -webkit-transition: border-color 300ms ease-in-out;
-  -moz-transition: border-color 300ms ease-in-out;
-  -ms-transition: border-color 300ms ease-in-out;
-  -o-transition: border-color 300ms ease-in-out;
-  transition: border-color 300ms ease-in-out;
+       display: inline-block;
+       vertical-align: middle;
+       margin: 0.3em;
+       border-radius: 0.25em;
+       border: solid 1px transparent;
+       -webkit-transition: border-color 300ms ease-in-out;
+          -moz-transition: border-color 300ms ease-in-out;
+           -ms-transition: border-color 300ms ease-in-out;
+            -o-transition: border-color 300ms ease-in-out;
+               transition: border-color 300ms ease-in-out;
 }
 .oo-ui-toolGroup-empty {
-  display: none;
+       display: none;
 }
 .oo-ui-toolGroup .oo-ui-tool-link .oo-ui-iconElement-icon {
-  background-position: center center;
-  background-repeat: no-repeat;
+       background-position: center center;
+       background-repeat: no-repeat;
 }
 .oo-ui-toolGroup.oo-ui-widget-enabled:hover {
-  border-color: rgba(0, 0, 0, 0.1);
+       border-color: rgba(0, 0, 0, 0.1);
 }
 .oo-ui-toolGroup.oo-ui-widget-enabled .oo-ui-tool-link .oo-ui-tool-title {
-  color: #000;
+       color: #000000;
 }
 .oo-ui-barToolGroup > .oo-ui-iconElement-icon,
 .oo-ui-barToolGroup > .oo-ui-labelElement-label {
-  display: none;
+       display: none;
 }
 .oo-ui-barToolGroup .oo-ui-tool {
-  display: inline-block;
-  position: relative;
-  vertical-align: top;
+       display: inline-block;
+       position: relative;
+       vertical-align: top;
 }
 .oo-ui-barToolGroup .oo-ui-tool-link {
-  display: block;
+       display: block;
 }
 .oo-ui-barToolGroup .oo-ui-tool-link .oo-ui-iconElement-icon {
-  display: block;
+       display: block;
 }
 .oo-ui-barToolGroup .oo-ui-tool-link .oo-ui-tool-title {
-  display: none;
+       display: none;
 }
 .oo-ui-barToolGroup .oo-ui-tool.oo-ui-widget-disabled .oo-ui-tool-link {
-  cursor: default;
+       cursor: default;
 }
 .oo-ui-barToolGroup .oo-ui-tool-title,
 .oo-ui-barToolGroup .oo-ui-tool-accel {
-  display: none;
+       display: none;
 }
 .oo-ui-barToolGroup.oo-ui-widget-enabled .oo-ui-tool-link {
-  cursor: pointer;
+       cursor: pointer;
 }
 .oo-ui-barToolGroup .oo-ui-tool {
-  margin: -1px 0 -1px -1px;
-  border: solid 1px transparent;
+       margin: -1px 0 -1px -1px;
+       border: solid 1px transparent;
 }
 .oo-ui-barToolGroup .oo-ui-tool:first-child {
-  border-top-left-radius: 0.25em;
-  border-bottom-left-radius: 0.25em;
+       border-top-left-radius: 0.25em;
+       border-bottom-left-radius: 0.25em;
 }
 .oo-ui-barToolGroup .oo-ui-tool:last-child {
-  margin-right: -1px;
-  border-top-right-radius: 0.25em;
-  border-bottom-right-radius: 0.25em;
+       margin-right: -1px;
+       border-top-right-radius: 0.25em;
+       border-bottom-right-radius: 0.25em;
 }
 .oo-ui-barToolGroup .oo-ui-tool-link {
-  height: 1.5em;
-  padding: 0.25em;
+       height: 1.5em;
+       padding: 0.25em;
 }
 .oo-ui-barToolGroup .oo-ui-tool-link .oo-ui-iconElement-icon {
-  height: 1.5em;
-  width: 1.5em;
-  opacity: 0.8;
+       height: 1.5em;
+       width: 1.5em;
+       opacity: 0.8;
 }
 .oo-ui-barToolGroup.oo-ui-widget-enabled .oo-ui-tool.oo-ui-widget-enabled:hover {
-  border-color: rgba(0, 0, 0, 0.2);
+       border-color: rgba(0, 0, 0, 0.2);
 }
 .oo-ui-barToolGroup.oo-ui-widget-enabled .oo-ui-tool-active.oo-ui-widget-enabled {
-  border-color: rgba(0, 0, 0, 0.2);
-  box-shadow: inset 0 0.07em 0.07em 0 rgba(0, 0, 0, 0.07);
-  background: #f8fbfd;
-  filter: progid:DXImageTransform.Microsoft.gradient(GradientType=0, startColorstr='#f1f7fb', endColorstr='#ffffff');
-  background-image: -webkit-gradient(linear, right top, right bottom, color-stop(0%, #f1f7fb), color-stop(100%, #ffffff));
-  background-image: -webkit-linear-gradient(top, #f1f7fb 0%, #ffffff 100%);
-  background-image: -moz-linear-gradient(top, #f1f7fb 0%, #ffffff 100%);
-  background-image: -ms-linear-gradient(top, #f1f7fb 0%, #ffffff 100%);
-  background-image: -o-linear-gradient(top, #f1f7fb 0%, #ffffff 100%);
-  background-image: linear-gradient(top, #f1f7fb 0%, #ffffff 100%);
+       border-color: rgba(0, 0, 0, 0.2);
+       box-shadow: inset 0 0.07em 0.07em 0 rgba(0, 0, 0, 0.07);
+       background: #f8fbfd;
+       filter: progid:DXImageTransform.Microsoft.gradient(GradientType=0, startColorstr='#f1f7fb', endColorstr='#ffffff');
+       background-image: -webkit-gradient(linear, right top, right bottom, color-stop(0%, #f1f7fb), color-stop(100%, #ffffff));
+       background-image: -webkit-linear-gradient(top, #f1f7fb 0%, #ffffff 100%);
+       background-image:    -moz-linear-gradient(top, #f1f7fb 0%, #ffffff 100%);
+       background-image:     -ms-linear-gradient(top, #f1f7fb 0%, #ffffff 100%);
+       background-image:      -o-linear-gradient(top, #f1f7fb 0%, #ffffff 100%);
+       background-image:         linear-gradient(top, #f1f7fb 0%, #ffffff 100%);
 }
 .oo-ui-barToolGroup.oo-ui-widget-enabled .oo-ui-tool-active.oo-ui-widget-enabled + .oo-ui-tool-active.oo-ui-widget-enabled {
-  border-left-color: rgba(0, 0, 0, 0.1);
+       border-left-color: rgba(0, 0, 0, 0.1);
 }
 .oo-ui-barToolGroup.oo-ui-widget-enabled .oo-ui-tool.oo-ui-widget-disabled .oo-ui-tool-link .oo-ui-iconElement-icon {
-  opacity: 0.2;
+       opacity: 0.2;
 }
 .oo-ui-barToolGroup.oo-ui-widget-enabled .oo-ui-tool.oo-ui-widget-enabled .oo-ui-tool-link .oo-ui-iconElement-icon {
-  opacity: 0.8;
+       opacity: 0.8;
 }
 .oo-ui-barToolGroup.oo-ui-widget-enabled .oo-ui-tool.oo-ui-widget-enabled:hover .oo-ui-tool-link .oo-ui-iconElement-icon {
-  opacity: 1;
+       opacity: 1;
 }
 .oo-ui-barToolGroup.oo-ui-widget-disabled .oo-ui-tool-link .oo-ui-iconElement-icon {
-  opacity: 0.2;
+       opacity: 0.2;
 }
 .oo-ui-popupToolGroup {
-  position: relative;
-  height: 2em;
-  min-width: 2.5em;
+       position: relative;
+       height: 2em;
+       min-width: 2.5em;
 }
 .oo-ui-popupToolGroup-handle {
-  display: block;
-  cursor: pointer;
+       display: block;
+       cursor: pointer;
 }
 .oo-ui-popupToolGroup-handle .oo-ui-indicatorElement-indicator,
 .oo-ui-popupToolGroup-handle .oo-ui-iconElement-icon {
-  position: absolute;
-  background-position: center center;
-  background-repeat: no-repeat;
+       position: absolute;
+       background-position: center center;
+       background-repeat: no-repeat;
 }
 .oo-ui-popupToolGroup.oo-ui-widget-disabled .oo-ui-popupToolGroup-handle {
-  cursor: default;
+       cursor: default;
 }
 .oo-ui-popupToolGroup .oo-ui-toolGroup-tools {
-  display: none;
-  position: absolute;
-  z-index: 4;
+       display: none;
+       position: absolute;
+       z-index: 4;
 }
 .oo-ui-popupToolGroup .oo-ui-toolGroup-tools .oo-ui-iconElement-icon {
-  background-repeat: no-repeat;
-  background-position: center center;
+       background-repeat: no-repeat;
+       background-position: center center;
 }
 .oo-ui-popupToolGroup-active.oo-ui-widget-enabled > .oo-ui-toolGroup-tools {
-  display: block;
+       display: block;
 }
 .oo-ui-popupToolGroup-left > .oo-ui-toolGroup-tools {
-  left: 0;
+       left: 0;
 }
 .oo-ui-popupToolGroup-right > .oo-ui-toolGroup-tools {
-  right: 0;
+       right: 0;
 }
 .oo-ui-popupToolGroup .oo-ui-tool-link .oo-ui-iconElement-icon {
-  display: inline-block;
-  vertical-align: middle;
+       display: inline-block;
+       vertical-align: middle;
 }
 .oo-ui-popupToolGroup .oo-ui-tool-link .oo-ui-tool-title {
-  display: inline-block;
-  vertical-align: middle;
+       display: inline-block;
+       vertical-align: middle;
 }
 .oo-ui-popupToolGroup .oo-ui-tool-accel {
-  display: none;
+       display: none;
 }
 .oo-ui-popupToolGroup.oo-ui-indicatorElement.oo-ui-iconElement {
-  min-width: 3.5em;
+       min-width: 3.5em;
 }
 .oo-ui-popupToolGroup-handle .oo-ui-indicatorElement-indicator,
 .oo-ui-popupToolGroup-handle .oo-ui-iconElement-icon {
-  top: 0;
-  width: 2em;
-  height: 2em;
-  opacity: 0.8;
+       top: 0;
+       width: 2em;
+       height: 2em;
+       opacity: 0.8;
 }
 .oo-ui-popupToolGroup-handle .oo-ui-indicatorElement-indicator {
-  right: 0;
+       right: 0;
 }
 .oo-ui-popupToolGroup-handle .oo-ui-iconElement-icon {
-  left: 0.25em;
+       left: 0.25em;
 }
 .oo-ui-popupToolGroup-handle .oo-ui-labelElement-label {
-  line-height: 2.6em;
-  font-size: 0.8em;
-  margin: 0 1em;
+       line-height: 2.6em;
+       font-size: 0.8em;
+       margin: 0 1em;
 }
 .oo-ui-popupToolGroup-header {
-  line-height: 2.6em;
-  font-size: 0.8em;
-  margin: 0 0.6em;
-  font-weight: bold;
+       line-height: 2.6em;
+       font-size: 0.8em;
+       margin: 0 0.6em;
+       font-weight: bold;
 }
 .oo-ui-popupToolGroup-active.oo-ui-widget-enabled {
-  border-bottom-left-radius: 0;
-  border-bottom-right-radius: 0;
-  box-shadow: inset 0 0.07em 0.07em 0 rgba(0, 0, 0, 0.07);
-  background: #f8fbfd;
-  filter: progid:DXImageTransform.Microsoft.gradient(GradientType=0, startColorstr='#f1f7fb', endColorstr='#ffffff');
-  background-image: -webkit-gradient(linear, right top, right bottom, color-stop(0%, #f1f7fb), color-stop(100%, #ffffff));
-  background-image: -webkit-linear-gradient(top, #f1f7fb 0%, #ffffff 100%);
-  background-image: -moz-linear-gradient(top, #f1f7fb 0%, #ffffff 100%);
-  background-image: -ms-linear-gradient(top, #f1f7fb 0%, #ffffff 100%);
-  background-image: -o-linear-gradient(top, #f1f7fb 0%, #ffffff 100%);
-  background-image: linear-gradient(top, #f1f7fb 0%, #ffffff 100%);
+       border-bottom-left-radius: 0;
+       border-bottom-right-radius: 0;
+       box-shadow: inset 0 0.07em 0.07em 0 rgba(0, 0, 0, 0.07);
+       background: #f8fbfd;
+       filter: progid:DXImageTransform.Microsoft.gradient(GradientType=0, startColorstr='#f1f7fb', endColorstr='#ffffff');
+       background-image: -webkit-gradient(linear, right top, right bottom, color-stop(0%, #f1f7fb), color-stop(100%, #ffffff));
+       background-image: -webkit-linear-gradient(top, #f1f7fb 0%, #ffffff 100%);
+       background-image:    -moz-linear-gradient(top, #f1f7fb 0%, #ffffff 100%);
+       background-image:     -ms-linear-gradient(top, #f1f7fb 0%, #ffffff 100%);
+       background-image:      -o-linear-gradient(top, #f1f7fb 0%, #ffffff 100%);
+       background-image:         linear-gradient(top, #f1f7fb 0%, #ffffff 100%);
 }
 .oo-ui-popupToolGroup.oo-ui-iconElement .oo-ui-popupToolGroup-handle .oo-ui-labelElement-label {
-  margin-left: 3em;
+       margin-left: 3em;
 }
 .oo-ui-popupToolGroup.oo-ui-indicatorElement .oo-ui-popupToolGroup-handle .oo-ui-labelElement-label {
-  margin-right: 2.25em;
+       margin-right: 2.25em;
 }
 .oo-ui-popupToolGroup .oo-ui-toolGroup-tools {
-  top: 2em;
-  margin: 0 -1px;
-  border: solid 1px #ccc;
-  background-color: white;
-  box-shadow: 0 0.25em 1em rgba(0, 0, 0, 0.25);
+       top: 2em;
+       margin: 0 -1px;
+       border: solid 1px #cccccc;
+       background-color: white;
+       box-shadow: 0 0.25em 1em rgba(0, 0, 0, 0.25);
 }
 .oo-ui-popupToolGroup .oo-ui-tool-link .oo-ui-iconElement-icon {
-  height: 2em;
-  width: 2em;
-  margin-right: 0.25em;
+       height: 2em;
+       width: 2em;
+       margin-right: 0.25em;
 }
 .oo-ui-popupToolGroup .oo-ui-tool-link .oo-ui-tool-title {
-  line-height: 2em;
-  font-size: 0.8em;
+       line-height: 2em;
+       font-size: 0.8em;
 }
 .oo-ui-listToolGroup .oo-ui-tool {
-  display: inline-block;
-  width: 100%;
-  -webkit-box-sizing: border-box;
-  -moz-box-sizing: border-box;
-  box-sizing: border-box;
+       display: inline-block;
+       width: 100%;
+       -webkit-box-sizing: border-box;
+          -moz-box-sizing: border-box;
+               box-sizing: border-box;
 }
 .oo-ui-listToolGroup .oo-ui-tool-link {
-  display: block;
-  cursor: pointer;
-  white-space: nowrap;
+       display: block;
+       cursor: pointer;
+       white-space: nowrap;
 }
 .oo-ui-listToolGroup .oo-ui-tool.oo-ui-widget-disabled .oo-ui-tool-link {
-  cursor: default;
+       cursor: default;
 }
 .oo-ui-listToolGroup .oo-ui-toolGroup-tools {
-  padding: 0.25em;
+       padding: 0.25em;
 }
 .oo-ui-listToolGroup.oo-ui-popupToolGroup-active {
-  border-color: rgba(0, 0, 0, 0.2);
+       border-color: rgba(0, 0, 0, 0.2);
 }
 .oo-ui-listToolGroup .oo-ui-tool {
-  border: solid 1px transparent;
-  margin: -1px 0;
+       border: solid 1px transparent;
+       margin: -1px 0;
 }
 .oo-ui-listToolGroup .oo-ui-tool-link {
-  padding-right: 0.5em;
+       padding-right: 0.5em;
 }
 .oo-ui-listToolGroup .oo-ui-tool-active.oo-ui-widget-enabled {
-  border-color: rgba(0, 0, 0, 0.1);
-  box-shadow: inset 0 0.07em 0.07em 0 rgba(0, 0, 0, 0.07);
-  background: #f8fbfd;
-  filter: progid:DXImageTransform.Microsoft.gradient(GradientType=0, startColorstr='#f1f7fb', endColorstr='#ffffff');
-  background-image: -webkit-gradient(linear, right top, right bottom, color-stop(0%, #f1f7fb), color-stop(100%, #ffffff));
-  background-image: -webkit-linear-gradient(top, #f1f7fb 0%, #ffffff 100%);
-  background-image: -moz-linear-gradient(top, #f1f7fb 0%, #ffffff 100%);
-  background-image: -ms-linear-gradient(top, #f1f7fb 0%, #ffffff 100%);
-  background-image: -o-linear-gradient(top, #f1f7fb 0%, #ffffff 100%);
-  background-image: linear-gradient(top, #f1f7fb 0%, #ffffff 100%);
+       border-color: rgba(0, 0, 0, 0.1);
+       box-shadow: inset 0 0.07em 0.07em 0 rgba(0, 0, 0, 0.07);
+       background: #f8fbfd;
+       filter: progid:DXImageTransform.Microsoft.gradient(GradientType=0, startColorstr='#f1f7fb', endColorstr='#ffffff');
+       background-image: -webkit-gradient(linear, right top, right bottom, color-stop(0%, #f1f7fb), color-stop(100%, #ffffff));
+       background-image: -webkit-linear-gradient(top, #f1f7fb 0%, #ffffff 100%);
+       background-image:    -moz-linear-gradient(top, #f1f7fb 0%, #ffffff 100%);
+       background-image:     -ms-linear-gradient(top, #f1f7fb 0%, #ffffff 100%);
+       background-image:      -o-linear-gradient(top, #f1f7fb 0%, #ffffff 100%);
+       background-image:         linear-gradient(top, #f1f7fb 0%, #ffffff 100%);
 }
 .oo-ui-listToolGroup .oo-ui-tool-active.oo-ui-widget-enabled + .oo-ui-tool-active.oo-ui-widget-enabled {
-  border-top-color: rgba(0, 0, 0, 0.1);
+       border-top-color: rgba(0, 0, 0, 0.1);
 }
 .oo-ui-listToolGroup .oo-ui-tool-active.oo-ui-widget-enabled:hover {
-  border-color: rgba(0, 0, 0, 0.2);
+       border-color: rgba(0, 0, 0, 0.2);
 }
 .oo-ui-listToolGroup .oo-ui-tool.oo-ui-widget-enabled:hover {
-  border-color: rgba(0, 0, 0, 0.2);
+       border-color: rgba(0, 0, 0, 0.2);
 }
 .oo-ui-listToolGroup .oo-ui-tool.oo-ui-widget-enabled .oo-ui-tool-link .oo-ui-iconElement-icon {
-  opacity: 0.8;
+       opacity: 0.8;
 }
 .oo-ui-listToolGroup .oo-ui-tool.oo-ui-widget-enabled:hover .oo-ui-tool-link .oo-ui-iconElement-icon {
-  opacity: 1;
+       opacity: 1;
 }
 .oo-ui-listToolGroup .oo-ui-tool.oo-ui-widget-disabled .oo-ui-tool-link .oo-ui-tool-title {
-  color: #ccc;
+       color: #cccccc;
 }
 .oo-ui-listToolGroup .oo-ui-tool.oo-ui-widget-disabled .oo-ui-tool-link .oo-ui-iconElement-icon {
-  opacity: 0.2;
+       opacity: 0.2;
 }
 .oo-ui-listToolGroup.oo-ui-widget-disabled {
-  color: #ccc;
+       color: #cccccc;
 }
 .oo-ui-listToolGroup.oo-ui-widget-disabled .oo-ui-indicatorElement-indicator,
 .oo-ui-listToolGroup.oo-ui-widget-disabled .oo-ui-iconElement-icon {
-  opacity: 0.2;
+       opacity: 0.2;
 }
 .oo-ui-menuToolGroup {
-  border-color: rgba(0, 0, 0, 0.1);
+       border-color: rgba(0, 0, 0, 0.1);
 }
 .oo-ui-menuToolGroup .oo-ui-tool {
-  display: block;
+       display: block;
 }
 .oo-ui-menuToolGroup .oo-ui-tool-link {
-  display: block;
-  cursor: pointer;
-  white-space: nowrap;
+       display: block;
+       cursor: pointer;
+       white-space: nowrap;
 }
 .oo-ui-menuToolGroup .oo-ui-tool-link .oo-ui-iconElement-icon {
-  background-image: none;
+       background-image: none;
 }
 .oo-ui-menuToolGroup .oo-ui-tool-active .oo-ui-tool-link .oo-ui-iconElement-icon {
-  background-image: /* @embed */ url(images/icons/check.svg);
+       background-image: /* @embed */ url(images/icons/check.svg);
 }
 .oo-ui-menuToolGroup .oo-ui-tool.oo-ui-widget-disabled .oo-ui-tool-link {
-  cursor: default;
+       cursor: default;
 }
 .oo-ui-menuToolGroup .oo-ui-popupToolGroup-handle {
-  min-width: 8em;
+       min-width: 8em;
 }
 .oo-ui-menuToolGroup .oo-ui-toolGroup-tools {
-  padding: 0.25em 0 0.25em 0;
+       padding: 0.25em 0 0.25em 0;
 }
 .oo-ui-menuToolGroup.oo-ui-widget-enabled:hover {
-  border-color: rgba(0, 0, 0, 0.2);
+       border-color: rgba(0, 0, 0, 0.2);
 }
 .oo-ui-menuToolGroup.oo-ui-popupToolGroup-active {
-  border-color: rgba(0, 0, 0, 0.25);
+       border-color: rgba(0, 0, 0, 0.25);
 }
 .oo-ui-menuToolGroup .oo-ui-tool-link {
-  padding: 0 1em 0 0.25em;
+       padding: 0 1em 0 0.25em;
 }
 .oo-ui-menuToolGroup .oo-ui-tool.oo-ui-widget-enabled:hover {
-  background-color: #e1f3ff;
+       background-color: #e1f3ff;
 }
 .oo-ui-menuToolGroup .oo-ui-tool.oo-ui-widget-disabled .oo-ui-tool-link .oo-ui-tool-title {
-  color: #ccc;
+       color: #cccccc;
 }
 .oo-ui-menuToolGroup .oo-ui-tool.oo-ui-widget-disabled .oo-ui-tool-link .oo-ui-iconElement-icon {
-  opacity: 0.2;
+       opacity: 0.2;
 }
 .oo-ui-menuToolGroup.oo-ui-widget-disabled {
-  color: #ccc;
-  border-color: rgba(0, 0, 0, 0.05);
+       color: #cccccc;
+       border-color: rgba(0, 0, 0, 0.05);
 }
 .oo-ui-menuToolGroup.oo-ui-widget-disabled .oo-ui-indicatorElement-indicator,
 .oo-ui-menuToolGroup.oo-ui-widget-disabled .oo-ui-iconElement-icon {
-  opacity: 0.2;
+       opacity: 0.2;
 }
 .oo-ui-toolbar {
-  clear: both;
+       clear: both;
 }
 .oo-ui-toolbar-bar {
-  line-height: 1em;
+       line-height: 1em;
 }
 .oo-ui-toolbar-actions {
-  float: right;
+       float: right;
 }
 .oo-ui-toolbar-tools {
-  display: inline;
+       display: inline;
 }
 .oo-ui-toolbar-tools,
 .oo-ui-toolbar-actions,
 .oo-ui-toolbar-shadow {
-  -webkit-touch-callout: none;
-  -webkit-user-select: none;
-  -moz-user-select: none;
-  -ms-user-select: none;
-  user-select: none;
+       -webkit-touch-callout: none;
+       -webkit-user-select: none;
+          -moz-user-select: none;
+           -ms-user-select: none;
+               user-select: none;
 }
 .oo-ui-toolbar-actions .oo-ui-popupWidget {
-  -webkit-touch-callout: default;
-  -webkit-user-select: all;
-  -moz-user-select: all;
-  -ms-user-select: all;
-  user-select: all;
+       -webkit-touch-callout: default;
+       -webkit-user-select: all;
+          -moz-user-select: all;
+           -ms-user-select: all;
+               user-select: all;
 }
 .oo-ui-toolbar-shadow {
-  background-position: left top;
-  background-repeat: repeat-x;
-  position: absolute;
-  width: 100%;
-  pointer-events: none;
+       background-position: left top;
+       background-repeat: repeat-x;
+       position: absolute;
+       width: 100%;
+       pointer-events: none;
 }
 .oo-ui-toolbar-bar {
-  border-bottom: solid 1px #ccc;
-  background: #f8fbfd;
-  filter: progid:DXImageTransform.Microsoft.gradient(GradientType=0, startColorstr='#ffffff', endColorstr='#f1f7fb');
-  background-image: -webkit-gradient(linear, right top, right bottom, color-stop(0%, #ffffff), color-stop(100%, #f1f7fb));
-  background-image: -webkit-linear-gradient(top, #ffffff 0%, #f1f7fb 100%);
-  background-image: -moz-linear-gradient(top, #ffffff 0%, #f1f7fb 100%);
-  background-image: -ms-linear-gradient(top, #ffffff 0%, #f1f7fb 100%);
-  background-image: -o-linear-gradient(top, #ffffff 0%, #f1f7fb 100%);
-  background-image: linear-gradient(top, #ffffff 0%, #f1f7fb 100%);
+       border-bottom: solid 1px #cccccc;
+       background: #f8fbfd;
+       filter: progid:DXImageTransform.Microsoft.gradient(GradientType=0, startColorstr='#ffffff', endColorstr='#f1f7fb');
+       background-image: -webkit-gradient(linear, right top, right bottom, color-stop(0%, #ffffff), color-stop(100%, #f1f7fb));
+       background-image: -webkit-linear-gradient(top, #ffffff 0%, #f1f7fb 100%);
+       background-image:    -moz-linear-gradient(top, #ffffff 0%, #f1f7fb 100%);
+       background-image:     -ms-linear-gradient(top, #ffffff 0%, #f1f7fb 100%);
+       background-image:      -o-linear-gradient(top, #ffffff 0%, #f1f7fb 100%);
+       background-image:         linear-gradient(top, #ffffff 0%, #f1f7fb 100%);
 }
 .oo-ui-toolbar-bar .oo-ui-toolbar-bar {
-  border: none;
-  background: none;
+       border: none;
+       background: none;
 }
 .oo-ui-toolbar-shadow {
-  background-image: /* @embed */ url(images/toolbar-shadow.png);
-  bottom: -9px;
-  height: 9px;
-  opacity: 0.125;
-  -webkit-transition: opacity 500ms ease-in-out;
-  -moz-transition: opacity 500ms ease-in-out;
-  -ms-transition: opacity 500ms ease-in-out;
-  -o-transition: opacity 500ms ease-in-out;
-  transition: opacity 500ms ease-in-out;
+       background-image: /* @embed */ url(images/toolbar-shadow.png);
+       bottom: -9px;
+       height: 9px;
+       opacity: 0.125;
+       -webkit-transition: opacity 500ms ease-in-out;
+          -moz-transition: opacity 500ms ease-in-out;
+           -ms-transition: opacity 500ms ease-in-out;
+            -o-transition: opacity 500ms ease-in-out;
+               transition: opacity 500ms ease-in-out;
 }
 .oo-ui-optionWidget {
-  position: relative;
-  display: block;
-  cursor: pointer;
-  padding: 0.5em 2em 0.5em 3em;
-  border: none;
+       position: relative;
+       display: block;
+       cursor: pointer;
+       padding: 0.5em 2em 0.5em 3em;
+       border: none;
 }
 .oo-ui-optionWidget.oo-ui-widget-disabled {
-  cursor: default;
+       cursor: default;
 }
 .oo-ui-optionWidget .oo-ui-labelElement-label {
-  display: block;
-  white-space: nowrap;
-  text-overflow: ellipsis;
-  overflow: hidden;
+       display: block;
+       white-space: nowrap;
+       text-overflow: ellipsis;
+       overflow: hidden;
 }
 .oo-ui-optionWidget-highlighted {
-  background-color: #e1f3ff;
+       background-color: #e1f3ff;
 }
 .oo-ui-optionWidget .oo-ui-labelElement-label {
-  line-height: 1.5em;
+       line-height: 1.5em;
 }
 .oo-ui-selectWidget-depressed .oo-ui-optionWidget-selected {
-  background-color: #a7dcff;
+       background-color: #a7dcff;
 }
 .oo-ui-selectWidget-pressed .oo-ui-optionWidget-pressed {
-  background-color: #a7dcff;
+       background-color: #a7dcff;
 }
 .oo-ui-optionWidget.oo-ui-widget-disabled {
-  color: #ccc;
+       color: #cccccc;
 }
 .oo-ui-decoratedOptionWidget .oo-ui-iconElement-icon,
 .oo-ui-decoratedOptionWidget .oo-ui-indicatorElement-indicator {
-  position: absolute;
-  background-repeat: no-repeat;
-  background-position: center center;
+       position: absolute;
+       background-repeat: no-repeat;
+       background-position: center center;
 }
 .oo-ui-decoratedOptionWidget .oo-ui-iconElement-icon,
 .oo-ui-decoratedOptionWidget .oo-ui-indicatorElement-indicator {
-  top: 50%;
-  width: 2em;
-  height: 2em;
-  margin-top: -1em;
+       top: 50%;
+       width: 2em;
+       height: 2em;
+       margin-top: -1em;
 }
 .oo-ui-decoratedOptionWidget .oo-ui-iconElement-icon {
-  left: 0.5em;
+       left: 0.5em;
 }
 .oo-ui-decoratedOptionWidget .oo-ui-indicatorElement-indicator {
-  right: 0.5em;
+       right: 0.5em;
 }
 .oo-ui-buttonSelectWidget {
-  display: inline-block;
-  white-space: nowrap;
-  border-radius: 0.3em;
+       display: inline-block;
+       white-space: nowrap;
+       border-radius: 0.3em;
 }
 .oo-ui-buttonSelectWidget .oo-ui-buttonOptionWidget .oo-ui-buttonElement-button {
-  border-radius: 0;
-  margin-left: -1px;
+       border-radius: 0;
+       margin-left: -1px;
 }
 .oo-ui-buttonSelectWidget .oo-ui-buttonOptionWidget:first-child .oo-ui-buttonElement-button {
-  border-bottom-left-radius: 0.3em;
-  border-top-left-radius: 0.3em;
-  margin-left: 0;
+       border-bottom-left-radius: 0.3em;
+       border-top-left-radius: 0.3em;
+       margin-left: 0;
 }
 .oo-ui-buttonSelectWidget .oo-ui-buttonOptionWidget:last-child .oo-ui-buttonElement-button {
-  border-bottom-right-radius: 0.3em;
-  border-top-right-radius: 0.3em;
+       border-bottom-right-radius: 0.3em;
+       border-top-right-radius: 0.3em;
 }
 .oo-ui-buttonOptionWidget {
-  display: inline-block;
-  padding: 0;
-  background-color: transparent;
+       display: inline-block;
+       padding: 0;
+       background-color: transparent;
 }
 .oo-ui-buttonOptionWidget .oo-ui-buttonElement-button {
-  position: relative;
+       position: relative;
 }
 .oo-ui-buttonOptionWidget.oo-ui-iconElement .oo-ui-iconElement-icon,
 .oo-ui-buttonOptionWidget.oo-ui-indicatorElement .oo-ui-indicatorElement-indicator {
-  position: static;
-  display: inline-block;
-  vertical-align: middle;
+       position: static;
+       display: inline-block;
+       vertical-align: middle;
 }
 .oo-ui-buttonOptionWidget .oo-ui-buttonElement-button {
-  height: 1.9em;
+       height: 1.9em;
 }
 .oo-ui-buttonOptionWidget.oo-ui-iconElement .oo-ui-iconElement-icon,
 .oo-ui-buttonOptionWidget.oo-ui-indicatorElement .oo-ui-indicatorElement-indicator {
-  height: 1.9em;
-  margin-top: 0;
+       height: 1.9em;
+       margin-top: 0;
 }
 .oo-ui-buttonOptionWidget.oo-ui-optionWidget-selected,
 .oo-ui-buttonOptionWidget.oo-ui-optionWidget-pressed,
 .oo-ui-buttonOptionWidget.oo-ui-optionWidget-highlighted {
-  background-color: transparent;
+       background-color: transparent;
 }
 .oo-ui-labelWidget {
-  display: inline-block;
-  padding: 0.5em 0;
+       display: inline-block;
+       padding: 0.5em 0;
 }
 .oo-ui-iconWidget {
-  display: inline-block;
-  vertical-align: middle;
-  background-position: center center;
-  background-repeat: no-repeat;
-  line-height: 2.5em;
-  height: 1.9em;
-  width: 1.9em;
-  opacity: 0.8;
+       display: inline-block;
+       vertical-align: middle;
+       background-position: center center;
+       background-repeat: no-repeat;
+       line-height: 2.5em;
+       height: 1.9em;
+       width: 1.9em;
+       opacity: 0.8;
 }
 .oo-ui-iconWidget.oo-ui-widget-disabled {
-  opacity: 0.2;
+       opacity: 0.2;
 }
 .oo-ui-indicatorWidget {
-  display: inline-block;
-  vertical-align: middle;
-  background-position: center center;
-  background-repeat: no-repeat;
-  line-height: 2.5em;
-  height: 1.9em;
-  width: 1.9em;
-  opacity: 0.8;
+       display: inline-block;
+       vertical-align: middle;
+       background-position: center center;
+       background-repeat: no-repeat;
+       line-height: 2.5em;
+       height: 1.9em;
+       width: 1.9em;
+       opacity: 0.8;
 }
 .oo-ui-indicatorWidget.oo-ui-widget-disabled {
-  opacity: 0.2;
+       opacity: 0.2;
 }
 .oo-ui-buttonWidget {
-  display: inline-block;
-  vertical-align: middle;
+       display: inline-block;
+       vertical-align: middle;
 }
 .oo-ui-buttonGroupWidget {
-  display: inline-block;
-  white-space: nowrap;
-  border-radius: 0.3em;
+       display: inline-block;
+       white-space: nowrap;
+       border-radius: 0.3em;
 }
 .oo-ui-buttonGroupWidget .oo-ui-buttonElement-framed .oo-ui-buttonElement-button {
-  border-radius: 0;
-  margin-bottom: -1px;
-  margin-left: -1px;
+       border-radius: 0;
+       margin-bottom: -1px;
+       margin-left: -1px;
 }
 .oo-ui-buttonGroupWidget .oo-ui-buttonElement-framed:first-child .oo-ui-buttonElement-button {
-  border-bottom-left-radius: 0.3em;
-  border-top-left-radius: 0.3em;
-  margin-left: 0;
+       border-bottom-left-radius: 0.3em;
+       border-top-left-radius: 0.3em;
+       margin-left: 0;
 }
 .oo-ui-buttonGroupWidget .oo-ui-buttonElement-framed:last-child .oo-ui-buttonElement-button {
-  border-bottom-right-radius: 0.3em;
-  border-top-right-radius: 0.3em;
+       border-bottom-right-radius: 0.3em;
+       border-top-right-radius: 0.3em;
 }
 .oo-ui-toggleSwitchWidget {
-  position: relative;
-  display: inline-block;
-  vertical-align: middle;
-  overflow: hidden;
-  cursor: pointer;
-  -webkit-box-sizing: border-box;
-  -moz-box-sizing: border-box;
-  box-sizing: border-box;
-  -webkit-transform: translateZ(0px);
-  -moz-transform: translateZ(0px);
-  -ms-transform: translateZ(0px);
-  -o-transform: translateZ(0px);
-  transform: translateZ(0px);
-  height: 2em;
-  width: 4em;
-  border-radius: 1em;
-  box-shadow: 0 0 0 white, inset 0 0.1em 0.2em #ddd;
-  border: solid 1px #ccc;
-  background: #eeeeee;
-  filter: progid:DXImageTransform.Microsoft.gradient(GradientType=0, startColorstr='#dddddd', endColorstr='#ffffff');
-  background-image: -webkit-gradient(linear, right top, right bottom, color-stop(0%, #dddddd), color-stop(100%, #ffffff));
-  background-image: -webkit-linear-gradient(top, #dddddd 0%, #ffffff 100%);
-  background-image: -moz-linear-gradient(top, #dddddd 0%, #ffffff 100%);
-  background-image: -ms-linear-gradient(top, #dddddd 0%, #ffffff 100%);
-  background-image: -o-linear-gradient(top, #dddddd 0%, #ffffff 100%);
-  background-image: linear-gradient(top, #dddddd 0%, #ffffff 100%);
+       position: relative;
+       display: inline-block;
+       vertical-align: middle;
+       overflow: hidden;
+       cursor: pointer;
+       -webkit-box-sizing: border-box;
+          -moz-box-sizing: border-box;
+               box-sizing: border-box;
+       -webkit-transform: translateZ(0px);
+          -moz-transform: translateZ(0px);
+           -ms-transform: translateZ(0px);
+            -o-transform: translateZ(0px);
+               transform: translateZ(0px);
+       height: 2em;
+       width: 4em;
+       border-radius: 1em;
+       box-shadow: 0 0 0 white, inset 0 0.1em 0.2em #dddddd;
+       border: solid 1px #cccccc;
+       background: #eeeeee;
+       filter: progid:DXImageTransform.Microsoft.gradient(GradientType=0, startColorstr='#dddddd', endColorstr='#ffffff');
+       background-image: -webkit-gradient(linear, right top, right bottom, color-stop(0%, #dddddd), color-stop(100%, #ffffff));
+       background-image: -webkit-linear-gradient(top, #dddddd 0%, #ffffff 100%);
+       background-image:    -moz-linear-gradient(top, #dddddd 0%, #ffffff 100%);
+       background-image:     -ms-linear-gradient(top, #dddddd 0%, #ffffff 100%);
+       background-image:      -o-linear-gradient(top, #dddddd 0%, #ffffff 100%);
+       background-image:         linear-gradient(top, #dddddd 0%, #ffffff 100%);
 }
 .oo-ui-toggleSwitchWidget.oo-ui-widget-disabled {
-  cursor: default;
+       cursor: default;
 }
 .oo-ui-toggleSwitchWidget-grip {
-  position: absolute;
-  display: block;
-  -webkit-box-sizing: border-box;
-  -moz-box-sizing: border-box;
-  box-sizing: border-box;
+       position: absolute;
+       display: block;
+       -webkit-box-sizing: border-box;
+          -moz-box-sizing: border-box;
+               box-sizing: border-box;
 }
 .oo-ui-toggleSwitchWidget .oo-ui-toggleSwitchWidget-glow {
-  position: absolute;
-  top: 0;
-  bottom: 0;
-  right: 0;
-  left: 0;
-  -webkit-touch-callout: none;
-  -webkit-user-select: none;
-  -moz-user-select: none;
-  -ms-user-select: none;
-  user-select: none;
+       position: absolute;
+       top: 0;
+       bottom: 0;
+       right: 0;
+       left: 0;
+       -webkit-touch-callout: none;
+       -webkit-user-select: none;
+          -moz-user-select: none;
+           -ms-user-select: none;
+               user-select: none;
 }
 .oo-ui-toggleWidget-off .oo-ui-toggleSwitchWidget-glow {
-  display: none;
+       display: none;
 }
 .oo-ui-toggleSwitchWidget.oo-ui-widget-disabled {
-  opacity: 0.5;
+       opacity: 0.5;
 }
 .oo-ui-toggleSwitchWidget-grip {
-  top: 0.25em;
-  left: 0.25em;
-  width: 1.5em;
-  height: 1.5em;
-  margin-top: -1px;
-  border-radius: 1em;
-  box-shadow: 0 0.1em 0.25em rgba(0, 0, 0, 0.1);
-  border: 1px #c9c9c9 solid;
-  -webkit-transition: left 200ms ease-in-out, margin-left 200ms ease-in-out;
-  -moz-transition: left 200ms ease-in-out, margin-left 200ms ease-in-out;
-  -ms-transition: left 200ms ease-in-out, margin-left 200ms ease-in-out;
-  -o-transition: left 200ms ease-in-out, margin-left 200ms ease-in-out;
-  transition: left 200ms ease-in-out, margin-left 200ms ease-in-out;
-  background: #eeeeee;
-  filter: progid:DXImageTransform.Microsoft.gradient(GradientType=0, startColorstr='#ffffff', endColorstr='#dddddd');
-  background-image: -webkit-gradient(linear, right top, right bottom, color-stop(0%, #ffffff), color-stop(100%, #dddddd));
-  background-image: -webkit-linear-gradient(top, #ffffff 0%, #dddddd 100%);
-  background-image: -moz-linear-gradient(top, #ffffff 0%, #dddddd 100%);
-  background-image: -ms-linear-gradient(top, #ffffff 0%, #dddddd 100%);
-  background-image: -o-linear-gradient(top, #ffffff 0%, #dddddd 100%);
-  background-image: linear-gradient(top, #ffffff 0%, #dddddd 100%);
+       top: 0.25em;
+       left: 0.25em;
+       width: 1.5em;
+       height: 1.5em;
+       margin-top: -1px;
+       border-radius: 1em;
+       box-shadow: 0 0.1em 0.25em rgba(0, 0, 0, 0.1);
+       border: 1px #c9c9c9 solid;
+       -webkit-transition: left 200ms ease-in-out, margin-left 200ms ease-in-out;
+          -moz-transition: left 200ms ease-in-out, margin-left 200ms ease-in-out;
+           -ms-transition: left 200ms ease-in-out, margin-left 200ms ease-in-out;
+            -o-transition: left 200ms ease-in-out, margin-left 200ms ease-in-out;
+               transition: left 200ms ease-in-out, margin-left 200ms ease-in-out;
+       background: #eeeeee;
+       filter: progid:DXImageTransform.Microsoft.gradient(GradientType=0, startColorstr='#ffffff', endColorstr='#dddddd');
+       background-image: -webkit-gradient(linear, right top, right bottom, color-stop(0%, #ffffff), color-stop(100%, #dddddd));
+       background-image: -webkit-linear-gradient(top, #ffffff 0%, #dddddd 100%);
+       background-image:    -moz-linear-gradient(top, #ffffff 0%, #dddddd 100%);
+       background-image:     -ms-linear-gradient(top, #ffffff 0%, #dddddd 100%);
+       background-image:      -o-linear-gradient(top, #ffffff 0%, #dddddd 100%);
+       background-image:         linear-gradient(top, #ffffff 0%, #dddddd 100%);
 }
 .oo-ui-toggleSwitchWidget.oo-ui-widget-enabled:hover,
 .oo-ui-toggleSwitchWidget.oo-ui-widget-enabled:hover .oo-ui-toggleSwitchWidget-grip {
-  border-color: #aaa;
+       border-color: #aaaaaa;
 }
 .oo-ui-toggleSwitchWidget .oo-ui-toggleSwitchWidget-glow {
-  border-radius: 1em;
-  box-shadow: inset 0 1px 4px 0 rgba(0, 0, 0, 0.07);
-  -webkit-transition: opacity 200ms ease-in-out;
-  -moz-transition: opacity 200ms ease-in-out;
-  -ms-transition: opacity 200ms ease-in-out;
-  -o-transition: opacity 200ms ease-in-out;
-  transition: opacity 200ms ease-in-out;
-  background: #cde7f4;
-  filter: progid:DXImageTransform.Microsoft.gradient(GradientType=0, startColorstr='#b0d9ee', endColorstr='#eaf4fa');
-  background-image: -webkit-gradient(linear, right top, right bottom, color-stop(0%, #b0d9ee), color-stop(100%, #eaf4fa));
-  background-image: -webkit-linear-gradient(top, #b0d9ee 0%, #eaf4fa 100%);
-  background-image: -moz-linear-gradient(top, #b0d9ee 0%, #eaf4fa 100%);
-  background-image: -ms-linear-gradient(top, #b0d9ee 0%, #eaf4fa 100%);
-  background-image: -o-linear-gradient(top, #b0d9ee 0%, #eaf4fa 100%);
-  background-image: linear-gradient(top, #b0d9ee 0%, #eaf4fa 100%);
+       border-radius: 1em;
+       box-shadow: inset 0 1px 4px 0 rgba(0, 0, 0, 0.07);
+       -webkit-transition: opacity 200ms ease-in-out;
+          -moz-transition: opacity 200ms ease-in-out;
+           -ms-transition: opacity 200ms ease-in-out;
+            -o-transition: opacity 200ms ease-in-out;
+               transition: opacity 200ms ease-in-out;
+       background: #cde7f4;
+       filter: progid:DXImageTransform.Microsoft.gradient(GradientType=0, startColorstr='#b0d9ee', endColorstr='#eaf4fa');
+       background-image: -webkit-gradient(linear, right top, right bottom, color-stop(0%, #b0d9ee), color-stop(100%, #eaf4fa));
+       background-image: -webkit-linear-gradient(top, #b0d9ee 0%, #eaf4fa 100%);
+       background-image:    -moz-linear-gradient(top, #b0d9ee 0%, #eaf4fa 100%);
+       background-image:     -ms-linear-gradient(top, #b0d9ee 0%, #eaf4fa 100%);
+       background-image:      -o-linear-gradient(top, #b0d9ee 0%, #eaf4fa 100%);
+       background-image:         linear-gradient(top, #b0d9ee 0%, #eaf4fa 100%);
 }
 .oo-ui-toggleWidget-on .oo-ui-toggleSwitchWidget-glow {
-  opacity: 1;
+       opacity: 1;
 }
 .oo-ui-toggleWidget-on .oo-ui-toggleSwitchWidget-grip {
-  left: 2.25em;
-  margin-left: -2px;
+       left: 2.25em;
+       margin-left: -2px;
 }
 .oo-ui-toggleWidget-off .oo-ui-toggleSwitchWidget-glow {
-  display: block;
-  opacity: 0;
+       display: block;
+       opacity: 0;
 }
 .oo-ui-toggleWidget-off .oo-ui-toggleSwitchWidget-grip {
-  left: 0.25em;
-  margin-left: 0;
+       left: 0.25em;
+       margin-left: 0;
+}
+.oo-ui-actionWidget.oo-ui-pendingElement-pending {
+       background-image: /* @embed */ url(images/textures/pending.gif);
 }
 .oo-ui-popupWidget-popup {
-  position: absolute;
-  overflow: hidden;
-  z-index: 1;
+       position: absolute;
+       overflow: hidden;
+       z-index: 1;
 }
 .oo-ui-popupWidget-anchor {
-  display: none;
-  z-index: 1;
+       display: none;
+       z-index: 1;
 }
 .oo-ui-popupWidget-anchored .oo-ui-popupWidget-anchor {
-  display: block;
-  position: absolute;
-  background-repeat: no-repeat;
+       display: block;
+       position: absolute;
+       background-repeat: no-repeat;
 }
 .oo-ui-popupWidget-head {
-  -webkit-touch-callout: none;
-  -webkit-user-select: none;
-  -moz-user-select: none;
-  -ms-user-select: none;
-  user-select: none;
+       -webkit-touch-callout: none;
+       -webkit-user-select: none;
+          -moz-user-select: none;
+           -ms-user-select: none;
+               user-select: none;
 }
 .oo-ui-popupWidget-head .oo-ui-buttonWidget {
-  float: right;
+       float: right;
 }
 .oo-ui-popupWidget-head .oo-ui-labelElement-label {
-  float: left;
-  cursor: default;
+       float: left;
+       cursor: default;
 }
 .oo-ui-popupWidget-body {
-  clear: both;
-  overflow: hidden;
+       clear: both;
+       overflow: hidden;
 }
 .oo-ui-popupWidget-popup {
-  border: solid 1px #ccc;
-  border-radius: 0.25em;
-  background-color: #fff;
-  box-shadow: 0 0.15em 0.5em 0 rgba(0, 0, 0, 0.2);
+       border: solid 1px #cccccc;
+       border-radius: 0.25em;
+       background-color: #ffffff;
+       box-shadow: 0 0.15em 0.5em 0 rgba(0, 0, 0, 0.2);
 }
 .oo-ui-popupWidget-anchored .oo-ui-popupWidget-popup {
-  margin-top: 7px;
+       margin-top: 7px;
 }
 .oo-ui-popupWidget-anchored .oo-ui-popupWidget-anchor {
-  width: 15px;
-  height: 8px;
-  margin-left: -7px;
-  background-image: /* @embed */ url(images/anchor.svg);
+       width: 15px;
+       height: 8px;
+       margin-left: -7px;
+       background-image: /* @embed */ url(images/anchor.svg);
 }
 .oo-ui-popupWidget-transitioning .oo-ui-popupWidget-popup {
-  -webkit-transition: width 100ms ease-in-out, height 100ms ease-in-out, left 100ms ease-in-out;
-  -moz-transition: width 100ms ease-in-out, height 100ms ease-in-out, left 100ms ease-in-out;
-  -ms-transition: width 100ms ease-in-out, height 100ms ease-in-out, left 100ms ease-in-out;
-  -o-transition: width 100ms ease-in-out, height 100ms ease-in-out, left 100ms ease-in-out;
-  transition: width 100ms ease-in-out, height 100ms ease-in-out, left 100ms ease-in-out;
+       -webkit-transition: width 100ms ease-in-out, height 100ms ease-in-out, left 100ms ease-in-out;
+          -moz-transition: width 100ms ease-in-out, height 100ms ease-in-out, left 100ms ease-in-out;
+           -ms-transition: width 100ms ease-in-out, height 100ms ease-in-out, left 100ms ease-in-out;
+            -o-transition: width 100ms ease-in-out, height 100ms ease-in-out, left 100ms ease-in-out;
+               transition: width 100ms ease-in-out, height 100ms ease-in-out, left 100ms ease-in-out;
 }
 .oo-ui-popupWidget-head {
-  height: 2.5em;
+       height: 2.5em;
 }
 .oo-ui-popupWidget-head .oo-ui-buttonWidget {
-  margin: 0.25em;
+       margin: 0.25em;
 }
 .oo-ui-popupWidget-head .oo-ui-labelElement-label {
-  margin: 0.75em 1em;
+       margin: 0.75em 1em;
 }
 .oo-ui-popupWidget-body {
-  box-shadow: 0 0 0.66em rgba(0, 0, 0, 0.25);
+       box-shadow: 0 0 0.66em rgba(0, 0, 0, 0.25);
 }
 .oo-ui-popupWidget-body-padded {
-  padding: 0 1em;
+       padding: 0 1em;
 }
 .oo-ui-popupButtonWidget {
-  position: relative;
+       position: relative;
 }
 .oo-ui-popupButtonWidget .oo-ui-popupWidget {
-  position: absolute;
-  left: 1em;
-  cursor: auto;
+       position: absolute;
+       left: 1em;
+       cursor: auto;
 }
 .oo-ui-textInputWidget {
-  position: relative;
-  -webkit-box-sizing: border-box;
-  -moz-box-sizing: border-box;
-  box-sizing: border-box;
-  width: 20em;
+       position: relative;
+       -webkit-box-sizing: border-box;
+          -moz-box-sizing: border-box;
+               box-sizing: border-box;
+       width: 20em;
 }
 .oo-ui-textInputWidget input,
 .oo-ui-textInputWidget textarea {
-  display: inline-block;
-  width: 100%;
-  resize: none;
-  -webkit-box-sizing: border-box;
-  -moz-box-sizing: border-box;
-  box-sizing: border-box;
+       display: inline-block;
+       width: 100%;
+       resize: none;
+       -webkit-box-sizing: border-box;
+          -moz-box-sizing: border-box;
+               box-sizing: border-box;
+}
+.oo-ui-textInputWidget.oo-ui-pendingElement-pending input,
+.oo-ui-textInputWidget.oo-ui-pendingElement-pending textarea {
+       background-image: /* @embed */ url(images/textures/pending.gif);
 }
 .oo-ui-textInputWidget > .oo-ui-iconElement-icon,
 .oo-ui-textInputWidget > .oo-ui-indicatorElement-indicator {
-  position: absolute;
-  top: 0;
-  height: 100%;
-  background-repeat: no-repeat;
-  cursor: pointer;
-  -webkit-touch-callout: none;
-  -webkit-user-select: none;
-  -moz-user-select: none;
-  -ms-user-select: none;
-  user-select: none;
+       position: absolute;
+       top: 0;
+       height: 100%;
+       background-repeat: no-repeat;
+       cursor: pointer;
+       -webkit-touch-callout: none;
+       -webkit-user-select: none;
+          -moz-user-select: none;
+           -ms-user-select: none;
+               user-select: none;
 }
 .oo-ui-textInputWidget > .oo-ui-iconElement-icon {
-  left: 0;
+       left: 0;
 }
 .oo-ui-textInputWidget > .oo-ui-indicatorElement-indicator {
-  right: 0;
+       right: 0;
 }
 .oo-ui-textInputWidget input,
 .oo-ui-textInputWidget textarea {
-  padding: 0.5em;
-  font-size: 1em;
-  font-family: sans-serif;
-  background-color: #fff;
-  border: solid 1px #ccc;
-  box-shadow: 0 0 0 white, inset 0 0.1em 0.2em #ddd;
-  border-radius: 0.25em;
-  -webkit-transition: border-color 200ms, box-shadow 200ms;
-  -moz-transition: border-color 200ms, box-shadow 200ms;
-  -ms-transition: border-color 200ms, box-shadow 200ms;
-  -o-transition: border-color 200ms, box-shadow 200ms;
-  transition: border-color 200ms, box-shadow 200ms;
+       padding: 0.5em;
+       font-size: 1em;
+       font-family: sans-serif;
+       background-color: #ffffff;
+       border: solid 1px #cccccc;
+       box-shadow: 0 0 0 white, inset 0 0.1em 0.2em #dddddd;
+       border-radius: 0.25em;
+       -webkit-transition: border-color 200ms, box-shadow 200ms;
+          -moz-transition: border-color 200ms, box-shadow 200ms;
+           -ms-transition: border-color 200ms, box-shadow 200ms;
+            -o-transition: border-color 200ms, box-shadow 200ms;
+               transition: border-color 200ms, box-shadow 200ms;
 }
 .oo-ui-textInputWidget-decorated input,
 .oo-ui-textInputWidget-decorated textarea {
-  padding-left: 2em;
+       padding-left: 2em;
 }
 .oo-ui-textInputWidget-icon {
-  width: 2em;
+       width: 2em;
 }
 .oo-ui-textInputWidget.oo-ui-widget-enabled input:focus,
 .oo-ui-textInputWidget.oo-ui-widget-enabled textarea:focus {
-  outline: none;
-  border-color: #a7dcff;
-  box-shadow: 0 0 0.3em #a7dcff, 0 0 0 white;
+       outline: none;
+       border-color: #a7dcff;
+       box-shadow: 0 0 0.3em #a7dcff, 0 0 0 white;
 }
 .oo-ui-textInputWidget input[readonly],
 .oo-ui-textInputWidget textarea[readonly] {
-  color: #777;
-  text-shadow: 0 1px 1px #fff;
+       color: #777777;
+       text-shadow: 0 1px 1px #ffffff;
 }
-.oo-ui-textInputWidget-pending input,
-.oo-ui-textInputWidget-pending textarea {
-  background-color: transparent;
+.oo-ui-textInputWidget.oo-ui-pendingElement-pending input,
+.oo-ui-textInputWidget.oo-ui-pendingElement-pending textarea {
+       background-color: transparent;
 }
 .oo-ui-textInputWidget.oo-ui-widget-disabled input,
 .oo-ui-textInputWidget.oo-ui-widget-disabled input:focus,
 .oo-ui-textInputWidget.oo-ui-widget-disabled textarea,
 .oo-ui-textInputWidget.oo-ui-widget-disabled textarea:focus {
-  color: #ccc;
-  text-shadow: 0 1px 1px #fff;
-  border-color: #ddd;
-  background-color: #f3f3f3;
+       color: #cccccc;
+       text-shadow: 0 1px 1px #ffffff;
+       border-color: #dddddd;
+       background-color: #f3f3f3;
 }
 .oo-ui-textInputWidget .oo-ui-iconElement-icon,
 .oo-ui-textInputWidget .oo-ui-indicatorElement-indicator {
-  opacity: 0.8;
+       opacity: 0.8;
 }
 .oo-ui-textInputWidget.oo-ui-iconElement input,
 .oo-ui-textInputWidget.oo-ui-iconElement textarea {
-  padding-left: 2em;
+       padding-left: 2em;
 }
 .oo-ui-textInputWidget.oo-ui-iconElement .oo-ui-iconElement-icon {
-  width: 2em;
-  background-position: right center;
+       width: 2em;
+       background-position: right center;
 }
 .oo-ui-textInputWidget.oo-ui-indicatorElement input,
 .oo-ui-textInputWidget.oo-ui-indicatorElement textarea {
-  padding-right: 1.5em;
+       padding-right: 1.5em;
 }
 .oo-ui-textInputWidget.oo-ui-indicatorElement .oo-ui-indicatorElement-indicator {
-  width: 1.5em;
-  background-position: left center;
+       width: 1.5em;
+       background-position: left center;
 }
 .oo-ui-menuWidget {
-  position: absolute;
-  background: #fff;
-  margin-top: -1px;
-  border: solid 1px #ccc;
-  border-radius: 0 0 0.25em 0.25em;
-  box-shadow: 0 0.15em 1em 0 rgba(0, 0, 0, 0.2);
+       position: absolute;
+       background: #ffffff;
+       margin-top: -1px;
+       border: solid 1px #cccccc;
+       border-radius: 0 0 0.25em 0.25em;
+       box-shadow: 0 0.15em 1em 0 rgba(0, 0, 0, 0.2);
 }
 .oo-ui-menuWidget input {
-  position: absolute;
-  width: 0;
-  height: 0;
-  overflow: hidden;
-  opacity: 0;
+       position: absolute;
+       width: 0;
+       height: 0;
+       overflow: hidden;
+       opacity: 0;
 }
 .oo-ui-menuItemWidget {
-  position: relative;
+       position: relative;
 }
 .oo-ui-menuItemWidget .oo-ui-iconElement-icon {
-  display: none;
+       display: none;
 }
 .oo-ui-menuItemWidget.oo-ui-optionWidget-selected {
-  background-color: transparent;
+       background-color: transparent;
 }
 .oo-ui-menuItemWidget.oo-ui-optionWidget-selected .oo-ui-iconElement-icon {
-  display: block;
+       display: block;
 }
 .oo-ui-menuItemWidget.oo-ui-optionWidget-selected {
-  background-color: transparent;
+       background-color: transparent;
 }
 .oo-ui-menuItemWidget.oo-ui-optionWidget-highlighted,
 .oo-ui-menuItemWidget.oo-ui-optionWidget-highlighted.oo-ui-optionWidget-selected {
-  background-color: #e1f3ff;
+       background-color: #e1f3ff;
 }
 .oo-ui-menuSectionItemWidget {
-  cursor: default;
-  padding: 0.33em 0.75em;
-  color: #888;
+       cursor: default;
+       padding: 0.33em 0.75em;
+       color: #888888;
 }
 .oo-ui-inlineMenuWidget {
-  position: relative;
-  display: inline-block;
-  margin: 0.25em 0;
-  min-width: 20em;
+       position: relative;
+       display: inline-block;
+       margin: 0.25em 0;
+       min-width: 20em;
 }
 .oo-ui-inlineMenuWidget-handle {
-  width: 100%;
-  display: inline-block;
-  cursor: pointer;
-  -webkit-touch-callout: none;
-  -webkit-user-select: none;
-  -moz-user-select: none;
-  -ms-user-select: none;
-  user-select: none;
-  -webkit-box-sizing: border-box;
-  -moz-box-sizing: border-box;
-  box-sizing: border-box;
+       width: 100%;
+       display: inline-block;
+       cursor: pointer;
+       -webkit-touch-callout: none;
+       -webkit-user-select: none;
+          -moz-user-select: none;
+           -ms-user-select: none;
+               user-select: none;
+       -webkit-box-sizing: border-box;
+          -moz-box-sizing: border-box;
+               box-sizing: border-box;
 }
 .oo-ui-inlineMenuWidget-handle .oo-ui-indicatorElement-indicator,
 .oo-ui-inlineMenuWidget-handle .oo-ui-iconElement-icon {
-  position: absolute;
-  background-position: center center;
-  background-repeat: no-repeat;
+       position: absolute;
+       background-position: center center;
+       background-repeat: no-repeat;
 }
 .oo-ui-inlineMenuWidget .oo-ui-menuWidget {
-  z-index: 1;
-  width: 100%;
+       z-index: 1;
+       width: 100%;
 }
 .oo-ui-inlineMenuWidget.oo-ui-widget-disabled .oo-ui-inlineMenuWidget-handle {
-  cursor: default;
+       cursor: default;
 }
 .oo-ui-inlineMenuWidget-handle {
-  height: 2.5em;
-  border: solid 1px rgba(0, 0, 0, 0.1);
-  border-radius: 0.25em;
+       height: 2.5em;
+       border: solid 1px rgba(0, 0, 0, 0.1);
+       border-radius: 0.25em;
 }
 .oo-ui-inlineMenuWidget-handle:hover {
-  border-color: rgba(0, 0, 0, 0.2);
+       border-color: rgba(0, 0, 0, 0.2);
 }
 .oo-ui-inlineMenuWidget-handle .oo-ui-indicatorElement-indicator {
-  right: 0;
+       right: 0;
 }
 .oo-ui-inlineMenuWidget-handle .oo-ui-iconElement-icon {
-  left: 0.25em;
+       left: 0.25em;
 }
 .oo-ui-inlineMenuWidget-handle .oo-ui-labelElement-label {
-  line-height: 2.5em;
-  margin: 0 0.5em;
+       line-height: 2.5em;
+       margin: 0 0.5em;
 }
 .oo-ui-inlineMenuWidget-handle .oo-ui-indicatorElement-indicator,
 .oo-ui-inlineMenuWidget-handle .oo-ui-iconElement-icon {
-  top: 0;
-  width: 2.5em;
-  height: 2.5em;
-  opacity: 0.8;
+       top: 0;
+       width: 2.5em;
+       height: 2.5em;
+       opacity: 0.8;
 }
 .oo-ui-inlineMenuWidget.oo-ui-widget-disabled .oo-ui-inlineMenuWidget-handle {
-  color: #ccc;
-  text-shadow: 0 1px 1px #fff;
-  border-color: #ddd;
-  background-color: #f3f3f3;
+       color: #cccccc;
+       text-shadow: 0 1px 1px #ffffff;
+       border-color: #dddddd;
+       background-color: #f3f3f3;
 }
 .oo-ui-inlineMenuWidget.oo-ui-widget-disabled .oo-ui-indicatorElement-indicator {
-  opacity: 0.2;
+       opacity: 0.2;
 }
 .oo-ui-inlineMenuWidget.oo-ui-iconElement .oo-ui-inlineMenuWidget-handle .oo-ui-labelElement-label {
-  margin-left: 3em;
+       margin-left: 3em;
 }
 .oo-ui-inlineMenuWidget.oo-ui-indicatorElement .oo-ui-inlineMenuWidget-handle .oo-ui-labelElement-label {
-  margin-right: 2em;
+       margin-right: 2em;
 }
 .oo-ui-outlineItemWidget {
-  position: relative;
-  cursor: pointer;
-  -webkit-touch-callout: none;
-  -webkit-user-select: none;
-  -moz-user-select: none;
-  -ms-user-select: none;
-  user-select: none;
-  font-size: 1.1em;
-  padding: 0.75em;
+       position: relative;
+       cursor: pointer;
+       -webkit-touch-callout: none;
+       -webkit-user-select: none;
+          -moz-user-select: none;
+           -ms-user-select: none;
+               user-select: none;
+       font-size: 1.1em;
+       padding: 0.75em;
 }
 .oo-ui-outlineItemWidget.oo-ui-indicatorElement .oo-ui-labelElement-label {
-  padding-right: 1.5em;
+       padding-right: 1.5em;
 }
 .oo-ui-outlineItemWidget.oo-ui-indicatorElement .oo-ui-indicatorElement-indicator {
-  opacity: 0.5;
+       opacity: 0.5;
 }
 .oo-ui-outlineItemWidget-level-0 {
-  padding-left: 3.5em;
+       padding-left: 3.5em;
 }
 .oo-ui-outlineItemWidget-level-0 .oo-ui-iconElement-icon {
-  left: 1em;
+       left: 1em;
 }
 .oo-ui-outlineItemWidget-level-1 {
-  padding-left: 5em;
+       padding-left: 5em;
 }
 .oo-ui-outlineItemWidget-level-1 .oo-ui-iconElement-icon {
-  left: 2.5em;
+       left: 2.5em;
 }
 .oo-ui-outlineItemWidget-level-2 {
-  padding-left: 6.5em;
+       padding-left: 6.5em;
 }
 .oo-ui-outlineItemWidget-level-2 .oo-ui-iconElement-icon {
-  left: 4em;
+       left: 4em;
 }
 .oo-ui-selectWidget-depressed .oo-ui-outlineItemWidget.oo-ui-optionWidget-selected {
-  background-color: #a7dcff;
-  text-shadow: 0 1px 1px rgba(255, 255, 255, 0.5);
+       background-color: #a7dcff;
+       text-shadow: 0 1px 1px rgba(255, 255, 255, 0.5);
 }
 .oo-ui-outlineItemWidget.oo-ui-flaggedElement-important {
-  font-weight: bold;
+       font-weight: bold;
 }
 .oo-ui-outlineItemWidget.oo-ui-flaggedElement-placeholder {
-  font-style: italic;
+       font-style: italic;
 }
 .oo-ui-outlineItemWidget.oo-ui-flaggedElement-empty .oo-ui-iconElement-icon {
-  opacity: 0.5;
+       opacity: 0.5;
 }
 .oo-ui-outlineItemWidget.oo-ui-flaggedElement-empty .oo-ui-labelElement-label {
-  color: #777;
+       color: #777777;
 }
 .oo-ui-outlineControlsWidget {
-  height: 3em;
-  background-color: #fff;
+       height: 3em;
+       background-color: #ffffff;
 }
 .oo-ui-outlineControlsWidget-items,
 .oo-ui-outlineControlsWidget-movers {
-  float: left;
-  -webkit-box-sizing: border-box;
-  -moz-box-sizing: border-box;
-  box-sizing: border-box;
+       float: left;
+       -webkit-box-sizing: border-box;
+          -moz-box-sizing: border-box;
+               box-sizing: border-box;
 }
 .oo-ui-outlineControlsWidget > .oo-ui-iconElement-icon {
-  float: left;
-  background-position: right center;
-  background-repeat: no-repeat;
+       float: left;
+       background-position: right center;
+       background-repeat: no-repeat;
 }
 .oo-ui-outlineControlsWidget-items {
-  float: left;
+       float: left;
 }
 .oo-ui-outlineControlsWidget-items .oo-ui-buttonWidget {
-  float: left;
+       float: left;
 }
 .oo-ui-outlineControlsWidget-movers {
-  float: right;
+       float: right;
 }
 .oo-ui-outlineControlsWidget-movers .oo-ui-buttonWidget {
-  float: right;
+       float: right;
 }
 .oo-ui-outlineControlsWidget-items,
 .oo-ui-outlineControlsWidget-movers {
-  height: 2em;
-  margin: 0.5em;
-  padding: 0;
+       height: 2em;
+       margin: 0.5em;
+       padding: 0;
 }
 .oo-ui-outlineControlsWidget > .oo-ui-iconElement-icon {
-  width: 1.5em;
-  height: 2em;
-  margin: 0.5em 0 0.5em 0.5em;
-  opacity: 0.2;
+       width: 1.5em;
+       height: 2em;
+       margin: 0.5em 0 0.5em 0.5em;
+       opacity: 0.2;
 }
 .oo-ui-outlineControlsWidget-items {
-  margin-left: 0;
+       margin-left: 0;
 }
 .oo-ui-comboBoxWidget > .oo-ui-selectWidget {
-  z-index: 1;
-  min-width: 20em;
+       z-index: 1;
+       min-width: 20em;
 }
 .oo-ui-comboBoxWidget > .oo-ui-selectWidget-handle {
-  border: solid 1px rgba(0, 0, 0, 0.1);
-  border-radius: 0.25em;
+       border: solid 1px rgba(0, 0, 0, 0.1);
+       border-radius: 0.25em;
 }
 .oo-ui-comboBoxWidget > .oo-ui-selectWidget-handle:hover {
-  border-color: rgba(0, 0, 0, 0.2);
+       border-color: rgba(0, 0, 0, 0.2);
 }
 .oo-ui-comboBoxWidget > .oo-ui-selectWidget.oo-ui-widget-disabled .oo-ui-textInputWidget.oo-ui-indicatorElement .oo-ui-indicatorElement-indicator,
 .oo-ui-comboBoxWidget > .oo-ui-selectWidget-empty .oo-ui-textInputWidget.oo-ui-indicatorElement .oo-ui-indicatorElement-indicator {
-  cursor: default;
-  opacity: 0.2;
+       cursor: default;
+       opacity: 0.2;
 }
 .oo-ui-searchWidget-query {
-  position: absolute;
-  top: 0;
-  left: 0;
-  right: 0;
+       position: absolute;
+       top: 0;
+       left: 0;
+       right: 0;
 }
 .oo-ui-searchWidget-query .oo-ui-textInputWidget {
-  width: 100%;
+       width: 100%;
 }
 .oo-ui-searchWidget-results {
-  position: absolute;
-  bottom: 0;
-  left: 0;
-  right: 0;
-  overflow-x: hidden;
-  overflow-y: auto;
+       position: absolute;
+       bottom: 0;
+       left: 0;
+       right: 0;
+       overflow-x: hidden;
+       overflow-y: auto;
 }
 .oo-ui-searchWidget-query {
-  height: 4em;
-  padding: 0 1em;
-  box-shadow: 0 0 0.5em rgba(0, 0, 0, 0.2);
+       height: 4em;
+       padding: 0 1em;
+       box-shadow: 0 0 0.5em rgba(0, 0, 0, 0.2);
 }
 .oo-ui-searchWidget-query .oo-ui-textInputWidget {
-  margin: 0.75em 0;
+       margin: 0.75em 0;
 }
 .oo-ui-searchWidget-results {
-  top: 4em;
-  padding: 1em;
-  line-height: 0;
+       top: 4em;
+       padding: 1em;
+       line-height: 0;
 }
 .oo-ui-window {
-  line-height: 1em;
-  /* Content div takes focus when opened, so hide outline */
+       line-height: 1em;
+       /* Content div takes focus when opened, so hide outline */
 }
 .oo-ui-window-frame {
-  -webkit-box-sizing: border-box;
-  -moz-box-sizing: border-box;
-  box-sizing: border-box;
+       -webkit-box-sizing: border-box;
+          -moz-box-sizing: border-box;
+               box-sizing: border-box;
 }
 .oo-ui-window-frame > iframe {
-  width: 100%;
-  height: 100%;
-  margin: 0;
-  padding: 0;
+       width: 100%;
+       height: 100%;
+       margin: 0;
+       padding: 0;
 }
 .oo-ui-window-content:focus {
-  outline: none;
+       outline: none;
 }
 .oo-ui-window-head,
 .oo-ui-window-foot {
-  -webkit-touch-callout: none;
-  -webkit-user-select: none;
-  -moz-user-select: none;
-  -ms-user-select: none;
-  user-select: none;
+       -webkit-touch-callout: none;
+       -webkit-user-select: none;
+          -moz-user-select: none;
+           -ms-user-select: none;
+               user-select: none;
 }
 .oo-ui-window-body {
-  margin: 0;
-  padding: 0;
-  background: none;
+       margin: 0;
+       padding: 0;
+       background: none;
 }
 .oo-ui-window-overlay {
-  position: absolute;
-  top: 0;
-  left: 0;
+       position: absolute;
+       top: 0;
+       left: 0;
 }
 .oo-ui-window-isolated {
-  background-color: transparent;
-  background-image: none;
-  font-family: sans-serif;
-  font-size: 0.8em;
+       background-color: transparent;
+       background-image: none;
+       font-family: sans-serif;
+       font-size: 0.8em;
 }
 .oo-ui-dialog-content > .oo-ui-window-head,
 .oo-ui-dialog-content > .oo-ui-window-body,
 .oo-ui-dialog-content > .oo-ui-window-foot {
-  position: absolute;
-  left: 0;
-  right: 0;
-  overflow: hidden;
-  -webkit-box-sizing: border-box;
-  -moz-box-sizing: border-box;
-  box-sizing: border-box;
+       position: absolute;
+       left: 0;
+       right: 0;
+       overflow: hidden;
+       -webkit-box-sizing: border-box;
+          -moz-box-sizing: border-box;
+               box-sizing: border-box;
 }
 .oo-ui-dialog-content > .oo-ui-window-head {
-  z-index: 1;
-  top: 0;
+       z-index: 1;
+       top: 0;
+}
+.oo-ui-dialog-content > .oo-ui-window-head.oo-ui-pendingElement-pending {
+       background-image: /* @embed */ url(images/textures/pending.gif);
 }
 .oo-ui-dialog-content > .oo-ui-window-body {
-  z-index: 2;
-  top: 0;
-  bottom: 0;
+       z-index: 2;
+       top: 0;
+       bottom: 0;
 }
 .oo-ui-dialog-content > .oo-ui-window-foot {
-  z-index: 1;
-  bottom: 0;
+       z-index: 1;
+       bottom: 0;
 }
 .oo-ui-dialog-content > .oo-ui-window-overlay {
-  z-index: 3;
+       z-index: 3;
 }
 .oo-ui-dialog-content > .oo-ui-window-body {
-  box-shadow: 0 0 0.66em rgba(0, 0, 0, 0.25);
+       box-shadow: 0 0 0.66em rgba(0, 0, 0, 0.25);
 }
 .oo-ui-messageDialog-actions-horizontal {
-  display: table;
-  table-layout: fixed;
-  width: 100%;
+       display: table;
+       table-layout: fixed;
+       width: 100%;
 }
 .oo-ui-messageDialog-actions-horizontal .oo-ui-actionWidget {
-  display: table-cell;
-  width: 1%;
+       display: table-cell;
+       width: 1%;
 }
 .oo-ui-messageDialog-actions-vertical {
-  display: block;
+       display: block;
 }
 .oo-ui-messageDialog-actions-vertical .oo-ui-actionWidget {
-  display: block;
-  overflow: hidden;
-  text-overflow: ellipsis;
+       display: block;
+       overflow: hidden;
+       text-overflow: ellipsis;
 }
 .oo-ui-messageDialog-actions .oo-ui-actionWidget {
-  position: relative;
-  text-align: center;
+       position: relative;
+       text-align: center;
 }
 .oo-ui-messageDialog-actions .oo-ui-actionWidget .oo-ui-buttonElement-button {
-  display: block;
+       display: block;
 }
 .oo-ui-messageDialog-actions .oo-ui-actionWidget .oo-ui-labelElement-label {
-  position: relative;
-  top: auto;
-  bottom: auto;
-  display: inline;
-  white-space: nowrap;
+       position: relative;
+       top: auto;
+       bottom: auto;
+       display: inline;
+       white-space: nowrap;
 }
 .oo-ui-messageDialog-content .oo-ui-window-body {
-  box-shadow: 0 0 0.33em rgba(0, 0, 0, 0.33);
+       box-shadow: 0 0 0.33em rgba(0, 0, 0, 0.33);
 }
 .oo-ui-messageDialog-title,
 .oo-ui-messageDialog-message {
-  display: block;
-  text-align: center;
-  padding-top: 0.5em;
+       display: block;
+       text-align: center;
+       padding-top: 0.5em;
 }
 .oo-ui-messageDialog-title {
-  font-size: 1.5em;
-  line-height: 1em;
-  color: #000;
+       font-size: 1.5em;
+       line-height: 1em;
+       color: #000000;
 }
 .oo-ui-messageDialog-message {
-  font-size: 0.9em;
-  line-height: 1.25em;
-  color: #666;
+       font-size: 0.9em;
+       line-height: 1.25em;
+       color: #666666;
 }
 .oo-ui-messageDialog-message-verbose {
-  font-size: 1.1em;
-  line-height: 1.5em;
-  text-align: left;
+       font-size: 1.1em;
+       line-height: 1.5em;
+       text-align: left;
 }
 .oo-ui-messageDialog-actions-horizontal .oo-ui-actionWidget {
-  border-right: solid 1px #e5e5e5;
+       border-right: solid 1px #e5e5e5;
 }
 .oo-ui-messageDialog-actions-horizontal .oo-ui-actionWidget:last-child {
-  border-right-width: 0;
+       border-right-width: 0;
 }
 .oo-ui-messageDialog-actions-vertical .oo-ui-actionWidget {
-  border-bottom: solid 1px #e5e5e5;
+       border-bottom: solid 1px #e5e5e5;
 }
 .oo-ui-messageDialog-actions-vertical .oo-ui-actionWidget:last-child {
-  border-bottom-width: 0;
+       border-bottom-width: 0;
 }
 .oo-ui-messageDialog-actions .oo-ui-actionWidget .oo-ui-labelElement-label {
-  text-align: center;
-  line-height: 3.4em;
-  padding: 0 2em;
+       text-align: center;
+       line-height: 3.4em;
+       padding: 0 2em;
 }
 .oo-ui-messageDialog-actions .oo-ui-actionWidget:hover {
-  background-color: rgba(0, 0, 0, 0.05);
+       background-color: rgba(0, 0, 0, 0.05);
 }
 .oo-ui-messageDialog-actions .oo-ui-actionWidget:active {
-  background-color: rgba(0, 0, 0, 0.1);
+       background-color: rgba(0, 0, 0, 0.1);
 }
 .oo-ui-messageDialog-actions .oo-ui-actionWidget.oo-ui-flaggedElement-primary:hover {
-  background-color: rgba(8, 126, 204, 0.05);
+       background-color: rgba(8, 126, 204, 0.05);
 }
 .oo-ui-messageDialog-actions .oo-ui-actionWidget.oo-ui-flaggedElement-primary:active {
-  background-color: rgba(8, 126, 204, 0.1);
+       background-color: rgba(8, 126, 204, 0.1);
 }
 .oo-ui-messageDialog-actions .oo-ui-actionWidget.oo-ui-flaggedElement-primary .oo-ui-labelElement-label {
-  font-weight: bold;
+       font-weight: bold;
 }
 .oo-ui-messageDialog-actions .oo-ui-actionWidget.oo-ui-flaggedElement-constructive:hover {
-  background-color: rgba(118, 171, 54, 0.05);
+       background-color: rgba(118, 171, 54, 0.05);
 }
 .oo-ui-messageDialog-actions .oo-ui-actionWidget.oo-ui-flaggedElement-constructive:active {
-  background-color: rgba(118, 171, 54, 0.1);
+       background-color: rgba(118, 171, 54, 0.1);
 }
 .oo-ui-messageDialog-actions .oo-ui-actionWidget.oo-ui-flaggedElement-destructive:hover {
-  background-color: rgba(212, 83, 83, 0.05);
+       background-color: rgba(212, 83, 83, 0.05);
 }
 .oo-ui-messageDialog-actions .oo-ui-actionWidget.oo-ui-flaggedElement-destructive:active {
-  background-color: rgba(212, 83, 83, 0.1);
+       background-color: rgba(212, 83, 83, 0.1);
 }
 .oo-ui-processDialog-location {
-  overflow: hidden;
-  text-overflow: ellipsis;
-  white-space: nowrap;
+       overflow: hidden;
+       text-overflow: ellipsis;
+       white-space: nowrap;
 }
 .oo-ui-processDialog-title {
-  display: inline;
-  padding: 0;
+       display: inline;
+       padding: 0;
 }
 .oo-ui-processDialog-actions-safe .oo-ui-actionWidget,
 .oo-ui-processDialog-actions-primary .oo-ui-actionWidget,
 .oo-ui-processDialog-actions-other .oo-ui-actionWidget {
-  white-space: nowrap;
+       white-space: nowrap;
 }
 .oo-ui-processDialog-actions-safe,
 .oo-ui-processDialog-actions-primary {
-  position: absolute;
-  top: 0;
-  bottom: 0;
+       position: absolute;
+       top: 0;
+       bottom: 0;
 }
 .oo-ui-processDialog-actions-safe {
-  left: 0;
+       left: 0;
 }
 .oo-ui-processDialog-actions-primary {
-  right: 0;
+       right: 0;
 }
 .oo-ui-processDialog-errors {
-  display: none;
-  position: absolute;
-  top: 0;
-  left: 0;
-  right: 0;
-  bottom: 0;
-  z-index: 2;
-  overflow-x: hidden;
-  overflow-y: auto;
+       display: none;
+       position: absolute;
+       top: 0;
+       left: 0;
+       right: 0;
+       bottom: 0;
+       z-index: 2;
+       overflow-x: hidden;
+       overflow-y: auto;
 }
 .oo-ui-processDialog-content .oo-ui-window-head {
-  height: 3.4em;
+       height: 3.4em;
 }
 .oo-ui-processDialog-content .oo-ui-window-body {
-  top: 3.4em;
-  box-shadow: 0 0 0.33em rgba(0, 0, 0, 0.33);
+       top: 3.4em;
+       box-shadow: 0 0 0.33em rgba(0, 0, 0, 0.33);
 }
 .oo-ui-processDialog-navigation {
-  position: relative;
-  height: 3.4em;
-  padding: 0 1em;
+       position: relative;
+       height: 3.4em;
+       padding: 0 1em;
 }
 .oo-ui-processDialog-location {
-  padding: 0.75em 0;
-  height: 1.9em;
-  cursor: default;
-  text-align: center;
+       padding: 0.75em 0;
+       height: 1.9em;
+       cursor: default;
+       text-align: center;
 }
 .oo-ui-processDialog-title {
-  font-weight: bold;
-  line-height: 1.9em;
+       font-weight: bold;
+       line-height: 1.9em;
 }
 .oo-ui-processDialog-actions-safe .oo-ui-actionWidget .oo-ui-buttonElement-button,
 .oo-ui-processDialog-actions-primary .oo-ui-actionWidget .oo-ui-buttonElement-button,
 .oo-ui-processDialog-actions-other .oo-ui-actionWidget .oo-ui-buttonElement-button {
-  padding-top: 0.75em;
-  padding-bottom: 0.75em;
-  min-width: 1.9em;
-  min-height: 1.9em;
+       padding-top: 0.75em;
+       padding-bottom: 0.75em;
+       min-width: 1.9em;
+       min-height: 1.9em;
 }
 .oo-ui-processDialog-actions-safe .oo-ui-actionWidget .oo-ui-labelElement-label,
 .oo-ui-processDialog-actions-primary .oo-ui-actionWidget .oo-ui-labelElement-label,
 .oo-ui-processDialog-actions-other .oo-ui-actionWidget .oo-ui-labelElement-label {
-  line-height: 1.9em;
-  padding: 0 1em;
+       line-height: 1.9em;
+       padding: 0 1em;
 }
 .oo-ui-processDialog-actions-safe .oo-ui-actionWidget .oo-ui-iconElement-icon,
 .oo-ui-processDialog-actions-primary .oo-ui-actionWidget .oo-ui-iconElement-icon,
 .oo-ui-processDialog-actions-other .oo-ui-actionWidget .oo-ui-iconElement-icon {
-  position: absolute;
-  margin-top: -0.125em;
+       position: absolute;
+       margin-top: -0.125em;
 }
 .oo-ui-processDialog-actions-safe .oo-ui-actionWidget.oo-ui-buttonElement-framed,
 .oo-ui-processDialog-actions-primary .oo-ui-actionWidget.oo-ui-buttonElement-framed,
 .oo-ui-processDialog-actions-other .oo-ui-actionWidget.oo-ui-buttonElement-framed {
-  margin: 0.75em 0 0.75em 0.75em;
+       margin: 0.75em 0 0.75em 0.75em;
 }
 .oo-ui-processDialog-actions-safe .oo-ui-actionWidget.oo-ui-buttonElement-framed .oo-ui-buttonElement-button,
 .oo-ui-processDialog-actions-primary .oo-ui-actionWidget.oo-ui-buttonElement-framed .oo-ui-buttonElement-button,
 .oo-ui-processDialog-actions-other .oo-ui-actionWidget.oo-ui-buttonElement-framed .oo-ui-buttonElement-button {
-  padding: 0;
-  vertical-align: middle;
+       padding: 0;
+       vertical-align: middle;
 }
 .oo-ui-processDialog-actions-safe .oo-ui-actionWidget:hover,
 .oo-ui-processDialog-actions-primary .oo-ui-actionWidget:hover {
-  background-color: rgba(0, 0, 0, 0.05);
+       background-color: rgba(0, 0, 0, 0.05);
 }
 .oo-ui-processDialog-actions-safe .oo-ui-actionWidget:active,
 .oo-ui-processDialog-actions-primary .oo-ui-actionWidget:active {
-  background-color: rgba(0, 0, 0, 0.1);
+       background-color: rgba(0, 0, 0, 0.1);
 }
 .oo-ui-processDialog-actions-safe .oo-ui-actionWidget.oo-ui-buttonElement-framed,
 .oo-ui-processDialog-actions-primary .oo-ui-actionWidget.oo-ui-buttonElement-framed {
-  margin: 0.75em;
+       margin: 0.75em;
 }
 .oo-ui-processDialog-actions-safe .oo-ui-actionWidget.oo-ui-buttonElement-framed .oo-ui-buttonElement-button,
 .oo-ui-processDialog-actions-primary .oo-ui-actionWidget.oo-ui-buttonElement-framed .oo-ui-buttonElement-button {
-  /* Adjust for border so text aligns with title */
-  margin: -1px;
+       /* Adjust for border so text aligns with title */
+       margin: -1px;
 }
 .oo-ui-processDialog-actions-safe .oo-ui-actionWidget.oo-ui-flaggedElement-primary:hover,
 .oo-ui-processDialog-actions-primary .oo-ui-actionWidget.oo-ui-flaggedElement-primary:hover {
-  background-color: rgba(8, 126, 204, 0.05);
+       background-color: rgba(8, 126, 204, 0.05);
 }
 .oo-ui-processDialog-actions-safe .oo-ui-actionWidget.oo-ui-flaggedElement-primary:active,
 .oo-ui-processDialog-actions-primary .oo-ui-actionWidget.oo-ui-flaggedElement-primary:active {
-  background-color: rgba(8, 126, 204, 0.1);
+       background-color: rgba(8, 126, 204, 0.1);
 }
 .oo-ui-processDialog-actions-safe .oo-ui-actionWidget.oo-ui-flaggedElement-primary .oo-ui-labelElement-label,
 .oo-ui-processDialog-actions-primary .oo-ui-actionWidget.oo-ui-flaggedElement-primary .oo-ui-labelElement-label {
-  font-weight: bold;
+       font-weight: bold;
 }
 .oo-ui-processDialog-actions-safe .oo-ui-actionWidget.oo-ui-flaggedElement-constructive:hover,
 .oo-ui-processDialog-actions-primary .oo-ui-actionWidget.oo-ui-flaggedElement-constructive:hover {
-  background-color: rgba(118, 171, 54, 0.05);
+       background-color: rgba(118, 171, 54, 0.05);
 }
 .oo-ui-processDialog-actions-safe .oo-ui-actionWidget.oo-ui-flaggedElement-constructive:active,
 .oo-ui-processDialog-actions-primary .oo-ui-actionWidget.oo-ui-flaggedElement-constructive:active {
-  background-color: rgba(118, 171, 54, 0.1);
+       background-color: rgba(118, 171, 54, 0.1);
 }
 .oo-ui-processDialog-actions-safe .oo-ui-actionWidget.oo-ui-flaggedElement-destructive:hover,
 .oo-ui-processDialog-actions-primary .oo-ui-actionWidget.oo-ui-flaggedElement-destructive:hover {
-  background-color: rgba(212, 83, 83, 0.05);
+       background-color: rgba(212, 83, 83, 0.05);
 }
 .oo-ui-processDialog-actions-safe .oo-ui-actionWidget.oo-ui-flaggedElement-destructive:active,
 .oo-ui-processDialog-actions-primary .oo-ui-actionWidget.oo-ui-flaggedElement-destructive:active {
-  background-color: rgba(212, 83, 83, 0.1);
+       background-color: rgba(212, 83, 83, 0.1);
 }
 .oo-ui-processDialog-actions-safe .oo-ui-actionWidget.oo-ui-iconElement .oo-ui-iconElement-icon {
-  left: 0.5em;
+       left: 0.5em;
 }
 .oo-ui-processDialog-actions-safe .oo-ui-actionWidget.oo-ui-iconElement .oo-ui-labelElement-label {
-  padding-left: 2.25em;
+       padding-left: 2.25em;
 }
 .oo-ui-processDialog-actions-primary .oo-ui-actionWidget.oo-ui-iconElement .oo-ui-iconElement-icon {
-  right: 0.5em;
+       right: 0.5em;
 }
 .oo-ui-processDialog-actions-primary .oo-ui-actionWidget.oo-ui-iconElement .oo-ui-labelElement-label {
-  padding-right: 2.25em;
+       padding-right: 2.25em;
 }
 .oo-ui-processDialog > .oo-ui-window-frame {
-  min-height: 5em;
+       min-height: 5em;
 }
 .oo-ui-processDialog-errors {
-  background-color: rgba(255, 255, 255, 0.9);
-  padding: 3em 3em 1.5em 3em;
-  text-align: center;
+       background-color: rgba(255, 255, 255, 0.9);
+       padding: 3em 3em 1.5em 3em;
+       text-align: center;
 }
 .oo-ui-processDialog-errors .oo-ui-buttonWidget {
-  margin: 2em 1em 2em 1em;
+       margin: 2em 1em 2em 1em;
 }
 .oo-ui-processDialog-errors-title {
-  font-size: 1.5em;
-  color: #000;
-  margin-bottom: 2em;
+       font-size: 1.5em;
+       color: #000000;
+       margin-bottom: 2em;
 }
 .oo-ui-processDialog-error {
-  text-align: left;
-  margin: 1em;
-  padding: 1em;
-  border: solid 1px #ff9e9e;
-  background-color: #fff7f7;
-  border-radius: 0.25em;
+       text-align: left;
+       margin: 1em;
+       padding: 1em;
+       border: solid 1px #ff9e9e;
+       background-color: #fff7f7;
+       border-radius: 0.25em;
 }
 .oo-ui-windowManager-modal > .oo-ui-dialog {
-  position: fixed;
-  width: 0;
-  height: 0;
-  overflow: hidden;
+       position: fixed;
+       width: 0;
+       height: 0;
+       overflow: hidden;
 }
 .oo-ui-windowManager-modal > .oo-ui-dialog.oo-ui-window-setup {
-  width: auto;
-  height: auto;
-  top: 0;
-  right: 0;
-  bottom: 0;
-  left: 0;
-  padding: 1em;
+       width: auto;
+       height: auto;
+       top: 0;
+       right: 0;
+       bottom: 0;
+       left: 0;
+       padding: 1em;
 }
 .oo-ui-windowManager-modal > .oo-ui-dialog.oo-ui-window-setup > .oo-ui-window-frame {
-  position: fixed;
-  right: 0;
-  left: 0;
-  margin: auto;
-  overflow: hidden;
-  max-width: 100%;
-  max-height: 100%;
+       position: absolute;
+       right: 0;
+       left: 0;
+       margin: auto;
+       overflow: hidden;
+       max-width: 100%;
+       max-height: 100%;
 }
 .oo-ui-windowManager-modal > .oo-ui-dialog.oo-ui-window-setup > .oo-ui-window-frame > iframe {
-  width: 100%;
-  height: 100%;
+       width: 100%;
+       height: 100%;
 }
 .oo-ui-windowManager-fullscreen > .oo-ui-dialog > .oo-ui-window-frame {
-  width: 100%;
-  height: 100%;
-  top: 0;
-  bottom: 0;
+       width: 100%;
+       height: 100%;
+       top: 0;
+       bottom: 0;
 }
 .oo-ui-windowManager-modal > .oo-ui-dialog {
-  background-color: rgba(255, 255, 255, 0.5);
-  opacity: 0;
-  -webkit-transition: opacity 250ms ease-in-out;
-  -moz-transition: opacity 250ms ease-in-out;
-  -ms-transition: opacity 250ms ease-in-out;
-  -o-transition: opacity 250ms ease-in-out;
-  transition: opacity 250ms ease-in-out;
+       background-color: rgba(255, 255, 255, 0.5);
+       opacity: 0;
+       -webkit-transition: opacity 250ms ease-in-out;
+          -moz-transition: opacity 250ms ease-in-out;
+           -ms-transition: opacity 250ms ease-in-out;
+            -o-transition: opacity 250ms ease-in-out;
+               transition: opacity 250ms ease-in-out;
 }
 .oo-ui-windowManager-modal > .oo-ui-dialog > .oo-ui-window-frame {
-  top: 1em;
-  bottom: 1em;
-  background-color: #fff;
-  -webkit-transform: scale(0.5);
-  -moz-transform: scale(0.5);
-  -ms-transform: scale(0.5);
-  -o-transform: scale(0.5);
-  transform: scale(0.5);
-  -webkit-transition: all 250ms ease-in-out;
-  -moz-transition: all 250ms ease-in-out;
-  -ms-transition: all 250ms ease-in-out;
-  -o-transition: all 250ms ease-in-out;
-  transition: all 250ms ease-in-out;
+       top: 1em;
+       bottom: 1em;
+       background-color: #ffffff;
+       -webkit-transform: scale(0.5);
+          -moz-transform: scale(0.5);
+           -ms-transform: scale(0.5);
+            -o-transform: scale(0.5);
+               transform: scale(0.5);
+       -webkit-transition: all 250ms ease-in-out;
+          -moz-transition: all 250ms ease-in-out;
+           -ms-transition: all 250ms ease-in-out;
+            -o-transition: all 250ms ease-in-out;
+               transition: all 250ms ease-in-out;
 }
 .oo-ui-windowManager-modal > .oo-ui-dialog.oo-ui-window-ready {
-  opacity: 1;
+       opacity: 1;
 }
 .oo-ui-windowManager-modal > .oo-ui-dialog.oo-ui-window-ready > .oo-ui-window-frame {
-  -webkit-transform: scale(1);
-  -moz-transform: scale(1);
-  -ms-transform: scale(1);
-  -o-transform: scale(1);
-  transform: scale(1);
+       -webkit-transform: scale(1);
+          -moz-transform: scale(1);
+           -ms-transform: scale(1);
+            -o-transform: scale(1);
+               transform: scale(1);
 }
 .oo-ui-windowManager-modal.oo-ui-windowManager-floating > .oo-ui-dialog > .oo-ui-window-frame {
-  border: solid 1px #ccc;
-  border-radius: 0.5em;
-  box-shadow: 0 0.2em 1em rgba(0, 0, 0, 0.3);
+       border: solid 1px #cccccc;
+       border-radius: 0.5em;
+       box-shadow: 0 0.2em 1em rgba(0, 0, 0, 0.3);
 }
diff --git a/resources/lib/oojs-ui/oojs-ui-apex.rtl.css b/resources/lib/oojs-ui/oojs-ui-apex.rtl.css
new file mode 100644 (file)
index 0000000..7dd7b61
--- /dev/null
@@ -0,0 +1,1929 @@
+/*!
+ * OOjs UI v0.1.0
+ * https://www.mediawiki.org/wiki/OOjs_UI
+ *
+ * Copyright 2011–2014 OOjs Team and other contributors.
+ * Released under the MIT license
+ * http://oojs.mit-license.org
+ *
+ * Date: 2014-09-11T19:39:50Z
+ */
+/*
+ * Blank theme mixins.
+ *
+ * Base styles invoke these mixins at the end of their definitions. Override these mixins to add
+ * additional rules to the base styles.
+ */
+/*
+ * Base styles.
+ *
+ * Themes should include this file after defining their variables and mixins.
+ */
+/* @noflip */
+.oo-ui-rtl {
+  direction: rtl;
+}
+/* @noflip */
+.oo-ui-ltr {
+  direction: ltr;
+}
+.oo-ui-buttonElement > .oo-ui-buttonElement-button {
+  cursor: pointer;
+  display: inline-block;
+  vertical-align: middle;
+  -webkit-touch-callout: none;
+  -webkit-user-select: none;
+  -moz-user-select: none;
+  -ms-user-select: none;
+  user-select: none;
+}
+.oo-ui-buttonElement > .oo-ui-buttonElement-button > .oo-ui-iconElement-icon {
+  display: none;
+}
+.oo-ui-buttonElement > .oo-ui-buttonElement-button > .oo-ui-indicatorElement-indicator {
+  display: none;
+}
+.oo-ui-buttonElement.oo-ui-widget-disabled > .oo-ui-buttonElement-button {
+  cursor: default;
+}
+.oo-ui-buttonElement.oo-ui-indicatorElement > .oo-ui-buttonElement-button > .oo-ui-indicatorElement-indicator,
+.oo-ui-buttonElement.oo-ui-iconElement > .oo-ui-buttonElement-button > .oo-ui-iconElement-icon {
+  display: inline-block;
+  vertical-align: middle;
+  background-position: center center;
+  background-repeat: no-repeat;
+}
+.oo-ui-buttonElement-frameless {
+  display: inline-block;
+  position: relative;
+}
+.oo-ui-buttonElement-frameless > .oo-ui-buttonElement-button > .oo-ui-labelElement-label {
+  display: inline-block;
+  vertical-align: middle;
+}
+.oo-ui-buttonElement-framed > .oo-ui-buttonElement-button {
+  display: inline-block;
+  vertical-align: top;
+  text-align: center;
+}
+.oo-ui-buttonElement-framed > .oo-ui-buttonElement-button > .oo-ui-labelElement-label {
+  display: inline-block;
+  vertical-align: middle;
+}
+.oo-ui-buttonElement-framed.oo-ui-widget-disabled > .oo-ui-buttonElement-button,
+.oo-ui-buttonElement-framed.oo-ui-widget-disabled.oo-ui-buttonElement-active > .oo-ui-buttonElement-button,
+.oo-ui-buttonElement-framed.oo-ui-widget-disabled.oo-ui-buttonElement-pressed > .oo-ui-buttonElement-button {
+  cursor: default;
+}
+.oo-ui-buttonElement > .oo-ui-buttonElement-button {
+  color: #333;
+}
+.oo-ui-buttonElement > .oo-ui-buttonElement-button > .oo-ui-iconElement-icon {
+  margin-right: 0;
+}
+.oo-ui-buttonElement > .oo-ui-buttonElement-button > .oo-ui-indicatorElement-indicator {
+  margin-left: -0.75em;
+}
+.oo-ui-buttonElement.oo-ui-indicatorElement > .oo-ui-buttonElement-button > .oo-ui-indicatorElement-indicator,
+.oo-ui-buttonElement.oo-ui-iconElement > .oo-ui-buttonElement-button > .oo-ui-iconElement-icon {
+  opacity: 0.8;
+  width: 1.9em;
+  height: 1.9em;
+}
+.oo-ui-buttonElement-frameless > .oo-ui-buttonElement-button > .oo-ui-iconElement-icon {
+  /* Don't animate opacities for now, causes wiggling in Chrome (bug 63020) */
+  /*.oo-ui-transition(opacity 200ms);*/
+}
+.oo-ui-buttonElement-frameless > .oo-ui-buttonElement-button:hover > .oo-ui-iconElement-icon,
+.oo-ui-buttonElement-frameless > .oo-ui-buttonElement-button:focus > .oo-ui-iconElement-icon {
+  opacity: 1;
+}
+.oo-ui-buttonElement-frameless > .oo-ui-buttonElement-button:hover > .oo-ui-labelElement-label,
+.oo-ui-buttonElement-frameless > .oo-ui-buttonElement-button:focus > .oo-ui-labelElement-label {
+  color: #000;
+}
+.oo-ui-buttonElement-frameless > .oo-ui-buttonElement-button > .oo-ui-labelElement-label {
+  color: #333;
+  margin-right: 0.25em;
+}
+.oo-ui-buttonElement-frameless.oo-ui-flaggedElement-primary > .oo-ui-buttonElement-button > .oo-ui-labelElement-label {
+  color: #087ecc;
+}
+.oo-ui-buttonElement-frameless.oo-ui-flaggedElement-constructive > .oo-ui-buttonElement-button > .oo-ui-labelElement-label {
+  color: #76ab36;
+}
+.oo-ui-buttonElement-frameless.oo-ui-flaggedElement-destructive > .oo-ui-buttonElement-button > .oo-ui-labelElement-label {
+  color: #d45353;
+}
+.oo-ui-buttonElement-frameless.oo-ui-widget-disabled > .oo-ui-buttonElement-button > .oo-ui-iconElement-icon {
+  opacity: 0.2;
+}
+.oo-ui-buttonElement-frameless.oo-ui-widget-disabled > .oo-ui-buttonElement-button > .oo-ui-labelElement-label {
+  color: #ccc;
+}
+.oo-ui-buttonElement-framed > .oo-ui-buttonElement-button {
+  margin: 0.1em 0;
+  padding: 0.2em 0.8em;
+  border-radius: 0.3em;
+  text-shadow: 0 1px 1px rgba(255, 255, 255, 0.5);
+  border: 1px #c9c9c9 solid;
+  -webkit-transition: border-color 100ms ease-in-out;
+  -moz-transition: border-color 100ms ease-in-out;
+  -ms-transition: border-color 100ms ease-in-out;
+  -o-transition: border-color 100ms ease-in-out;
+  transition: border-color 100ms ease-in-out;
+  background: #eeeeee;
+  filter: progid:DXImageTransform.Microsoft.gradient(GradientType=0, startColorstr='#ffffff', endColorstr='#dddddd');
+  background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #ffffff), color-stop(100%, #dddddd));
+  background-image: -webkit-linear-gradient(top, #ffffff 0%, #dddddd 100%);
+  background-image: -moz-linear-gradient(top, #ffffff 0%, #dddddd 100%);
+  background-image: -ms-linear-gradient(top, #ffffff 0%, #dddddd 100%);
+  background-image: -o-linear-gradient(top, #ffffff 0%, #dddddd 100%);
+  background-image: linear-gradient(top, #ffffff 0%, #dddddd 100%);
+}
+.oo-ui-buttonElement-framed > .oo-ui-buttonElement-button:hover,
+.oo-ui-buttonElement-framed > .oo-ui-buttonElement-button:focus {
+  border-color: #aaa;
+}
+.oo-ui-buttonElement-framed > .oo-ui-buttonElement-button > .oo-ui-labelElement-label {
+  line-height: 1.9em;
+}
+.oo-ui-buttonElement-framed.oo-ui-buttonElement-active > .oo-ui-buttonElement-button,
+.oo-ui-buttonElement-framed.oo-ui-buttonElement-pressed > .oo-ui-buttonElement-button {
+  box-shadow: inset 0 1px 4px 0 rgba(0, 0, 0, 0.07);
+  color: black;
+  border-color: #c9c9c9;
+  background: #eeeeee;
+  filter: progid:DXImageTransform.Microsoft.gradient(GradientType=0, startColorstr='#dddddd', endColorstr='#ffffff');
+  background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #dddddd), color-stop(100%, #ffffff));
+  background-image: -webkit-linear-gradient(top, #dddddd 0%, #ffffff 100%);
+  background-image: -moz-linear-gradient(top, #dddddd 0%, #ffffff 100%);
+  background-image: -ms-linear-gradient(top, #dddddd 0%, #ffffff 100%);
+  background-image: -o-linear-gradient(top, #dddddd 0%, #ffffff 100%);
+  background-image: linear-gradient(top, #dddddd 0%, #ffffff 100%);
+}
+.oo-ui-buttonElement-framed.oo-ui-iconElement > .oo-ui-buttonElement-button > .oo-ui-iconElement-icon {
+  margin-right: -0.5em;
+  margin-left: -0.5em;
+}
+.oo-ui-buttonElement-framed.oo-ui-iconElement.oo-ui-labelElement > .oo-ui-buttonElement-button > .oo-ui-iconElement-icon {
+  margin-right: -0.5em;
+  margin-left: 0.3em;
+}
+.oo-ui-buttonElement-framed.oo-ui-flaggedElement-primary > .oo-ui-buttonElement-button {
+  border: solid 1px #a6cee1;
+  background: #cde7f4;
+  filter: progid:DXImageTransform.Microsoft.gradient(GradientType=0, startColorstr='#eaf4fa', endColorstr='#b0d9ee');
+  background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #eaf4fa), color-stop(100%, #b0d9ee));
+  background-image: -webkit-linear-gradient(top, #eaf4fa 0%, #b0d9ee 100%);
+  background-image: -moz-linear-gradient(top, #eaf4fa 0%, #b0d9ee 100%);
+  background-image: -ms-linear-gradient(top, #eaf4fa 0%, #b0d9ee 100%);
+  background-image: -o-linear-gradient(top, #eaf4fa 0%, #b0d9ee 100%);
+  background-image: linear-gradient(top, #eaf4fa 0%, #b0d9ee 100%);
+}
+.oo-ui-buttonElement-framed.oo-ui-flaggedElement-primary > .oo-ui-buttonElement-button:hover,
+.oo-ui-buttonElement-framed.oo-ui-flaggedElement-primary > .oo-ui-buttonElement-button:focus {
+  border-color: #9dc2d4;
+}
+.oo-ui-buttonElement-framed.oo-ui-flaggedElement-primary.oo-ui-buttonElement-active > .oo-ui-buttonElement-button,
+.oo-ui-buttonElement-framed.oo-ui-flaggedElement-primary.oo-ui-buttonElement-pressed > .oo-ui-buttonElement-button {
+  border: solid 1px #a6cee1;
+  background: #cde7f4;
+  filter: progid:DXImageTransform.Microsoft.gradient(GradientType=0, startColorstr='#b0d9ee', endColorstr='#eaf4fa');
+  background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #b0d9ee), color-stop(100%, #eaf4fa));
+  background-image: -webkit-linear-gradient(top, #b0d9ee 0%, #eaf4fa 100%);
+  background-image: -moz-linear-gradient(top, #b0d9ee 0%, #eaf4fa 100%);
+  background-image: -ms-linear-gradient(top, #b0d9ee 0%, #eaf4fa 100%);
+  background-image: -o-linear-gradient(top, #b0d9ee 0%, #eaf4fa 100%);
+  background-image: linear-gradient(top, #b0d9ee 0%, #eaf4fa 100%);
+}
+.oo-ui-buttonElement-framed.oo-ui-flaggedElement-constructive > .oo-ui-buttonElement-button {
+  border: solid 1px #b8d892;
+  background: #daf0be;
+  filter: progid:DXImageTransform.Microsoft.gradient(GradientType=0, startColorstr='#f0fbe1', endColorstr='#c3e59a');
+  background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #f0fbe1), color-stop(100%, #c3e59a));
+  background-image: -webkit-linear-gradient(top, #f0fbe1 0%, #c3e59a 100%);
+  background-image: -moz-linear-gradient(top, #f0fbe1 0%, #c3e59a 100%);
+  background-image: -ms-linear-gradient(top, #f0fbe1 0%, #c3e59a 100%);
+  background-image: -o-linear-gradient(top, #f0fbe1 0%, #c3e59a 100%);
+  background-image: linear-gradient(top, #f0fbe1 0%, #c3e59a 100%);
+}
+.oo-ui-buttonElement-framed.oo-ui-flaggedElement-constructive > .oo-ui-buttonElement-button:hover,
+.oo-ui-buttonElement-framed.oo-ui-flaggedElement-constructive > .oo-ui-buttonElement-button:focus {
+  border-color: #adcb89;
+}
+.oo-ui-buttonElement-framed.oo-ui-flaggedElement-constructive.oo-ui-buttonElement-active > .oo-ui-buttonElement-button,
+.oo-ui-buttonElement-framed.oo-ui-flaggedElement-constructive.oo-ui-buttonElement-pressed > .oo-ui-buttonElement-button {
+  border: solid 1px #b8d892;
+  background: #daf0be;
+  filter: progid:DXImageTransform.Microsoft.gradient(GradientType=0, startColorstr='#c3e59a', endColorstr='#f0fbe1');
+  background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #c3e59a), color-stop(100%, #f0fbe1));
+  background-image: -webkit-linear-gradient(top, #c3e59a 0%, #f0fbe1 100%);
+  background-image: -moz-linear-gradient(top, #c3e59a 0%, #f0fbe1 100%);
+  background-image: -ms-linear-gradient(top, #c3e59a 0%, #f0fbe1 100%);
+  background-image: -o-linear-gradient(top, #c3e59a 0%, #f0fbe1 100%);
+  background-image: linear-gradient(top, #c3e59a 0%, #f0fbe1 100%);
+}
+.oo-ui-buttonElement-framed.oo-ui-flaggedElement-destructive > .oo-ui-buttonElement-button {
+  color: #d45353;
+}
+.oo-ui-buttonElement-framed.oo-ui-widget-disabled > .oo-ui-buttonElement-button,
+.oo-ui-buttonElement-framed.oo-ui-widget-disabled.oo-ui-buttonElement-active > .oo-ui-buttonElement-button,
+.oo-ui-buttonElement-framed.oo-ui-widget-disabled.oo-ui-buttonElement-pressed > .oo-ui-buttonElement-button {
+  opacity: 0.5;
+  box-shadow: none;
+  color: #333;
+  background: #eee;
+  border-color: #ccc;
+}
+.oo-ui-buttonElement-framed.oo-ui-widget-disabled > .oo-ui-buttonElement-button:hover,
+.oo-ui-buttonElement-framed.oo-ui-widget-disabled.oo-ui-buttonElement-active > .oo-ui-buttonElement-button:hover,
+.oo-ui-buttonElement-framed.oo-ui-widget-disabled.oo-ui-buttonElement-pressed > .oo-ui-buttonElement-button:hover,
+.oo-ui-buttonElement-framed.oo-ui-widget-disabled > .oo-ui-buttonElement-button:focus,
+.oo-ui-buttonElement-framed.oo-ui-widget-disabled.oo-ui-buttonElement-active > .oo-ui-buttonElement-button:focus,
+.oo-ui-buttonElement-framed.oo-ui-widget-disabled.oo-ui-buttonElement-pressed > .oo-ui-buttonElement-button:focus {
+  border-color: #ccc;
+  box-shadow: none;
+}
+.oo-ui-clippableElement-clippable {
+  -webkit-box-sizing: border-box;
+  -moz-box-sizing: border-box;
+  box-sizing: border-box;
+}
+.oo-ui-bookletLayout-stackLayout.oo-ui-stackLayout-continuous .oo-ui-panelLayout-scrollable {
+  overflow-y: hidden;
+}
+.oo-ui-bookletLayout-stackLayout .oo-ui-panelLayout {
+  width: 100%;
+  -webkit-box-sizing: border-box;
+  -moz-box-sizing: border-box;
+  box-sizing: border-box;
+}
+.oo-ui-bookletLayout-stackLayout .oo-ui-panelLayout-scrollable {
+  overflow-y: auto;
+}
+.oo-ui-bookletLayout-stackLayout .oo-ui-panelLayout-padded {
+  padding: 2em;
+}
+.oo-ui-bookletLayout-outlinePanel-editable .oo-ui-outlineWidget {
+  position: absolute;
+  top: 0;
+  right: 0;
+  left: 0;
+  bottom: 3em;
+  overflow-y: auto;
+}
+.oo-ui-bookletLayout-outlinePanel .oo-ui-outlineControlsWidget {
+  position: absolute;
+  bottom: 0;
+  right: 0;
+  left: 0;
+}
+.oo-ui-bookletLayout-stackLayout .oo-ui-panelLayout {
+  padding: 1.5em;
+}
+.oo-ui-bookletLayout-outlinePanel {
+  border-left: solid 1px #ddd;
+}
+.oo-ui-bookletLayout-outlinePanel .oo-ui-outlineControlsWidget {
+  box-shadow: 0 0 0.25em rgba(0, 0, 0, 0.25);
+}
+.oo-ui-fieldLayout {
+  margin-bottom: 1em;
+}
+.oo-ui-fieldLayout:before,
+.oo-ui-fieldLayout:after {
+  content: " ";
+  display: table;
+}
+.oo-ui-fieldLayout:after {
+  clear: both;
+}
+.oo-ui-fieldLayout.oo-ui-fieldLayout-align-left > .oo-ui-labelElement-label,
+.oo-ui-fieldLayout.oo-ui-fieldLayout-align-right > .oo-ui-labelElement-label {
+  display: block;
+  float: right;
+}
+.oo-ui-fieldLayout.oo-ui-fieldLayout-align-left > .oo-ui-fieldLayout-field,
+.oo-ui-fieldLayout.oo-ui-fieldLayout-align-right > .oo-ui-fieldLayout-field {
+  display: block;
+  float: right;
+}
+.oo-ui-fieldLayout.oo-ui-fieldLayout-align-right > .oo-ui-labelElement-label {
+  text-align: left;
+}
+.oo-ui-fieldLayout.oo-ui-fieldLayout-align-inline > .oo-ui-labelElement-label {
+  display: inline-block;
+  vertical-align: middle;
+}
+.oo-ui-fieldLayout.oo-ui-fieldLayout-align-inline > .oo-ui-fieldLayout-field {
+  display: inline-block;
+  vertical-align: middle;
+}
+.oo-ui-fieldLayout.oo-ui-fieldLayout-align-top > .oo-ui-labelElement-label {
+  display: inline-block;
+}
+.oo-ui-fieldLayout > .oo-ui-popupButtonWidget > .oo-ui-popupWidget > .oo-ui-popupWidget-popup {
+  z-index: 1;
+}
+.oo-ui-fieldLayout:last-child {
+  margin-bottom: 0;
+}
+.oo-ui-fieldLayout.oo-ui-fieldLayout-align-left > .oo-ui-labelElement-label,
+.oo-ui-fieldLayout.oo-ui-fieldLayout-align-right > .oo-ui-labelElement-label {
+  padding-top: 0.5em;
+  margin-left: 5%;
+  width: 35%;
+}
+.oo-ui-fieldLayout.oo-ui-fieldLayout-align-left > .oo-ui-fieldLayout-field,
+.oo-ui-fieldLayout.oo-ui-fieldLayout-align-right > .oo-ui-fieldLayout-field {
+  width: 60%;
+}
+.oo-ui-fieldLayout.oo-ui-fieldLayout-align-inline > .oo-ui-labelElement-label {
+  padding: 0.75em 0.5em 0.5em 0.5em;
+}
+.oo-ui-fieldLayout.oo-ui-fieldLayout-align-inline > .oo-ui-fieldLayout-field {
+  padding: 0.5em 0;
+}
+.oo-ui-fieldLayout.oo-ui-fieldLayout-align-top > .oo-ui-labelElement-label {
+  padding: 0.5em 0;
+}
+.oo-ui-fieldLayout > .oo-ui-popupButtonWidget > .oo-ui-buttonElement-button > .oo-ui-iconElement-icon {
+  margin-top: 0.25em;
+}
+.oo-ui-fieldLayout-disabled .oo-ui-labelElement-label {
+  color: #ccc;
+}
+.oo-ui-fieldsetLayout {
+  position: relative;
+  margin: 0;
+  padding: 0;
+  border: none;
+}
+.oo-ui-fieldsetLayout.oo-ui-iconElement > .oo-ui-iconElement-icon {
+  display: block;
+  position: absolute;
+  background-position: center center;
+  background-repeat: no-repeat;
+}
+.oo-ui-fieldsetLayout.oo-ui-labelElement > .oo-ui-labelElement-label {
+  display: inline-block;
+}
+.oo-ui-fieldsetLayout + .oo-ui-fieldsetLayout {
+  margin-top: 2em;
+}
+.oo-ui-fieldsetLayout > .oo-ui-labelElement-label {
+  font-size: 1.5em;
+  margin-bottom: 0.5em;
+  padding: 0.25em 0;
+}
+.oo-ui-fieldsetLayout.oo-ui-iconElement > .oo-ui-labelElement-label {
+  padding-right: 1.75em;
+  line-height: 1.33em;
+}
+.oo-ui-fieldsetLayout.oo-ui-iconElement > .oo-ui-iconElement-icon {
+  right: 0;
+  top: 0.25em;
+  width: 2em;
+  height: 2em;
+}
+.oo-ui-gridLayout {
+  position: absolute;
+  top: 0;
+  right: 0;
+  left: 0;
+  bottom: 0;
+}
+.oo-ui-panelLayout {
+  position: relative;
+}
+.oo-ui-panelLayout-scrollable {
+  overflow-y: auto;
+}
+.oo-ui-panelLayout-expanded {
+  position: absolute;
+  top: 0;
+  right: 0;
+  left: 0;
+  bottom: 0;
+}
+.oo-ui-panelLayout-padded {
+  padding: 1.25em;
+}
+.oo-ui-stackLayout > .oo-ui-panelLayout {
+  display: none;
+}
+.oo-ui-stackLayout-continuous > .oo-ui-panelLayout {
+  display: block;
+  position: relative;
+}
+.oo-ui-popupTool .oo-ui-popupWidget-popup,
+.oo-ui-popupTool .oo-ui-popupWidget-anchor {
+  z-index: 4;
+}
+.oo-ui-popupTool .oo-ui-popupWidget {
+  margin-right: 1.25em;
+  font-size: 0.8em;
+}
+.oo-ui-toolGroup {
+  display: inline-block;
+  vertical-align: middle;
+  margin: 0.3em;
+  border-radius: 0.25em;
+  border: solid 1px transparent;
+  -webkit-transition: border-color 300ms ease-in-out;
+  -moz-transition: border-color 300ms ease-in-out;
+  -ms-transition: border-color 300ms ease-in-out;
+  -o-transition: border-color 300ms ease-in-out;
+  transition: border-color 300ms ease-in-out;
+}
+.oo-ui-toolGroup-empty {
+  display: none;
+}
+.oo-ui-toolGroup .oo-ui-tool-link .oo-ui-iconElement-icon {
+  background-position: center center;
+  background-repeat: no-repeat;
+}
+.oo-ui-toolGroup.oo-ui-widget-enabled:hover {
+  border-color: rgba(0, 0, 0, 0.1);
+}
+.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-tool {
+  display: inline-block;
+  position: relative;
+  vertical-align: top;
+}
+.oo-ui-barToolGroup .oo-ui-tool-link {
+  display: block;
+}
+.oo-ui-barToolGroup .oo-ui-tool-link .oo-ui-iconElement-icon {
+  display: block;
+}
+.oo-ui-barToolGroup .oo-ui-tool-link .oo-ui-tool-title {
+  display: none;
+}
+.oo-ui-barToolGroup .oo-ui-tool.oo-ui-widget-disabled .oo-ui-tool-link {
+  cursor: default;
+}
+.oo-ui-barToolGroup .oo-ui-tool-title,
+.oo-ui-barToolGroup .oo-ui-tool-accel {
+  display: none;
+}
+.oo-ui-barToolGroup.oo-ui-widget-enabled .oo-ui-tool-link {
+  cursor: pointer;
+}
+.oo-ui-barToolGroup .oo-ui-tool {
+  margin: -1px -1px -1px 0;
+  border: solid 1px transparent;
+}
+.oo-ui-barToolGroup .oo-ui-tool:first-child {
+  border-top-right-radius: 0.25em;
+  border-bottom-right-radius: 0.25em;
+}
+.oo-ui-barToolGroup .oo-ui-tool:last-child {
+  margin-left: -1px;
+  border-top-left-radius: 0.25em;
+  border-bottom-left-radius: 0.25em;
+}
+.oo-ui-barToolGroup .oo-ui-tool-link {
+  height: 1.5em;
+  padding: 0.25em;
+}
+.oo-ui-barToolGroup .oo-ui-tool-link .oo-ui-iconElement-icon {
+  height: 1.5em;
+  width: 1.5em;
+  opacity: 0.8;
+}
+.oo-ui-barToolGroup.oo-ui-widget-enabled .oo-ui-tool.oo-ui-widget-enabled:hover {
+  border-color: rgba(0, 0, 0, 0.2);
+}
+.oo-ui-barToolGroup.oo-ui-widget-enabled .oo-ui-tool-active.oo-ui-widget-enabled {
+  border-color: rgba(0, 0, 0, 0.2);
+  box-shadow: inset 0 0.07em 0.07em 0 rgba(0, 0, 0, 0.07);
+  background: #f8fbfd;
+  filter: progid:DXImageTransform.Microsoft.gradient(GradientType=0, startColorstr='#f1f7fb', endColorstr='#ffffff');
+  background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #f1f7fb), color-stop(100%, #ffffff));
+  background-image: -webkit-linear-gradient(top, #f1f7fb 0%, #ffffff 100%);
+  background-image: -moz-linear-gradient(top, #f1f7fb 0%, #ffffff 100%);
+  background-image: -ms-linear-gradient(top, #f1f7fb 0%, #ffffff 100%);
+  background-image: -o-linear-gradient(top, #f1f7fb 0%, #ffffff 100%);
+  background-image: linear-gradient(top, #f1f7fb 0%, #ffffff 100%);
+}
+.oo-ui-barToolGroup.oo-ui-widget-enabled .oo-ui-tool-active.oo-ui-widget-enabled + .oo-ui-tool-active.oo-ui-widget-enabled {
+  border-right-color: rgba(0, 0, 0, 0.1);
+}
+.oo-ui-barToolGroup.oo-ui-widget-enabled .oo-ui-tool.oo-ui-widget-disabled .oo-ui-tool-link .oo-ui-iconElement-icon {
+  opacity: 0.2;
+}
+.oo-ui-barToolGroup.oo-ui-widget-enabled .oo-ui-tool.oo-ui-widget-enabled .oo-ui-tool-link .oo-ui-iconElement-icon {
+  opacity: 0.8;
+}
+.oo-ui-barToolGroup.oo-ui-widget-enabled .oo-ui-tool.oo-ui-widget-enabled:hover .oo-ui-tool-link .oo-ui-iconElement-icon {
+  opacity: 1;
+}
+.oo-ui-barToolGroup.oo-ui-widget-disabled .oo-ui-tool-link .oo-ui-iconElement-icon {
+  opacity: 0.2;
+}
+.oo-ui-popupToolGroup {
+  position: relative;
+  height: 2em;
+  min-width: 2.5em;
+}
+.oo-ui-popupToolGroup-handle {
+  display: block;
+  cursor: pointer;
+}
+.oo-ui-popupToolGroup-handle .oo-ui-indicatorElement-indicator,
+.oo-ui-popupToolGroup-handle .oo-ui-iconElement-icon {
+  position: absolute;
+  background-position: center center;
+  background-repeat: no-repeat;
+}
+.oo-ui-popupToolGroup.oo-ui-widget-disabled .oo-ui-popupToolGroup-handle {
+  cursor: default;
+}
+.oo-ui-popupToolGroup .oo-ui-toolGroup-tools {
+  display: none;
+  position: absolute;
+  z-index: 4;
+}
+.oo-ui-popupToolGroup .oo-ui-toolGroup-tools .oo-ui-iconElement-icon {
+  background-repeat: no-repeat;
+  background-position: center center;
+}
+.oo-ui-popupToolGroup-active.oo-ui-widget-enabled > .oo-ui-toolGroup-tools {
+  display: block;
+}
+.oo-ui-popupToolGroup-left > .oo-ui-toolGroup-tools {
+  right: 0;
+}
+.oo-ui-popupToolGroup-right > .oo-ui-toolGroup-tools {
+  left: 0;
+}
+.oo-ui-popupToolGroup .oo-ui-tool-link .oo-ui-iconElement-icon {
+  display: inline-block;
+  vertical-align: middle;
+}
+.oo-ui-popupToolGroup .oo-ui-tool-link .oo-ui-tool-title {
+  display: inline-block;
+  vertical-align: middle;
+}
+.oo-ui-popupToolGroup .oo-ui-tool-accel {
+  display: none;
+}
+.oo-ui-popupToolGroup.oo-ui-indicatorElement.oo-ui-iconElement {
+  min-width: 3.5em;
+}
+.oo-ui-popupToolGroup-handle .oo-ui-indicatorElement-indicator,
+.oo-ui-popupToolGroup-handle .oo-ui-iconElement-icon {
+  top: 0;
+  width: 2em;
+  height: 2em;
+  opacity: 0.8;
+}
+.oo-ui-popupToolGroup-handle .oo-ui-indicatorElement-indicator {
+  left: 0;
+}
+.oo-ui-popupToolGroup-handle .oo-ui-iconElement-icon {
+  right: 0.25em;
+}
+.oo-ui-popupToolGroup-handle .oo-ui-labelElement-label {
+  line-height: 2.6em;
+  font-size: 0.8em;
+  margin: 0 1em;
+}
+.oo-ui-popupToolGroup-header {
+  line-height: 2.6em;
+  font-size: 0.8em;
+  margin: 0 0.6em;
+  font-weight: bold;
+}
+.oo-ui-popupToolGroup-active.oo-ui-widget-enabled {
+  border-bottom-right-radius: 0;
+  border-bottom-left-radius: 0;
+  box-shadow: inset 0 0.07em 0.07em 0 rgba(0, 0, 0, 0.07);
+  background: #f8fbfd;
+  filter: progid:DXImageTransform.Microsoft.gradient(GradientType=0, startColorstr='#f1f7fb', endColorstr='#ffffff');
+  background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #f1f7fb), color-stop(100%, #ffffff));
+  background-image: -webkit-linear-gradient(top, #f1f7fb 0%, #ffffff 100%);
+  background-image: -moz-linear-gradient(top, #f1f7fb 0%, #ffffff 100%);
+  background-image: -ms-linear-gradient(top, #f1f7fb 0%, #ffffff 100%);
+  background-image: -o-linear-gradient(top, #f1f7fb 0%, #ffffff 100%);
+  background-image: linear-gradient(top, #f1f7fb 0%, #ffffff 100%);
+}
+.oo-ui-popupToolGroup.oo-ui-iconElement .oo-ui-popupToolGroup-handle .oo-ui-labelElement-label {
+  margin-right: 3em;
+}
+.oo-ui-popupToolGroup.oo-ui-indicatorElement .oo-ui-popupToolGroup-handle .oo-ui-labelElement-label {
+  margin-left: 2.25em;
+}
+.oo-ui-popupToolGroup .oo-ui-toolGroup-tools {
+  top: 2em;
+  margin: 0 -1px;
+  border: solid 1px #ccc;
+  background-color: white;
+  box-shadow: 0 0.25em 1em rgba(0, 0, 0, 0.25);
+}
+.oo-ui-popupToolGroup .oo-ui-tool-link .oo-ui-iconElement-icon {
+  height: 2em;
+  width: 2em;
+  margin-left: 0.25em;
+}
+.oo-ui-popupToolGroup .oo-ui-tool-link .oo-ui-tool-title {
+  line-height: 2em;
+  font-size: 0.8em;
+}
+.oo-ui-listToolGroup .oo-ui-tool {
+  display: inline-block;
+  width: 100%;
+  -webkit-box-sizing: border-box;
+  -moz-box-sizing: border-box;
+  box-sizing: border-box;
+}
+.oo-ui-listToolGroup .oo-ui-tool-link {
+  display: block;
+  cursor: pointer;
+  white-space: nowrap;
+}
+.oo-ui-listToolGroup .oo-ui-tool.oo-ui-widget-disabled .oo-ui-tool-link {
+  cursor: default;
+}
+.oo-ui-listToolGroup .oo-ui-toolGroup-tools {
+  padding: 0.25em;
+}
+.oo-ui-listToolGroup.oo-ui-popupToolGroup-active {
+  border-color: rgba(0, 0, 0, 0.2);
+}
+.oo-ui-listToolGroup .oo-ui-tool {
+  border: solid 1px transparent;
+  margin: -1px 0;
+}
+.oo-ui-listToolGroup .oo-ui-tool-link {
+  padding-left: 0.5em;
+}
+.oo-ui-listToolGroup .oo-ui-tool-active.oo-ui-widget-enabled {
+  border-color: rgba(0, 0, 0, 0.1);
+  box-shadow: inset 0 0.07em 0.07em 0 rgba(0, 0, 0, 0.07);
+  background: #f8fbfd;
+  filter: progid:DXImageTransform.Microsoft.gradient(GradientType=0, startColorstr='#f1f7fb', endColorstr='#ffffff');
+  background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #f1f7fb), color-stop(100%, #ffffff));
+  background-image: -webkit-linear-gradient(top, #f1f7fb 0%, #ffffff 100%);
+  background-image: -moz-linear-gradient(top, #f1f7fb 0%, #ffffff 100%);
+  background-image: -ms-linear-gradient(top, #f1f7fb 0%, #ffffff 100%);
+  background-image: -o-linear-gradient(top, #f1f7fb 0%, #ffffff 100%);
+  background-image: linear-gradient(top, #f1f7fb 0%, #ffffff 100%);
+}
+.oo-ui-listToolGroup .oo-ui-tool-active.oo-ui-widget-enabled + .oo-ui-tool-active.oo-ui-widget-enabled {
+  border-top-color: rgba(0, 0, 0, 0.1);
+}
+.oo-ui-listToolGroup .oo-ui-tool-active.oo-ui-widget-enabled:hover {
+  border-color: rgba(0, 0, 0, 0.2);
+}
+.oo-ui-listToolGroup .oo-ui-tool.oo-ui-widget-enabled:hover {
+  border-color: rgba(0, 0, 0, 0.2);
+}
+.oo-ui-listToolGroup .oo-ui-tool.oo-ui-widget-enabled .oo-ui-tool-link .oo-ui-iconElement-icon {
+  opacity: 0.8;
+}
+.oo-ui-listToolGroup .oo-ui-tool.oo-ui-widget-enabled:hover .oo-ui-tool-link .oo-ui-iconElement-icon {
+  opacity: 1;
+}
+.oo-ui-listToolGroup .oo-ui-tool.oo-ui-widget-disabled .oo-ui-tool-link .oo-ui-tool-title {
+  color: #ccc;
+}
+.oo-ui-listToolGroup .oo-ui-tool.oo-ui-widget-disabled .oo-ui-tool-link .oo-ui-iconElement-icon {
+  opacity: 0.2;
+}
+.oo-ui-listToolGroup.oo-ui-widget-disabled {
+  color: #ccc;
+}
+.oo-ui-listToolGroup.oo-ui-widget-disabled .oo-ui-indicatorElement-indicator,
+.oo-ui-listToolGroup.oo-ui-widget-disabled .oo-ui-iconElement-icon {
+  opacity: 0.2;
+}
+.oo-ui-menuToolGroup {
+  border-color: rgba(0, 0, 0, 0.1);
+}
+.oo-ui-menuToolGroup .oo-ui-tool {
+  display: block;
+}
+.oo-ui-menuToolGroup .oo-ui-tool-link {
+  display: block;
+  cursor: pointer;
+  white-space: nowrap;
+}
+.oo-ui-menuToolGroup .oo-ui-tool-link .oo-ui-iconElement-icon {
+  background-image: none;
+}
+.oo-ui-menuToolGroup .oo-ui-tool-active .oo-ui-tool-link .oo-ui-iconElement-icon {
+  background-image: /* @embed */ url(images/icons/check.svg);
+}
+.oo-ui-menuToolGroup .oo-ui-tool.oo-ui-widget-disabled .oo-ui-tool-link {
+  cursor: default;
+}
+.oo-ui-menuToolGroup .oo-ui-popupToolGroup-handle {
+  min-width: 8em;
+}
+.oo-ui-menuToolGroup .oo-ui-toolGroup-tools {
+  padding: 0.25em 0 0.25em 0;
+}
+.oo-ui-menuToolGroup.oo-ui-widget-enabled:hover {
+  border-color: rgba(0, 0, 0, 0.2);
+}
+.oo-ui-menuToolGroup.oo-ui-popupToolGroup-active {
+  border-color: rgba(0, 0, 0, 0.25);
+}
+.oo-ui-menuToolGroup .oo-ui-tool-link {
+  padding: 0 0.25em 0 1em;
+}
+.oo-ui-menuToolGroup .oo-ui-tool.oo-ui-widget-enabled:hover {
+  background-color: #e1f3ff;
+}
+.oo-ui-menuToolGroup .oo-ui-tool.oo-ui-widget-disabled .oo-ui-tool-link .oo-ui-tool-title {
+  color: #ccc;
+}
+.oo-ui-menuToolGroup .oo-ui-tool.oo-ui-widget-disabled .oo-ui-tool-link .oo-ui-iconElement-icon {
+  opacity: 0.2;
+}
+.oo-ui-menuToolGroup.oo-ui-widget-disabled {
+  color: #ccc;
+  border-color: rgba(0, 0, 0, 0.05);
+}
+.oo-ui-menuToolGroup.oo-ui-widget-disabled .oo-ui-indicatorElement-indicator,
+.oo-ui-menuToolGroup.oo-ui-widget-disabled .oo-ui-iconElement-icon {
+  opacity: 0.2;
+}
+.oo-ui-toolbar {
+  clear: both;
+}
+.oo-ui-toolbar-bar {
+  line-height: 1em;
+}
+.oo-ui-toolbar-actions {
+  float: left;
+}
+.oo-ui-toolbar-tools {
+  display: inline;
+}
+.oo-ui-toolbar-tools,
+.oo-ui-toolbar-actions,
+.oo-ui-toolbar-shadow {
+  -webkit-touch-callout: none;
+  -webkit-user-select: none;
+  -moz-user-select: none;
+  -ms-user-select: none;
+  user-select: none;
+}
+.oo-ui-toolbar-actions .oo-ui-popupWidget {
+  -webkit-touch-callout: default;
+  -webkit-user-select: all;
+  -moz-user-select: all;
+  -ms-user-select: all;
+  user-select: all;
+}
+.oo-ui-toolbar-shadow {
+  background-position: right top;
+  background-repeat: repeat-x;
+  position: absolute;
+  width: 100%;
+  pointer-events: none;
+}
+.oo-ui-toolbar-bar {
+  border-bottom: solid 1px #ccc;
+  background: #f8fbfd;
+  filter: progid:DXImageTransform.Microsoft.gradient(GradientType=0, startColorstr='#ffffff', endColorstr='#f1f7fb');
+  background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #ffffff), color-stop(100%, #f1f7fb));
+  background-image: -webkit-linear-gradient(top, #ffffff 0%, #f1f7fb 100%);
+  background-image: -moz-linear-gradient(top, #ffffff 0%, #f1f7fb 100%);
+  background-image: -ms-linear-gradient(top, #ffffff 0%, #f1f7fb 100%);
+  background-image: -o-linear-gradient(top, #ffffff 0%, #f1f7fb 100%);
+  background-image: linear-gradient(top, #ffffff 0%, #f1f7fb 100%);
+}
+.oo-ui-toolbar-bar .oo-ui-toolbar-bar {
+  border: none;
+  background: none;
+}
+.oo-ui-toolbar-shadow {
+  background-image: /* @embed */ url(images/toolbar-shadow.png);
+  bottom: -9px;
+  height: 9px;
+  opacity: 0.125;
+  -webkit-transition: opacity 500ms ease-in-out;
+  -moz-transition: opacity 500ms ease-in-out;
+  -ms-transition: opacity 500ms ease-in-out;
+  -o-transition: opacity 500ms ease-in-out;
+  transition: opacity 500ms ease-in-out;
+}
+.oo-ui-optionWidget {
+  position: relative;
+  display: block;
+  cursor: pointer;
+  padding: 0.5em 3em 0.5em 2em;
+  border: none;
+}
+.oo-ui-optionWidget.oo-ui-widget-disabled {
+  cursor: default;
+}
+.oo-ui-optionWidget .oo-ui-labelElement-label {
+  display: block;
+  white-space: nowrap;
+  text-overflow: ellipsis;
+  overflow: hidden;
+}
+.oo-ui-optionWidget-highlighted {
+  background-color: #e1f3ff;
+}
+.oo-ui-optionWidget .oo-ui-labelElement-label {
+  line-height: 1.5em;
+}
+.oo-ui-selectWidget-depressed .oo-ui-optionWidget-selected {
+  background-color: #a7dcff;
+}
+.oo-ui-selectWidget-pressed .oo-ui-optionWidget-pressed {
+  background-color: #a7dcff;
+}
+.oo-ui-optionWidget.oo-ui-widget-disabled {
+  color: #ccc;
+}
+.oo-ui-decoratedOptionWidget .oo-ui-iconElement-icon,
+.oo-ui-decoratedOptionWidget .oo-ui-indicatorElement-indicator {
+  position: absolute;
+  background-repeat: no-repeat;
+  background-position: center center;
+}
+.oo-ui-decoratedOptionWidget .oo-ui-iconElement-icon,
+.oo-ui-decoratedOptionWidget .oo-ui-indicatorElement-indicator {
+  top: 50%;
+  width: 2em;
+  height: 2em;
+  margin-top: -1em;
+}
+.oo-ui-decoratedOptionWidget .oo-ui-iconElement-icon {
+  right: 0.5em;
+}
+.oo-ui-decoratedOptionWidget .oo-ui-indicatorElement-indicator {
+  left: 0.5em;
+}
+.oo-ui-buttonSelectWidget {
+  display: inline-block;
+  white-space: nowrap;
+  border-radius: 0.3em;
+}
+.oo-ui-buttonSelectWidget .oo-ui-buttonOptionWidget .oo-ui-buttonElement-button {
+  border-radius: 0;
+  margin-right: -1px;
+}
+.oo-ui-buttonSelectWidget .oo-ui-buttonOptionWidget:first-child .oo-ui-buttonElement-button {
+  border-bottom-right-radius: 0.3em;
+  border-top-right-radius: 0.3em;
+  margin-right: 0;
+}
+.oo-ui-buttonSelectWidget .oo-ui-buttonOptionWidget:last-child .oo-ui-buttonElement-button {
+  border-bottom-left-radius: 0.3em;
+  border-top-left-radius: 0.3em;
+}
+.oo-ui-buttonOptionWidget {
+  display: inline-block;
+  padding: 0;
+  background-color: transparent;
+}
+.oo-ui-buttonOptionWidget .oo-ui-buttonElement-button {
+  position: relative;
+}
+.oo-ui-buttonOptionWidget.oo-ui-iconElement .oo-ui-iconElement-icon,
+.oo-ui-buttonOptionWidget.oo-ui-indicatorElement .oo-ui-indicatorElement-indicator {
+  position: static;
+  display: inline-block;
+  vertical-align: middle;
+}
+.oo-ui-buttonOptionWidget .oo-ui-buttonElement-button {
+  height: 1.9em;
+}
+.oo-ui-buttonOptionWidget.oo-ui-iconElement .oo-ui-iconElement-icon,
+.oo-ui-buttonOptionWidget.oo-ui-indicatorElement .oo-ui-indicatorElement-indicator {
+  height: 1.9em;
+  margin-top: 0;
+}
+.oo-ui-buttonOptionWidget.oo-ui-optionWidget-selected,
+.oo-ui-buttonOptionWidget.oo-ui-optionWidget-pressed,
+.oo-ui-buttonOptionWidget.oo-ui-optionWidget-highlighted {
+  background-color: transparent;
+}
+.oo-ui-labelWidget {
+  display: inline-block;
+  padding: 0.5em 0;
+}
+.oo-ui-iconWidget {
+  display: inline-block;
+  vertical-align: middle;
+  background-position: center center;
+  background-repeat: no-repeat;
+  line-height: 2.5em;
+  height: 1.9em;
+  width: 1.9em;
+  opacity: 0.8;
+}
+.oo-ui-iconWidget.oo-ui-widget-disabled {
+  opacity: 0.2;
+}
+.oo-ui-indicatorWidget {
+  display: inline-block;
+  vertical-align: middle;
+  background-position: center center;
+  background-repeat: no-repeat;
+  line-height: 2.5em;
+  height: 1.9em;
+  width: 1.9em;
+  opacity: 0.8;
+}
+.oo-ui-indicatorWidget.oo-ui-widget-disabled {
+  opacity: 0.2;
+}
+.oo-ui-buttonWidget {
+  display: inline-block;
+  vertical-align: middle;
+}
+.oo-ui-buttonGroupWidget {
+  display: inline-block;
+  white-space: nowrap;
+  border-radius: 0.3em;
+}
+.oo-ui-buttonGroupWidget .oo-ui-buttonElement-framed .oo-ui-buttonElement-button {
+  border-radius: 0;
+  margin-bottom: -1px;
+  margin-right: -1px;
+}
+.oo-ui-buttonGroupWidget .oo-ui-buttonElement-framed:first-child .oo-ui-buttonElement-button {
+  border-bottom-right-radius: 0.3em;
+  border-top-right-radius: 0.3em;
+  margin-right: 0;
+}
+.oo-ui-buttonGroupWidget .oo-ui-buttonElement-framed:last-child .oo-ui-buttonElement-button {
+  border-bottom-left-radius: 0.3em;
+  border-top-left-radius: 0.3em;
+}
+.oo-ui-toggleSwitchWidget {
+  position: relative;
+  display: inline-block;
+  vertical-align: middle;
+  overflow: hidden;
+  cursor: pointer;
+  -webkit-box-sizing: border-box;
+  -moz-box-sizing: border-box;
+  box-sizing: border-box;
+  -webkit-transform: translateZ(0px);
+  -moz-transform: translateZ(0px);
+  -ms-transform: translateZ(0px);
+  -o-transform: translateZ(0px);
+  transform: translateZ(0px);
+  height: 2em;
+  width: 4em;
+  border-radius: 1em;
+  box-shadow: 0 0 0 white, inset 0 0.1em 0.2em #ddd;
+  border: solid 1px #ccc;
+  background: #eeeeee;
+  filter: progid:DXImageTransform.Microsoft.gradient(GradientType=0, startColorstr='#dddddd', endColorstr='#ffffff');
+  background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #dddddd), color-stop(100%, #ffffff));
+  background-image: -webkit-linear-gradient(top, #dddddd 0%, #ffffff 100%);
+  background-image: -moz-linear-gradient(top, #dddddd 0%, #ffffff 100%);
+  background-image: -ms-linear-gradient(top, #dddddd 0%, #ffffff 100%);
+  background-image: -o-linear-gradient(top, #dddddd 0%, #ffffff 100%);
+  background-image: linear-gradient(top, #dddddd 0%, #ffffff 100%);
+}
+.oo-ui-toggleSwitchWidget.oo-ui-widget-disabled {
+  cursor: default;
+}
+.oo-ui-toggleSwitchWidget-grip {
+  position: absolute;
+  display: block;
+  -webkit-box-sizing: border-box;
+  -moz-box-sizing: border-box;
+  box-sizing: border-box;
+}
+.oo-ui-toggleSwitchWidget .oo-ui-toggleSwitchWidget-glow {
+  position: absolute;
+  top: 0;
+  bottom: 0;
+  left: 0;
+  right: 0;
+  -webkit-touch-callout: none;
+  -webkit-user-select: none;
+  -moz-user-select: none;
+  -ms-user-select: none;
+  user-select: none;
+}
+.oo-ui-toggleWidget-off .oo-ui-toggleSwitchWidget-glow {
+  display: none;
+}
+.oo-ui-toggleSwitchWidget.oo-ui-widget-disabled {
+  opacity: 0.5;
+}
+.oo-ui-toggleSwitchWidget-grip {
+  top: 0.25em;
+  right: 0.25em;
+  width: 1.5em;
+  height: 1.5em;
+  margin-top: -1px;
+  border-radius: 1em;
+  box-shadow: 0 0.1em 0.25em rgba(0, 0, 0, 0.1);
+  border: 1px #c9c9c9 solid;
+  -webkit-transition: right 200ms ease-in-out, margin-right 200ms ease-in-out;
+  -moz-transition: right 200ms ease-in-out, margin-right 200ms ease-in-out;
+  -ms-transition: right 200ms ease-in-out, margin-right 200ms ease-in-out;
+  -o-transition: right 200ms ease-in-out, margin-right 200ms ease-in-out;
+  transition: right 200ms ease-in-out, margin-right 200ms ease-in-out;
+  background: #eeeeee;
+  filter: progid:DXImageTransform.Microsoft.gradient(GradientType=0, startColorstr='#ffffff', endColorstr='#dddddd');
+  background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #ffffff), color-stop(100%, #dddddd));
+  background-image: -webkit-linear-gradient(top, #ffffff 0%, #dddddd 100%);
+  background-image: -moz-linear-gradient(top, #ffffff 0%, #dddddd 100%);
+  background-image: -ms-linear-gradient(top, #ffffff 0%, #dddddd 100%);
+  background-image: -o-linear-gradient(top, #ffffff 0%, #dddddd 100%);
+  background-image: linear-gradient(top, #ffffff 0%, #dddddd 100%);
+}
+.oo-ui-toggleSwitchWidget.oo-ui-widget-enabled:hover,
+.oo-ui-toggleSwitchWidget.oo-ui-widget-enabled:hover .oo-ui-toggleSwitchWidget-grip {
+  border-color: #aaa;
+}
+.oo-ui-toggleSwitchWidget .oo-ui-toggleSwitchWidget-glow {
+  border-radius: 1em;
+  box-shadow: inset 0 1px 4px 0 rgba(0, 0, 0, 0.07);
+  -webkit-transition: opacity 200ms ease-in-out;
+  -moz-transition: opacity 200ms ease-in-out;
+  -ms-transition: opacity 200ms ease-in-out;
+  -o-transition: opacity 200ms ease-in-out;
+  transition: opacity 200ms ease-in-out;
+  background: #cde7f4;
+  filter: progid:DXImageTransform.Microsoft.gradient(GradientType=0, startColorstr='#b0d9ee', endColorstr='#eaf4fa');
+  background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #b0d9ee), color-stop(100%, #eaf4fa));
+  background-image: -webkit-linear-gradient(top, #b0d9ee 0%, #eaf4fa 100%);
+  background-image: -moz-linear-gradient(top, #b0d9ee 0%, #eaf4fa 100%);
+  background-image: -ms-linear-gradient(top, #b0d9ee 0%, #eaf4fa 100%);
+  background-image: -o-linear-gradient(top, #b0d9ee 0%, #eaf4fa 100%);
+  background-image: linear-gradient(top, #b0d9ee 0%, #eaf4fa 100%);
+}
+.oo-ui-toggleWidget-on .oo-ui-toggleSwitchWidget-glow {
+  opacity: 1;
+}
+.oo-ui-toggleWidget-on .oo-ui-toggleSwitchWidget-grip {
+  right: 2.25em;
+  margin-right: -2px;
+}
+.oo-ui-toggleWidget-off .oo-ui-toggleSwitchWidget-glow {
+  display: block;
+  opacity: 0;
+}
+.oo-ui-toggleWidget-off .oo-ui-toggleSwitchWidget-grip {
+  right: 0.25em;
+  margin-right: 0;
+}
+.oo-ui-popupWidget-popup {
+  position: absolute;
+  overflow: hidden;
+  z-index: 1;
+}
+.oo-ui-popupWidget-anchor {
+  display: none;
+  z-index: 1;
+}
+.oo-ui-popupWidget-anchored .oo-ui-popupWidget-anchor {
+  display: block;
+  position: absolute;
+  background-repeat: no-repeat;
+}
+.oo-ui-popupWidget-head {
+  -webkit-touch-callout: none;
+  -webkit-user-select: none;
+  -moz-user-select: none;
+  -ms-user-select: none;
+  user-select: none;
+}
+.oo-ui-popupWidget-head .oo-ui-buttonWidget {
+  float: left;
+}
+.oo-ui-popupWidget-head .oo-ui-labelElement-label {
+  float: right;
+  cursor: default;
+}
+.oo-ui-popupWidget-body {
+  clear: both;
+  overflow: hidden;
+}
+.oo-ui-popupWidget-popup {
+  border: solid 1px #ccc;
+  border-radius: 0.25em;
+  background-color: #fff;
+  box-shadow: 0 0.15em 0.5em 0 rgba(0, 0, 0, 0.2);
+}
+.oo-ui-popupWidget-anchored .oo-ui-popupWidget-popup {
+  margin-top: 7px;
+}
+.oo-ui-popupWidget-anchored .oo-ui-popupWidget-anchor {
+  width: 15px;
+  height: 8px;
+  margin-right: -7px;
+  background-image: /* @embed */ url(images/anchor.svg);
+}
+.oo-ui-popupWidget-transitioning .oo-ui-popupWidget-popup {
+  -webkit-transition: width 100ms ease-in-out, height 100ms ease-in-out, right 100ms ease-in-out;
+  -moz-transition: width 100ms ease-in-out, height 100ms ease-in-out, right 100ms ease-in-out;
+  -ms-transition: width 100ms ease-in-out, height 100ms ease-in-out, right 100ms ease-in-out;
+  -o-transition: width 100ms ease-in-out, height 100ms ease-in-out, right 100ms ease-in-out;
+  transition: width 100ms ease-in-out, height 100ms ease-in-out, right 100ms ease-in-out;
+}
+.oo-ui-popupWidget-head {
+  height: 2.5em;
+}
+.oo-ui-popupWidget-head .oo-ui-buttonWidget {
+  margin: 0.25em;
+}
+.oo-ui-popupWidget-head .oo-ui-labelElement-label {
+  margin: 0.75em 1em;
+}
+.oo-ui-popupWidget-body {
+  box-shadow: 0 0 0.66em rgba(0, 0, 0, 0.25);
+}
+.oo-ui-popupWidget-body-padded {
+  padding: 0 1em;
+}
+.oo-ui-popupButtonWidget {
+  position: relative;
+}
+.oo-ui-popupButtonWidget .oo-ui-popupWidget {
+  position: absolute;
+  right: 1em;
+  cursor: auto;
+}
+.oo-ui-textInputWidget {
+  position: relative;
+  -webkit-box-sizing: border-box;
+  -moz-box-sizing: border-box;
+  box-sizing: border-box;
+  width: 20em;
+}
+.oo-ui-textInputWidget input,
+.oo-ui-textInputWidget textarea {
+  display: inline-block;
+  width: 100%;
+  resize: none;
+  -webkit-box-sizing: border-box;
+  -moz-box-sizing: border-box;
+  box-sizing: border-box;
+}
+.oo-ui-textInputWidget > .oo-ui-iconElement-icon,
+.oo-ui-textInputWidget > .oo-ui-indicatorElement-indicator {
+  position: absolute;
+  top: 0;
+  height: 100%;
+  background-repeat: no-repeat;
+  cursor: pointer;
+  -webkit-touch-callout: none;
+  -webkit-user-select: none;
+  -moz-user-select: none;
+  -ms-user-select: none;
+  user-select: none;
+}
+.oo-ui-textInputWidget > .oo-ui-iconElement-icon {
+  right: 0;
+}
+.oo-ui-textInputWidget > .oo-ui-indicatorElement-indicator {
+  left: 0;
+}
+.oo-ui-textInputWidget input,
+.oo-ui-textInputWidget textarea {
+  padding: 0.5em;
+  font-size: 1em;
+  font-family: sans-serif;
+  background-color: #fff;
+  border: solid 1px #ccc;
+  box-shadow: 0 0 0 white, inset 0 0.1em 0.2em #ddd;
+  border-radius: 0.25em;
+  -webkit-transition: border-color 200ms, box-shadow 200ms;
+  -moz-transition: border-color 200ms, box-shadow 200ms;
+  -ms-transition: border-color 200ms, box-shadow 200ms;
+  -o-transition: border-color 200ms, box-shadow 200ms;
+  transition: border-color 200ms, box-shadow 200ms;
+}
+.oo-ui-textInputWidget-decorated input,
+.oo-ui-textInputWidget-decorated textarea {
+  padding-right: 2em;
+}
+.oo-ui-textInputWidget-icon {
+  width: 2em;
+}
+.oo-ui-textInputWidget.oo-ui-widget-enabled input:focus,
+.oo-ui-textInputWidget.oo-ui-widget-enabled textarea:focus {
+  outline: none;
+  border-color: #a7dcff;
+  box-shadow: 0 0 0.3em #a7dcff, 0 0 0 white;
+}
+.oo-ui-textInputWidget input[readonly],
+.oo-ui-textInputWidget textarea[readonly] {
+  color: #777;
+  text-shadow: 0 1px 1px #fff;
+}
+.oo-ui-textInputWidget-pending input,
+.oo-ui-textInputWidget-pending textarea {
+  background-color: transparent;
+}
+.oo-ui-textInputWidget.oo-ui-widget-disabled input,
+.oo-ui-textInputWidget.oo-ui-widget-disabled input:focus,
+.oo-ui-textInputWidget.oo-ui-widget-disabled textarea,
+.oo-ui-textInputWidget.oo-ui-widget-disabled textarea:focus {
+  color: #ccc;
+  text-shadow: 0 1px 1px #fff;
+  border-color: #ddd;
+  background-color: #f3f3f3;
+}
+.oo-ui-textInputWidget .oo-ui-iconElement-icon,
+.oo-ui-textInputWidget .oo-ui-indicatorElement-indicator {
+  opacity: 0.8;
+}
+.oo-ui-textInputWidget.oo-ui-iconElement input,
+.oo-ui-textInputWidget.oo-ui-iconElement textarea {
+  padding-right: 2em;
+}
+.oo-ui-textInputWidget.oo-ui-iconElement .oo-ui-iconElement-icon {
+  width: 2em;
+  background-position: left center;
+}
+.oo-ui-textInputWidget.oo-ui-indicatorElement input,
+.oo-ui-textInputWidget.oo-ui-indicatorElement textarea {
+  padding-left: 1.5em;
+}
+.oo-ui-textInputWidget.oo-ui-indicatorElement .oo-ui-indicatorElement-indicator {
+  width: 1.5em;
+  background-position: right center;
+}
+.oo-ui-menuWidget {
+  position: absolute;
+  background: #fff;
+  margin-top: -1px;
+  border: solid 1px #ccc;
+  border-radius: 0 0 0.25em 0.25em;
+  box-shadow: 0 0.15em 1em 0 rgba(0, 0, 0, 0.2);
+}
+.oo-ui-menuWidget input {
+  position: absolute;
+  width: 0;
+  height: 0;
+  overflow: hidden;
+  opacity: 0;
+}
+.oo-ui-menuItemWidget {
+  position: relative;
+}
+.oo-ui-menuItemWidget .oo-ui-iconElement-icon {
+  display: none;
+}
+.oo-ui-menuItemWidget.oo-ui-optionWidget-selected {
+  background-color: transparent;
+}
+.oo-ui-menuItemWidget.oo-ui-optionWidget-selected .oo-ui-iconElement-icon {
+  display: block;
+}
+.oo-ui-menuItemWidget.oo-ui-optionWidget-selected {
+  background-color: transparent;
+}
+.oo-ui-menuItemWidget.oo-ui-optionWidget-highlighted,
+.oo-ui-menuItemWidget.oo-ui-optionWidget-highlighted.oo-ui-optionWidget-selected {
+  background-color: #e1f3ff;
+}
+.oo-ui-menuSectionItemWidget {
+  cursor: default;
+  padding: 0.33em 0.75em;
+  color: #888;
+}
+.oo-ui-inlineMenuWidget {
+  position: relative;
+  display: inline-block;
+  margin: 0.25em 0;
+  min-width: 20em;
+}
+.oo-ui-inlineMenuWidget-handle {
+  width: 100%;
+  display: inline-block;
+  cursor: pointer;
+  -webkit-touch-callout: none;
+  -webkit-user-select: none;
+  -moz-user-select: none;
+  -ms-user-select: none;
+  user-select: none;
+  -webkit-box-sizing: border-box;
+  -moz-box-sizing: border-box;
+  box-sizing: border-box;
+}
+.oo-ui-inlineMenuWidget-handle .oo-ui-indicatorElement-indicator,
+.oo-ui-inlineMenuWidget-handle .oo-ui-iconElement-icon {
+  position: absolute;
+  background-position: center center;
+  background-repeat: no-repeat;
+}
+.oo-ui-inlineMenuWidget .oo-ui-menuWidget {
+  z-index: 1;
+  width: 100%;
+}
+.oo-ui-inlineMenuWidget.oo-ui-widget-disabled .oo-ui-inlineMenuWidget-handle {
+  cursor: default;
+}
+.oo-ui-inlineMenuWidget-handle {
+  height: 2.5em;
+  border: solid 1px rgba(0, 0, 0, 0.1);
+  border-radius: 0.25em;
+}
+.oo-ui-inlineMenuWidget-handle:hover {
+  border-color: rgba(0, 0, 0, 0.2);
+}
+.oo-ui-inlineMenuWidget-handle .oo-ui-indicatorElement-indicator {
+  left: 0;
+}
+.oo-ui-inlineMenuWidget-handle .oo-ui-iconElement-icon {
+  right: 0.25em;
+}
+.oo-ui-inlineMenuWidget-handle .oo-ui-labelElement-label {
+  line-height: 2.5em;
+  margin: 0 0.5em;
+}
+.oo-ui-inlineMenuWidget-handle .oo-ui-indicatorElement-indicator,
+.oo-ui-inlineMenuWidget-handle .oo-ui-iconElement-icon {
+  top: 0;
+  width: 2.5em;
+  height: 2.5em;
+  opacity: 0.8;
+}
+.oo-ui-inlineMenuWidget.oo-ui-widget-disabled .oo-ui-inlineMenuWidget-handle {
+  color: #ccc;
+  text-shadow: 0 1px 1px #fff;
+  border-color: #ddd;
+  background-color: #f3f3f3;
+}
+.oo-ui-inlineMenuWidget.oo-ui-widget-disabled .oo-ui-indicatorElement-indicator {
+  opacity: 0.2;
+}
+.oo-ui-inlineMenuWidget.oo-ui-iconElement .oo-ui-inlineMenuWidget-handle .oo-ui-labelElement-label {
+  margin-right: 3em;
+}
+.oo-ui-inlineMenuWidget.oo-ui-indicatorElement .oo-ui-inlineMenuWidget-handle .oo-ui-labelElement-label {
+  margin-left: 2em;
+}
+.oo-ui-outlineItemWidget {
+  position: relative;
+  cursor: pointer;
+  -webkit-touch-callout: none;
+  -webkit-user-select: none;
+  -moz-user-select: none;
+  -ms-user-select: none;
+  user-select: none;
+  font-size: 1.1em;
+  padding: 0.75em;
+}
+.oo-ui-outlineItemWidget.oo-ui-indicatorElement .oo-ui-labelElement-label {
+  padding-left: 1.5em;
+}
+.oo-ui-outlineItemWidget.oo-ui-indicatorElement .oo-ui-indicatorElement-indicator {
+  opacity: 0.5;
+}
+.oo-ui-outlineItemWidget-level-0 {
+  padding-right: 3.5em;
+}
+.oo-ui-outlineItemWidget-level-0 .oo-ui-iconElement-icon {
+  right: 1em;
+}
+.oo-ui-outlineItemWidget-level-1 {
+  padding-right: 5em;
+}
+.oo-ui-outlineItemWidget-level-1 .oo-ui-iconElement-icon {
+  right: 2.5em;
+}
+.oo-ui-outlineItemWidget-level-2 {
+  padding-right: 6.5em;
+}
+.oo-ui-outlineItemWidget-level-2 .oo-ui-iconElement-icon {
+  right: 4em;
+}
+.oo-ui-selectWidget-depressed .oo-ui-outlineItemWidget.oo-ui-optionWidget-selected {
+  background-color: #a7dcff;
+  text-shadow: 0 1px 1px rgba(255, 255, 255, 0.5);
+}
+.oo-ui-outlineItemWidget.oo-ui-flaggedElement-important {
+  font-weight: bold;
+}
+.oo-ui-outlineItemWidget.oo-ui-flaggedElement-placeholder {
+  font-style: italic;
+}
+.oo-ui-outlineItemWidget.oo-ui-flaggedElement-empty .oo-ui-iconElement-icon {
+  opacity: 0.5;
+}
+.oo-ui-outlineItemWidget.oo-ui-flaggedElement-empty .oo-ui-labelElement-label {
+  color: #777;
+}
+.oo-ui-outlineControlsWidget {
+  height: 3em;
+  background-color: #fff;
+}
+.oo-ui-outlineControlsWidget-items,
+.oo-ui-outlineControlsWidget-movers {
+  float: right;
+  -webkit-box-sizing: border-box;
+  -moz-box-sizing: border-box;
+  box-sizing: border-box;
+}
+.oo-ui-outlineControlsWidget > .oo-ui-iconElement-icon {
+  float: right;
+  background-position: left center;
+  background-repeat: no-repeat;
+}
+.oo-ui-outlineControlsWidget-items {
+  float: right;
+}
+.oo-ui-outlineControlsWidget-items .oo-ui-buttonWidget {
+  float: right;
+}
+.oo-ui-outlineControlsWidget-movers {
+  float: left;
+}
+.oo-ui-outlineControlsWidget-movers .oo-ui-buttonWidget {
+  float: left;
+}
+.oo-ui-outlineControlsWidget-items,
+.oo-ui-outlineControlsWidget-movers {
+  height: 2em;
+  margin: 0.5em;
+  padding: 0;
+}
+.oo-ui-outlineControlsWidget > .oo-ui-iconElement-icon {
+  width: 1.5em;
+  height: 2em;
+  margin: 0.5em 0.5em 0.5em 0;
+  opacity: 0.2;
+}
+.oo-ui-outlineControlsWidget-items {
+  margin-right: 0;
+}
+.oo-ui-comboBoxWidget > .oo-ui-selectWidget {
+  z-index: 1;
+  min-width: 20em;
+}
+.oo-ui-comboBoxWidget > .oo-ui-selectWidget-handle {
+  border: solid 1px rgba(0, 0, 0, 0.1);
+  border-radius: 0.25em;
+}
+.oo-ui-comboBoxWidget > .oo-ui-selectWidget-handle:hover {
+  border-color: rgba(0, 0, 0, 0.2);
+}
+.oo-ui-comboBoxWidget > .oo-ui-selectWidget.oo-ui-widget-disabled .oo-ui-textInputWidget.oo-ui-indicatorElement .oo-ui-indicatorElement-indicator,
+.oo-ui-comboBoxWidget > .oo-ui-selectWidget-empty .oo-ui-textInputWidget.oo-ui-indicatorElement .oo-ui-indicatorElement-indicator {
+  cursor: default;
+  opacity: 0.2;
+}
+.oo-ui-searchWidget-query {
+  position: absolute;
+  top: 0;
+  right: 0;
+  left: 0;
+}
+.oo-ui-searchWidget-query .oo-ui-textInputWidget {
+  width: 100%;
+}
+.oo-ui-searchWidget-results {
+  position: absolute;
+  bottom: 0;
+  right: 0;
+  left: 0;
+  overflow-x: hidden;
+  overflow-y: auto;
+}
+.oo-ui-searchWidget-query {
+  height: 4em;
+  padding: 0 1em;
+  box-shadow: 0 0 0.5em rgba(0, 0, 0, 0.2);
+}
+.oo-ui-searchWidget-query .oo-ui-textInputWidget {
+  margin: 0.75em 0;
+}
+.oo-ui-searchWidget-results {
+  top: 4em;
+  padding: 1em;
+  line-height: 0;
+}
+.oo-ui-window {
+  line-height: 1em;
+  /* Content div takes focus when opened, so hide outline */
+}
+.oo-ui-window-frame {
+  -webkit-box-sizing: border-box;
+  -moz-box-sizing: border-box;
+  box-sizing: border-box;
+}
+.oo-ui-window-frame > iframe {
+  width: 100%;
+  height: 100%;
+  margin: 0;
+  padding: 0;
+}
+.oo-ui-window-content:focus {
+  outline: none;
+}
+.oo-ui-window-head,
+.oo-ui-window-foot {
+  -webkit-touch-callout: none;
+  -webkit-user-select: none;
+  -moz-user-select: none;
+  -ms-user-select: none;
+  user-select: none;
+}
+.oo-ui-window-body {
+  margin: 0;
+  padding: 0;
+  background: none;
+}
+.oo-ui-window-overlay {
+  position: absolute;
+  top: 0;
+  right: 0;
+}
+.oo-ui-window-isolated {
+  background-color: transparent;
+  background-image: none;
+  font-family: sans-serif;
+  font-size: 0.8em;
+}
+.oo-ui-dialog-content > .oo-ui-window-head,
+.oo-ui-dialog-content > .oo-ui-window-body,
+.oo-ui-dialog-content > .oo-ui-window-foot {
+  position: absolute;
+  right: 0;
+  left: 0;
+  overflow: hidden;
+  -webkit-box-sizing: border-box;
+  -moz-box-sizing: border-box;
+  box-sizing: border-box;
+}
+.oo-ui-dialog-content > .oo-ui-window-head {
+  z-index: 1;
+  top: 0;
+}
+.oo-ui-dialog-content > .oo-ui-window-body {
+  z-index: 2;
+  top: 0;
+  bottom: 0;
+}
+.oo-ui-dialog-content > .oo-ui-window-foot {
+  z-index: 1;
+  bottom: 0;
+}
+.oo-ui-dialog-content > .oo-ui-window-overlay {
+  z-index: 3;
+}
+.oo-ui-dialog-content > .oo-ui-window-body {
+  box-shadow: 0 0 0.66em rgba(0, 0, 0, 0.25);
+}
+.oo-ui-messageDialog-actions-horizontal {
+  display: table;
+  table-layout: fixed;
+  width: 100%;
+}
+.oo-ui-messageDialog-actions-horizontal .oo-ui-actionWidget {
+  display: table-cell;
+  width: 1%;
+}
+.oo-ui-messageDialog-actions-vertical {
+  display: block;
+}
+.oo-ui-messageDialog-actions-vertical .oo-ui-actionWidget {
+  display: block;
+  overflow: hidden;
+  text-overflow: ellipsis;
+}
+.oo-ui-messageDialog-actions .oo-ui-actionWidget {
+  position: relative;
+  text-align: center;
+}
+.oo-ui-messageDialog-actions .oo-ui-actionWidget .oo-ui-buttonElement-button {
+  display: block;
+}
+.oo-ui-messageDialog-actions .oo-ui-actionWidget .oo-ui-labelElement-label {
+  position: relative;
+  top: auto;
+  bottom: auto;
+  display: inline;
+  white-space: nowrap;
+}
+.oo-ui-messageDialog-content .oo-ui-window-body {
+  box-shadow: 0 0 0.33em rgba(0, 0, 0, 0.33);
+}
+.oo-ui-messageDialog-title,
+.oo-ui-messageDialog-message {
+  display: block;
+  text-align: center;
+  padding-top: 0.5em;
+}
+.oo-ui-messageDialog-title {
+  font-size: 1.5em;
+  line-height: 1em;
+  color: #000;
+}
+.oo-ui-messageDialog-message {
+  font-size: 0.9em;
+  line-height: 1.25em;
+  color: #666;
+}
+.oo-ui-messageDialog-message-verbose {
+  font-size: 1.1em;
+  line-height: 1.5em;
+  text-align: right;
+}
+.oo-ui-messageDialog-actions-horizontal .oo-ui-actionWidget {
+  border-left: solid 1px #e5e5e5;
+}
+.oo-ui-messageDialog-actions-horizontal .oo-ui-actionWidget:last-child {
+  border-left-width: 0;
+}
+.oo-ui-messageDialog-actions-vertical .oo-ui-actionWidget {
+  border-bottom: solid 1px #e5e5e5;
+}
+.oo-ui-messageDialog-actions-vertical .oo-ui-actionWidget:last-child {
+  border-bottom-width: 0;
+}
+.oo-ui-messageDialog-actions .oo-ui-actionWidget .oo-ui-labelElement-label {
+  text-align: center;
+  line-height: 3.4em;
+  padding: 0 2em;
+}
+.oo-ui-messageDialog-actions .oo-ui-actionWidget:hover {
+  background-color: rgba(0, 0, 0, 0.05);
+}
+.oo-ui-messageDialog-actions .oo-ui-actionWidget:active {
+  background-color: rgba(0, 0, 0, 0.1);
+}
+.oo-ui-messageDialog-actions .oo-ui-actionWidget.oo-ui-flaggedElement-primary:hover {
+  background-color: rgba(8, 126, 204, 0.05);
+}
+.oo-ui-messageDialog-actions .oo-ui-actionWidget.oo-ui-flaggedElement-primary:active {
+  background-color: rgba(8, 126, 204, 0.1);
+}
+.oo-ui-messageDialog-actions .oo-ui-actionWidget.oo-ui-flaggedElement-primary .oo-ui-labelElement-label {
+  font-weight: bold;
+}
+.oo-ui-messageDialog-actions .oo-ui-actionWidget.oo-ui-flaggedElement-constructive:hover {
+  background-color: rgba(118, 171, 54, 0.05);
+}
+.oo-ui-messageDialog-actions .oo-ui-actionWidget.oo-ui-flaggedElement-constructive:active {
+  background-color: rgba(118, 171, 54, 0.1);
+}
+.oo-ui-messageDialog-actions .oo-ui-actionWidget.oo-ui-flaggedElement-destructive:hover {
+  background-color: rgba(212, 83, 83, 0.05);
+}
+.oo-ui-messageDialog-actions .oo-ui-actionWidget.oo-ui-flaggedElement-destructive:active {
+  background-color: rgba(212, 83, 83, 0.1);
+}
+.oo-ui-processDialog-location {
+  overflow: hidden;
+  text-overflow: ellipsis;
+  white-space: nowrap;
+}
+.oo-ui-processDialog-title {
+  display: inline;
+  padding: 0;
+}
+.oo-ui-processDialog-actions-safe .oo-ui-actionWidget,
+.oo-ui-processDialog-actions-primary .oo-ui-actionWidget,
+.oo-ui-processDialog-actions-other .oo-ui-actionWidget {
+  white-space: nowrap;
+}
+.oo-ui-processDialog-actions-safe,
+.oo-ui-processDialog-actions-primary {
+  position: absolute;
+  top: 0;
+  bottom: 0;
+}
+.oo-ui-processDialog-actions-safe {
+  right: 0;
+}
+.oo-ui-processDialog-actions-primary {
+  left: 0;
+}
+.oo-ui-processDialog-errors {
+  display: none;
+  position: absolute;
+  top: 0;
+  right: 0;
+  left: 0;
+  bottom: 0;
+  z-index: 2;
+  overflow-x: hidden;
+  overflow-y: auto;
+}
+.oo-ui-processDialog-content .oo-ui-window-head {
+  height: 3.4em;
+}
+.oo-ui-processDialog-content .oo-ui-window-body {
+  top: 3.4em;
+  box-shadow: 0 0 0.33em rgba(0, 0, 0, 0.33);
+}
+.oo-ui-processDialog-navigation {
+  position: relative;
+  height: 3.4em;
+  padding: 0 1em;
+}
+.oo-ui-processDialog-location {
+  padding: 0.75em 0;
+  height: 1.9em;
+  cursor: default;
+  text-align: center;
+}
+.oo-ui-processDialog-title {
+  font-weight: bold;
+  line-height: 1.9em;
+}
+.oo-ui-processDialog-actions-safe .oo-ui-actionWidget .oo-ui-buttonElement-button,
+.oo-ui-processDialog-actions-primary .oo-ui-actionWidget .oo-ui-buttonElement-button,
+.oo-ui-processDialog-actions-other .oo-ui-actionWidget .oo-ui-buttonElement-button {
+  padding-top: 0.75em;
+  padding-bottom: 0.75em;
+  min-width: 1.9em;
+  min-height: 1.9em;
+}
+.oo-ui-processDialog-actions-safe .oo-ui-actionWidget .oo-ui-labelElement-label,
+.oo-ui-processDialog-actions-primary .oo-ui-actionWidget .oo-ui-labelElement-label,
+.oo-ui-processDialog-actions-other .oo-ui-actionWidget .oo-ui-labelElement-label {
+  line-height: 1.9em;
+  padding: 0 1em;
+}
+.oo-ui-processDialog-actions-safe .oo-ui-actionWidget .oo-ui-iconElement-icon,
+.oo-ui-processDialog-actions-primary .oo-ui-actionWidget .oo-ui-iconElement-icon,
+.oo-ui-processDialog-actions-other .oo-ui-actionWidget .oo-ui-iconElement-icon {
+  position: absolute;
+  margin-top: -0.125em;
+}
+.oo-ui-processDialog-actions-safe .oo-ui-actionWidget.oo-ui-buttonElement-framed,
+.oo-ui-processDialog-actions-primary .oo-ui-actionWidget.oo-ui-buttonElement-framed,
+.oo-ui-processDialog-actions-other .oo-ui-actionWidget.oo-ui-buttonElement-framed {
+  margin: 0.75em 0.75em 0.75em 0;
+}
+.oo-ui-processDialog-actions-safe .oo-ui-actionWidget.oo-ui-buttonElement-framed .oo-ui-buttonElement-button,
+.oo-ui-processDialog-actions-primary .oo-ui-actionWidget.oo-ui-buttonElement-framed .oo-ui-buttonElement-button,
+.oo-ui-processDialog-actions-other .oo-ui-actionWidget.oo-ui-buttonElement-framed .oo-ui-buttonElement-button {
+  padding: 0;
+  vertical-align: middle;
+}
+.oo-ui-processDialog-actions-safe .oo-ui-actionWidget:hover,
+.oo-ui-processDialog-actions-primary .oo-ui-actionWidget:hover {
+  background-color: rgba(0, 0, 0, 0.05);
+}
+.oo-ui-processDialog-actions-safe .oo-ui-actionWidget:active,
+.oo-ui-processDialog-actions-primary .oo-ui-actionWidget:active {
+  background-color: rgba(0, 0, 0, 0.1);
+}
+.oo-ui-processDialog-actions-safe .oo-ui-actionWidget.oo-ui-buttonElement-framed,
+.oo-ui-processDialog-actions-primary .oo-ui-actionWidget.oo-ui-buttonElement-framed {
+  margin: 0.75em;
+}
+.oo-ui-processDialog-actions-safe .oo-ui-actionWidget.oo-ui-buttonElement-framed .oo-ui-buttonElement-button,
+.oo-ui-processDialog-actions-primary .oo-ui-actionWidget.oo-ui-buttonElement-framed .oo-ui-buttonElement-button {
+  /* Adjust for border so text aligns with title */
+  margin: -1px;
+}
+.oo-ui-processDialog-actions-safe .oo-ui-actionWidget.oo-ui-flaggedElement-primary:hover,
+.oo-ui-processDialog-actions-primary .oo-ui-actionWidget.oo-ui-flaggedElement-primary:hover {
+  background-color: rgba(8, 126, 204, 0.05);
+}
+.oo-ui-processDialog-actions-safe .oo-ui-actionWidget.oo-ui-flaggedElement-primary:active,
+.oo-ui-processDialog-actions-primary .oo-ui-actionWidget.oo-ui-flaggedElement-primary:active {
+  background-color: rgba(8, 126, 204, 0.1);
+}
+.oo-ui-processDialog-actions-safe .oo-ui-actionWidget.oo-ui-flaggedElement-primary .oo-ui-labelElement-label,
+.oo-ui-processDialog-actions-primary .oo-ui-actionWidget.oo-ui-flaggedElement-primary .oo-ui-labelElement-label {
+  font-weight: bold;
+}
+.oo-ui-processDialog-actions-safe .oo-ui-actionWidget.oo-ui-flaggedElement-constructive:hover,
+.oo-ui-processDialog-actions-primary .oo-ui-actionWidget.oo-ui-flaggedElement-constructive:hover {
+  background-color: rgba(118, 171, 54, 0.05);
+}
+.oo-ui-processDialog-actions-safe .oo-ui-actionWidget.oo-ui-flaggedElement-constructive:active,
+.oo-ui-processDialog-actions-primary .oo-ui-actionWidget.oo-ui-flaggedElement-constructive:active {
+  background-color: rgba(118, 171, 54, 0.1);
+}
+.oo-ui-processDialog-actions-safe .oo-ui-actionWidget.oo-ui-flaggedElement-destructive:hover,
+.oo-ui-processDialog-actions-primary .oo-ui-actionWidget.oo-ui-flaggedElement-destructive:hover {
+  background-color: rgba(212, 83, 83, 0.05);
+}
+.oo-ui-processDialog-actions-safe .oo-ui-actionWidget.oo-ui-flaggedElement-destructive:active,
+.oo-ui-processDialog-actions-primary .oo-ui-actionWidget.oo-ui-flaggedElement-destructive:active {
+  background-color: rgba(212, 83, 83, 0.1);
+}
+.oo-ui-processDialog-actions-safe .oo-ui-actionWidget.oo-ui-iconElement .oo-ui-iconElement-icon {
+  right: 0.5em;
+}
+.oo-ui-processDialog-actions-safe .oo-ui-actionWidget.oo-ui-iconElement .oo-ui-labelElement-label {
+  padding-right: 2.25em;
+}
+.oo-ui-processDialog-actions-primary .oo-ui-actionWidget.oo-ui-iconElement .oo-ui-iconElement-icon {
+  left: 0.5em;
+}
+.oo-ui-processDialog-actions-primary .oo-ui-actionWidget.oo-ui-iconElement .oo-ui-labelElement-label {
+  padding-left: 2.25em;
+}
+.oo-ui-processDialog > .oo-ui-window-frame {
+  min-height: 5em;
+}
+.oo-ui-processDialog-errors {
+  background-color: rgba(255, 255, 255, 0.9);
+  padding: 3em 3em 1.5em 3em;
+  text-align: center;
+}
+.oo-ui-processDialog-errors .oo-ui-buttonWidget {
+  margin: 2em 1em 2em 1em;
+}
+.oo-ui-processDialog-errors-title {
+  font-size: 1.5em;
+  color: #000;
+  margin-bottom: 2em;
+}
+.oo-ui-processDialog-error {
+  text-align: right;
+  margin: 1em;
+  padding: 1em;
+  border: solid 1px #ff9e9e;
+  background-color: #fff7f7;
+  border-radius: 0.25em;
+}
+.oo-ui-windowManager-modal > .oo-ui-dialog {
+  position: fixed;
+  width: 0;
+  height: 0;
+  overflow: hidden;
+}
+.oo-ui-windowManager-modal > .oo-ui-dialog.oo-ui-window-setup {
+  width: auto;
+  height: auto;
+  top: 0;
+  left: 0;
+  bottom: 0;
+  right: 0;
+  padding: 1em;
+}
+.oo-ui-windowManager-modal > .oo-ui-dialog.oo-ui-window-setup > .oo-ui-window-frame {
+  position: fixed;
+  left: 0;
+  right: 0;
+  margin: auto;
+  overflow: hidden;
+  max-width: 100%;
+  max-height: 100%;
+}
+.oo-ui-windowManager-modal > .oo-ui-dialog.oo-ui-window-setup > .oo-ui-window-frame > iframe {
+  width: 100%;
+  height: 100%;
+}
+.oo-ui-windowManager-fullscreen > .oo-ui-dialog > .oo-ui-window-frame {
+  width: 100%;
+  height: 100%;
+  top: 0;
+  bottom: 0;
+}
+.oo-ui-windowManager-modal > .oo-ui-dialog {
+  background-color: rgba(255, 255, 255, 0.5);
+  opacity: 0;
+  -webkit-transition: opacity 250ms ease-in-out;
+  -moz-transition: opacity 250ms ease-in-out;
+  -ms-transition: opacity 250ms ease-in-out;
+  -o-transition: opacity 250ms ease-in-out;
+  transition: opacity 250ms ease-in-out;
+}
+.oo-ui-windowManager-modal > .oo-ui-dialog > .oo-ui-window-frame {
+  top: 1em;
+  bottom: 1em;
+  background-color: #fff;
+  -webkit-transform: scale(0.5);
+  -moz-transform: scale(0.5);
+  -ms-transform: scale(0.5);
+  -o-transform: scale(0.5);
+  transform: scale(0.5);
+  -webkit-transition: all 250ms ease-in-out;
+  -moz-transition: all 250ms ease-in-out;
+  -ms-transition: all 250ms ease-in-out;
+  -o-transition: all 250ms ease-in-out;
+  transition: all 250ms ease-in-out;
+}
+.oo-ui-windowManager-modal > .oo-ui-dialog.oo-ui-window-ready {
+  opacity: 1;
+}
+.oo-ui-windowManager-modal > .oo-ui-dialog.oo-ui-window-ready > .oo-ui-window-frame {
+  -webkit-transform: scale(1);
+  -moz-transform: scale(1);
+  -ms-transform: scale(1);
+  -o-transform: scale(1);
+  transform: scale(1);
+}
+.oo-ui-windowManager-modal.oo-ui-windowManager-floating > .oo-ui-dialog > .oo-ui-window-frame {
+  border: solid 1px #ccc;
+  border-radius: 0.5em;
+  box-shadow: 0 0.2em 1em rgba(0, 0, 0, 0.3);
+}
index 4fd859a..36492c0 100644 (file)
@@ -1,12 +1,12 @@
 /*!
- * OOjs UI v0.1.0-pre (f9c217dfa4)
+ * OOjs UI v0.1.0-pre (f2c3f12959)
  * https://www.mediawiki.org/wiki/OOjs_UI
  *
  * Copyright 2011–2014 OOjs Team and other contributors.
  * Released under the MIT license
  * http://oojs.mit-license.org
  *
- * Date: 2014-09-10T17:25:40Z
+ * Date: 2014-09-18T23:22:20Z
  */
 /*
  * Blank theme mixins.
  */
 /* @noflip */
 .oo-ui-rtl {
-  direction: rtl;
+       direction: rtl;
 }
 /* @noflip */
 .oo-ui-ltr {
-  direction: ltr;
+       direction: ltr;
 }
 .oo-ui-buttonElement > .oo-ui-buttonElement-button {
-  cursor: pointer;
-  display: inline-block;
-  vertical-align: middle;
-  -webkit-touch-callout: none;
-  -webkit-user-select: none;
-  -moz-user-select: none;
-  -ms-user-select: none;
-  user-select: none;
+       cursor: pointer;
+       display: inline-block;
+       vertical-align: middle;
+       -webkit-touch-callout: none;
+       -webkit-user-select: none;
+          -moz-user-select: none;
+           -ms-user-select: none;
+               user-select: none;
 }
 .oo-ui-buttonElement > .oo-ui-buttonElement-button > .oo-ui-iconElement-icon {
-  display: none;
+       display: none;
 }
 .oo-ui-buttonElement > .oo-ui-buttonElement-button > .oo-ui-indicatorElement-indicator {
-  display: none;
+       display: none;
 }
 .oo-ui-buttonElement.oo-ui-widget-disabled > .oo-ui-buttonElement-button {
-  cursor: default;
+       cursor: default;
 }
 .oo-ui-buttonElement.oo-ui-indicatorElement > .oo-ui-buttonElement-button > .oo-ui-indicatorElement-indicator,
 .oo-ui-buttonElement.oo-ui-iconElement > .oo-ui-buttonElement-button > .oo-ui-iconElement-icon {
-  display: inline-block;
-  vertical-align: middle;
-  background-position: center center;
-  background-repeat: no-repeat;
+       display: inline-block;
+       vertical-align: middle;
+       background-position: center center;
+       background-repeat: no-repeat;
 }
 .oo-ui-buttonElement-frameless {
-  display: inline-block;
-  position: relative;
+       display: inline-block;
+       position: relative;
 }
 .oo-ui-buttonElement-frameless > .oo-ui-buttonElement-button > .oo-ui-labelElement-label {
-  display: inline-block;
-  vertical-align: middle;
+       display: inline-block;
+       vertical-align: middle;
 }
 .oo-ui-buttonElement-framed > .oo-ui-buttonElement-button {
-  display: inline-block;
-  vertical-align: top;
-  text-align: center;
+       display: inline-block;
+       vertical-align: top;
+       text-align: center;
 }
 .oo-ui-buttonElement-framed > .oo-ui-buttonElement-button > .oo-ui-labelElement-label {
-  display: inline-block;
-  vertical-align: middle;
+       display: inline-block;
+       vertical-align: middle;
 }
 .oo-ui-buttonElement-framed.oo-ui-widget-disabled > .oo-ui-buttonElement-button,
 .oo-ui-buttonElement-framed.oo-ui-widget-disabled.oo-ui-buttonElement-active > .oo-ui-buttonElement-button,
 .oo-ui-buttonElement-framed.oo-ui-widget-disabled.oo-ui-buttonElement-pressed > .oo-ui-buttonElement-button {
-  cursor: default;
+       cursor: default;
 }
 .oo-ui-buttonElement > .oo-ui-buttonElement-button > .oo-ui-iconElement-icon {
-  margin-left: 0;
+       margin-left: 0;
 }
 .oo-ui-buttonElement > .oo-ui-buttonElement-button > .oo-ui-indicatorElement-indicator {
-  margin-right: -0.75em;
+       margin-right: -0.75em;
 }
 .oo-ui-buttonElement.oo-ui-indicatorElement .oo-ui-buttonElement-button > .oo-ui-indicatorElement-indicator,
 .oo-ui-buttonElement.oo-ui-iconElement .oo-ui-buttonElement-button > .oo-ui-iconElement-icon {
-  width: 3.35em;
-  height: 3.35em;
-  background-size: 2em auto;
+       width: 3.35em;
+       height: 3.35em;
+       background-size: 2em auto;
 }
 .oo-ui-buttonElement-frameless > .oo-ui-buttonElement-button > .oo-ui-labelElement-label {
-  margin-left: 0.25em;
+       margin-left: 0.25em;
 }
 .oo-ui-buttonElement-framed > .oo-ui-buttonElement-button > .oo-ui-labelElement-label {
-  line-height: 1.9em;
+       line-height: 1.9em;
 }
 .oo-ui-clippableElement-clippable {
-  -webkit-box-sizing: border-box;
-  -moz-box-sizing: border-box;
-  box-sizing: border-box;
+       -webkit-box-sizing: border-box;
+          -moz-box-sizing: border-box;
+               box-sizing: border-box;
 }
 .oo-ui-bookletLayout-stackLayout.oo-ui-stackLayout-continuous .oo-ui-panelLayout-scrollable {
-  overflow-y: hidden;
+       overflow-y: hidden;
 }
 .oo-ui-bookletLayout-stackLayout .oo-ui-panelLayout {
-  width: 100%;
-  -webkit-box-sizing: border-box;
-  -moz-box-sizing: border-box;
-  box-sizing: border-box;
+       width: 100%;
+       -webkit-box-sizing: border-box;
+          -moz-box-sizing: border-box;
+               box-sizing: border-box;
 }
 .oo-ui-bookletLayout-stackLayout .oo-ui-panelLayout-scrollable {
-  overflow-y: auto;
+       overflow-y: auto;
 }
 .oo-ui-bookletLayout-stackLayout .oo-ui-panelLayout-padded {
-  padding: 2em;
+       padding: 2em;
 }
 .oo-ui-bookletLayout-outlinePanel-editable .oo-ui-outlineWidget {
-  position: absolute;
-  top: 0;
-  left: 0;
-  right: 0;
-  bottom: 3em;
-  overflow-y: auto;
+       position: absolute;
+       top: 0;
+       left: 0;
+       right: 0;
+       bottom: 3em;
+       overflow-y: auto;
 }
 .oo-ui-bookletLayout-outlinePanel .oo-ui-outlineControlsWidget {
-  position: absolute;
-  bottom: 0;
-  left: 0;
-  right: 0;
+       position: absolute;
+       bottom: 0;
+       left: 0;
+       right: 0;
 }
 .oo-ui-bookletLayout-stackLayout .oo-ui-panelLayout {
-  padding: 0 0 1em;
+       padding: 0 0 1em;
 }
 .oo-ui-fieldLayout {
-  margin-bottom: 1em;
+       margin-bottom: 1em;
 }
 .oo-ui-fieldLayout:before,
 .oo-ui-fieldLayout:after {
-  content: " ";
-  display: table;
+       content: " ";
+       display: table;
 }
 .oo-ui-fieldLayout:after {
-  clear: both;
+       clear: both;
 }
 .oo-ui-fieldLayout.oo-ui-fieldLayout-align-left > .oo-ui-labelElement-label,
 .oo-ui-fieldLayout.oo-ui-fieldLayout-align-right > .oo-ui-labelElement-label {
-  display: block;
-  float: left;
+       display: block;
+       float: left;
 }
 .oo-ui-fieldLayout.oo-ui-fieldLayout-align-left > .oo-ui-fieldLayout-field,
 .oo-ui-fieldLayout.oo-ui-fieldLayout-align-right > .oo-ui-fieldLayout-field {
-  display: block;
-  float: left;
+       display: block;
+       float: left;
 }
 .oo-ui-fieldLayout.oo-ui-fieldLayout-align-right > .oo-ui-labelElement-label {
-  text-align: right;
+       text-align: right;
 }
 .oo-ui-fieldLayout.oo-ui-fieldLayout-align-inline > .oo-ui-labelElement-label {
-  display: inline-block;
-  vertical-align: middle;
+       display: inline-block;
+       vertical-align: middle;
 }
 .oo-ui-fieldLayout.oo-ui-fieldLayout-align-inline > .oo-ui-fieldLayout-field {
-  display: inline-block;
-  vertical-align: middle;
+       display: inline-block;
+       vertical-align: middle;
 }
 .oo-ui-fieldLayout.oo-ui-fieldLayout-align-top > .oo-ui-labelElement-label {
-  display: inline-block;
+       display: inline-block;
 }
 .oo-ui-fieldLayout > .oo-ui-popupButtonWidget > .oo-ui-popupWidget > .oo-ui-popupWidget-popup {
-  z-index: 1;
+       z-index: 1;
+}
+.oo-ui-fieldLayout .oo-ui-fieldLayout-help {
+       float: right;
+}
+.oo-ui-fieldLayout .oo-ui-fieldLayout-help-content {
+       padding: 0.5em 0.75em;
 }
 .oo-ui-fieldLayout:last-child {
-  margin-bottom: 0;
+       margin-bottom: 0;
 }
 .oo-ui-fieldLayout.oo-ui-fieldLayout-align-left > .oo-ui-labelElement-label,
 .oo-ui-fieldLayout.oo-ui-fieldLayout-align-right > .oo-ui-labelElement-label {
-  padding-top: 0.5em;
-  margin-right: 5%;
-  width: 35%;
+       padding-top: 0.5em;
+       margin-right: 5%;
+       width: 35%;
 }
 .oo-ui-fieldLayout.oo-ui-fieldLayout-align-left > .oo-ui-fieldLayout-field,
 .oo-ui-fieldLayout.oo-ui-fieldLayout-align-right > .oo-ui-fieldLayout-field {
-  width: 60%;
+       width: 60%;
 }
 .oo-ui-fieldLayout.oo-ui-fieldLayout-align-inline > .oo-ui-labelElement-label {
-  padding: 0.75em 0.5em 0.5em 0.5em;
+       padding: 0.75em 0.5em 0.5em 0.5em;
 }
 .oo-ui-fieldLayout.oo-ui-fieldLayout-align-inline > .oo-ui-fieldLayout-field {
-  padding: 0.5em 0;
+       padding: 0.5em 0;
 }
 .oo-ui-fieldLayout.oo-ui-fieldLayout-align-top > .oo-ui-labelElement-label {
-  padding: 0.5em 0;
+       padding: 0.5em 0;
 }
 .oo-ui-fieldLayout > .oo-ui-popupButtonWidget > .oo-ui-buttonElement-button > .oo-ui-iconElement-icon {
-  margin-top: 0.25em;
+       margin-top: 0.25em;
 }
 .oo-ui-fieldLayout-disabled .oo-ui-labelElement-label {
-  color: #ccc;
+       color: #cccccc;
 }
 .oo-ui-fieldsetLayout {
-  position: relative;
-  margin: 0;
-  padding: 0;
+       position: relative;
+       margin: 0;
+       padding: 0;
 }
 .oo-ui-fieldsetLayout.oo-ui-iconElement > .oo-ui-iconElement-icon {
-  display: block;
-  position: absolute;
-  background-position: center center;
-  background-repeat: no-repeat;
+       display: block;
+       position: absolute;
+       background-position: center center;
+       background-repeat: no-repeat;
 }
 .oo-ui-fieldsetLayout.oo-ui-labelElement > .oo-ui-labelElement-label {
-  display: inline-block;
+       display: inline-block;
 }
 .oo-ui-fieldsetLayout + .oo-ui-fieldsetLayout {
-  margin-top: 2em;
+       margin-top: 2em;
 }
 .oo-ui-fieldsetLayout > .oo-ui-labelElement-label {
-  margin-bottom: 0.5em;
-  padding: 0.25em 0;
+       margin-bottom: 0.5em;
+       padding: 0.25em 0;
 }
 .oo-ui-fieldsetLayout.oo-ui-iconElement > .oo-ui-labelElement-label {
-  padding-left: 1.75em;
-  line-height: 1.33em;
+       padding-left: 1.75em;
+       line-height: 1.33em;
 }
 .oo-ui-fieldsetLayout.oo-ui-iconElement > .oo-ui-iconElement-icon {
-  left: 0;
-  top: 0.25em;
-  width: 2em;
-  height: 2em;
+       left: 0;
+       top: 0.25em;
+       width: 2em;
+       height: 2em;
 }
 .oo-ui-gridLayout {
-  position: absolute;
-  top: 0;
-  left: 0;
-  right: 0;
-  bottom: 0;
+       position: absolute;
+       top: 0;
+       left: 0;
+       right: 0;
+       bottom: 0;
 }
 .oo-ui-panelLayout {
-  position: relative;
-  padding: 1em 3.35em;
+       position: relative;
+       padding: 1em 3.35em;
 }
 .oo-ui-panelLayout-scrollable {
-  overflow-y: auto;
+       overflow-y: auto;
 }
 .oo-ui-panelLayout-expanded {
-  position: absolute;
-  top: 0;
-  left: 0;
-  right: 0;
-  bottom: 0;
+       position: absolute;
+       top: 0;
+       left: 0;
+       right: 0;
+       bottom: 0;
 }
 .oo-ui-stackLayout > .oo-ui-panelLayout {
-  display: none;
+       display: none;
 }
 .oo-ui-stackLayout-continuous > .oo-ui-panelLayout {
-  display: block;
-  position: relative;
+       display: block;
+       position: relative;
 }
 .oo-ui-popupTool .oo-ui-popupWidget-popup,
 .oo-ui-popupTool .oo-ui-popupWidget-anchor {
-  z-index: 4;
+       z-index: 4;
 }
 .oo-ui-popupTool .oo-ui-popupWidget {
-  margin-left: 1.25em;
-  font-size: 0.8em;
+       margin-left: 1.25em;
+       font-size: 0.8em;
 }
 .oo-ui-toolGroup {
-  display: inline-block;
-  vertical-align: middle;
-  margin: 0.3em;
+       display: inline-block;
+       vertical-align: middle;
+       margin: 0.3em;
 }
 .oo-ui-toolGroup-empty {
-  display: none;
+       display: none;
 }
 .oo-ui-toolGroup .oo-ui-tool-link .oo-ui-iconElement-icon {
-  background-position: center center;
-  background-repeat: no-repeat;
+       background-position: center center;
+       background-repeat: no-repeat;
 }
 .oo-ui-barToolGroup > .oo-ui-iconElement-icon,
 .oo-ui-barToolGroup > .oo-ui-labelElement-label {
-  display: none;
+       display: none;
 }
 .oo-ui-barToolGroup .oo-ui-tool {
-  display: inline-block;
-  position: relative;
-  vertical-align: top;
+       display: inline-block;
+       position: relative;
+       vertical-align: top;
 }
 .oo-ui-barToolGroup .oo-ui-tool-link {
-  display: block;
+       display: block;
 }
 .oo-ui-barToolGroup .oo-ui-tool-link .oo-ui-iconElement-icon {
-  display: block;
+       display: block;
 }
 .oo-ui-barToolGroup .oo-ui-tool-link .oo-ui-tool-title {
-  display: none;
+       display: none;
 }
 .oo-ui-barToolGroup .oo-ui-tool.oo-ui-widget-disabled .oo-ui-tool-link {
-  cursor: default;
+       cursor: default;
 }
 .oo-ui-barToolGroup .oo-ui-tool-title,
 .oo-ui-barToolGroup .oo-ui-tool-accel {
-  display: none;
+       display: none;
 }
 .oo-ui-barToolGroup.oo-ui-widget-enabled .oo-ui-tool-link {
-  cursor: pointer;
+       cursor: pointer;
 }
 .oo-ui-barToolGroup .oo-ui-tool-link {
-  height: 1.5em;
-  padding: 0.25em;
+       height: 1.5em;
+       padding: 0.25em;
 }
 .oo-ui-barToolGroup .oo-ui-tool-link .oo-ui-iconElement-icon {
-  height: 1.5em;
-  width: 1.5em;
+       height: 1.5em;
+       width: 1.5em;
 }
 .oo-ui-popupToolGroup {
-  position: relative;
-  height: 2em;
-  min-width: 2.5em;
+       position: relative;
+       height: 2em;
+       min-width: 2.5em;
 }
 .oo-ui-popupToolGroup-handle {
-  display: block;
-  cursor: pointer;
+       display: block;
+       cursor: pointer;
 }
 .oo-ui-popupToolGroup-handle .oo-ui-indicatorElement-indicator,
 .oo-ui-popupToolGroup-handle .oo-ui-iconElement-icon {
-  position: absolute;
-  background-position: center center;
-  background-repeat: no-repeat;
+       position: absolute;
+       background-position: center center;
+       background-repeat: no-repeat;
 }
 .oo-ui-popupToolGroup.oo-ui-widget-disabled .oo-ui-popupToolGroup-handle {
-  cursor: default;
+       cursor: default;
 }
 .oo-ui-popupToolGroup .oo-ui-toolGroup-tools {
-  display: none;
-  position: absolute;
-  z-index: 4;
+       display: none;
+       position: absolute;
+       z-index: 4;
 }
 .oo-ui-popupToolGroup .oo-ui-toolGroup-tools .oo-ui-iconElement-icon {
-  background-repeat: no-repeat;
-  background-position: center center;
+       background-repeat: no-repeat;
+       background-position: center center;
 }
 .oo-ui-popupToolGroup-active.oo-ui-widget-enabled > .oo-ui-toolGroup-tools {
-  display: block;
+       display: block;
 }
 .oo-ui-popupToolGroup-left > .oo-ui-toolGroup-tools {
-  left: 0;
+       left: 0;
 }
 .oo-ui-popupToolGroup-right > .oo-ui-toolGroup-tools {
-  right: 0;
+       right: 0;
 }
 .oo-ui-popupToolGroup .oo-ui-tool-link .oo-ui-iconElement-icon {
-  display: inline-block;
-  vertical-align: middle;
+       display: inline-block;
+       vertical-align: middle;
 }
 .oo-ui-popupToolGroup .oo-ui-tool-link .oo-ui-tool-title {
-  display: inline-block;
-  vertical-align: middle;
+       display: inline-block;
+       vertical-align: middle;
 }
 .oo-ui-popupToolGroup .oo-ui-tool-accel {
-  display: none;
+       display: none;
 }
 .oo-ui-popupToolGroup.oo-ui-indicatorElement.oo-ui-iconElement {
-  min-width: 3.5em;
+       min-width: 3.5em;
 }
 .oo-ui-popupToolGroup-handle .oo-ui-indicatorElement-indicator,
 .oo-ui-popupToolGroup-handle .oo-ui-iconElement-icon {
-  top: 0;
-  width: 2em;
-  height: 2em;
+       top: 0;
+       width: 2em;
+       height: 2em;
 }
 .oo-ui-popupToolGroup-handle .oo-ui-indicatorElement-indicator {
-  right: 0;
+       right: 0;
 }
 .oo-ui-popupToolGroup-handle .oo-ui-iconElement-icon {
-  left: 0.25em;
+       left: 0.25em;
 }
 .oo-ui-popupToolGroup-handle .oo-ui-labelElement-label {
-  line-height: 2.6em;
-  font-size: 0.8em;
-  margin: 0 1em;
+       line-height: 2.6em;
+       font-size: 0.8em;
+       margin: 0 1em;
 }
 .oo-ui-popupToolGroup-header {
-  line-height: 2.6em;
-  font-size: 0.8em;
-  margin: 0 0.6em;
-  font-weight: bold;
+       line-height: 2.6em;
+       font-size: 0.8em;
+       margin: 0 0.6em;
+       font-weight: bold;
 }
 .oo-ui-popupToolGroup.oo-ui-iconElement .oo-ui-popupToolGroup-handle .oo-ui-labelElement-label {
-  margin-left: 3em;
+       margin-left: 3em;
 }
 .oo-ui-popupToolGroup.oo-ui-indicatorElement .oo-ui-popupToolGroup-handle .oo-ui-labelElement-label {
-  margin-right: 2.25em;
+       margin-right: 2.25em;
 }
 .oo-ui-popupToolGroup .oo-ui-toolGroup-tools {
-  top: 2.3em;
-  margin: 0 -1px;
-  border: solid 1px #dddddd;
-  background-color: white;
+       top: 2.3em;
+       margin: 0 -1px;
+       border: solid 1px #dddddd;
+       background-color: white;
 }
 .oo-ui-popupToolGroup .oo-ui-tool-link .oo-ui-iconElement-icon {
-  height: 2em;
-  width: 2em;
-  margin-right: 0.25em;
+       height: 2em;
+       width: 2em;
+       margin-right: 0.25em;
 }
 .oo-ui-popupToolGroup .oo-ui-tool-link .oo-ui-tool-title {
-  line-height: 2em;
-  font-size: 0.8em;
+       line-height: 2em;
+       font-size: 0.8em;
 }
 .oo-ui-listToolGroup .oo-ui-tool {
-  display: inline-block;
-  width: 100%;
-  -webkit-box-sizing: border-box;
-  -moz-box-sizing: border-box;
-  box-sizing: border-box;
+       display: inline-block;
+       width: 100%;
+       -webkit-box-sizing: border-box;
+          -moz-box-sizing: border-box;
+               box-sizing: border-box;
 }
 .oo-ui-listToolGroup .oo-ui-tool-link {
-  display: block;
-  cursor: pointer;
-  white-space: nowrap;
+       display: block;
+       cursor: pointer;
+       white-space: nowrap;
 }
 .oo-ui-listToolGroup .oo-ui-tool.oo-ui-widget-disabled .oo-ui-tool-link {
-  cursor: default;
+       cursor: default;
 }
 .oo-ui-listToolGroup .oo-ui-toolGroup-tools {
-  padding: 0.25em;
+       padding: 0.25em;
 }
 .oo-ui-listToolGroup .oo-ui-tool-link {
-  padding-right: 0.5em;
+       padding-right: 0.5em;
 }
 .oo-ui-menuToolGroup .oo-ui-tool {
-  display: block;
+       display: block;
 }
 .oo-ui-menuToolGroup .oo-ui-tool-link {
-  display: block;
-  cursor: pointer;
-  white-space: nowrap;
+       display: block;
+       cursor: pointer;
+       white-space: nowrap;
 }
 .oo-ui-menuToolGroup .oo-ui-tool-link .oo-ui-iconElement-icon {
-  background-image: none;
+       background-image: none;
 }
 .oo-ui-menuToolGroup .oo-ui-tool-active .oo-ui-tool-link .oo-ui-iconElement-icon {
-  background-image: /* @embed */ url(images/icons/check.svg);
+       background-image: /* @embed */ url(images/icons/check.svg);
 }
 .oo-ui-menuToolGroup .oo-ui-tool.oo-ui-widget-disabled .oo-ui-tool-link {
-  cursor: default;
+       cursor: default;
 }
 .oo-ui-menuToolGroup .oo-ui-popupToolGroup-handle {
-  min-width: 8em;
+       min-width: 8em;
 }
 .oo-ui-menuToolGroup .oo-ui-toolGroup-tools {
-  padding: 0.25em 0 0.25em 0;
+       padding: 0.25em 0 0.25em 0;
 }
 .oo-ui-menuToolGroup .oo-ui-tool-link {
-  padding: 0 1em 0 0.25em;
+       padding: 0 1em 0 0.25em;
 }
 .oo-ui-toolbar {
-  clear: both;
+       clear: both;
 }
 .oo-ui-toolbar-bar {
-  line-height: 1em;
+       line-height: 1em;
 }
 .oo-ui-toolbar-actions {
-  float: right;
+       float: right;
 }
 .oo-ui-toolbar-tools {
-  display: inline;
+       display: inline;
 }
 .oo-ui-toolbar-tools,
 .oo-ui-toolbar-actions,
 .oo-ui-toolbar-shadow {
-  -webkit-touch-callout: none;
-  -webkit-user-select: none;
-  -moz-user-select: none;
-  -ms-user-select: none;
-  user-select: none;
+       -webkit-touch-callout: none;
+       -webkit-user-select: none;
+          -moz-user-select: none;
+           -ms-user-select: none;
+               user-select: none;
 }
 .oo-ui-toolbar-actions .oo-ui-popupWidget {
-  -webkit-touch-callout: default;
-  -webkit-user-select: all;
-  -moz-user-select: all;
-  -ms-user-select: all;
-  user-select: all;
+       -webkit-touch-callout: default;
+       -webkit-user-select: all;
+          -moz-user-select: all;
+           -ms-user-select: all;
+               user-select: all;
 }
 .oo-ui-toolbar-shadow {
-  background-position: left top;
-  background-repeat: repeat-x;
-  position: absolute;
-  width: 100%;
-  pointer-events: none;
+       background-position: left top;
+       background-repeat: repeat-x;
+       position: absolute;
+       width: 100%;
+       pointer-events: none;
 }
 .oo-ui-toolbar-bar {
-  border-bottom: solid 1px #dddddd;
-  background: white;
+       border-bottom: solid 1px #dddddd;
+       background: white;
 }
 .oo-ui-toolbar-bar .oo-ui-toolbar-bar {
-  border: none;
-  background: none;
+       border: none;
+       background: none;
 }
 .oo-ui-selectWidget {
-  margin: 0;
-  padding: 0;
+       margin: 0;
+       padding: 0;
 }
 .oo-ui-optionWidget {
-  position: relative;
-  display: block;
-  cursor: pointer;
-  padding: 0.8em 1em 0.8em 3.35em;
-  border: none;
-  font-weight: bold;
+       position: relative;
+       display: block;
+       cursor: pointer;
+       padding: 0.8em 1em 0.8em 3.35em;
+       border: none;
+       font-weight: bold;
 }
 .oo-ui-optionWidget.oo-ui-widget-disabled {
-  cursor: default;
+       cursor: default;
 }
 .oo-ui-optionWidget .oo-ui-labelElement-label {
-  display: block;
-  white-space: nowrap;
-  text-overflow: ellipsis;
-  overflow: hidden;
+       display: block;
+       white-space: nowrap;
+       text-overflow: ellipsis;
+       overflow: hidden;
 }
 .oo-ui-optionWidget .oo-ui-labelElement-label {
-  line-height: 1.5em;
+       line-height: 1.5em;
 }
 .oo-ui-optionWidget.oo-ui-indicatorElement .oo-ui-labelElement-label {
-  padding-right: 1.5em;
+       padding-right: 1.5em;
 }
 .oo-ui-optionWidget-level-0 {
-  padding-left: 3.5em;
+       padding-left: 3.5em;
 }
 .oo-ui-optionWidget-level-0 .oo-ui-iconElement-icon {
-  left: 1em;
+       left: 1em;
 }
 .oo-ui-optionWidget-level-1 {
-  padding-left: 5em;
+       padding-left: 5em;
 }
 .oo-ui-optionWidget-level-1 .oo-ui-iconElement-icon {
-  left: 2.5em;
+       left: 2.5em;
 }
 .oo-ui-optionWidget-level-2 {
-  padding-left: 6.5em;
+       padding-left: 6.5em;
 }
 .oo-ui-optionWidget-level-2 .oo-ui-iconElement-icon {
-  left: 4em;
+       left: 4em;
 }
 .oo-ui-decoratedOptionWidget .oo-ui-iconElement-icon,
 .oo-ui-decoratedOptionWidget .oo-ui-indicatorElement-indicator {
-  position: absolute;
-  background-repeat: no-repeat;
-  background-position: center center;
+       position: absolute;
+       background-repeat: no-repeat;
+       background-position: center center;
 }
 .oo-ui-decoratedOptionWidget .oo-ui-iconElement-icon,
 .oo-ui-decoratedOptionWidget .oo-ui-indicatorElement-indicator {
-  top: 50%;
-  width: 2em;
-  height: 2em;
-  margin-top: -1em;
+       top: 50%;
+       width: 2em;
+       height: 2em;
+       margin-top: -1em;
 }
 .oo-ui-decoratedOptionWidget .oo-ui-iconElement-icon {
-  left: 0.5em;
+       left: 0.5em;
 }
 .oo-ui-decoratedOptionWidget .oo-ui-indicatorElement-indicator {
-  right: 0.5em;
+       right: 0.5em;
 }
 .oo-ui-buttonSelectWidget {
-  display: inline-block;
-  white-space: nowrap;
+       display: inline-block;
+       white-space: nowrap;
 }
 .oo-ui-buttonOptionWidget {
-  display: inline-block;
-  padding: 0;
-  background-color: transparent;
+       display: inline-block;
+       padding: 0;
+       background-color: transparent;
 }
 .oo-ui-buttonOptionWidget .oo-ui-buttonElement-button {
-  position: relative;
+       position: relative;
 }
 .oo-ui-buttonOptionWidget.oo-ui-iconElement .oo-ui-iconElement-icon,
 .oo-ui-buttonOptionWidget.oo-ui-indicatorElement .oo-ui-indicatorElement-indicator {
-  position: static;
-  display: inline-block;
-  vertical-align: middle;
+       position: static;
+       display: inline-block;
+       vertical-align: middle;
 }
 .oo-ui-buttonOptionWidget .oo-ui-buttonElement-button {
-  height: 1.9em;
+       height: 1.9em;
 }
 .oo-ui-buttonOptionWidget.oo-ui-iconElement .oo-ui-iconElement-icon,
 .oo-ui-buttonOptionWidget.oo-ui-indicatorElement .oo-ui-indicatorElement-indicator {
-  height: 1.9em;
-  margin-top: 0;
+       height: 1.9em;
+       margin-top: 0;
 }
 .oo-ui-labelWidget {
-  display: inline-block;
-  padding: 0.5em 0;
+       display: inline-block;
+       padding: 0.5em 0;
 }
 .oo-ui-iconWidget {
-  display: inline-block;
-  vertical-align: middle;
-  background-position: center center;
-  background-repeat: no-repeat;
-  line-height: 2.5em;
-  height: 1.9em;
-  width: 1.9em;
-  opacity: 0.8;
+       display: inline-block;
+       vertical-align: middle;
+       background-position: center center;
+       background-repeat: no-repeat;
+       line-height: 2.5em;
+       height: 1.9em;
+       width: 1.9em;
+       opacity: 0.8;
 }
 .oo-ui-iconWidget.oo-ui-widget-disabled {
-  opacity: 0.2;
+       opacity: 0.2;
 }
 .oo-ui-indicatorWidget {
-  display: inline-block;
-  vertical-align: middle;
-  background-position: center center;
-  background-repeat: no-repeat;
-  line-height: 2.5em;
-  height: 1.9em;
-  width: 1.9em;
-  opacity: 0.8;
+       display: inline-block;
+       vertical-align: middle;
+       background-position: center center;
+       background-repeat: no-repeat;
+       line-height: 2.5em;
+       height: 1.9em;
+       width: 1.9em;
+       opacity: 0.8;
 }
 .oo-ui-indicatorWidget.oo-ui-widget-disabled {
-  opacity: 0.2;
+       opacity: 0.2;
 }
 .oo-ui-buttonWidget {
-  display: inline-block;
-  vertical-align: middle;
+       display: inline-block;
+       vertical-align: middle;
 }
 .oo-ui-buttonGroupWidget {
-  border-radius: 0.3em;
+       border-radius: 0.3em;
 }
 .oo-ui-buttonGroupWidget .oo-ui-buttonElement-framed .oo-ui-buttonElement-button {
-  border-radius: 0;
-  margin-bottom: -1px;
-  margin-left: -1px;
+       border-radius: 0;
+       margin-bottom: -1px;
+       margin-left: -1px;
 }
 .oo-ui-buttonGroupWidget .oo-ui-buttonElement-framed:first-child .oo-ui-buttonElement-button {
-  border-bottom-left-radius: 0.3em;
-  border-top-left-radius: 0.3em;
-  margin-left: 0;
+       border-bottom-left-radius: 0.3em;
+       border-top-left-radius: 0.3em;
+       margin-left: 0;
 }
 .oo-ui-buttonGroupWidget .oo-ui-buttonElement-framed:last-child .oo-ui-buttonElement-button {
-  border-bottom-right-radius: 0.3em;
-  border-top-right-radius: 0.3em;
+       border-bottom-right-radius: 0.3em;
+       border-top-right-radius: 0.3em;
 }
 .oo-ui-toggleSwitchWidget {
-  position: relative;
-  display: inline-block;
-  vertical-align: middle;
-  overflow: hidden;
-  cursor: pointer;
-  -webkit-box-sizing: border-box;
-  -moz-box-sizing: border-box;
-  box-sizing: border-box;
-  -webkit-transform: translateZ(0px);
-  -moz-transform: translateZ(0px);
-  -ms-transform: translateZ(0px);
-  -o-transform: translateZ(0px);
-  transform: translateZ(0px);
-  height: 2em;
-  width: 4em;
+       position: relative;
+       display: inline-block;
+       vertical-align: middle;
+       overflow: hidden;
+       cursor: pointer;
+       -webkit-box-sizing: border-box;
+          -moz-box-sizing: border-box;
+               box-sizing: border-box;
+       -webkit-transform: translateZ(0px);
+          -moz-transform: translateZ(0px);
+           -ms-transform: translateZ(0px);
+            -o-transform: translateZ(0px);
+               transform: translateZ(0px);
+       height: 2em;
+       width: 4em;
 }
 .oo-ui-toggleSwitchWidget.oo-ui-widget-disabled {
-  cursor: default;
+       cursor: default;
 }
 .oo-ui-toggleSwitchWidget-grip {
-  position: absolute;
-  display: block;
-  -webkit-box-sizing: border-box;
-  -moz-box-sizing: border-box;
-  box-sizing: border-box;
+       position: absolute;
+       display: block;
+       -webkit-box-sizing: border-box;
+          -moz-box-sizing: border-box;
+               box-sizing: border-box;
 }
 .oo-ui-toggleSwitchWidget .oo-ui-toggleSwitchWidget-glow {
-  position: absolute;
-  top: 0;
-  bottom: 0;
-  right: 0;
-  left: 0;
-  -webkit-touch-callout: none;
-  -webkit-user-select: none;
-  -moz-user-select: none;
-  -ms-user-select: none;
-  user-select: none;
+       position: absolute;
+       top: 0;
+       bottom: 0;
+       right: 0;
+       left: 0;
+       -webkit-touch-callout: none;
+       -webkit-user-select: none;
+          -moz-user-select: none;
+           -ms-user-select: none;
+               user-select: none;
 }
 .oo-ui-toggleWidget-off .oo-ui-toggleSwitchWidget-glow {
-  display: none;
+       display: none;
 }
 .oo-ui-toggleSwitchWidget-grip {
-  top: 0.25em;
-  left: 0.25em;
-  width: 1.5em;
-  height: 1.5em;
-  margin-top: -1px;
-  -webkit-transition: left 200ms ease-in-out, margin-left 200ms ease-in-out;
-  -moz-transition: left 200ms ease-in-out, margin-left 200ms ease-in-out;
-  -ms-transition: left 200ms ease-in-out, margin-left 200ms ease-in-out;
-  -o-transition: left 200ms ease-in-out, margin-left 200ms ease-in-out;
-  transition: left 200ms ease-in-out, margin-left 200ms ease-in-out;
+       top: 0.25em;
+       left: 0.25em;
+       width: 1.5em;
+       height: 1.5em;
+       margin-top: -1px;
+       -webkit-transition: left 200ms ease-in-out, margin-left 200ms ease-in-out;
+          -moz-transition: left 200ms ease-in-out, margin-left 200ms ease-in-out;
+           -ms-transition: left 200ms ease-in-out, margin-left 200ms ease-in-out;
+            -o-transition: left 200ms ease-in-out, margin-left 200ms ease-in-out;
+               transition: left 200ms ease-in-out, margin-left 200ms ease-in-out;
 }
 .oo-ui-toggleSwitchWidget .oo-ui-toggleSwitchWidget-glow {
-  -webkit-transition: opacity 200ms ease-in-out;
-  -moz-transition: opacity 200ms ease-in-out;
-  -ms-transition: opacity 200ms ease-in-out;
-  -o-transition: opacity 200ms ease-in-out;
-  transition: opacity 200ms ease-in-out;
+       -webkit-transition: opacity 200ms ease-in-out;
+          -moz-transition: opacity 200ms ease-in-out;
+           -ms-transition: opacity 200ms ease-in-out;
+            -o-transition: opacity 200ms ease-in-out;
+               transition: opacity 200ms ease-in-out;
 }
 .oo-ui-toggleWidget-on .oo-ui-toggleSwitchWidget-grip {
-  left: 2.25em;
-  margin-left: -2px;
+       left: 2.25em;
+       margin-left: -2px;
 }
 .oo-ui-toggleWidget-off .oo-ui-toggleSwitchWidget-grip {
-  left: 0.25em;
-  margin-left: 0;
+       left: 0.25em;
+       margin-left: 0;
+}
+.oo-ui-actionWidget.oo-ui-pendingElement-pending {
+       background-image: /* @embed */ url(images/textures/pending.gif);
 }
 .oo-ui-popupWidget-popup {
-  position: absolute;
-  overflow: hidden;
-  z-index: 1;
+       position: absolute;
+       overflow: hidden;
+       z-index: 1;
 }
 .oo-ui-popupWidget-anchor {
-  display: none;
-  z-index: 1;
+       display: none;
+       z-index: 1;
 }
 .oo-ui-popupWidget-anchored .oo-ui-popupWidget-anchor {
-  display: block;
-  position: absolute;
-  background-repeat: no-repeat;
+       display: block;
+       position: absolute;
+       background-repeat: no-repeat;
 }
 .oo-ui-popupWidget-head {
-  -webkit-touch-callout: none;
-  -webkit-user-select: none;
-  -moz-user-select: none;
-  -ms-user-select: none;
-  user-select: none;
+       -webkit-touch-callout: none;
+       -webkit-user-select: none;
+          -moz-user-select: none;
+           -ms-user-select: none;
+               user-select: none;
 }
 .oo-ui-popupWidget-head .oo-ui-buttonWidget {
-  float: right;
+       float: right;
 }
 .oo-ui-popupWidget-head .oo-ui-labelElement-label {
-  float: left;
-  cursor: default;
+       float: left;
+       cursor: default;
 }
 .oo-ui-popupWidget-body {
-  clear: both;
-  overflow: hidden;
+       clear: both;
+       overflow: hidden;
 }
 .oo-ui-popupWidget-anchored .oo-ui-popupWidget-popup {
-  margin-top: 7px;
+       margin-top: 7px;
 }
 .oo-ui-popupWidget-head {
-  height: 2.5em;
+       height: 2.5em;
 }
 .oo-ui-popupWidget-head .oo-ui-buttonWidget {
-  margin: 0.25em;
+       margin: 0.25em;
 }
 .oo-ui-popupWidget-head .oo-ui-labelElement-label {
-  margin: 0.75em 1em;
+       margin: 0.75em 1em;
 }
 .oo-ui-popupWidget-body-padded {
-  padding: 0 1em;
+       padding: 0 1em;
 }
 .oo-ui-popupButtonWidget {
-  position: relative;
+       position: relative;
 }
 .oo-ui-popupButtonWidget .oo-ui-popupWidget {
-  position: absolute;
-  left: 1em;
-  cursor: auto;
+       position: absolute;
+       left: 1em;
+       cursor: auto;
 }
 .oo-ui-lookupInputWidget-menu {
-  background-color: #fff;
+       background-color: #ffffff;
 }
 .oo-ui-textInputWidget {
-  position: relative;
-  -webkit-box-sizing: border-box;
-  -moz-box-sizing: border-box;
-  box-sizing: border-box;
+       position: relative;
+       -webkit-box-sizing: border-box;
+          -moz-box-sizing: border-box;
+               box-sizing: border-box;
 }
 .oo-ui-textInputWidget input,
 .oo-ui-textInputWidget textarea {
-  display: inline-block;
-  width: 100%;
-  resize: none;
-  -webkit-box-sizing: border-box;
-  -moz-box-sizing: border-box;
-  box-sizing: border-box;
+       display: inline-block;
+       width: 100%;
+       resize: none;
+       -webkit-box-sizing: border-box;
+          -moz-box-sizing: border-box;
+               box-sizing: border-box;
+}
+.oo-ui-textInputWidget.oo-ui-pendingElement-pending input,
+.oo-ui-textInputWidget.oo-ui-pendingElement-pending textarea {
+       background-image: /* @embed */ url(images/textures/pending.gif);
 }
 .oo-ui-textInputWidget > .oo-ui-iconElement-icon,
 .oo-ui-textInputWidget > .oo-ui-indicatorElement-indicator {
-  position: absolute;
-  top: 0;
-  height: 100%;
-  background-repeat: no-repeat;
-  cursor: pointer;
-  -webkit-touch-callout: none;
-  -webkit-user-select: none;
-  -moz-user-select: none;
-  -ms-user-select: none;
-  user-select: none;
+       position: absolute;
+       top: 0;
+       height: 100%;
+       background-repeat: no-repeat;
+       cursor: pointer;
+       -webkit-touch-callout: none;
+       -webkit-user-select: none;
+          -moz-user-select: none;
+           -ms-user-select: none;
+               user-select: none;
 }
 .oo-ui-textInputWidget > .oo-ui-iconElement-icon {
-  left: 0;
+       left: 0;
 }
 .oo-ui-textInputWidget > .oo-ui-indicatorElement-indicator {
-  right: 0;
+       right: 0;
 }
 .oo-ui-textInputWidget input,
 .oo-ui-textInputWidget textarea {
-  padding: .8em 1em;
+       padding: 0.8em 1em;
 }
 .oo-ui-menuWidget {
-  position: absolute;
-  background: white;
-  border: solid 1px #dddddd;
+       position: absolute;
+       background: white;
+       border: solid 1px #dddddd;
 }
 .oo-ui-menuWidget input {
-  position: absolute;
-  width: 0;
-  height: 0;
-  overflow: hidden;
-  opacity: 0;
+       position: absolute;
+       width: 0;
+       height: 0;
+       overflow: hidden;
+       opacity: 0;
 }
 .oo-ui-menuItemWidget {
-  position: relative;
+       position: relative;
 }
 .oo-ui-menuItemWidget .oo-ui-iconElement-icon {
-  display: none;
+       display: none;
 }
 .oo-ui-menuItemWidget.oo-ui-optionWidget-selected {
-  background-color: transparent;
+       background-color: transparent;
 }
 .oo-ui-menuItemWidget.oo-ui-optionWidget-selected .oo-ui-iconElement-icon {
-  display: block;
+       display: block;
 }
 .oo-ui-menuItemWidget.oo-ui-optionWidget-selected {
-  background: #347bff;
-  color: #ffffff;
+       background: #347bff;
+       color: #ffffff;
 }
 .oo-ui-menuItemWidget .oo-ui-iconElement-icon {
-  background-size: 24px auto;
+       background-size: 24px auto;
 }
 .oo-ui-menuSectionItemWidget {
-  cursor: default;
-  font-weight: normal;
-  color: #777777;
-  border: none;
+       cursor: default;
+       font-weight: normal;
+       color: #777777;
+       border: none;
 }
 .oo-ui-inlineMenuWidget {
-  position: relative;
-  display: inline-block;
-  margin: 0.25em 0;
-  min-width: 20em;
+       position: relative;
+       display: inline-block;
+       margin: 0.25em 0;
+       min-width: 20em;
 }
 .oo-ui-inlineMenuWidget-handle {
-  width: 100%;
-  display: inline-block;
-  cursor: pointer;
-  -webkit-touch-callout: none;
-  -webkit-user-select: none;
-  -moz-user-select: none;
-  -ms-user-select: none;
-  user-select: none;
-  -webkit-box-sizing: border-box;
-  -moz-box-sizing: border-box;
-  box-sizing: border-box;
+       width: 100%;
+       display: inline-block;
+       cursor: pointer;
+       -webkit-touch-callout: none;
+       -webkit-user-select: none;
+          -moz-user-select: none;
+           -ms-user-select: none;
+               user-select: none;
+       -webkit-box-sizing: border-box;
+          -moz-box-sizing: border-box;
+               box-sizing: border-box;
 }
 .oo-ui-inlineMenuWidget-handle .oo-ui-indicatorElement-indicator,
 .oo-ui-inlineMenuWidget-handle .oo-ui-iconElement-icon {
-  position: absolute;
-  background-position: center center;
-  background-repeat: no-repeat;
+       position: absolute;
+       background-position: center center;
+       background-repeat: no-repeat;
 }
 .oo-ui-inlineMenuWidget .oo-ui-menuWidget {
-  z-index: 1;
-  width: 100%;
+       z-index: 1;
+       width: 100%;
 }
 .oo-ui-inlineMenuWidget.oo-ui-widget-disabled .oo-ui-inlineMenuWidget-handle {
-  cursor: default;
+       cursor: default;
 }
 .oo-ui-inlineMenuWidget-handle {
-  height: 2.5em;
+       height: 2.5em;
 }
 .oo-ui-inlineMenuWidget-handle .oo-ui-indicatorElement-indicator,
 .oo-ui-inlineMenuWidget-handle .oo-ui-iconElement-icon {
-  top: 0;
-  width: 2.5em;
-  height: 2.5em;
+       top: 0;
+       width: 2.5em;
+       height: 2.5em;
 }
 .oo-ui-inlineMenuWidget-handle .oo-ui-indicatorElement-indicator {
-  right: 0;
+       right: 0;
 }
 .oo-ui-inlineMenuWidget-handle .oo-ui-iconElement-icon {
-  left: 0.25em;
+       left: 0.25em;
 }
 .oo-ui-inlineMenuWidget-handle .oo-ui-labelElement-label {
-  line-height: 2.5em;
-  margin: 0 0.5em;
+       line-height: 2.5em;
+       margin: 0 0.5em;
 }
 .oo-ui-inlineMenuWidget.oo-ui-iconElement .oo-ui-inlineMenuWidget-handle .oo-ui-labelElement-label {
-  margin-left: 3em;
+       margin-left: 3em;
 }
 .oo-ui-inlineMenuWidget.oo-ui-indicatorElement .oo-ui-inlineMenuWidget-handle .oo-ui-labelElement-label {
-  margin-right: 2em;
+       margin-right: 2em;
 }
 .oo-ui-outlineItemWidget {
-  position: relative;
-  cursor: pointer;
-  -webkit-touch-callout: none;
-  -webkit-user-select: none;
-  -moz-user-select: none;
-  -ms-user-select: none;
-  user-select: none;
-  padding: 0.75em;
+       position: relative;
+       cursor: pointer;
+       -webkit-touch-callout: none;
+       -webkit-user-select: none;
+          -moz-user-select: none;
+           -ms-user-select: none;
+               user-select: none;
+       padding: 0.75em;
 }
 .oo-ui-outlineControlsWidget {
-  height: 3em;
+       height: 3em;
 }
 .oo-ui-outlineControlsWidget-items,
 .oo-ui-outlineControlsWidget-movers {
-  float: left;
-  -webkit-box-sizing: border-box;
-  -moz-box-sizing: border-box;
-  box-sizing: border-box;
+       float: left;
+       -webkit-box-sizing: border-box;
+          -moz-box-sizing: border-box;
+               box-sizing: border-box;
 }
 .oo-ui-outlineControlsWidget > .oo-ui-iconElement-icon {
-  float: left;
-  background-position: right center;
-  background-repeat: no-repeat;
+       float: left;
+       background-position: right center;
+       background-repeat: no-repeat;
 }
 .oo-ui-outlineControlsWidget-items {
-  float: left;
+       float: left;
 }
 .oo-ui-outlineControlsWidget-items .oo-ui-buttonWidget {
-  float: left;
+       float: left;
 }
 .oo-ui-outlineControlsWidget-movers {
-  float: right;
+       float: right;
 }
 .oo-ui-outlineControlsWidget-movers .oo-ui-buttonWidget {
-  float: right;
+       float: right;
 }
 .oo-ui-outlineControlsWidget-items,
 .oo-ui-outlineControlsWidget-movers {
-  height: 2em;
-  margin: 0.5em;
-  padding: 0;
+       height: 2em;
+       margin: 0.5em;
+       padding: 0;
 }
 .oo-ui-outlineControlsWidget > .oo-ui-iconElement-icon {
-  width: 1.5em;
-  height: 2em;
-  margin: 0.5em 0 0.5em 0.5em;
+       width: 1.5em;
+       height: 2em;
+       margin: 0.5em 0 0.5em 0.5em;
 }
 .oo-ui-outlineControlsWidget-items {
-  margin-left: 0;
+       margin-left: 0;
 }
 .oo-ui-comboBoxWidget > .oo-ui-selectWidget {
-  z-index: 1;
+       z-index: 1;
 }
 .oo-ui-comboBoxWidget > .oo-ui-selectWidget > .oo-ui-selectWidget {
-  min-width: 20em;
+       min-width: 20em;
 }
 .oo-ui-searchWidget-query {
-  position: absolute;
-  top: 0;
-  left: 0;
-  right: 0;
+       position: absolute;
+       top: 0;
+       left: 0;
+       right: 0;
 }
 .oo-ui-searchWidget-query .oo-ui-textInputWidget {
-  width: 100%;
+       width: 100%;
 }
 .oo-ui-searchWidget-results {
-  position: absolute;
-  bottom: 0;
-  left: 0;
-  right: 0;
-  overflow-x: hidden;
-  overflow-y: auto;
+       position: absolute;
+       bottom: 0;
+       left: 0;
+       right: 0;
+       overflow-x: hidden;
+       overflow-y: auto;
 }
 .oo-ui-searchWidget-query {
-  height: 4em;
-  padding: 0 1em;
+       height: 4em;
+       padding: 0 1em;
 }
 .oo-ui-searchWidget-query .oo-ui-textInputWidget {
-  margin: 0.75em 0;
+       margin: 0.75em 0;
 }
 .oo-ui-searchWidget-results {
-  top: 4em;
-  padding: 1em;
-  line-height: 0;
+       top: 4em;
+       padding: 1em;
+       line-height: 0;
 }
 .oo-ui-window {
-  line-height: 1em;
-  /* Content div takes focus when opened, so hide outline */
+       line-height: 1em;
+       /* Content div takes focus when opened, so hide outline */
 }
 .oo-ui-window-frame {
-  -webkit-box-sizing: border-box;
-  -moz-box-sizing: border-box;
-  box-sizing: border-box;
+       -webkit-box-sizing: border-box;
+          -moz-box-sizing: border-box;
+               box-sizing: border-box;
 }
 .oo-ui-window-frame > iframe {
-  width: 100%;
-  height: 100%;
-  margin: 0;
-  padding: 0;
+       width: 100%;
+       height: 100%;
+       margin: 0;
+       padding: 0;
 }
 .oo-ui-window-content:focus {
-  outline: none;
+       outline: none;
 }
 .oo-ui-window-head,
 .oo-ui-window-foot {
-  -webkit-touch-callout: none;
-  -webkit-user-select: none;
-  -moz-user-select: none;
-  -ms-user-select: none;
-  user-select: none;
+       -webkit-touch-callout: none;
+       -webkit-user-select: none;
+          -moz-user-select: none;
+           -ms-user-select: none;
+               user-select: none;
 }
 .oo-ui-window-body {
-  margin: 0;
-  padding: 0;
-  background: none;
+       margin: 0;
+       padding: 0;
+       background: none;
 }
 .oo-ui-window-overlay {
-  position: absolute;
-  top: 0;
-  left: 0;
+       position: absolute;
+       top: 0;
+       left: 0;
 }
 .oo-ui-dialog-content > .oo-ui-window-head,
 .oo-ui-dialog-content > .oo-ui-window-body,
 .oo-ui-dialog-content > .oo-ui-window-foot {
-  position: absolute;
-  left: 0;
-  right: 0;
-  overflow: hidden;
-  -webkit-box-sizing: border-box;
-  -moz-box-sizing: border-box;
-  box-sizing: border-box;
+       position: absolute;
+       left: 0;
+       right: 0;
+       overflow: hidden;
+       -webkit-box-sizing: border-box;
+          -moz-box-sizing: border-box;
+               box-sizing: border-box;
 }
 .oo-ui-dialog-content > .oo-ui-window-head {
-  z-index: 1;
-  top: 0;
+       z-index: 1;
+       top: 0;
+}
+.oo-ui-dialog-content > .oo-ui-window-head.oo-ui-pendingElement-pending {
+       background-image: /* @embed */ url(images/textures/pending.gif);
 }
 .oo-ui-dialog-content > .oo-ui-window-body {
-  z-index: 2;
-  top: 0;
-  bottom: 0;
+       z-index: 2;
+       top: 0;
+       bottom: 0;
 }
 .oo-ui-dialog-content > .oo-ui-window-foot {
-  z-index: 1;
-  bottom: 0;
+       z-index: 1;
+       bottom: 0;
 }
 .oo-ui-dialog-content > .oo-ui-window-overlay {
-  z-index: 3;
+       z-index: 3;
 }
 .oo-ui-messageDialog-actions-horizontal {
-  display: table;
-  table-layout: fixed;
-  width: 100%;
+       display: table;
+       table-layout: fixed;
+       width: 100%;
 }
 .oo-ui-messageDialog-actions-horizontal .oo-ui-actionWidget {
-  display: table-cell;
-  width: 1%;
+       display: table-cell;
+       width: 1%;
 }
 .oo-ui-messageDialog-actions-vertical {
-  display: block;
+       display: block;
 }
 .oo-ui-messageDialog-actions-vertical .oo-ui-actionWidget {
-  display: block;
-  overflow: hidden;
-  text-overflow: ellipsis;
+       display: block;
+       overflow: hidden;
+       text-overflow: ellipsis;
 }
 .oo-ui-messageDialog-actions .oo-ui-actionWidget {
-  position: relative;
-  text-align: center;
+       position: relative;
+       text-align: center;
 }
 .oo-ui-messageDialog-actions .oo-ui-actionWidget .oo-ui-buttonElement-button {
-  display: block;
+       display: block;
 }
 .oo-ui-messageDialog-actions .oo-ui-actionWidget .oo-ui-labelElement-label {
-  position: relative;
-  top: auto;
-  bottom: auto;
-  display: inline;
-  white-space: nowrap;
+       position: relative;
+       top: auto;
+       bottom: auto;
+       display: inline;
+       white-space: nowrap;
 }
 .oo-ui-messageDialog-title,
 .oo-ui-messageDialog-message {
-  display: block;
-  text-align: center;
-  padding-top: 0.5em;
+       display: block;
+       text-align: center;
+       padding-top: 0.5em;
 }
 .oo-ui-messageDialog-title {
-  font-size: 1.5em;
-  line-height: 1em;
-  color: #000;
+       font-size: 1.5em;
+       line-height: 1em;
+       color: #000000;
 }
 .oo-ui-messageDialog-message {
-  font-size: 0.9em;
-  line-height: 1.25em;
-  color: #666;
+       font-size: 0.9em;
+       line-height: 1.25em;
+       color: #666666;
 }
 .oo-ui-messageDialog-message-verbose {
-  font-size: 1.1em;
-  line-height: 1.5em;
-  text-align: left;
+       font-size: 1.1em;
+       line-height: 1.5em;
+       text-align: left;
 }
 .oo-ui-messageDialog-actions-horizontal .oo-ui-actionWidget {
-  border-right: solid 1px #e5e5e5;
+       border-right: solid 1px #e5e5e5;
 }
 .oo-ui-messageDialog-actions-horizontal .oo-ui-actionWidget:last-child {
-  border-right-width: 0;
+       border-right-width: 0;
 }
 .oo-ui-messageDialog-actions-vertical .oo-ui-actionWidget {
-  border-bottom: solid 1px #e5e5e5;
+       border-bottom: solid 1px #e5e5e5;
 }
 .oo-ui-messageDialog-actions-vertical .oo-ui-actionWidget:last-child {
-  border-bottom-width: 0;
+       border-bottom-width: 0;
 }
 .oo-ui-messageDialog-actions .oo-ui-actionWidget .oo-ui-labelElement-label {
-  text-align: center;
-  line-height: 3.4em;
-  padding: 0 2em;
+       text-align: center;
+       line-height: 3.4em;
+       padding: 0 2em;
 }
 .oo-ui-messageDialog-actions .oo-ui-actionWidget:hover {
-  background-color: rgba(0, 0, 0, 0.05);
+       background-color: rgba(0, 0, 0, 0.05);
 }
 .oo-ui-messageDialog-actions .oo-ui-actionWidget:active {
-  background-color: rgba(0, 0, 0, 0.1);
+       background-color: rgba(0, 0, 0, 0.1);
 }
 .oo-ui-messageDialog-actions .oo-ui-actionWidget.oo-ui-flaggedElement-primary:hover {
-  background-color: rgba(8, 126, 204, 0.05);
+       background-color: rgba(8, 126, 204, 0.05);
 }
 .oo-ui-messageDialog-actions .oo-ui-actionWidget.oo-ui-flaggedElement-primary:active {
-  background-color: rgba(8, 126, 204, 0.1);
+       background-color: rgba(8, 126, 204, 0.1);
 }
 .oo-ui-messageDialog-actions .oo-ui-actionWidget.oo-ui-flaggedElement-primary .oo-ui-labelElement-label {
-  font-weight: bold;
+       font-weight: bold;
 }
 .oo-ui-messageDialog-actions .oo-ui-actionWidget.oo-ui-flaggedElement-constructive:hover {
-  background-color: rgba(118, 171, 54, 0.05);
+       background-color: rgba(118, 171, 54, 0.05);
 }
 .oo-ui-messageDialog-actions .oo-ui-actionWidget.oo-ui-flaggedElement-constructive:active {
-  background-color: rgba(118, 171, 54, 0.1);
+       background-color: rgba(118, 171, 54, 0.1);
 }
 .oo-ui-messageDialog-actions .oo-ui-actionWidget.oo-ui-flaggedElement-destructive:hover {
-  background-color: rgba(212, 83, 83, 0.05);
+       background-color: rgba(212, 83, 83, 0.05);
 }
 .oo-ui-messageDialog-actions .oo-ui-actionWidget.oo-ui-flaggedElement-destructive:active {
-  background-color: rgba(212, 83, 83, 0.1);
+       background-color: rgba(212, 83, 83, 0.1);
 }
 .oo-ui-processDialog-location {
-  overflow: hidden;
-  text-overflow: ellipsis;
-  white-space: nowrap;
+       overflow: hidden;
+       text-overflow: ellipsis;
+       white-space: nowrap;
 }
 .oo-ui-processDialog-title {
-  display: inline;
-  padding: 0;
+       display: inline;
+       padding: 0;
 }
 .oo-ui-processDialog-actions-safe .oo-ui-actionWidget,
 .oo-ui-processDialog-actions-primary .oo-ui-actionWidget,
 .oo-ui-processDialog-actions-other .oo-ui-actionWidget {
-  white-space: nowrap;
+       white-space: nowrap;
 }
 .oo-ui-processDialog-actions-safe,
 .oo-ui-processDialog-actions-primary {
-  position: absolute;
-  top: 0;
-  bottom: 0;
+       position: absolute;
+       top: 0;
+       bottom: 0;
 }
 .oo-ui-processDialog-actions-safe {
-  left: 0;
+       left: 0;
 }
 .oo-ui-processDialog-actions-primary {
-  right: 0;
+       right: 0;
 }
 .oo-ui-processDialog-errors {
-  display: none;
-  position: absolute;
-  top: 0;
-  left: 0;
-  right: 0;
-  bottom: 0;
-  z-index: 2;
-  overflow-x: hidden;
-  overflow-y: auto;
+       display: none;
+       position: absolute;
+       top: 0;
+       left: 0;
+       right: 0;
+       bottom: 0;
+       z-index: 2;
+       overflow-x: hidden;
+       overflow-y: auto;
 }
 .oo-ui-processDialog-content .oo-ui-window-head {
-  height: 3.35em;
-  border-bottom: 1px solid #dddddd;
-  -webkit-box-sizing: border-box;
-  -moz-box-sizing: border-box;
-  box-sizing: border-box;
+       height: 3.35em;
+       border-bottom: 1px solid #dddddd;
+       -webkit-box-sizing: border-box;
+          -moz-box-sizing: border-box;
+               box-sizing: border-box;
 }
 .oo-ui-processDialog-content .oo-ui-window-body {
-  top: 3.35em;
-  padding: 2em 0;
+       top: 3.35em;
+       padding: 2em 0;
 }
 .oo-ui-processDialog-navigation {
-  position: relative;
-  height: 3.35em;
-  padding: 0 1em;
+       position: relative;
+       height: 3.35em;
+       padding: 0 1em;
 }
 .oo-ui-processDialog-location {
-  padding: 0.75em 0;
-  height: 1.85em;
-  cursor: default;
-  text-align: center;
+       padding: 0.75em 0;
+       height: 1.85em;
+       cursor: default;
+       text-align: center;
 }
 .oo-ui-processDialog-title {
-  font-weight: bold;
-  line-height: 1.85em;
+       font-weight: bold;
+       line-height: 1.85em;
 }
 .oo-ui-processDialog-actions-safe .oo-ui-actionWidget .oo-ui-buttonElement-button,
 .oo-ui-processDialog-actions-primary .oo-ui-actionWidget .oo-ui-buttonElement-button,
 .oo-ui-processDialog-actions-other .oo-ui-actionWidget .oo-ui-buttonElement-button {
-  padding: 0.35em 0.75em;
-  min-width: 1.85em;
-  min-height: 1.85em;
-  border: 1px solid #dddddd;
-  border-radius: 4px;
+       padding: 0.35em 0.75em;
+       min-width: 1.85em;
+       min-height: 1.85em;
+       border: 1px solid #dddddd;
+       border-radius: 4px;
 }
 .oo-ui-processDialog-actions-safe .oo-ui-actionWidget .oo-ui-labelElement-label,
 .oo-ui-processDialog-actions-primary .oo-ui-actionWidget .oo-ui-labelElement-label,
 .oo-ui-processDialog-actions-other .oo-ui-actionWidget .oo-ui-labelElement-label {
-  line-height: 1.85em;
-  padding: 0 1em;
-  font-weight: bold;
-  color: #777777;
+       line-height: 1.85em;
+       padding: 0 1em;
+       font-weight: bold;
+       color: #777777;
 }
 .oo-ui-processDialog-actions-safe .oo-ui-actionWidget .oo-ui-iconElement-icon,
 .oo-ui-processDialog-actions-primary .oo-ui-actionWidget .oo-ui-iconElement-icon,
 .oo-ui-processDialog-actions-other .oo-ui-actionWidget .oo-ui-iconElement-icon {
-  position: absolute;
-  margin-top: -0.125em;
+       position: absolute;
+       margin-top: -0.125em;
 }
 .oo-ui-processDialog-actions-safe .oo-ui-actionWidget.oo-ui-buttonElement-framed .oo-ui-buttonElement-button,
 .oo-ui-processDialog-actions-primary .oo-ui-actionWidget.oo-ui-buttonElement-framed .oo-ui-buttonElement-button,
 .oo-ui-processDialog-actions-other .oo-ui-actionWidget.oo-ui-buttonElement-framed .oo-ui-buttonElement-button {
-  vertical-align: middle;
+       vertical-align: middle;
 }
 .oo-ui-processDialog-actions-safe .oo-ui-actionWidget.oo-ui-flaggedElement-destructive .oo-ui-buttonElement-button,
 .oo-ui-processDialog-actions-primary .oo-ui-actionWidget.oo-ui-flaggedElement-destructive .oo-ui-buttonElement-button,
 .oo-ui-processDialog-actions-other .oo-ui-actionWidget.oo-ui-flaggedElement-destructive .oo-ui-buttonElement-button {
-  border: 1px solid transparent;
+       border: 1px solid transparent;
 }
 .oo-ui-processDialog-actions-safe .oo-ui-actionWidget.oo-ui-flaggedElement-destructive .oo-ui-labelElement-label,
 .oo-ui-processDialog-actions-primary .oo-ui-actionWidget.oo-ui-flaggedElement-destructive .oo-ui-labelElement-label,
 .oo-ui-processDialog-actions-other .oo-ui-actionWidget.oo-ui-flaggedElement-destructive .oo-ui-labelElement-label {
-  color: #d11d13;
+       color: #d11d13;
 }
 .oo-ui-processDialog-actions-safe .oo-ui-actionWidget .oo-ui-buttonElement-button,
 .oo-ui-processDialog-actions-primary .oo-ui-actionWidget .oo-ui-buttonElement-button {
-  padding: 0.75em 0.35em;
-  border: none;
-  border-radius: 0;
+       padding: 0.75em 0.35em;
+       border: none;
+       border-radius: 0;
 }
 .oo-ui-processDialog-actions-safe .oo-ui-actionWidget.oo-ui-flaggedElement-primary .oo-ui-buttonElement-button,
 .oo-ui-processDialog-actions-primary .oo-ui-actionWidget.oo-ui-flaggedElement-primary .oo-ui-buttonElement-button {
-  background-color: #347bff;
+       background-color: #347bff;
 }
 .oo-ui-processDialog-actions-safe .oo-ui-actionWidget.oo-ui-flaggedElement-primary .oo-ui-labelElement-label,
 .oo-ui-processDialog-actions-primary .oo-ui-actionWidget.oo-ui-flaggedElement-primary .oo-ui-labelElement-label {
-  color: #ffffff;
+       color: #ffffff;
 }
 .oo-ui-processDialog-actions-safe .oo-ui-actionWidget.oo-ui-iconElement .oo-ui-iconElement-icon {
-  left: 0.5em;
+       left: 0.5em;
 }
 .oo-ui-processDialog-actions-safe .oo-ui-actionWidget.oo-ui-iconElement .oo-ui-labelElement-label {
-  padding-left: 2.25em;
+       padding-left: 2.25em;
 }
 .oo-ui-processDialog-actions-primary .oo-ui-actionWidget.oo-ui-iconElement .oo-ui-iconElement-icon {
-  right: 0.5em;
+       right: 0.5em;
 }
 .oo-ui-processDialog-actions-primary .oo-ui-actionWidget.oo-ui-iconElement .oo-ui-labelElement-label {
-  padding-right: 2.25em;
+       padding-right: 2.25em;
 }
 .oo-ui-processDialog-actions-other {
-  position: absolute;
-  bottom: 1em;
+       position: absolute;
+       bottom: 1em;
 }
 .oo-ui-processDialog > .oo-ui-window-frame {
-  min-height: 5em;
+       min-height: 5em;
 }
 .oo-ui-processDialog-errors {
-  background-color: rgba(255, 255, 255, 0.9);
-  padding: 3em 3em 1.5em 3em;
-  text-align: center;
+       background-color: rgba(255, 255, 255, 0.9);
+       padding: 3em 3em 1.5em 3em;
+       text-align: center;
 }
 .oo-ui-processDialog-errors .oo-ui-buttonWidget {
-  margin: 2em 1em 2em 1em;
+       margin: 2em 1em 2em 1em;
 }
 .oo-ui-processDialog-errors-title {
-  font-size: 1.5em;
-  color: #000;
-  margin-bottom: 2em;
+       font-size: 1.5em;
+       color: #000000;
+       margin-bottom: 2em;
 }
 .oo-ui-processDialog-error {
-  text-align: left;
-  margin: 1em;
-  padding: 1em;
-  border: solid 1px #ff9e9e;
-  background-color: #fff7f7;
-  border-radius: 0.25em;
+       text-align: left;
+       margin: 1em;
+       padding: 1em;
+       border: solid 1px #ff9e9e;
+       background-color: #fff7f7;
+       border-radius: 0.25em;
 }
 .oo-ui-windowManager-modal > .oo-ui-dialog {
-  position: fixed;
-  width: 0;
-  height: 0;
-  overflow: hidden;
+       position: fixed;
+       width: 0;
+       height: 0;
+       overflow: hidden;
 }
 .oo-ui-windowManager-modal > .oo-ui-dialog.oo-ui-window-setup {
-  width: auto;
-  height: auto;
-  top: 0;
-  right: 0;
-  bottom: 0;
-  left: 0;
-  padding: 1em;
+       width: auto;
+       height: auto;
+       top: 0;
+       right: 0;
+       bottom: 0;
+       left: 0;
+       padding: 1em;
 }
 .oo-ui-windowManager-modal > .oo-ui-dialog.oo-ui-window-setup > .oo-ui-window-frame {
-  position: fixed;
-  right: 0;
-  left: 0;
-  margin: auto;
-  overflow: hidden;
-  max-width: 100%;
-  max-height: 100%;
+       position: absolute;
+       right: 0;
+       left: 0;
+       margin: auto;
+       overflow: hidden;
+       max-width: 100%;
+       max-height: 100%;
 }
 .oo-ui-windowManager-modal > .oo-ui-dialog.oo-ui-window-setup > .oo-ui-window-frame > iframe {
-  width: 100%;
-  height: 100%;
+       width: 100%;
+       height: 100%;
 }
 .oo-ui-windowManager-fullscreen > .oo-ui-dialog > .oo-ui-window-frame {
-  width: 100%;
-  height: 100%;
-  top: 0;
-  bottom: 0;
+       width: 100%;
+       height: 100%;
+       top: 0;
+       bottom: 0;
 }
 .oo-ui-windowManager-modal > .oo-ui-dialog {
-  background-color: rgba(255, 255, 255, 0.5);
-  opacity: 0;
-  -webkit-transition: opacity 250ms ease-in-out;
-  -moz-transition: opacity 250ms ease-in-out;
-  -ms-transition: opacity 250ms ease-in-out;
-  -o-transition: opacity 250ms ease-in-out;
-  transition: opacity 250ms ease-in-out;
+       background-color: rgba(255, 255, 255, 0.5);
+       opacity: 0;
+       -webkit-transition: opacity 250ms ease-in-out;
+          -moz-transition: opacity 250ms ease-in-out;
+           -ms-transition: opacity 250ms ease-in-out;
+            -o-transition: opacity 250ms ease-in-out;
+               transition: opacity 250ms ease-in-out;
 }
 .oo-ui-windowManager-modal > .oo-ui-dialog > .oo-ui-window-frame {
-  top: 0;
-  bottom: 0;
-  background-color: #fff;
-  -webkit-transform: translate3d(0, -200%, 0);
-  -moz-transform: translate3d(0, -200%, 0);
-  -ms-transform: translate3d(0, -200%, 0);
-  -o-transform: translate3d(0, -200%, 0);
-  transform: translate3d(0, -200%, 0);
-  -webkit-transition: transform 250ms ease-in-out;
-  -moz-transition: transform 250ms ease-in-out;
-  -ms-transition: transform 250ms ease-in-out;
-  -o-transition: transform 250ms ease-in-out;
-  transition: transform 250ms ease-in-out;
+       top: 0;
+       bottom: 0;
+       background-color: #ffffff;
+       -webkit-transform: translate3d(0, -200%, 0);
+          -moz-transform: translate3d(0, -200%, 0);
+           -ms-transform: translate3d(0, -200%, 0);
+            -o-transform: translate3d(0, -200%, 0);
+               transform: translate3d(0, -200%, 0);
+       -webkit-transition: transform 250ms ease-in-out;
+          -moz-transition: transform 250ms ease-in-out;
+           -ms-transition: transform 250ms ease-in-out;
+            -o-transition: transform 250ms ease-in-out;
+               transition: transform 250ms ease-in-out;
 }
 .oo-ui-windowManager-modal > .oo-ui-dialog.oo-ui-window-ready {
-  opacity: 1;
+       opacity: 1;
 }
 .oo-ui-windowManager-modal > .oo-ui-dialog.oo-ui-window-ready > .oo-ui-window-frame {
-  -webkit-transform: translate3d(0, 0, 0);
-  -moz-transform: translate3d(0, 0, 0);
-  -ms-transform: translate3d(0, 0, 0);
-  -o-transform: translate3d(0, 0, 0);
-  transform: translate3d(0, 0, 0);
+       -webkit-transform: translate3d(0, 0, 0);
+          -moz-transform: translate3d(0, 0, 0);
+           -ms-transform: translate3d(0, 0, 0);
+            -o-transform: translate3d(0, 0, 0);
+               transform: translate3d(0, 0, 0);
 }
 .oo-ui-windowManager-modal.oo-ui-windowManager-floating > .oo-ui-dialog > .oo-ui-window-frame {
-  border: solid 1px #ccc;
-  border-radius: 0.5em;
-  box-shadow: 0 0.2em 1em rgba(0, 0, 0, 0.3);
+       border: solid 1px #cccccc;
+       border-radius: 0.5em;
+       box-shadow: 0 0.2em 1em rgba(0, 0, 0, 0.3);
 }
 
 /*
  * additional rules to the base styles.
  */
 .oo-ui-icon-check {
-  background-image: /* @embed */ url(themes/minerva/images/icons/check.png);
-  background: #347bff;
+       background-image: /* @embed */ url(themes/minerva/images/icons/check.png);
+       background: #347bff;
 }
diff --git a/resources/lib/oojs-ui/oojs-ui-minerva.rtl.css b/resources/lib/oojs-ui/oojs-ui-minerva.rtl.css
new file mode 100644 (file)
index 0000000..e452952
--- /dev/null
@@ -0,0 +1,1381 @@
+/*!
+ * OOjs UI v0.1.0
+ * https://www.mediawiki.org/wiki/OOjs_UI
+ *
+ * Copyright 2011–2014 OOjs Team and other contributors.
+ * Released under the MIT license
+ * http://oojs.mit-license.org
+ *
+ * Date: 2014-09-11T19:39:50Z
+ */
+/*
+ * Blank theme mixins.
+ *
+ * Base styles invoke these mixins at the end of their definitions. Override these mixins to add
+ * additional rules to the base styles.
+ */
+/*
+ * Base styles.
+ *
+ * Themes should include this file after defining their variables and mixins.
+ */
+/* @noflip */
+.oo-ui-rtl {
+  direction: rtl;
+}
+/* @noflip */
+.oo-ui-ltr {
+  direction: ltr;
+}
+.oo-ui-buttonElement > .oo-ui-buttonElement-button {
+  cursor: pointer;
+  display: inline-block;
+  vertical-align: middle;
+  -webkit-touch-callout: none;
+  -webkit-user-select: none;
+  -moz-user-select: none;
+  -ms-user-select: none;
+  user-select: none;
+}
+.oo-ui-buttonElement > .oo-ui-buttonElement-button > .oo-ui-iconElement-icon {
+  display: none;
+}
+.oo-ui-buttonElement > .oo-ui-buttonElement-button > .oo-ui-indicatorElement-indicator {
+  display: none;
+}
+.oo-ui-buttonElement.oo-ui-widget-disabled > .oo-ui-buttonElement-button {
+  cursor: default;
+}
+.oo-ui-buttonElement.oo-ui-indicatorElement > .oo-ui-buttonElement-button > .oo-ui-indicatorElement-indicator,
+.oo-ui-buttonElement.oo-ui-iconElement > .oo-ui-buttonElement-button > .oo-ui-iconElement-icon {
+  display: inline-block;
+  vertical-align: middle;
+  background-position: center center;
+  background-repeat: no-repeat;
+}
+.oo-ui-buttonElement-frameless {
+  display: inline-block;
+  position: relative;
+}
+.oo-ui-buttonElement-frameless > .oo-ui-buttonElement-button > .oo-ui-labelElement-label {
+  display: inline-block;
+  vertical-align: middle;
+}
+.oo-ui-buttonElement-framed > .oo-ui-buttonElement-button {
+  display: inline-block;
+  vertical-align: top;
+  text-align: center;
+}
+.oo-ui-buttonElement-framed > .oo-ui-buttonElement-button > .oo-ui-labelElement-label {
+  display: inline-block;
+  vertical-align: middle;
+}
+.oo-ui-buttonElement-framed.oo-ui-widget-disabled > .oo-ui-buttonElement-button,
+.oo-ui-buttonElement-framed.oo-ui-widget-disabled.oo-ui-buttonElement-active > .oo-ui-buttonElement-button,
+.oo-ui-buttonElement-framed.oo-ui-widget-disabled.oo-ui-buttonElement-pressed > .oo-ui-buttonElement-button {
+  cursor: default;
+}
+.oo-ui-buttonElement > .oo-ui-buttonElement-button > .oo-ui-iconElement-icon {
+  margin-right: 0;
+}
+.oo-ui-buttonElement > .oo-ui-buttonElement-button > .oo-ui-indicatorElement-indicator {
+  margin-left: -0.75em;
+}
+.oo-ui-buttonElement.oo-ui-indicatorElement .oo-ui-buttonElement-button > .oo-ui-indicatorElement-indicator,
+.oo-ui-buttonElement.oo-ui-iconElement .oo-ui-buttonElement-button > .oo-ui-iconElement-icon {
+  width: 3.35em;
+  height: 3.35em;
+  background-size: 2em auto;
+}
+.oo-ui-buttonElement-frameless > .oo-ui-buttonElement-button > .oo-ui-labelElement-label {
+  margin-right: 0.25em;
+}
+.oo-ui-buttonElement-framed > .oo-ui-buttonElement-button > .oo-ui-labelElement-label {
+  line-height: 1.9em;
+}
+.oo-ui-clippableElement-clippable {
+  -webkit-box-sizing: border-box;
+  -moz-box-sizing: border-box;
+  box-sizing: border-box;
+}
+.oo-ui-bookletLayout-stackLayout.oo-ui-stackLayout-continuous .oo-ui-panelLayout-scrollable {
+  overflow-y: hidden;
+}
+.oo-ui-bookletLayout-stackLayout .oo-ui-panelLayout {
+  width: 100%;
+  -webkit-box-sizing: border-box;
+  -moz-box-sizing: border-box;
+  box-sizing: border-box;
+}
+.oo-ui-bookletLayout-stackLayout .oo-ui-panelLayout-scrollable {
+  overflow-y: auto;
+}
+.oo-ui-bookletLayout-stackLayout .oo-ui-panelLayout-padded {
+  padding: 2em;
+}
+.oo-ui-bookletLayout-outlinePanel-editable .oo-ui-outlineWidget {
+  position: absolute;
+  top: 0;
+  right: 0;
+  left: 0;
+  bottom: 3em;
+  overflow-y: auto;
+}
+.oo-ui-bookletLayout-outlinePanel .oo-ui-outlineControlsWidget {
+  position: absolute;
+  bottom: 0;
+  right: 0;
+  left: 0;
+}
+.oo-ui-bookletLayout-stackLayout .oo-ui-panelLayout {
+  padding: 0 0 1em;
+}
+.oo-ui-fieldLayout {
+  margin-bottom: 1em;
+}
+.oo-ui-fieldLayout:before,
+.oo-ui-fieldLayout:after {
+  content: " ";
+  display: table;
+}
+.oo-ui-fieldLayout:after {
+  clear: both;
+}
+.oo-ui-fieldLayout.oo-ui-fieldLayout-align-left > .oo-ui-labelElement-label,
+.oo-ui-fieldLayout.oo-ui-fieldLayout-align-right > .oo-ui-labelElement-label {
+  display: block;
+  float: right;
+}
+.oo-ui-fieldLayout.oo-ui-fieldLayout-align-left > .oo-ui-fieldLayout-field,
+.oo-ui-fieldLayout.oo-ui-fieldLayout-align-right > .oo-ui-fieldLayout-field {
+  display: block;
+  float: right;
+}
+.oo-ui-fieldLayout.oo-ui-fieldLayout-align-right > .oo-ui-labelElement-label {
+  text-align: left;
+}
+.oo-ui-fieldLayout.oo-ui-fieldLayout-align-inline > .oo-ui-labelElement-label {
+  display: inline-block;
+  vertical-align: middle;
+}
+.oo-ui-fieldLayout.oo-ui-fieldLayout-align-inline > .oo-ui-fieldLayout-field {
+  display: inline-block;
+  vertical-align: middle;
+}
+.oo-ui-fieldLayout.oo-ui-fieldLayout-align-top > .oo-ui-labelElement-label {
+  display: inline-block;
+}
+.oo-ui-fieldLayout > .oo-ui-popupButtonWidget > .oo-ui-popupWidget > .oo-ui-popupWidget-popup {
+  z-index: 1;
+}
+.oo-ui-fieldLayout:last-child {
+  margin-bottom: 0;
+}
+.oo-ui-fieldLayout.oo-ui-fieldLayout-align-left > .oo-ui-labelElement-label,
+.oo-ui-fieldLayout.oo-ui-fieldLayout-align-right > .oo-ui-labelElement-label {
+  padding-top: 0.5em;
+  margin-left: 5%;
+  width: 35%;
+}
+.oo-ui-fieldLayout.oo-ui-fieldLayout-align-left > .oo-ui-fieldLayout-field,
+.oo-ui-fieldLayout.oo-ui-fieldLayout-align-right > .oo-ui-fieldLayout-field {
+  width: 60%;
+}
+.oo-ui-fieldLayout.oo-ui-fieldLayout-align-inline > .oo-ui-labelElement-label {
+  padding: 0.75em 0.5em 0.5em 0.5em;
+}
+.oo-ui-fieldLayout.oo-ui-fieldLayout-align-inline > .oo-ui-fieldLayout-field {
+  padding: 0.5em 0;
+}
+.oo-ui-fieldLayout.oo-ui-fieldLayout-align-top > .oo-ui-labelElement-label {
+  padding: 0.5em 0;
+}
+.oo-ui-fieldLayout > .oo-ui-popupButtonWidget > .oo-ui-buttonElement-button > .oo-ui-iconElement-icon {
+  margin-top: 0.25em;
+}
+.oo-ui-fieldLayout-disabled .oo-ui-labelElement-label {
+  color: #ccc;
+}
+.oo-ui-fieldsetLayout {
+  position: relative;
+  margin: 0;
+  padding: 0;
+}
+.oo-ui-fieldsetLayout.oo-ui-iconElement > .oo-ui-iconElement-icon {
+  display: block;
+  position: absolute;
+  background-position: center center;
+  background-repeat: no-repeat;
+}
+.oo-ui-fieldsetLayout.oo-ui-labelElement > .oo-ui-labelElement-label {
+  display: inline-block;
+}
+.oo-ui-fieldsetLayout + .oo-ui-fieldsetLayout {
+  margin-top: 2em;
+}
+.oo-ui-fieldsetLayout > .oo-ui-labelElement-label {
+  margin-bottom: 0.5em;
+  padding: 0.25em 0;
+}
+.oo-ui-fieldsetLayout.oo-ui-iconElement > .oo-ui-labelElement-label {
+  padding-right: 1.75em;
+  line-height: 1.33em;
+}
+.oo-ui-fieldsetLayout.oo-ui-iconElement > .oo-ui-iconElement-icon {
+  right: 0;
+  top: 0.25em;
+  width: 2em;
+  height: 2em;
+}
+.oo-ui-gridLayout {
+  position: absolute;
+  top: 0;
+  right: 0;
+  left: 0;
+  bottom: 0;
+}
+.oo-ui-panelLayout {
+  position: relative;
+  padding: 1em 3.35em;
+}
+.oo-ui-panelLayout-scrollable {
+  overflow-y: auto;
+}
+.oo-ui-panelLayout-expanded {
+  position: absolute;
+  top: 0;
+  right: 0;
+  left: 0;
+  bottom: 0;
+}
+.oo-ui-stackLayout > .oo-ui-panelLayout {
+  display: none;
+}
+.oo-ui-stackLayout-continuous > .oo-ui-panelLayout {
+  display: block;
+  position: relative;
+}
+.oo-ui-popupTool .oo-ui-popupWidget-popup,
+.oo-ui-popupTool .oo-ui-popupWidget-anchor {
+  z-index: 4;
+}
+.oo-ui-popupTool .oo-ui-popupWidget {
+  margin-right: 1.25em;
+  font-size: 0.8em;
+}
+.oo-ui-toolGroup {
+  display: inline-block;
+  vertical-align: middle;
+  margin: 0.3em;
+}
+.oo-ui-toolGroup-empty {
+  display: none;
+}
+.oo-ui-toolGroup .oo-ui-tool-link .oo-ui-iconElement-icon {
+  background-position: center center;
+  background-repeat: no-repeat;
+}
+.oo-ui-barToolGroup > .oo-ui-iconElement-icon,
+.oo-ui-barToolGroup > .oo-ui-labelElement-label {
+  display: none;
+}
+.oo-ui-barToolGroup .oo-ui-tool {
+  display: inline-block;
+  position: relative;
+  vertical-align: top;
+}
+.oo-ui-barToolGroup .oo-ui-tool-link {
+  display: block;
+}
+.oo-ui-barToolGroup .oo-ui-tool-link .oo-ui-iconElement-icon {
+  display: block;
+}
+.oo-ui-barToolGroup .oo-ui-tool-link .oo-ui-tool-title {
+  display: none;
+}
+.oo-ui-barToolGroup .oo-ui-tool.oo-ui-widget-disabled .oo-ui-tool-link {
+  cursor: default;
+}
+.oo-ui-barToolGroup .oo-ui-tool-title,
+.oo-ui-barToolGroup .oo-ui-tool-accel {
+  display: none;
+}
+.oo-ui-barToolGroup.oo-ui-widget-enabled .oo-ui-tool-link {
+  cursor: pointer;
+}
+.oo-ui-barToolGroup .oo-ui-tool-link {
+  height: 1.5em;
+  padding: 0.25em;
+}
+.oo-ui-barToolGroup .oo-ui-tool-link .oo-ui-iconElement-icon {
+  height: 1.5em;
+  width: 1.5em;
+}
+.oo-ui-popupToolGroup {
+  position: relative;
+  height: 2em;
+  min-width: 2.5em;
+}
+.oo-ui-popupToolGroup-handle {
+  display: block;
+  cursor: pointer;
+}
+.oo-ui-popupToolGroup-handle .oo-ui-indicatorElement-indicator,
+.oo-ui-popupToolGroup-handle .oo-ui-iconElement-icon {
+  position: absolute;
+  background-position: center center;
+  background-repeat: no-repeat;
+}
+.oo-ui-popupToolGroup.oo-ui-widget-disabled .oo-ui-popupToolGroup-handle {
+  cursor: default;
+}
+.oo-ui-popupToolGroup .oo-ui-toolGroup-tools {
+  display: none;
+  position: absolute;
+  z-index: 4;
+}
+.oo-ui-popupToolGroup .oo-ui-toolGroup-tools .oo-ui-iconElement-icon {
+  background-repeat: no-repeat;
+  background-position: center center;
+}
+.oo-ui-popupToolGroup-active.oo-ui-widget-enabled > .oo-ui-toolGroup-tools {
+  display: block;
+}
+.oo-ui-popupToolGroup-left > .oo-ui-toolGroup-tools {
+  right: 0;
+}
+.oo-ui-popupToolGroup-right > .oo-ui-toolGroup-tools {
+  left: 0;
+}
+.oo-ui-popupToolGroup .oo-ui-tool-link .oo-ui-iconElement-icon {
+  display: inline-block;
+  vertical-align: middle;
+}
+.oo-ui-popupToolGroup .oo-ui-tool-link .oo-ui-tool-title {
+  display: inline-block;
+  vertical-align: middle;
+}
+.oo-ui-popupToolGroup .oo-ui-tool-accel {
+  display: none;
+}
+.oo-ui-popupToolGroup.oo-ui-indicatorElement.oo-ui-iconElement {
+  min-width: 3.5em;
+}
+.oo-ui-popupToolGroup-handle .oo-ui-indicatorElement-indicator,
+.oo-ui-popupToolGroup-handle .oo-ui-iconElement-icon {
+  top: 0;
+  width: 2em;
+  height: 2em;
+}
+.oo-ui-popupToolGroup-handle .oo-ui-indicatorElement-indicator {
+  left: 0;
+}
+.oo-ui-popupToolGroup-handle .oo-ui-iconElement-icon {
+  right: 0.25em;
+}
+.oo-ui-popupToolGroup-handle .oo-ui-labelElement-label {
+  line-height: 2.6em;
+  font-size: 0.8em;
+  margin: 0 1em;
+}
+.oo-ui-popupToolGroup-header {
+  line-height: 2.6em;
+  font-size: 0.8em;
+  margin: 0 0.6em;
+  font-weight: bold;
+}
+.oo-ui-popupToolGroup.oo-ui-iconElement .oo-ui-popupToolGroup-handle .oo-ui-labelElement-label {
+  margin-right: 3em;
+}
+.oo-ui-popupToolGroup.oo-ui-indicatorElement .oo-ui-popupToolGroup-handle .oo-ui-labelElement-label {
+  margin-left: 2.25em;
+}
+.oo-ui-popupToolGroup .oo-ui-toolGroup-tools {
+  top: 2.3em;
+  margin: 0 -1px;
+  border: solid 1px #dddddd;
+  background-color: white;
+}
+.oo-ui-popupToolGroup .oo-ui-tool-link .oo-ui-iconElement-icon {
+  height: 2em;
+  width: 2em;
+  margin-left: 0.25em;
+}
+.oo-ui-popupToolGroup .oo-ui-tool-link .oo-ui-tool-title {
+  line-height: 2em;
+  font-size: 0.8em;
+}
+.oo-ui-listToolGroup .oo-ui-tool {
+  display: inline-block;
+  width: 100%;
+  -webkit-box-sizing: border-box;
+  -moz-box-sizing: border-box;
+  box-sizing: border-box;
+}
+.oo-ui-listToolGroup .oo-ui-tool-link {
+  display: block;
+  cursor: pointer;
+  white-space: nowrap;
+}
+.oo-ui-listToolGroup .oo-ui-tool.oo-ui-widget-disabled .oo-ui-tool-link {
+  cursor: default;
+}
+.oo-ui-listToolGroup .oo-ui-toolGroup-tools {
+  padding: 0.25em;
+}
+.oo-ui-listToolGroup .oo-ui-tool-link {
+  padding-left: 0.5em;
+}
+.oo-ui-menuToolGroup .oo-ui-tool {
+  display: block;
+}
+.oo-ui-menuToolGroup .oo-ui-tool-link {
+  display: block;
+  cursor: pointer;
+  white-space: nowrap;
+}
+.oo-ui-menuToolGroup .oo-ui-tool-link .oo-ui-iconElement-icon {
+  background-image: none;
+}
+.oo-ui-menuToolGroup .oo-ui-tool-active .oo-ui-tool-link .oo-ui-iconElement-icon {
+  background-image: /* @embed */ url(images/icons/check.svg);
+}
+.oo-ui-menuToolGroup .oo-ui-tool.oo-ui-widget-disabled .oo-ui-tool-link {
+  cursor: default;
+}
+.oo-ui-menuToolGroup .oo-ui-popupToolGroup-handle {
+  min-width: 8em;
+}
+.oo-ui-menuToolGroup .oo-ui-toolGroup-tools {
+  padding: 0.25em 0 0.25em 0;
+}
+.oo-ui-menuToolGroup .oo-ui-tool-link {
+  padding: 0 0.25em 0 1em;
+}
+.oo-ui-toolbar {
+  clear: both;
+}
+.oo-ui-toolbar-bar {
+  line-height: 1em;
+}
+.oo-ui-toolbar-actions {
+  float: left;
+}
+.oo-ui-toolbar-tools {
+  display: inline;
+}
+.oo-ui-toolbar-tools,
+.oo-ui-toolbar-actions,
+.oo-ui-toolbar-shadow {
+  -webkit-touch-callout: none;
+  -webkit-user-select: none;
+  -moz-user-select: none;
+  -ms-user-select: none;
+  user-select: none;
+}
+.oo-ui-toolbar-actions .oo-ui-popupWidget {
+  -webkit-touch-callout: default;
+  -webkit-user-select: all;
+  -moz-user-select: all;
+  -ms-user-select: all;
+  user-select: all;
+}
+.oo-ui-toolbar-shadow {
+  background-position: right top;
+  background-repeat: repeat-x;
+  position: absolute;
+  width: 100%;
+  pointer-events: none;
+}
+.oo-ui-toolbar-bar {
+  border-bottom: solid 1px #dddddd;
+  background: white;
+}
+.oo-ui-toolbar-bar .oo-ui-toolbar-bar {
+  border: none;
+  background: none;
+}
+.oo-ui-selectWidget {
+  margin: 0;
+  padding: 0;
+}
+.oo-ui-optionWidget {
+  position: relative;
+  display: block;
+  cursor: pointer;
+  padding: 0.8em 3.35em 0.8em 1em;
+  border: none;
+  font-weight: bold;
+}
+.oo-ui-optionWidget.oo-ui-widget-disabled {
+  cursor: default;
+}
+.oo-ui-optionWidget .oo-ui-labelElement-label {
+  display: block;
+  white-space: nowrap;
+  text-overflow: ellipsis;
+  overflow: hidden;
+}
+.oo-ui-optionWidget .oo-ui-labelElement-label {
+  line-height: 1.5em;
+}
+.oo-ui-optionWidget.oo-ui-indicatorElement .oo-ui-labelElement-label {
+  padding-left: 1.5em;
+}
+.oo-ui-optionWidget-level-0 {
+  padding-right: 3.5em;
+}
+.oo-ui-optionWidget-level-0 .oo-ui-iconElement-icon {
+  right: 1em;
+}
+.oo-ui-optionWidget-level-1 {
+  padding-right: 5em;
+}
+.oo-ui-optionWidget-level-1 .oo-ui-iconElement-icon {
+  right: 2.5em;
+}
+.oo-ui-optionWidget-level-2 {
+  padding-right: 6.5em;
+}
+.oo-ui-optionWidget-level-2 .oo-ui-iconElement-icon {
+  right: 4em;
+}
+.oo-ui-decoratedOptionWidget .oo-ui-iconElement-icon,
+.oo-ui-decoratedOptionWidget .oo-ui-indicatorElement-indicator {
+  position: absolute;
+  background-repeat: no-repeat;
+  background-position: center center;
+}
+.oo-ui-decoratedOptionWidget .oo-ui-iconElement-icon,
+.oo-ui-decoratedOptionWidget .oo-ui-indicatorElement-indicator {
+  top: 50%;
+  width: 2em;
+  height: 2em;
+  margin-top: -1em;
+}
+.oo-ui-decoratedOptionWidget .oo-ui-iconElement-icon {
+  right: 0.5em;
+}
+.oo-ui-decoratedOptionWidget .oo-ui-indicatorElement-indicator {
+  left: 0.5em;
+}
+.oo-ui-buttonSelectWidget {
+  display: inline-block;
+  white-space: nowrap;
+}
+.oo-ui-buttonOptionWidget {
+  display: inline-block;
+  padding: 0;
+  background-color: transparent;
+}
+.oo-ui-buttonOptionWidget .oo-ui-buttonElement-button {
+  position: relative;
+}
+.oo-ui-buttonOptionWidget.oo-ui-iconElement .oo-ui-iconElement-icon,
+.oo-ui-buttonOptionWidget.oo-ui-indicatorElement .oo-ui-indicatorElement-indicator {
+  position: static;
+  display: inline-block;
+  vertical-align: middle;
+}
+.oo-ui-buttonOptionWidget .oo-ui-buttonElement-button {
+  height: 1.9em;
+}
+.oo-ui-buttonOptionWidget.oo-ui-iconElement .oo-ui-iconElement-icon,
+.oo-ui-buttonOptionWidget.oo-ui-indicatorElement .oo-ui-indicatorElement-indicator {
+  height: 1.9em;
+  margin-top: 0;
+}
+.oo-ui-labelWidget {
+  display: inline-block;
+  padding: 0.5em 0;
+}
+.oo-ui-iconWidget {
+  display: inline-block;
+  vertical-align: middle;
+  background-position: center center;
+  background-repeat: no-repeat;
+  line-height: 2.5em;
+  height: 1.9em;
+  width: 1.9em;
+  opacity: 0.8;
+}
+.oo-ui-iconWidget.oo-ui-widget-disabled {
+  opacity: 0.2;
+}
+.oo-ui-indicatorWidget {
+  display: inline-block;
+  vertical-align: middle;
+  background-position: center center;
+  background-repeat: no-repeat;
+  line-height: 2.5em;
+  height: 1.9em;
+  width: 1.9em;
+  opacity: 0.8;
+}
+.oo-ui-indicatorWidget.oo-ui-widget-disabled {
+  opacity: 0.2;
+}
+.oo-ui-buttonWidget {
+  display: inline-block;
+  vertical-align: middle;
+}
+.oo-ui-buttonGroupWidget {
+  border-radius: 0.3em;
+}
+.oo-ui-buttonGroupWidget .oo-ui-buttonElement-framed .oo-ui-buttonElement-button {
+  border-radius: 0;
+  margin-bottom: -1px;
+  margin-right: -1px;
+}
+.oo-ui-buttonGroupWidget .oo-ui-buttonElement-framed:first-child .oo-ui-buttonElement-button {
+  border-bottom-right-radius: 0.3em;
+  border-top-right-radius: 0.3em;
+  margin-right: 0;
+}
+.oo-ui-buttonGroupWidget .oo-ui-buttonElement-framed:last-child .oo-ui-buttonElement-button {
+  border-bottom-left-radius: 0.3em;
+  border-top-left-radius: 0.3em;
+}
+.oo-ui-toggleSwitchWidget {
+  position: relative;
+  display: inline-block;
+  vertical-align: middle;
+  overflow: hidden;
+  cursor: pointer;
+  -webkit-box-sizing: border-box;
+  -moz-box-sizing: border-box;
+  box-sizing: border-box;
+  -webkit-transform: translateZ(0px);
+  -moz-transform: translateZ(0px);
+  -ms-transform: translateZ(0px);
+  -o-transform: translateZ(0px);
+  transform: translateZ(0px);
+  height: 2em;
+  width: 4em;
+}
+.oo-ui-toggleSwitchWidget.oo-ui-widget-disabled {
+  cursor: default;
+}
+.oo-ui-toggleSwitchWidget-grip {
+  position: absolute;
+  display: block;
+  -webkit-box-sizing: border-box;
+  -moz-box-sizing: border-box;
+  box-sizing: border-box;
+}
+.oo-ui-toggleSwitchWidget .oo-ui-toggleSwitchWidget-glow {
+  position: absolute;
+  top: 0;
+  bottom: 0;
+  left: 0;
+  right: 0;
+  -webkit-touch-callout: none;
+  -webkit-user-select: none;
+  -moz-user-select: none;
+  -ms-user-select: none;
+  user-select: none;
+}
+.oo-ui-toggleWidget-off .oo-ui-toggleSwitchWidget-glow {
+  display: none;
+}
+.oo-ui-toggleSwitchWidget-grip {
+  top: 0.25em;
+  right: 0.25em;
+  width: 1.5em;
+  height: 1.5em;
+  margin-top: -1px;
+  -webkit-transition: right 200ms ease-in-out, margin-right 200ms ease-in-out;
+  -moz-transition: right 200ms ease-in-out, margin-right 200ms ease-in-out;
+  -ms-transition: right 200ms ease-in-out, margin-right 200ms ease-in-out;
+  -o-transition: right 200ms ease-in-out, margin-right 200ms ease-in-out;
+  transition: right 200ms ease-in-out, margin-right 200ms ease-in-out;
+}
+.oo-ui-toggleSwitchWidget .oo-ui-toggleSwitchWidget-glow {
+  -webkit-transition: opacity 200ms ease-in-out;
+  -moz-transition: opacity 200ms ease-in-out;
+  -ms-transition: opacity 200ms ease-in-out;
+  -o-transition: opacity 200ms ease-in-out;
+  transition: opacity 200ms ease-in-out;
+}
+.oo-ui-toggleWidget-on .oo-ui-toggleSwitchWidget-grip {
+  right: 2.25em;
+  margin-right: -2px;
+}
+.oo-ui-toggleWidget-off .oo-ui-toggleSwitchWidget-grip {
+  right: 0.25em;
+  margin-right: 0;
+}
+.oo-ui-popupWidget-popup {
+  position: absolute;
+  overflow: hidden;
+  z-index: 1;
+}
+.oo-ui-popupWidget-anchor {
+  display: none;
+  z-index: 1;
+}
+.oo-ui-popupWidget-anchored .oo-ui-popupWidget-anchor {
+  display: block;
+  position: absolute;
+  background-repeat: no-repeat;
+}
+.oo-ui-popupWidget-head {
+  -webkit-touch-callout: none;
+  -webkit-user-select: none;
+  -moz-user-select: none;
+  -ms-user-select: none;
+  user-select: none;
+}
+.oo-ui-popupWidget-head .oo-ui-buttonWidget {
+  float: left;
+}
+.oo-ui-popupWidget-head .oo-ui-labelElement-label {
+  float: right;
+  cursor: default;
+}
+.oo-ui-popupWidget-body {
+  clear: both;
+  overflow: hidden;
+}
+.oo-ui-popupWidget-anchored .oo-ui-popupWidget-popup {
+  margin-top: 7px;
+}
+.oo-ui-popupWidget-head {
+  height: 2.5em;
+}
+.oo-ui-popupWidget-head .oo-ui-buttonWidget {
+  margin: 0.25em;
+}
+.oo-ui-popupWidget-head .oo-ui-labelElement-label {
+  margin: 0.75em 1em;
+}
+.oo-ui-popupWidget-body-padded {
+  padding: 0 1em;
+}
+.oo-ui-popupButtonWidget {
+  position: relative;
+}
+.oo-ui-popupButtonWidget .oo-ui-popupWidget {
+  position: absolute;
+  right: 1em;
+  cursor: auto;
+}
+.oo-ui-lookupInputWidget-menu {
+  background-color: #fff;
+}
+.oo-ui-textInputWidget {
+  position: relative;
+  -webkit-box-sizing: border-box;
+  -moz-box-sizing: border-box;
+  box-sizing: border-box;
+}
+.oo-ui-textInputWidget input,
+.oo-ui-textInputWidget textarea {
+  display: inline-block;
+  width: 100%;
+  resize: none;
+  -webkit-box-sizing: border-box;
+  -moz-box-sizing: border-box;
+  box-sizing: border-box;
+}
+.oo-ui-textInputWidget > .oo-ui-iconElement-icon,
+.oo-ui-textInputWidget > .oo-ui-indicatorElement-indicator {
+  position: absolute;
+  top: 0;
+  height: 100%;
+  background-repeat: no-repeat;
+  cursor: pointer;
+  -webkit-touch-callout: none;
+  -webkit-user-select: none;
+  -moz-user-select: none;
+  -ms-user-select: none;
+  user-select: none;
+}
+.oo-ui-textInputWidget > .oo-ui-iconElement-icon {
+  right: 0;
+}
+.oo-ui-textInputWidget > .oo-ui-indicatorElement-indicator {
+  left: 0;
+}
+.oo-ui-textInputWidget input,
+.oo-ui-textInputWidget textarea {
+  padding: .8em 1em;
+}
+.oo-ui-menuWidget {
+  position: absolute;
+  background: white;
+  border: solid 1px #dddddd;
+}
+.oo-ui-menuWidget input {
+  position: absolute;
+  width: 0;
+  height: 0;
+  overflow: hidden;
+  opacity: 0;
+}
+.oo-ui-menuItemWidget {
+  position: relative;
+}
+.oo-ui-menuItemWidget .oo-ui-iconElement-icon {
+  display: none;
+}
+.oo-ui-menuItemWidget.oo-ui-optionWidget-selected {
+  background-color: transparent;
+}
+.oo-ui-menuItemWidget.oo-ui-optionWidget-selected .oo-ui-iconElement-icon {
+  display: block;
+}
+.oo-ui-menuItemWidget.oo-ui-optionWidget-selected {
+  background: #347bff;
+  color: #ffffff;
+}
+.oo-ui-menuItemWidget .oo-ui-iconElement-icon {
+  background-size: 24px auto;
+}
+.oo-ui-menuSectionItemWidget {
+  cursor: default;
+  font-weight: normal;
+  color: #777777;
+  border: none;
+}
+.oo-ui-inlineMenuWidget {
+  position: relative;
+  display: inline-block;
+  margin: 0.25em 0;
+  min-width: 20em;
+}
+.oo-ui-inlineMenuWidget-handle {
+  width: 100%;
+  display: inline-block;
+  cursor: pointer;
+  -webkit-touch-callout: none;
+  -webkit-user-select: none;
+  -moz-user-select: none;
+  -ms-user-select: none;
+  user-select: none;
+  -webkit-box-sizing: border-box;
+  -moz-box-sizing: border-box;
+  box-sizing: border-box;
+}
+.oo-ui-inlineMenuWidget-handle .oo-ui-indicatorElement-indicator,
+.oo-ui-inlineMenuWidget-handle .oo-ui-iconElement-icon {
+  position: absolute;
+  background-position: center center;
+  background-repeat: no-repeat;
+}
+.oo-ui-inlineMenuWidget .oo-ui-menuWidget {
+  z-index: 1;
+  width: 100%;
+}
+.oo-ui-inlineMenuWidget.oo-ui-widget-disabled .oo-ui-inlineMenuWidget-handle {
+  cursor: default;
+}
+.oo-ui-inlineMenuWidget-handle {
+  height: 2.5em;
+}
+.oo-ui-inlineMenuWidget-handle .oo-ui-indicatorElement-indicator,
+.oo-ui-inlineMenuWidget-handle .oo-ui-iconElement-icon {
+  top: 0;
+  width: 2.5em;
+  height: 2.5em;
+}
+.oo-ui-inlineMenuWidget-handle .oo-ui-indicatorElement-indicator {
+  left: 0;
+}
+.oo-ui-inlineMenuWidget-handle .oo-ui-iconElement-icon {
+  right: 0.25em;
+}
+.oo-ui-inlineMenuWidget-handle .oo-ui-labelElement-label {
+  line-height: 2.5em;
+  margin: 0 0.5em;
+}
+.oo-ui-inlineMenuWidget.oo-ui-iconElement .oo-ui-inlineMenuWidget-handle .oo-ui-labelElement-label {
+  margin-right: 3em;
+}
+.oo-ui-inlineMenuWidget.oo-ui-indicatorElement .oo-ui-inlineMenuWidget-handle .oo-ui-labelElement-label {
+  margin-left: 2em;
+}
+.oo-ui-outlineItemWidget {
+  position: relative;
+  cursor: pointer;
+  -webkit-touch-callout: none;
+  -webkit-user-select: none;
+  -moz-user-select: none;
+  -ms-user-select: none;
+  user-select: none;
+  padding: 0.75em;
+}
+.oo-ui-outlineControlsWidget {
+  height: 3em;
+}
+.oo-ui-outlineControlsWidget-items,
+.oo-ui-outlineControlsWidget-movers {
+  float: right;
+  -webkit-box-sizing: border-box;
+  -moz-box-sizing: border-box;
+  box-sizing: border-box;
+}
+.oo-ui-outlineControlsWidget > .oo-ui-iconElement-icon {
+  float: right;
+  background-position: left center;
+  background-repeat: no-repeat;
+}
+.oo-ui-outlineControlsWidget-items {
+  float: right;
+}
+.oo-ui-outlineControlsWidget-items .oo-ui-buttonWidget {
+  float: right;
+}
+.oo-ui-outlineControlsWidget-movers {
+  float: left;
+}
+.oo-ui-outlineControlsWidget-movers .oo-ui-buttonWidget {
+  float: left;
+}
+.oo-ui-outlineControlsWidget-items,
+.oo-ui-outlineControlsWidget-movers {
+  height: 2em;
+  margin: 0.5em;
+  padding: 0;
+}
+.oo-ui-outlineControlsWidget > .oo-ui-iconElement-icon {
+  width: 1.5em;
+  height: 2em;
+  margin: 0.5em 0.5em 0.5em 0;
+}
+.oo-ui-outlineControlsWidget-items {
+  margin-right: 0;
+}
+.oo-ui-comboBoxWidget > .oo-ui-selectWidget {
+  z-index: 1;
+}
+.oo-ui-comboBoxWidget > .oo-ui-selectWidget > .oo-ui-selectWidget {
+  min-width: 20em;
+}
+.oo-ui-searchWidget-query {
+  position: absolute;
+  top: 0;
+  right: 0;
+  left: 0;
+}
+.oo-ui-searchWidget-query .oo-ui-textInputWidget {
+  width: 100%;
+}
+.oo-ui-searchWidget-results {
+  position: absolute;
+  bottom: 0;
+  right: 0;
+  left: 0;
+  overflow-x: hidden;
+  overflow-y: auto;
+}
+.oo-ui-searchWidget-query {
+  height: 4em;
+  padding: 0 1em;
+}
+.oo-ui-searchWidget-query .oo-ui-textInputWidget {
+  margin: 0.75em 0;
+}
+.oo-ui-searchWidget-results {
+  top: 4em;
+  padding: 1em;
+  line-height: 0;
+}
+.oo-ui-window {
+  line-height: 1em;
+  /* Content div takes focus when opened, so hide outline */
+}
+.oo-ui-window-frame {
+  -webkit-box-sizing: border-box;
+  -moz-box-sizing: border-box;
+  box-sizing: border-box;
+}
+.oo-ui-window-frame > iframe {
+  width: 100%;
+  height: 100%;
+  margin: 0;
+  padding: 0;
+}
+.oo-ui-window-content:focus {
+  outline: none;
+}
+.oo-ui-window-head,
+.oo-ui-window-foot {
+  -webkit-touch-callout: none;
+  -webkit-user-select: none;
+  -moz-user-select: none;
+  -ms-user-select: none;
+  user-select: none;
+}
+.oo-ui-window-body {
+  margin: 0;
+  padding: 0;
+  background: none;
+}
+.oo-ui-window-overlay {
+  position: absolute;
+  top: 0;
+  right: 0;
+}
+.oo-ui-dialog-content > .oo-ui-window-head,
+.oo-ui-dialog-content > .oo-ui-window-body,
+.oo-ui-dialog-content > .oo-ui-window-foot {
+  position: absolute;
+  right: 0;
+  left: 0;
+  overflow: hidden;
+  -webkit-box-sizing: border-box;
+  -moz-box-sizing: border-box;
+  box-sizing: border-box;
+}
+.oo-ui-dialog-content > .oo-ui-window-head {
+  z-index: 1;
+  top: 0;
+}
+.oo-ui-dialog-content > .oo-ui-window-body {
+  z-index: 2;
+  top: 0;
+  bottom: 0;
+}
+.oo-ui-dialog-content > .oo-ui-window-foot {
+  z-index: 1;
+  bottom: 0;
+}
+.oo-ui-dialog-content > .oo-ui-window-overlay {
+  z-index: 3;
+}
+.oo-ui-messageDialog-actions-horizontal {
+  display: table;
+  table-layout: fixed;
+  width: 100%;
+}
+.oo-ui-messageDialog-actions-horizontal .oo-ui-actionWidget {
+  display: table-cell;
+  width: 1%;
+}
+.oo-ui-messageDialog-actions-vertical {
+  display: block;
+}
+.oo-ui-messageDialog-actions-vertical .oo-ui-actionWidget {
+  display: block;
+  overflow: hidden;
+  text-overflow: ellipsis;
+}
+.oo-ui-messageDialog-actions .oo-ui-actionWidget {
+  position: relative;
+  text-align: center;
+}
+.oo-ui-messageDialog-actions .oo-ui-actionWidget .oo-ui-buttonElement-button {
+  display: block;
+}
+.oo-ui-messageDialog-actions .oo-ui-actionWidget .oo-ui-labelElement-label {
+  position: relative;
+  top: auto;
+  bottom: auto;
+  display: inline;
+  white-space: nowrap;
+}
+.oo-ui-messageDialog-title,
+.oo-ui-messageDialog-message {
+  display: block;
+  text-align: center;
+  padding-top: 0.5em;
+}
+.oo-ui-messageDialog-title {
+  font-size: 1.5em;
+  line-height: 1em;
+  color: #000;
+}
+.oo-ui-messageDialog-message {
+  font-size: 0.9em;
+  line-height: 1.25em;
+  color: #666;
+}
+.oo-ui-messageDialog-message-verbose {
+  font-size: 1.1em;
+  line-height: 1.5em;
+  text-align: right;
+}
+.oo-ui-messageDialog-actions-horizontal .oo-ui-actionWidget {
+  border-left: solid 1px #e5e5e5;
+}
+.oo-ui-messageDialog-actions-horizontal .oo-ui-actionWidget:last-child {
+  border-left-width: 0;
+}
+.oo-ui-messageDialog-actions-vertical .oo-ui-actionWidget {
+  border-bottom: solid 1px #e5e5e5;
+}
+.oo-ui-messageDialog-actions-vertical .oo-ui-actionWidget:last-child {
+  border-bottom-width: 0;
+}
+.oo-ui-messageDialog-actions .oo-ui-actionWidget .oo-ui-labelElement-label {
+  text-align: center;
+  line-height: 3.4em;
+  padding: 0 2em;
+}
+.oo-ui-messageDialog-actions .oo-ui-actionWidget:hover {
+  background-color: rgba(0, 0, 0, 0.05);
+}
+.oo-ui-messageDialog-actions .oo-ui-actionWidget:active {
+  background-color: rgba(0, 0, 0, 0.1);
+}
+.oo-ui-messageDialog-actions .oo-ui-actionWidget.oo-ui-flaggedElement-primary:hover {
+  background-color: rgba(8, 126, 204, 0.05);
+}
+.oo-ui-messageDialog-actions .oo-ui-actionWidget.oo-ui-flaggedElement-primary:active {
+  background-color: rgba(8, 126, 204, 0.1);
+}
+.oo-ui-messageDialog-actions .oo-ui-actionWidget.oo-ui-flaggedElement-primary .oo-ui-labelElement-label {
+  font-weight: bold;
+}
+.oo-ui-messageDialog-actions .oo-ui-actionWidget.oo-ui-flaggedElement-constructive:hover {
+  background-color: rgba(118, 171, 54, 0.05);
+}
+.oo-ui-messageDialog-actions .oo-ui-actionWidget.oo-ui-flaggedElement-constructive:active {
+  background-color: rgba(118, 171, 54, 0.1);
+}
+.oo-ui-messageDialog-actions .oo-ui-actionWidget.oo-ui-flaggedElement-destructive:hover {
+  background-color: rgba(212, 83, 83, 0.05);
+}
+.oo-ui-messageDialog-actions .oo-ui-actionWidget.oo-ui-flaggedElement-destructive:active {
+  background-color: rgba(212, 83, 83, 0.1);
+}
+.oo-ui-processDialog-location {
+  overflow: hidden;
+  text-overflow: ellipsis;
+  white-space: nowrap;
+}
+.oo-ui-processDialog-title {
+  display: inline;
+  padding: 0;
+}
+.oo-ui-processDialog-actions-safe .oo-ui-actionWidget,
+.oo-ui-processDialog-actions-primary .oo-ui-actionWidget,
+.oo-ui-processDialog-actions-other .oo-ui-actionWidget {
+  white-space: nowrap;
+}
+.oo-ui-processDialog-actions-safe,
+.oo-ui-processDialog-actions-primary {
+  position: absolute;
+  top: 0;
+  bottom: 0;
+}
+.oo-ui-processDialog-actions-safe {
+  right: 0;
+}
+.oo-ui-processDialog-actions-primary {
+  left: 0;
+}
+.oo-ui-processDialog-errors {
+  display: none;
+  position: absolute;
+  top: 0;
+  right: 0;
+  left: 0;
+  bottom: 0;
+  z-index: 2;
+  overflow-x: hidden;
+  overflow-y: auto;
+}
+.oo-ui-processDialog-content .oo-ui-window-head {
+  height: 3.35em;
+  border-bottom: 1px solid #dddddd;
+  -webkit-box-sizing: border-box;
+  -moz-box-sizing: border-box;
+  box-sizing: border-box;
+}
+.oo-ui-processDialog-content .oo-ui-window-body {
+  top: 3.35em;
+  padding: 2em 0;
+}
+.oo-ui-processDialog-navigation {
+  position: relative;
+  height: 3.35em;
+  padding: 0 1em;
+}
+.oo-ui-processDialog-location {
+  padding: 0.75em 0;
+  height: 1.85em;
+  cursor: default;
+  text-align: center;
+}
+.oo-ui-processDialog-title {
+  font-weight: bold;
+  line-height: 1.85em;
+}
+.oo-ui-processDialog-actions-safe .oo-ui-actionWidget .oo-ui-buttonElement-button,
+.oo-ui-processDialog-actions-primary .oo-ui-actionWidget .oo-ui-buttonElement-button,
+.oo-ui-processDialog-actions-other .oo-ui-actionWidget .oo-ui-buttonElement-button {
+  padding: 0.35em 0.75em;
+  min-width: 1.85em;
+  min-height: 1.85em;
+  border: 1px solid #dddddd;
+  border-radius: 4px;
+}
+.oo-ui-processDialog-actions-safe .oo-ui-actionWidget .oo-ui-labelElement-label,
+.oo-ui-processDialog-actions-primary .oo-ui-actionWidget .oo-ui-labelElement-label,
+.oo-ui-processDialog-actions-other .oo-ui-actionWidget .oo-ui-labelElement-label {
+  line-height: 1.85em;
+  padding: 0 1em;
+  font-weight: bold;
+  color: #777777;
+}
+.oo-ui-processDialog-actions-safe .oo-ui-actionWidget .oo-ui-iconElement-icon,
+.oo-ui-processDialog-actions-primary .oo-ui-actionWidget .oo-ui-iconElement-icon,
+.oo-ui-processDialog-actions-other .oo-ui-actionWidget .oo-ui-iconElement-icon {
+  position: absolute;
+  margin-top: -0.125em;
+}
+.oo-ui-processDialog-actions-safe .oo-ui-actionWidget.oo-ui-buttonElement-framed .oo-ui-buttonElement-button,
+.oo-ui-processDialog-actions-primary .oo-ui-actionWidget.oo-ui-buttonElement-framed .oo-ui-buttonElement-button,
+.oo-ui-processDialog-actions-other .oo-ui-actionWidget.oo-ui-buttonElement-framed .oo-ui-buttonElement-button {
+  vertical-align: middle;
+}
+.oo-ui-processDialog-actions-safe .oo-ui-actionWidget.oo-ui-flaggedElement-destructive .oo-ui-buttonElement-button,
+.oo-ui-processDialog-actions-primary .oo-ui-actionWidget.oo-ui-flaggedElement-destructive .oo-ui-buttonElement-button,
+.oo-ui-processDialog-actions-other .oo-ui-actionWidget.oo-ui-flaggedElement-destructive .oo-ui-buttonElement-button {
+  border: 1px solid transparent;
+}
+.oo-ui-processDialog-actions-safe .oo-ui-actionWidget.oo-ui-flaggedElement-destructive .oo-ui-labelElement-label,
+.oo-ui-processDialog-actions-primary .oo-ui-actionWidget.oo-ui-flaggedElement-destructive .oo-ui-labelElement-label,
+.oo-ui-processDialog-actions-other .oo-ui-actionWidget.oo-ui-flaggedElement-destructive .oo-ui-labelElement-label {
+  color: #d11d13;
+}
+.oo-ui-processDialog-actions-safe .oo-ui-actionWidget .oo-ui-buttonElement-button,
+.oo-ui-processDialog-actions-primary .oo-ui-actionWidget .oo-ui-buttonElement-button {
+  padding: 0.75em 0.35em;
+  border: none;
+  border-radius: 0;
+}
+.oo-ui-processDialog-actions-safe .oo-ui-actionWidget.oo-ui-flaggedElement-primary .oo-ui-buttonElement-button,
+.oo-ui-processDialog-actions-primary .oo-ui-actionWidget.oo-ui-flaggedElement-primary .oo-ui-buttonElement-button {
+  background-color: #347bff;
+}
+.oo-ui-processDialog-actions-safe .oo-ui-actionWidget.oo-ui-flaggedElement-primary .oo-ui-labelElement-label,
+.oo-ui-processDialog-actions-primary .oo-ui-actionWidget.oo-ui-flaggedElement-primary .oo-ui-labelElement-label {
+  color: #ffffff;
+}
+.oo-ui-processDialog-actions-safe .oo-ui-actionWidget.oo-ui-iconElement .oo-ui-iconElement-icon {
+  right: 0.5em;
+}
+.oo-ui-processDialog-actions-safe .oo-ui-actionWidget.oo-ui-iconElement .oo-ui-labelElement-label {
+  padding-right: 2.25em;
+}
+.oo-ui-processDialog-actions-primary .oo-ui-actionWidget.oo-ui-iconElement .oo-ui-iconElement-icon {
+  left: 0.5em;
+}
+.oo-ui-processDialog-actions-primary .oo-ui-actionWidget.oo-ui-iconElement .oo-ui-labelElement-label {
+  padding-left: 2.25em;
+}
+.oo-ui-processDialog-actions-other {
+  position: absolute;
+  bottom: 1em;
+}
+.oo-ui-processDialog > .oo-ui-window-frame {
+  min-height: 5em;
+}
+.oo-ui-processDialog-errors {
+  background-color: rgba(255, 255, 255, 0.9);
+  padding: 3em 3em 1.5em 3em;
+  text-align: center;
+}
+.oo-ui-processDialog-errors .oo-ui-buttonWidget {
+  margin: 2em 1em 2em 1em;
+}
+.oo-ui-processDialog-errors-title {
+  font-size: 1.5em;
+  color: #000;
+  margin-bottom: 2em;
+}
+.oo-ui-processDialog-error {
+  text-align: right;
+  margin: 1em;
+  padding: 1em;
+  border: solid 1px #ff9e9e;
+  background-color: #fff7f7;
+  border-radius: 0.25em;
+}
+.oo-ui-windowManager-modal > .oo-ui-dialog {
+  position: fixed;
+  width: 0;
+  height: 0;
+  overflow: hidden;
+}
+.oo-ui-windowManager-modal > .oo-ui-dialog.oo-ui-window-setup {
+  width: auto;
+  height: auto;
+  top: 0;
+  left: 0;
+  bottom: 0;
+  right: 0;
+  padding: 1em;
+}
+.oo-ui-windowManager-modal > .oo-ui-dialog.oo-ui-window-setup > .oo-ui-window-frame {
+  position: fixed;
+  left: 0;
+  right: 0;
+  margin: auto;
+  overflow: hidden;
+  max-width: 100%;
+  max-height: 100%;
+}
+.oo-ui-windowManager-modal > .oo-ui-dialog.oo-ui-window-setup > .oo-ui-window-frame > iframe {
+  width: 100%;
+  height: 100%;
+}
+.oo-ui-windowManager-fullscreen > .oo-ui-dialog > .oo-ui-window-frame {
+  width: 100%;
+  height: 100%;
+  top: 0;
+  bottom: 0;
+}
+.oo-ui-windowManager-modal > .oo-ui-dialog {
+  background-color: rgba(255, 255, 255, 0.5);
+  opacity: 0;
+  -webkit-transition: opacity 250ms ease-in-out;
+  -moz-transition: opacity 250ms ease-in-out;
+  -ms-transition: opacity 250ms ease-in-out;
+  -o-transition: opacity 250ms ease-in-out;
+  transition: opacity 250ms ease-in-out;
+}
+.oo-ui-windowManager-modal > .oo-ui-dialog > .oo-ui-window-frame {
+  top: 0;
+  bottom: 0;
+  background-color: #fff;
+  -webkit-transform: translate3d(0, -200%, 0);
+  -moz-transform: translate3d(0, -200%, 0);
+  -ms-transform: translate3d(0, -200%, 0);
+  -o-transform: translate3d(0, -200%, 0);
+  transform: translate3d(0, -200%, 0);
+  -webkit-transition: transform 250ms ease-in-out;
+  -moz-transition: transform 250ms ease-in-out;
+  -ms-transition: transform 250ms ease-in-out;
+  -o-transition: transform 250ms ease-in-out;
+  transition: transform 250ms ease-in-out;
+}
+.oo-ui-windowManager-modal > .oo-ui-dialog.oo-ui-window-ready {
+  opacity: 1;
+}
+.oo-ui-windowManager-modal > .oo-ui-dialog.oo-ui-window-ready > .oo-ui-window-frame {
+  -webkit-transform: translate3d(0, 0, 0);
+  -moz-transform: translate3d(0, 0, 0);
+  -ms-transform: translate3d(0, 0, 0);
+  -o-transform: translate3d(0, 0, 0);
+  transform: translate3d(0, 0, 0);
+}
+.oo-ui-windowManager-modal.oo-ui-windowManager-floating > .oo-ui-dialog > .oo-ui-window-frame {
+  border: solid 1px #ccc;
+  border-radius: 0.5em;
+  box-shadow: 0 0.2em 1em rgba(0, 0, 0, 0.3);
+}
+
+/*
+ * Blank theme mixins.
+ *
+ * Base styles invoke these mixins at the end of their definitions. Override these mixins to add
+ * additional rules to the base styles.
+ */
+.oo-ui-icon-check {
+  background-image: /* @embed */ url(themes/minerva/images/icons/check.png);
+  background: #347bff;
+}
index 67eef40..33c8238 100644 (file)
@@ -1,12 +1,12 @@
 /*!
- * OOjs UI v0.1.0-pre (f9c217dfa4)
+ * OOjs UI v0.1.0-pre (f2c3f12959)
  * https://www.mediawiki.org/wiki/OOjs_UI
  *
  * Copyright 2011–2014 OOjs Team and other contributors.
  * Released under the MIT license
  * http://oojs.mit-license.org
  *
- * Date: 2014-09-10T17:25:40Z
+ * Date: 2014-09-18T23:22:20Z
  */
 ( function ( OO ) {
 
@@ -188,6 +188,88 @@ OO.ui.getLocalValue = function ( obj, lang, fallback ) {
 
 } )();
 
+/**
+ * Element that can be marked as pending.
+ *
+ * @abstract
+ * @class
+ *
+ * @constructor
+ * @param {Object} [config] Configuration options
+ */
+OO.ui.PendingElement = function OoUiPendingElement( config ) {
+       // Config initialisation
+       config = config || {};
+
+       // Properties
+       this.pending = 0;
+       this.$pending = null;
+
+       // Initialisation
+       this.setPendingElement( config.$pending || this.$element );
+};
+
+/* Setup */
+
+OO.initClass( OO.ui.PendingElement );
+
+/* Methods */
+
+/**
+ * Set the pending element (and clean up any existing one).
+ *
+ * @param {jQuery} $pending The element to set to pending.
+ */
+OO.ui.PendingElement.prototype.setPendingElement = function ( $pending ) {
+       if ( this.$pending ) {
+               this.$pending.removeClass( 'oo-ui-pendingElement-pending' );
+       }
+
+       this.$pending = $pending;
+       if ( this.pending > 0 ) {
+               this.$pending.addClass( 'oo-ui-pendingElement-pending' );
+       }
+};
+
+/**
+ * Check if input is pending.
+ *
+ * @return {boolean}
+ */
+OO.ui.PendingElement.prototype.isPending = function () {
+       return !!this.pending;
+};
+
+/**
+ * Increase the pending stack.
+ *
+ * @chainable
+ */
+OO.ui.PendingElement.prototype.pushPending = function () {
+       if ( this.pending === 0 ) {
+               this.$pending.addClass( 'oo-ui-pendingElement-pending' );
+       }
+       this.pending++;
+
+       return this;
+};
+
+/**
+ * Reduce the pending stack.
+ *
+ * Clamped at zero.
+ *
+ * @chainable
+ */
+OO.ui.PendingElement.prototype.popPending = function () {
+       if ( this.pending === 1 ) {
+               this.$pending.removeClass( 'oo-ui-pendingElement-pending' );
+       }
+       this.pending = Math.max( 0, this.pending - 1 );
+
+       return this;
+};
+
 /**
  * List of actions.
  *
@@ -869,7 +951,7 @@ OO.ui.Element.getDimensions = function ( el ) {
  * @static
  * @param {HTMLElement} el Element to find scrollable container for
  * @param {string} [dimension] Dimension of scrolling to look for; `x`, `y` or omit for either
- * @return {HTMLElement|Window} Closest scrollable container
+ * @return {HTMLElement} Closest scrollable container
  */
 OO.ui.Element.getClosestScrollableContainer = function ( el, dimension ) {
        var i, val,
@@ -1562,17 +1644,26 @@ OO.ui.Window.prototype.getSize = function () {
  * @return {number} Content height
  */
 OO.ui.Window.prototype.getContentHeight = function () {
+       // Temporarily resize the frame so getBodyHeight() can use scrollHeight measurements
+       var bodyHeight, oldHeight = this.$frame[0].style.height;
+       this.$frame[0].style.height = '1px';
+       bodyHeight = this.getBodyHeight();
+       this.$frame[0].style.height = oldHeight;
+
        return Math.round(
                // Add buffer for border
                ( this.$frame.outerHeight() - this.$frame.innerHeight() ) +
                // Use combined heights of children
-               ( this.$head.outerHeight( true ) + this.getBodyHeight() + this.$foot.outerHeight( true ) )
+               ( this.$head.outerHeight( true ) + bodyHeight + this.$foot.outerHeight( true ) )
        );
 };
 
 /**
  * Get the height of the dialog contents.
  *
+ * When this function is called, the dialog will temporarily have been resized
+ * to height=1px, so .scrollHeight measurements can be taken accurately.
+ *
  * @return {number} Height of content
  */
 OO.ui.Window.prototype.getBodyHeight = function () {
@@ -2056,6 +2147,7 @@ OO.ui.Window.prototype.load = function () {
  * @abstract
  * @class
  * @extends OO.ui.Window
+ * @mixins OO.ui.PendingElement
  *
  * @constructor
  * @param {Object} [config] Configuration options
@@ -2064,11 +2156,13 @@ OO.ui.Dialog = function OoUiDialog( config ) {
        // Parent constructor
        OO.ui.Dialog.super.call( this, config );
 
+       // Mixin constructors
+       OO.ui.PendingElement.call( this );
+
        // Properties
        this.actions = new OO.ui.ActionSet();
        this.attachedActions = [];
        this.currentAction = null;
-       this.pending = 0;
 
        // Events
        this.actions.connect( this, {
@@ -2086,6 +2180,7 @@ OO.ui.Dialog = function OoUiDialog( config ) {
 /* Setup */
 
 OO.inheritClass( OO.ui.Dialog, OO.ui.Window );
+OO.mixinClass( OO.ui.Dialog, OO.ui.PendingElement );
 
 /* Static Properties */
 
@@ -2173,15 +2268,6 @@ OO.ui.Dialog.prototype.onActionsChange = function () {
        }
 };
 
-/**
- * Check if input is pending.
- *
- * @return {boolean}
- */
-OO.ui.Dialog.prototype.isPending = function () {
-       return !!this.pending;
-};
-
 /**
  * Get set of actions.
  *
@@ -2216,7 +2302,7 @@ OO.ui.Dialog.prototype.getActionProcess = function ( action ) {
  * @inheritdoc
  *
  * @param {Object} [data] Dialog opening data
- * @param {jQuery|string|Function|null} [data.label] Dialog label, omit to use #static-label
+ * @param {jQuery|string|Function|null} [data.title] Dialog title, omit to use #static-title
  * @param {Object[]} [data.actions] List of OO.ui.ActionWidget configuration options for each
  *   action item, omit to use #static-actions
  */
@@ -2272,6 +2358,7 @@ OO.ui.Dialog.prototype.initialize = function () {
 
        // Initialization
        this.$content.addClass( 'oo-ui-dialog-content' );
+       this.setPendingElement( this.$head );
 };
 
 /**
@@ -2309,38 +2396,6 @@ OO.ui.Dialog.prototype.executeAction = function ( action ) {
                .always( OO.ui.bind( this.popPending, this ) );
 };
 
-/**
- * Increase the pending stack.
- *
- * @chainable
- */
-OO.ui.Dialog.prototype.pushPending = function () {
-       if ( this.pending === 0 ) {
-               this.$content.addClass( 'oo-ui-actionDialog-content-pending' );
-               this.$head.addClass( 'oo-ui-texture-pending' );
-       }
-       this.pending++;
-
-       return this;
-};
-
-/**
- * Reduce the pending stack.
- *
- * Clamped at zero.
- *
- * @chainable
- */
-OO.ui.Dialog.prototype.popPending = function () {
-       if ( this.pending === 1 ) {
-               this.$content.removeClass( 'oo-ui-actionDialog-content-pending' );
-               this.$head.removeClass( 'oo-ui-texture-pending' );
-       }
-       this.pending = Math.max( 0, this.pending - 1 );
-
-       return this;
-};
-
 /**
  * Collection of windows.
  *
@@ -2754,7 +2809,6 @@ OO.ui.WindowManager.prototype.openWindow = function ( win, data ) {
                                        manager.opening.notify( { state: 'setup' } );
                                        setTimeout( function () {
                                                win.ready( data ).then( function () {
-                                                       manager.updateWindowSize( win );
                                                        manager.opening.notify( { state: 'ready' } );
                                                        manager.opening = null;
                                                        manager.opened = $.Deferred();
@@ -4679,7 +4733,7 @@ OO.ui.ClippableElement.prototype.isClippedVertically = function () {
 };
 
 /**
- * Set the ideal size.
+ * Set the ideal size. These are the dimensions the element will have when it's not being clipped.
  *
  * @param {number|string} [width] Width as a number of pixels or CSS string with unit suffix
  * @param {number|string} [height] Height as a number of pixels or CSS string with unit suffix
@@ -4687,6 +4741,12 @@ OO.ui.ClippableElement.prototype.isClippedVertically = function () {
 OO.ui.ClippableElement.prototype.setIdealSize = function ( width, height ) {
        this.idealWidth = width;
        this.idealHeight = height;
+
+       if ( !this.clipping ) {
+               // Update dimensions
+               this.$clippable.css( { width: width, height: height } );
+       }
+       // While clipping, idealWidth and idealHeight are not considered
 };
 
 /**
@@ -6429,15 +6489,19 @@ OO.ui.FieldLayout = function OoUiFieldLayout( field, config ) {
        if ( config.help ) {
                this.popupButtonWidget = new OO.ui.PopupButtonWidget( {
                        $: this.$,
+                       classes: [ 'oo-ui-fieldLayout-help' ],
                        framed: false,
-                       icon: 'info',
-                       title: config.help
+                       icon: 'info'
                } );
 
-               this.popupButtonWidget.getPopup().$body.append( this.$( '<span>' ).text( config.help ) );
+               this.popupButtonWidget.getPopup().$body.append(
+                       this.$( '<div>' )
+                               .text( config.help )
+                               .addClass( 'oo-ui-fieldLayout-help-content' )
+               );
                this.$help = this.popupButtonWidget.$element;
        } else {
-               this.$help = this.$( '<div>' );
+               this.$help = this.$( [] );
        }
 
        // Events
@@ -8148,6 +8212,7 @@ OO.ui.ButtonWidget.prototype.setTarget = function ( target ) {
  *
  * @class
  * @extends OO.ui.ButtonWidget
+ * @mixins OO.ui.PendingElement
  *
  * @constructor
  * @param {Object} [config] Configuration options
@@ -8161,6 +8226,9 @@ OO.ui.ActionWidget = function OoUiActionWidget( config ) {
        // Parent constructor
        OO.ui.ActionWidget.super.call( this, config );
 
+       // Mixin constructors
+       OO.ui.PendingElement.call( this, config );
+
        // Properties
        this.action = config.action || '';
        this.modes = config.modes || [];
@@ -8174,6 +8242,7 @@ OO.ui.ActionWidget = function OoUiActionWidget( config ) {
 /* Setup */
 
 OO.inheritClass( OO.ui.ActionWidget, OO.ui.ButtonWidget );
+OO.mixinClass( OO.ui.ActionWidget, OO.ui.PendingElement );
 
 /* Events */
 
@@ -8868,6 +8937,7 @@ OO.ui.CheckboxInputWidget.prototype.onEdit = function () {
  * @extends OO.ui.InputWidget
  * @mixins OO.ui.IconElement
  * @mixins OO.ui.IndicatorElement
+ * @mixins OO.ui.PendingElement
  *
  * @constructor
  * @param {Object} [config] Configuration options
@@ -8886,9 +8956,9 @@ OO.ui.TextInputWidget = function OoUiTextInputWidget( config ) {
        // Mixin constructors
        OO.ui.IconElement.call( this, config );
        OO.ui.IndicatorElement.call( this, config );
+       OO.ui.PendingElement.call( this, config );
 
        // Properties
-       this.pending = 0;
        this.multiline = !!config.multiline;
        this.autosize = !!config.autosize;
        this.maxRows = config.maxRows !== undefined ? config.maxRows : 10;
@@ -8914,6 +8984,7 @@ OO.ui.TextInputWidget = function OoUiTextInputWidget( config ) {
 OO.inheritClass( OO.ui.TextInputWidget, OO.ui.InputWidget );
 OO.mixinClass( OO.ui.TextInputWidget, OO.ui.IconElement );
 OO.mixinClass( OO.ui.TextInputWidget, OO.ui.IndicatorElement );
+OO.mixinClass( OO.ui.TextInputWidget, OO.ui.PendingElement );
 
 /* Events */
 
@@ -9076,47 +9147,6 @@ OO.ui.TextInputWidget.prototype.isAutosizing = function () {
        return !!this.autosize;
 };
 
-/**
- * Check if input is pending.
- *
- * @return {boolean}
- */
-OO.ui.TextInputWidget.prototype.isPending = function () {
-       return !!this.pending;
-};
-
-/**
- * Increase the pending stack.
- *
- * @chainable
- */
-OO.ui.TextInputWidget.prototype.pushPending = function () {
-       if ( this.pending === 0 ) {
-               this.$element.addClass( 'oo-ui-textInputWidget-pending' );
-               this.$input.addClass( 'oo-ui-texture-pending' );
-       }
-       this.pending++;
-
-       return this;
-};
-
-/**
- * Reduce the pending stack.
- *
- * Clamped at zero.
- *
- * @chainable
- */
-OO.ui.TextInputWidget.prototype.popPending = function () {
-       if ( this.pending === 1 ) {
-               this.$element.removeClass( 'oo-ui-textInputWidget-pending' );
-               this.$input.removeClass( 'oo-ui-texture-pending' );
-       }
-       this.pending = Math.max( 0, this.pending - 1 );
-
-       return this;
-};
-
 /**
  * Select the contents of the input.
  *
@@ -9805,7 +9835,7 @@ OO.ui.PopupWidget = function OoUiPopupWidget( config ) {
        this.$head = this.$( '<div>' );
        this.$body = this.$( '<div>' );
        this.$anchor = this.$( '<div>' );
-       this.$container = config.$container || this.$( 'body' );
+       this.$container = config.$container; // If undefined, will be computed lazily in updateDimensions()
        this.autoClose = !!config.autoClose;
        this.$autoCloseIgnore = config.$autoCloseIgnore;
        this.transitionTimeout = null;
@@ -9987,26 +10017,37 @@ OO.ui.PopupWidget.prototype.setSize = function ( width, height, transition ) {
  * @chainable
  */
 OO.ui.PopupWidget.prototype.updateDimensions = function ( transition ) {
-       var widget = this,
-               padding = 10,
-               originOffset = Math.round( this.$element.offset().left ),
-               containerLeft = Math.round( this.$container.offset().left ),
-               containerWidth = this.$container.innerWidth(),
-               containerRight = containerLeft + containerWidth,
-               popupOffset = this.width * ( { left: 0, center: -0.5, right: -1 } )[this.align],
-               anchorWidth = this.$anchor.width(),
-               popupLeft = popupOffset - padding,
-               popupRight = popupOffset + padding + this.width + padding,
-               overlapLeft = ( originOffset + popupLeft ) - containerLeft,
-               overlapRight = containerRight - ( originOffset + popupRight );
+       var popupOffset, originOffset, containerLeft, containerWidth, containerRight,
+               popupLeft, popupRight, overlapLeft, overlapRight, anchorWidth,
+               widget = this,
+               padding = 10;
 
-       // Prevent transition from being interrupted
-       clearTimeout( this.transitionTimeout );
-       if ( transition ) {
-               // Enable transition
-               this.$element.addClass( 'oo-ui-popupWidget-transitioning' );
+       if ( !this.$container ) {
+               // Lazy-initialize $container if not specified in constructor
+               this.$container = this.$( this.getClosestScrollableElementContainer() );
        }
 
+       // Set height and width before measuring things, since it might cause our measurements
+       // to change (e.g. due to scrollbars appearing or disappearing)
+       this.$popup.css( {
+               width: this.width,
+               height: this.height !== null ? this.height : 'auto'
+       } );
+
+       // Compute initial popupOffset based on alignment
+       popupOffset = this.width * ( { left: 0, center: -0.5, right: -1 } )[this.align];
+
+       // Figure out if this will cause the popup to go beyond the edge of the container
+       originOffset = Math.round( this.$element.offset().left );
+       containerLeft = Math.round( this.$container.offset().left );
+       containerWidth = this.$container.innerWidth();
+       containerRight = containerLeft + containerWidth;
+       popupLeft = popupOffset - padding;
+       popupRight = popupOffset + padding + this.width + padding;
+       overlapLeft = ( originOffset + popupLeft ) - containerLeft;
+       overlapRight = containerRight - ( originOffset + popupRight );
+
+       // Adjust offset to make the popup not go beyond the edge, if needed
        if ( overlapRight < 0 ) {
                popupOffset += overlapRight;
        } else if ( overlapLeft < 0 ) {
@@ -10014,18 +10055,22 @@ OO.ui.PopupWidget.prototype.updateDimensions = function ( transition ) {
        }
 
        // Adjust offset to avoid anchor being rendered too close to the edge
+       anchorWidth = this.$anchor.width();
        if ( this.align === 'right' ) {
                popupOffset += anchorWidth;
        } else if ( this.align === 'left' ) {
                popupOffset -= anchorWidth;
        }
 
-       // Position body relative to anchor and resize
-       this.$popup.css( {
-               left: popupOffset,
-               width: this.width,
-               height: this.height !== null ? this.height : 'auto'
-       } );
+       // Prevent transition from being interrupted
+       clearTimeout( this.transitionTimeout );
+       if ( transition ) {
+               // Enable transition
+               this.$element.addClass( 'oo-ui-popupWidget-transitioning' );
+       }
+
+       // Position body relative to anchor
+       this.$popup.css( 'left', popupOffset );
 
        if ( transition ) {
                // Prevent transitioning after transition is complete
@@ -11060,6 +11105,13 @@ OO.ui.TextInputMenuWidget.prototype.toggle = function ( visible ) {
 
        var change = visible !== this.isVisible();
 
+       if ( change && visible ) {
+               // Make sure the width is set before the parent method runs.
+               // After this we have to call this.position(); again to actually
+               // position ourselves correctly.
+               this.position();
+       }
+
        // Parent method
        OO.ui.TextInputMenuWidget.super.prototype.toggle.call( this, visible );
 
@@ -11071,6 +11123,7 @@ OO.ui.TextInputMenuWidget.prototype.toggle = function ( visible ) {
                        this.$( this.getElementWindow() ).off( 'resize', this.onWindowResizeHandler );
                }
        }
+
        return this;
 };
 
@@ -11105,6 +11158,8 @@ OO.ui.TextInputMenuWidget.prototype.position = function () {
        }
        this.$element.css( dimensions );
        this.setIdealSize( $container.width() );
+       // We updated the position, so re-evaluate the clipping state
+       this.clip();
 
        return this;
 };
diff --git a/resources/lib/oojs-ui/oojs-ui.rtl.css b/resources/lib/oojs-ui/oojs-ui.rtl.css
new file mode 100644 (file)
index 0000000..7f1fa34
--- /dev/null
@@ -0,0 +1,112 @@
+/*!
+ * OOjs UI v0.1.0
+ * https://www.mediawiki.org/wiki/OOjs_UI
+ *
+ * Copyright 2011–2014 OOjs Team and other contributors.
+ * Released under the MIT license
+ * http://oojs.mit-license.org
+ *
+ * Date: 2014-09-11T19:39:50Z
+ */
+/*
+ * Blank theme mixins.
+ *
+ * Base styles invoke these mixins at the end of their definitions. Override these mixins to add
+ * additional rules to the base styles.
+ */
+.oo-ui-icon-add-item {
+  background-image: /* @embed */ url(images/icons/add-item.png);
+}
+.oo-ui-icon-advanced {
+  background-image: /* @embed */ url(images/icons/advanced.png);
+}
+.oo-ui-icon-alert {
+  background-image: /* @embed */ url(images/icons/alert.png);
+}
+.oo-ui-icon-check {
+  background-image: /* @embed */ url(images/icons/check.png);
+}
+.oo-ui-icon-clear {
+  background-image: /* @embed */ url(images/icons/clear.png);
+}
+.oo-ui-icon-close {
+  background-image: /* @embed */ url(images/icons/close.png);
+}
+.oo-ui-icon-code {
+  background-image: /* @embed */ url(images/icons/code.png);
+}
+.oo-ui-icon-collapse {
+  background-image: /* @embed */ url(images/icons/collapse.png);
+}
+.oo-ui-icon-comment {
+  background-image: /* @embed */ url(images/icons/comment.png);
+}
+.oo-ui-icon-expand {
+  background-image: /* @embed */ url(images/icons/expand.png);
+}
+.oo-ui-icon-help {
+  background-image: /* @embed */ url(images/icons/help.png);
+}
+.oo-ui-icon-info {
+  background-image: /* @embed */ url(images/icons/info.png);
+}
+.oo-ui-icon-link {
+  background-image: /* @embed */ url(images/icons/link.png);
+}
+.oo-ui-icon-menu {
+  background-image: /* @embed */ url(images/icons/menu.png);
+}
+.oo-ui-icon-next {
+  background-image: /* @embed */ url(images/icons/move-rtl.png);
+}
+.oo-ui-icon-picture {
+  background-image: /* @embed */ url(images/icons/picture.png);
+}
+.oo-ui-icon-previous {
+  background-image: /* @embed */ url(images/icons/move-ltr.png);
+}
+.oo-ui-icon-redo {
+  background-image: /* @embed */ url(images/icons/arched-arrow-rtl.png);
+}
+.oo-ui-icon-remove {
+  background-image: /* @embed */ url(images/icons/remove.png);
+}
+.oo-ui-icon-search {
+  background-image: /* @embed */ url(images/icons/search.png);
+}
+.oo-ui-icon-settings {
+  background-image: /* @embed */ url(images/icons/settings.png);
+}
+.oo-ui-icon-tag {
+  background-image: /* @embed */ url(images/icons/tag.png);
+}
+.oo-ui-icon-undo {
+  background-image: /* @embed */ url(images/icons/arched-arrow-ltr.png);
+}
+.oo-ui-icon-window {
+  background-image: /* @embed */ url(images/icons/window.png);
+}
+.oo-ui-indicator-alert {
+  background-image: /* @embed */ url(images/indicators/alert.png);
+}
+.oo-ui-indicator-down {
+  background-image: /* @embed */ url(images/indicators/arrow-down.png);
+}
+.oo-ui-indicator-next {
+  background-image: /* @embed */ url(images/indicators/arrow-rtl.png);
+}
+.oo-ui-indicator-previous {
+  background-image: /* @embed */ url(images/indicators/arrow-ltr.png);
+}
+.oo-ui-indicator-required {
+  background-image: /* @embed */ url(images/indicators/required.png);
+}
+.oo-ui-indicator-up {
+  background-image: /* @embed */ url(images/indicators/arrow-up.png);
+}
+.oo-ui-texture-pending {
+  background-image: /* @embed */ url(images/textures/pending.gif);
+}
+.oo-ui-texture-transparency {
+  background-image: /* @embed */ url(images/textures/transparency.png);
+}
index ffd1873..aafdff3 100644 (file)
@@ -1,12 +1,12 @@
 /*!
- * OOjs UI v0.1.0-pre (f9c217dfa4)
+ * OOjs UI v0.1.0-pre (f2c3f12959)
  * https://www.mediawiki.org/wiki/OOjs_UI
  *
  * Copyright 2011–2014 OOjs Team and other contributors.
  * Released under the MIT license
  * http://oojs.mit-license.org
  *
- * Date: 2014-09-10T17:25:40Z
+ * Date: 2014-09-18T23:22:20Z
  */
 /*
  * Blank theme mixins.
  * additional rules to the base styles.
  */
 .oo-ui-icon-add-item {
-  background-image: /* @embed */ url(images/icons/add-item.svg);
+       background-image: /* @embed */ url(images/icons/add-item.svg);
 }
 .oo-ui-icon-advanced {
-  background-image: /* @embed */ url(images/icons/advanced.svg);
+       background-image: /* @embed */ url(images/icons/advanced.svg);
 }
 .oo-ui-icon-alert {
-  background-image: /* @embed */ url(images/icons/alert.svg);
+       background-image: /* @embed */ url(images/icons/alert.svg);
 }
 .oo-ui-icon-check {
-  background-image: /* @embed */ url(images/icons/check.svg);
+       background-image: /* @embed */ url(images/icons/check.svg);
 }
 .oo-ui-icon-clear {
-  background-image: /* @embed */ url(images/icons/clear.svg);
+       background-image: /* @embed */ url(images/icons/clear.svg);
 }
 .oo-ui-icon-close {
-  background-image: /* @embed */ url(images/icons/close.svg);
+       background-image: /* @embed */ url(images/icons/close.svg);
 }
 .oo-ui-icon-code {
-  background-image: /* @embed */ url(images/icons/code.svg);
+       background-image: /* @embed */ url(images/icons/code.svg);
 }
 .oo-ui-icon-collapse {
-  background-image: /* @embed */ url(images/icons/collapse.svg);
+       background-image: /* @embed */ url(images/icons/collapse.svg);
 }
 .oo-ui-icon-comment {
-  background-image: /* @embed */ url(images/icons/comment.svg);
+       background-image: /* @embed */ url(images/icons/comment.svg);
 }
 .oo-ui-icon-expand {
-  background-image: /* @embed */ url(images/icons/expand.svg);
+       background-image: /* @embed */ url(images/icons/expand.svg);
 }
 .oo-ui-icon-help {
-  background-image: /* @embed */ url(images/icons/help.svg);
+       background-image: /* @embed */ url(images/icons/help.svg);
 }
 .oo-ui-icon-info {
-  background-image: /* @embed */ url(images/icons/info.svg);
+       background-image: /* @embed */ url(images/icons/info.svg);
 }
 .oo-ui-icon-link {
-  background-image: /* @embed */ url(images/icons/link.svg);
+       background-image: /* @embed */ url(images/icons/link.svg);
 }
 .oo-ui-icon-menu {
-  background-image: /* @embed */ url(images/icons/menu.svg);
+       background-image: /* @embed */ url(images/icons/menu.svg);
 }
 .oo-ui-icon-next {
-  background-image: /* @embed */ url(images/icons/move-ltr.svg);
+       background-image: /* @embed */ url(images/icons/move-ltr.svg);
 }
 .oo-ui-icon-picture {
-  background-image: /* @embed */ url(images/icons/picture.svg);
+       background-image: /* @embed */ url(images/icons/picture.svg);
 }
 .oo-ui-icon-previous {
-  background-image: /* @embed */ url(images/icons/move-rtl.svg);
+       background-image: /* @embed */ url(images/icons/move-rtl.svg);
 }
 .oo-ui-icon-redo {
-  background-image: /* @embed */ url(images/icons/arched-arrow-ltr.svg);
+       background-image: /* @embed */ url(images/icons/arched-arrow-ltr.svg);
 }
 .oo-ui-icon-remove {
-  background-image: /* @embed */ url(images/icons/remove.svg);
+       background-image: /* @embed */ url(images/icons/remove.svg);
 }
 .oo-ui-icon-search {
-  background-image: /* @embed */ url(images/icons/search.svg);
+       background-image: /* @embed */ url(images/icons/search.svg);
 }
 .oo-ui-icon-settings {
-  background-image: /* @embed */ url(images/icons/settings.svg);
+       background-image: /* @embed */ url(images/icons/settings.svg);
 }
 .oo-ui-icon-tag {
-  background-image: /* @embed */ url(images/icons/tag.svg);
+       background-image: /* @embed */ url(images/icons/tag.svg);
 }
 .oo-ui-icon-undo {
-  background-image: /* @embed */ url(images/icons/arched-arrow-rtl.svg);
+       background-image: /* @embed */ url(images/icons/arched-arrow-rtl.svg);
 }
 .oo-ui-icon-window {
-  background-image: /* @embed */ url(images/icons/window.svg);
+       background-image: /* @embed */ url(images/icons/window.svg);
 }
 .oo-ui-indicator-alert {
-  background-image: /* @embed */ url(images/indicators/alert.svg);
+       background-image: /* @embed */ url(images/indicators/alert.svg);
 }
 .oo-ui-indicator-down {
-  background-image: /* @embed */ url(images/indicators/arrow-down.svg);
+       background-image: /* @embed */ url(images/indicators/arrow-down.svg);
 }
 .oo-ui-indicator-next {
-  background-image: /* @embed */ url(images/indicators/arrow-ltr.svg);
+       background-image: /* @embed */ url(images/indicators/arrow-ltr.svg);
 }
 .oo-ui-indicator-previous {
-  background-image: /* @embed */ url(images/indicators/arrow-rtl.svg);
+       background-image: /* @embed */ url(images/indicators/arrow-rtl.svg);
 }
 .oo-ui-indicator-required {
-  background-image: /* @embed */ url(images/indicators/required.svg);
+       background-image: /* @embed */ url(images/indicators/required.svg);
 }
 .oo-ui-indicator-up {
-  background-image: /* @embed */ url(images/indicators/arrow-up.svg);
+       background-image: /* @embed */ url(images/indicators/arrow-up.svg);
 }
 .oo-ui-texture-pending {
-  background-image: /* @embed */ url(images/textures/pending.gif);
+       background-image: /* @embed */ url(images/textures/pending.gif);
 }
 .oo-ui-texture-transparency {
-  background-image: /* @embed */ url(images/textures/transparency.svg);
+       background-image: /* @embed */ url(images/textures/transparency.svg);
 }
diff --git a/resources/lib/oojs-ui/oojs-ui.svg.rtl.css b/resources/lib/oojs-ui/oojs-ui.svg.rtl.css
new file mode 100644 (file)
index 0000000..5a78d6b
--- /dev/null
@@ -0,0 +1,112 @@
+/*!
+ * OOjs UI v0.1.0
+ * https://www.mediawiki.org/wiki/OOjs_UI
+ *
+ * Copyright 2011–2014 OOjs Team and other contributors.
+ * Released under the MIT license
+ * http://oojs.mit-license.org
+ *
+ * Date: 2014-09-11T19:39:50Z
+ */
+/*
+ * Blank theme mixins.
+ *
+ * Base styles invoke these mixins at the end of their definitions. Override these mixins to add
+ * additional rules to the base styles.
+ */
+.oo-ui-icon-add-item {
+  background-image: /* @embed */ url(images/icons/add-item.svg);
+}
+.oo-ui-icon-advanced {
+  background-image: /* @embed */ url(images/icons/advanced.svg);
+}
+.oo-ui-icon-alert {
+  background-image: /* @embed */ url(images/icons/alert.svg);
+}
+.oo-ui-icon-check {
+  background-image: /* @embed */ url(images/icons/check.svg);
+}
+.oo-ui-icon-clear {
+  background-image: /* @embed */ url(images/icons/clear.svg);
+}
+.oo-ui-icon-close {
+  background-image: /* @embed */ url(images/icons/close.svg);
+}
+.oo-ui-icon-code {
+  background-image: /* @embed */ url(images/icons/code.svg);
+}
+.oo-ui-icon-collapse {
+  background-image: /* @embed */ url(images/icons/collapse.svg);
+}
+.oo-ui-icon-comment {
+  background-image: /* @embed */ url(images/icons/comment.svg);
+}
+.oo-ui-icon-expand {
+  background-image: /* @embed */ url(images/icons/expand.svg);
+}
+.oo-ui-icon-help {
+  background-image: /* @embed */ url(images/icons/help.svg);
+}
+.oo-ui-icon-info {
+  background-image: /* @embed */ url(images/icons/info.svg);
+}
+.oo-ui-icon-link {
+  background-image: /* @embed */ url(images/icons/link.svg);
+}
+.oo-ui-icon-menu {
+  background-image: /* @embed */ url(images/icons/menu.svg);
+}
+.oo-ui-icon-next {
+  background-image: /* @embed */ url(images/icons/move-rtl.svg);
+}
+.oo-ui-icon-picture {
+  background-image: /* @embed */ url(images/icons/picture.svg);
+}
+.oo-ui-icon-previous {
+  background-image: /* @embed */ url(images/icons/move-ltr.svg);
+}
+.oo-ui-icon-redo {
+  background-image: /* @embed */ url(images/icons/arched-arrow-rtl.svg);
+}
+.oo-ui-icon-remove {
+  background-image: /* @embed */ url(images/icons/remove.svg);
+}
+.oo-ui-icon-search {
+  background-image: /* @embed */ url(images/icons/search.svg);
+}
+.oo-ui-icon-settings {
+  background-image: /* @embed */ url(images/icons/settings.svg);
+}
+.oo-ui-icon-tag {
+  background-image: /* @embed */ url(images/icons/tag.svg);
+}
+.oo-ui-icon-undo {
+  background-image: /* @embed */ url(images/icons/arched-arrow-ltr.svg);
+}
+.oo-ui-icon-window {
+  background-image: /* @embed */ url(images/icons/window.svg);
+}
+.oo-ui-indicator-alert {
+  background-image: /* @embed */ url(images/indicators/alert.svg);
+}
+.oo-ui-indicator-down {
+  background-image: /* @embed */ url(images/indicators/arrow-down.svg);
+}
+.oo-ui-indicator-next {
+  background-image: /* @embed */ url(images/indicators/arrow-rtl.svg);
+}
+.oo-ui-indicator-previous {
+  background-image: /* @embed */ url(images/indicators/arrow-ltr.svg);
+}
+.oo-ui-indicator-required {
+  background-image: /* @embed */ url(images/indicators/required.svg);
+}
+.oo-ui-indicator-up {
+  background-image: /* @embed */ url(images/indicators/arrow-up.svg);
+}
+.oo-ui-texture-pending {
+  background-image: /* @embed */ url(images/textures/pending.gif);
+}
+.oo-ui-texture-transparency {
+  background-image: /* @embed */ url(images/textures/transparency.svg);
+}
index 4eaf611..c62df22 100644 (file)
@@ -1,12 +1,12 @@
 /*!
- * OOjs v1.1.0 optimised for jQuery
+ * OOjs v1.1.1 optimised for jQuery
  * https://www.mediawiki.org/wiki/OOjs
  *
  * Copyright 2011-2014 OOjs Team and other contributors.
  * Released under the MIT license
  * http://oojs.mit-license.org
  *
- * Date: 2014-08-31T21:15:46Z
+ * Date: 2014-09-11T00:40:09Z
  */
 ( function ( global ) {
 
@@ -253,7 +253,10 @@ oo.compare = function ( a, b, asymmetrical ) {
                aType = typeof aValue;
                bType = typeof bValue;
                if ( aType !== bType ||
-                       ( ( aType === 'string' || aType === 'number' ) && aValue !== bValue ) ||
+                       (
+                               ( aType === 'string' || aType === 'number' || aType === 'boolean' ) &&
+                               aValue !== bValue
+                       ) ||
                        ( aValue === Object( aValue ) && !oo.compare( aValue, bValue, asymmetrical ) ) ) {
                        return false;
                }
diff --git a/resources/src/mediawiki.action/mediawiki.action.edit.css b/resources/src/mediawiki.action/mediawiki.action.edit.css
new file mode 100644 (file)
index 0000000..45ba543
--- /dev/null
@@ -0,0 +1,18 @@
+/*!
+ * Styles for elements of the editing form, loaded only when JavaScript is enabled.
+ */
+
+.mw-toolbar-editbutton {
+       width: 23px;
+       height: 22px;
+       cursor: pointer;
+       vertical-align: middle;
+       /* Cross-browser inline-block */
+       /* Firefox 2 */
+       display: -moz-inline-block;
+       /* Modern browsers */
+       display: inline-block;
+       /* IE7 */
+       zoom: 1;
+       *display: inline;
+}
index e850276..4519b04 100644 (file)
@@ -15,6 +15,8 @@
         * @private
         */
        function insertButton( b, speedTip, tagOpen, tagClose, sampleText, imageId ) {
+               var $button;
+
                // Backwards compatibility
                if ( typeof b !== 'object' ) {
                        b = {
                                imageId: imageId
                        };
                }
-               var $image = $( '<img>' ).attr( {
-                       width: 23,
-                       height: 22,
+
+               if ( b.imageFile ) {
+                       $button = $( '<img>' ).attr( {
                        src: b.imageFile,
                        alt: b.speedTip,
                        title: b.speedTip,
                        id: b.imageId || undefined,
                        'class': 'mw-toolbar-editbutton'
-               } ).click( function ( e ) {
+                       } );
+               } else {
+                       $button = $( '<div>' ).attr( {
+                               title: b.speedTip,
+                               id: b.imageId || undefined,
+                               'class': 'mw-toolbar-editbutton'
+                       } );
+               }
+
+               $button.click( function ( e ) {
                        if ( b.onClick !== undefined ) {
                                b.onClick( e );
                        } else {
@@ -44,7 +55,7 @@
                        return false;
                } );
 
-               $toolbar.append( $image );
+               $toolbar.append( $button );
        }
 
        isReady = false;
@@ -74,7 +85,7 @@
                 * @param {Object} button Object with the following properties.
                 *  You are required to provide *either* the `onClick` parameter, or the three parameters
                 *  `tagOpen`, `tagClose` and `sampleText`, but not both (they're mutually exclusive).
-                * @param {string} button.imageFile Image to use for the button.
+                * @param {string} [button.imageFile] Image to use for the button.
                 * @param {string} button.speedTip Tooltip displayed when user mouses over the button.
                 * @param {Function} [button.onClick] Function to be executed when the button is clicked.
                 * @param {string} [button.tagOpen]
@@ -82,7 +93,8 @@
                 * @param {string} [button.sampleText] Alternative to `onClick`. `tagOpen`, `tagClose` and
                 *  `sampleText` together provide the markup that should be inserted into page text at
                 *  current cursor position.
-                * @param {string} [button.imageId] `id` attribute of the button HTML element.
+                * @param {string} [button.imageId] `id` attribute of the button HTML element. Can be
+         *  used to define the image with CSS if it's not provided as `imageFile`.
                 */
                addButton: function () {
                        if ( isReady ) {
diff --git a/resources/src/mediawiki.action/mediawiki.action.edit.toolbar/images/ar/button_bold.png b/resources/src/mediawiki.action/mediawiki.action.edit.toolbar/images/ar/button_bold.png
new file mode 100644 (file)
index 0000000..e524f6c
Binary files /dev/null and b/resources/src/mediawiki.action/mediawiki.action.edit.toolbar/images/ar/button_bold.png differ
diff --git a/resources/src/mediawiki.action/mediawiki.action.edit.toolbar/images/ar/button_headline.png b/resources/src/mediawiki.action/mediawiki.action.edit.toolbar/images/ar/button_headline.png
new file mode 100644 (file)
index 0000000..398e561
Binary files /dev/null and b/resources/src/mediawiki.action/mediawiki.action.edit.toolbar/images/ar/button_headline.png differ
diff --git a/resources/src/mediawiki.action/mediawiki.action.edit.toolbar/images/ar/button_italic.png b/resources/src/mediawiki.action/mediawiki.action.edit.toolbar/images/ar/button_italic.png
new file mode 100644 (file)
index 0000000..6ec73e9
Binary files /dev/null and b/resources/src/mediawiki.action/mediawiki.action.edit.toolbar/images/ar/button_italic.png differ
diff --git a/resources/src/mediawiki.action/mediawiki.action.edit.toolbar/images/ar/button_link.png b/resources/src/mediawiki.action/mediawiki.action.edit.toolbar/images/ar/button_link.png
new file mode 100644 (file)
index 0000000..c9c63f6
Binary files /dev/null and b/resources/src/mediawiki.action/mediawiki.action.edit.toolbar/images/ar/button_link.png differ
diff --git a/resources/src/mediawiki.action/mediawiki.action.edit.toolbar/images/ar/button_nowiki.png b/resources/src/mediawiki.action/mediawiki.action.edit.toolbar/images/ar/button_nowiki.png
new file mode 100644 (file)
index 0000000..743ea61
Binary files /dev/null and b/resources/src/mediawiki.action/mediawiki.action.edit.toolbar/images/ar/button_nowiki.png differ
diff --git a/resources/src/mediawiki.action/mediawiki.action.edit.toolbar/images/be-tarask/button_bold.png b/resources/src/mediawiki.action/mediawiki.action.edit.toolbar/images/be-tarask/button_bold.png
new file mode 100644 (file)
index 0000000..5c10cfe
Binary files /dev/null and b/resources/src/mediawiki.action/mediawiki.action.edit.toolbar/images/be-tarask/button_bold.png differ
diff --git a/resources/src/mediawiki.action/mediawiki.action.edit.toolbar/images/be-tarask/button_italic.png b/resources/src/mediawiki.action/mediawiki.action.edit.toolbar/images/be-tarask/button_italic.png
new file mode 100644 (file)
index 0000000..72209d7
Binary files /dev/null and b/resources/src/mediawiki.action/mediawiki.action.edit.toolbar/images/be-tarask/button_italic.png differ
diff --git a/resources/src/mediawiki.action/mediawiki.action.edit.toolbar/images/be-tarask/button_link.png b/resources/src/mediawiki.action/mediawiki.action.edit.toolbar/images/be-tarask/button_link.png
new file mode 100644 (file)
index 0000000..09c86fb
Binary files /dev/null and b/resources/src/mediawiki.action/mediawiki.action.edit.toolbar/images/be-tarask/button_link.png differ
diff --git a/resources/src/mediawiki.action/mediawiki.action.edit.toolbar/images/de/button_bold.png b/resources/src/mediawiki.action/mediawiki.action.edit.toolbar/images/de/button_bold.png
new file mode 100644 (file)
index 0000000..367d5bc
Binary files /dev/null and b/resources/src/mediawiki.action/mediawiki.action.edit.toolbar/images/de/button_bold.png differ
diff --git a/resources/src/mediawiki.action/mediawiki.action.edit.toolbar/images/de/button_italic.png b/resources/src/mediawiki.action/mediawiki.action.edit.toolbar/images/de/button_italic.png
new file mode 100644 (file)
index 0000000..fdd8c9f
Binary files /dev/null and b/resources/src/mediawiki.action/mediawiki.action.edit.toolbar/images/de/button_italic.png differ
diff --git a/resources/src/mediawiki.action/mediawiki.action.edit.toolbar/images/en/button_bold.png b/resources/src/mediawiki.action/mediawiki.action.edit.toolbar/images/en/button_bold.png
new file mode 100644 (file)
index 0000000..75c3f10
Binary files /dev/null and b/resources/src/mediawiki.action/mediawiki.action.edit.toolbar/images/en/button_bold.png differ
diff --git a/resources/src/mediawiki.action/mediawiki.action.edit.toolbar/images/en/button_extlink.png b/resources/src/mediawiki.action/mediawiki.action.edit.toolbar/images/en/button_extlink.png
new file mode 100644 (file)
index 0000000..458943c
Binary files /dev/null and b/resources/src/mediawiki.action/mediawiki.action.edit.toolbar/images/en/button_extlink.png differ
diff --git a/resources/src/mediawiki.action/mediawiki.action.edit.toolbar/images/en/button_headline.png b/resources/src/mediawiki.action/mediawiki.action.edit.toolbar/images/en/button_headline.png
new file mode 100644 (file)
index 0000000..9cf751d
Binary files /dev/null and b/resources/src/mediawiki.action/mediawiki.action.edit.toolbar/images/en/button_headline.png differ
diff --git a/resources/src/mediawiki.action/mediawiki.action.edit.toolbar/images/en/button_hr.png b/resources/src/mediawiki.action/mediawiki.action.edit.toolbar/images/en/button_hr.png
new file mode 100644 (file)
index 0000000..47e1ca4
Binary files /dev/null and b/resources/src/mediawiki.action/mediawiki.action.edit.toolbar/images/en/button_hr.png differ
diff --git a/resources/src/mediawiki.action/mediawiki.action.edit.toolbar/images/en/button_image.png b/resources/src/mediawiki.action/mediawiki.action.edit.toolbar/images/en/button_image.png
new file mode 100644 (file)
index 0000000..6919296
Binary files /dev/null and b/resources/src/mediawiki.action/mediawiki.action.edit.toolbar/images/en/button_image.png differ
diff --git a/resources/src/mediawiki.action/mediawiki.action.edit.toolbar/images/en/button_italic.png b/resources/src/mediawiki.action/mediawiki.action.edit.toolbar/images/en/button_italic.png
new file mode 100644 (file)
index 0000000..527fbd1
Binary files /dev/null and b/resources/src/mediawiki.action/mediawiki.action.edit.toolbar/images/en/button_italic.png differ
diff --git a/resources/src/mediawiki.action/mediawiki.action.edit.toolbar/images/en/button_link.png b/resources/src/mediawiki.action/mediawiki.action.edit.toolbar/images/en/button_link.png
new file mode 100644 (file)
index 0000000..eb5634b
Binary files /dev/null and b/resources/src/mediawiki.action/mediawiki.action.edit.toolbar/images/en/button_link.png differ
diff --git a/resources/src/mediawiki.action/mediawiki.action.edit.toolbar/images/en/button_media.png b/resources/src/mediawiki.action/mediawiki.action.edit.toolbar/images/en/button_media.png
new file mode 100644 (file)
index 0000000..4194ec1
Binary files /dev/null and b/resources/src/mediawiki.action/mediawiki.action.edit.toolbar/images/en/button_media.png differ
diff --git a/resources/src/mediawiki.action/mediawiki.action.edit.toolbar/images/en/button_nowiki.png b/resources/src/mediawiki.action/mediawiki.action.edit.toolbar/images/en/button_nowiki.png
new file mode 100644 (file)
index 0000000..2ba818d
Binary files /dev/null and b/resources/src/mediawiki.action/mediawiki.action.edit.toolbar/images/en/button_nowiki.png differ
diff --git a/resources/src/mediawiki.action/mediawiki.action.edit.toolbar/images/en/button_sig.png b/resources/src/mediawiki.action/mediawiki.action.edit.toolbar/images/en/button_sig.png
new file mode 100644 (file)
index 0000000..fe34b3f
Binary files /dev/null and b/resources/src/mediawiki.action/mediawiki.action.edit.toolbar/images/en/button_sig.png differ
diff --git a/resources/src/mediawiki.action/mediawiki.action.edit.toolbar/images/fa/button_bold.png b/resources/src/mediawiki.action/mediawiki.action.edit.toolbar/images/fa/button_bold.png
new file mode 100644 (file)
index 0000000..c54d094
Binary files /dev/null and b/resources/src/mediawiki.action/mediawiki.action.edit.toolbar/images/fa/button_bold.png differ
diff --git a/resources/src/mediawiki.action/mediawiki.action.edit.toolbar/images/fa/button_headline.png b/resources/src/mediawiki.action/mediawiki.action.edit.toolbar/images/fa/button_headline.png
new file mode 100644 (file)
index 0000000..9890d15
Binary files /dev/null and b/resources/src/mediawiki.action/mediawiki.action.edit.toolbar/images/fa/button_headline.png differ
diff --git a/resources/src/mediawiki.action/mediawiki.action.edit.toolbar/images/fa/button_italic.png b/resources/src/mediawiki.action/mediawiki.action.edit.toolbar/images/fa/button_italic.png
new file mode 100644 (file)
index 0000000..33f91ed
Binary files /dev/null and b/resources/src/mediawiki.action/mediawiki.action.edit.toolbar/images/fa/button_italic.png differ
diff --git a/resources/src/mediawiki.action/mediawiki.action.edit.toolbar/images/fa/button_link.png b/resources/src/mediawiki.action/mediawiki.action.edit.toolbar/images/fa/button_link.png
new file mode 100644 (file)
index 0000000..76b939e
Binary files /dev/null and b/resources/src/mediawiki.action/mediawiki.action.edit.toolbar/images/fa/button_link.png differ
diff --git a/resources/src/mediawiki.action/mediawiki.action.edit.toolbar/images/fa/button_nowiki.png b/resources/src/mediawiki.action/mediawiki.action.edit.toolbar/images/fa/button_nowiki.png
new file mode 100644 (file)
index 0000000..743ea61
Binary files /dev/null and b/resources/src/mediawiki.action/mediawiki.action.edit.toolbar/images/fa/button_nowiki.png differ
diff --git a/resources/src/mediawiki.action/mediawiki.action.edit.toolbar/images/ksh/LICENSE b/resources/src/mediawiki.action/mediawiki.action.edit.toolbar/images/ksh/LICENSE
new file mode 100644 (file)
index 0000000..47ecfe4
--- /dev/null
@@ -0,0 +1,7 @@
+
+button_italic.png
+-------------------
+Source : http://commons.wikimedia.org/wiki/Image:Button_S_italic.png
+License: Public domain
+Author : Purodha Blissenbach, http://ksh.wikipedia.org/wiki/User:Purodha
+
diff --git a/resources/src/mediawiki.action/mediawiki.action.edit.toolbar/images/ksh/button_italic.png b/resources/src/mediawiki.action/mediawiki.action.edit.toolbar/images/ksh/button_italic.png
new file mode 100644 (file)
index 0000000..15496c0
Binary files /dev/null and b/resources/src/mediawiki.action/mediawiki.action.edit.toolbar/images/ksh/button_italic.png differ
diff --git a/resources/src/mediawiki.action/mediawiki.action.edit.toolbar/images/ru/LICENSE b/resources/src/mediawiki.action/mediawiki.action.edit.toolbar/images/ru/LICENSE
new file mode 100644 (file)
index 0000000..bedcec6
--- /dev/null
@@ -0,0 +1,17 @@
+button_bold.png
+---------------
+Source : http://commons.wikimedia.org/wiki/Image:Button_bold_ukr.png
+License: Public domain
+Author : Alexey Belomoev
+
+button_italic.png
+------------------------
+Source : http://commons.wikimedia.org/wiki/Image:Button_italic_ukr.png
+License: Public domain
+Author : Alexey Belomoev
+
+button_link.png
+-----------------
+Source : http://commons.wikimedia.org/wiki/Image:Button_internal_link_ukr.png
+License: GPL
+Author : Saproj, Erik Möller
diff --git a/resources/src/mediawiki.action/mediawiki.action.edit.toolbar/images/ru/button_bold.png b/resources/src/mediawiki.action/mediawiki.action.edit.toolbar/images/ru/button_bold.png
new file mode 100644 (file)
index 0000000..eae30d9
Binary files /dev/null and b/resources/src/mediawiki.action/mediawiki.action.edit.toolbar/images/ru/button_bold.png differ
diff --git a/resources/src/mediawiki.action/mediawiki.action.edit.toolbar/images/ru/button_italic.png b/resources/src/mediawiki.action/mediawiki.action.edit.toolbar/images/ru/button_italic.png
new file mode 100644 (file)
index 0000000..b958d22
Binary files /dev/null and b/resources/src/mediawiki.action/mediawiki.action.edit.toolbar/images/ru/button_italic.png differ
diff --git a/resources/src/mediawiki.action/mediawiki.action.edit.toolbar/images/ru/button_link.png b/resources/src/mediawiki.action/mediawiki.action.edit.toolbar/images/ru/button_link.png
new file mode 100644 (file)
index 0000000..12ad373
Binary files /dev/null and b/resources/src/mediawiki.action/mediawiki.action.edit.toolbar/images/ru/button_link.png differ
diff --git a/resources/src/mediawiki.action/mediawiki.action.edit.toolbar/mediawiki.action.edit.toolbar.less b/resources/src/mediawiki.action/mediawiki.action.edit.toolbar/mediawiki.action.edit.toolbar.less
new file mode 100644 (file)
index 0000000..d65b284
--- /dev/null
@@ -0,0 +1,42 @@
+@import "mediawiki.mixins";
+
+#mw-editbutton-bold {
+       .background-image("images/@{button-bold}");
+}
+
+#mw-editbutton-italic {
+       .background-image("images/@{button-italic}");
+}
+
+#mw-editbutton-link {
+       .background-image("images/@{button-link}");
+}
+
+#mw-editbutton-extlink {
+       .background-image("images/@{button-extlink}");
+}
+
+#mw-editbutton-headline {
+       .background-image("images/@{button-headline}");
+}
+
+#mw-editbutton-image {
+       .background-image("images/@{button-image}");
+}
+
+#mw-editbutton-media {
+       .background-image("images/@{button-media}");
+}
+
+#mw-editbutton-nowiki {
+       .background-image("images/@{button-nowiki}");
+}
+
+// Who decided to make only this single one different than the name of the data item?
+#mw-editbutton-signature {
+       .background-image("images/@{button-sig}");
+}
+
+#mw-editbutton-hr {
+       .background-image("images/@{button-hr}");
+}
index 8feca4a..fdbb655 100644 (file)
@@ -3,7 +3,7 @@
  */
 
 /* Hide, but keep accessible for screen-readers. */
-.redirectTo {
+.redirectMsg p {
        overflow: hidden;
        height: 0;
        zoom: 1;
index 4424fbd..d92d3bb 100644 (file)
@@ -128,11 +128,6 @@ div.magnify a {
        user-select: none;
 }
 
-/* Temporary WMF deployment hack, to be removed before 1.24 release */
-div.magnify img {
-       display: none;
-}
-
 /* @noflip */
 div.tright {
        clear: right;
index dc142ca..f9069b6 100644 (file)
 ( function ( mw, $ ) {
 
 var ProtectionForm = window.ProtectionForm = {
-       existingMatch: false,
-
        /**
         * Set up the protection chaining interface (i.e. "unlock move permissions" checkbox)
         * on the protection form
-        *
-        * @param opts Object : parameters with members:
-        *     tableId              Identifier of the table containing UI bits
-        *     labelText            Text to use for the checkbox label
-        *     numTypes             The number of protection types
-        *     existingMatch        True if all the existing expiry times match
         */
-       init: function ( opts ) {
-               var box, boxbody, row, cell, check, label;
+       init: function () {
+               var $cell = $( '<td>' ), $row = $( '<tr>' ).append( $cell );
 
-               if ( !( document.createTextNode && document.getElementById && document.getElementsByTagName ) ) {
+               if ( !$( '#mwProtectSet' ).length ) {
                        return false;
                }
 
-               box = document.getElementById( opts.tableId );
-               if ( !box ) {
-                       return false;
+               if ( mw.config.get( 'wgCascadeableLevels' ) !== undefined ) {
+                       $( 'form#mw-Protect-Form' ).submit( this.toggleUnchainedInputs.bind( ProtectionForm, true ) );
                }
+               this.getExpirySelectors().each( function () {
+                       $( this ).change( ProtectionForm.updateExpiryList.bind( ProtectionForm, this ) );
+               } );
+               this.getExpiryInputs().each( function () {
+                       $( this ).on( 'keyup change', ProtectionForm.updateExpiry.bind( ProtectionForm, this ) );
+               } );
+               this.getLevelSelectors().each( function () {
+                       $( this ).change( ProtectionForm.updateLevels.bind( ProtectionForm, this ) );
+               } );
 
-               boxbody = box.getElementsByTagName( 'tbody' )[0];
-               row = document.createElement( 'tr' );
-               boxbody.insertBefore( row, boxbody.firstChild.nextSibling );
-
-               this.existingMatch = opts.existingMatch;
+               $( '#mwProtectSet > tbody > tr:first' ).after( $row );
 
-               cell = document.createElement( 'td' );
-               row.appendChild( cell );
                // If there is only one protection type, there is nothing to chain
-               if ( opts.numTypes > 1 ) {
-                       check = document.createElement( 'input' );
-                       check.id = 'mwProtectUnchained';
-                       check.type = 'checkbox';
-                       $( check ).click( function () {
-                               ProtectionForm.onChainClick();
-                       } );
-
-                       label = document.createElement( 'label' );
-                       label.htmlFor = 'mwProtectUnchained';
-                       label.appendChild( document.createTextNode( opts.labelText ) );
-
-                       cell.appendChild( check );
-                       cell.appendChild( document.createTextNode( ' ' ) );
-                       cell.appendChild( label );
+               if ( $( '[id ^= mw-protect-table-]' ).length > 1 ) {
+                       $cell.append(
+                               $( '<input>' )
+                                       .attr( { id: 'mwProtectUnchained', type: 'checkbox' } )
+                                       .click( this.onChainClick.bind( this ) )
+                                       .prop( 'checked', !this.areAllTypesMatching() ),
+                               document.createTextNode( ' ' ),
+                               $( '<label>' )
+                                       .attr( 'for', 'mwProtectUnchained' )
+                                       .text( mw.msg( 'protect-unchain-permissions' ) )
+                       );
 
-                       check.checked = !this.areAllTypesMatching();
-                       this.enableUnchainedInputs( check.checked );
+                       this.toggleUnchainedInputs( !this.areAllTypesMatching() );
                }
 
                $( '#mwProtect-reason' ).byteLimit( 180 );
 
                this.updateCascadeCheckbox();
-
-               return true;
        },
 
        /**
         * Sets the disabled attribute on the cascade checkbox depending on the current selected levels
         */
        updateCascadeCheckbox: function () {
-               var i, lists, items, selected;
-
-               // For non-existent titles, there is no cascade option
-               if ( !document.getElementById( 'mwProtect-cascade' ) ) {
-                       return;
-               }
-               lists = this.getLevelSelectors();
-               for ( i = 0; i < lists.length; i++ ) {
-                       if ( lists[i].selectedIndex > -1 ) {
-                               items = lists[i].getElementsByTagName( 'option' );
-                               selected = items[ lists[i].selectedIndex ].value;
-                               if ( !this.isCascadeableLevel( selected ) ) {
-                                       document.getElementById( 'mwProtect-cascade' ).checked = false;
-                                       document.getElementById( 'mwProtect-cascade' ).disabled = true;
-                                       return;
-                               }
+               this.getLevelSelectors().each( function () {
+                       if ( !ProtectionForm.isCascadeableLevel( $( this ).val() ) ) {
+                               $( '#mwProtect-cascade' ).prop( { checked: false, disabled: true } );
+                               return false;
+                       } else {
+                               $( '#mwProtect-cascade' ).prop( 'disabled', false );
                        }
-               }
-               document.getElementById( 'mwProtect-cascade' ).disabled = false;
+               } );
        },
 
        /**
         * Checks if a cerain protection level is cascadeable.
-        * @param level {String}
-        * @return {Boolean}
+        *
+        * @param {string} level
+        * @return {boolean}
         */
-       isCascadeableLevel: function (  level ) {
-               var cascadeLevels, len, i;
-
-               cascadeLevels = mw.config.get( 'wgCascadeableLevels' );
-               // cascadeLevels isn't defined on all pages
-               if ( cascadeLevels ) {
-                       for ( i = 0, len = cascadeLevels.length; i < len; i += 1 ) {
-                               if ( cascadeLevels[i] === level ) {
-                                       return true;
-                               }
-                       }
-               }
-               return false;
+       isCascadeableLevel: function ( level ) {
+               return $.inArray( level, mw.config.get( 'wgCascadeableLevels' ) ) !== -1;
        },
 
        /**
         * When protection levels are locked together, update the rest
         * when one action's level changes
         *
-        * @param source Element Level selector that changed
+        * @param {Element} source Level selector that changed
         */
        updateLevels: function ( source ) {
                if ( !this.isUnchained() ) {
@@ -123,28 +89,21 @@ var ProtectionForm = window.ProtectionForm = {
         * When protection levels are locked together, update the
         * expiries when one changes
         *
-        * @param source Element expiry input that changed
+        * @param {Element} source expiry input that changed
         */
 
        updateExpiry: function ( source ) {
-               var expiry, listId, list;
-
                if ( !this.isUnchained() ) {
-                       expiry = source.value;
-                       this.forEachExpiryInput( function ( element ) {
-                               element.value = expiry;
+                       this.getExpiryInputs().each( function () {
+                               this.value = source.value;
                        } );
                }
-               listId = source.id.replace( /^mwProtect-(\w+)-expires$/, 'mwProtectExpirySelection-$1' );
-               list = document.getElementById( listId );
-               if ( list && list.value !== 'othertime' ) {
-                       if ( this.isUnchained() ) {
-                               list.value = 'othertime';
-                       } else {
-                               this.forEachExpirySelector( function ( element ) {
-                                       element.value = 'othertime';
-                               } );
-                       }
+               if ( this.isUnchained() ) {
+                       $( '#' + source.id.replace( /^mwProtect-(\w+)-expires$/, 'mwProtectExpirySelection-$1' ) ).val( 'othertime' );
+               } else {
+                       this.getExpirySelectors().each( function () {
+                               this.value = 'othertime';
+                       } );
                }
        },
 
@@ -152,17 +111,15 @@ var ProtectionForm = window.ProtectionForm = {
         * When protection levels are locked together, update the
         * expiry lists when one changes and clear the custom inputs
         *
-        * @param source Element expiry selector that changed
+        * @param {Element} source Expiry selector that changed
         */
        updateExpiryList: function ( source ) {
-               var expiry;
                if ( !this.isUnchained() ) {
-                       expiry = source.value;
-                       this.forEachExpirySelector( function ( element ) {
-                               element.value = expiry;
+                       this.getExpirySelectors().each( function () {
+                               this.value = source.value;
                        } );
-                       this.forEachExpiryInput( function ( element ) {
-                               element.value = '';
+                       this.getExpiryInputs().each( function () {
+                               this.value = '';
                        } );
                }
        },
@@ -172,44 +129,35 @@ var ProtectionForm = window.ProtectionForm = {
         * when the user changes the "unlock move permissions" checkbox
         */
        onChainClick: function () {
-               if ( this.isUnchained() ) {
-                       this.enableUnchainedInputs( true );
-               } else {
+               this.toggleUnchainedInputs( this.isUnchained() );
+               if ( !this.isUnchained() ) {
                        this.setAllSelectors( this.getMaxLevel() );
-                       this.enableUnchainedInputs( false );
                }
                this.updateCascadeCheckbox();
        },
 
        /**
         * Returns true if the named attribute in all objects in the given array are matching
+        *
+        * @param {Object[]} objects
+        * @param {string} attrName
+        * @return {boolean}
         */
        matchAttribute: function ( objects, attrName ) {
-               var i, element, value;
-
-               // Check levels
-               value = null;
-               for ( i = 0; i < objects.length; i++ ) {
-                       element = objects[i];
-                       if ( value === null ) {
-                               value = element[attrName];
-                       } else {
-                               if ( value !== element[attrName] ) {
-                                       return false;
-                               }
-                       }
-               }
-               return true;
+               return $.map( objects, function ( object ) {
+                       return object[attrName];
+               } ).filter( function ( item, index, a ) {
+                       return index === a.indexOf( item );
+               } ).length === 1;
        },
 
        /**
         * Are all actions protected at the same level, with the same expiry time?
         *
-        * @return boolean
+        * @return {boolean}
         */
        areAllTypesMatching: function () {
-               return this.existingMatch
-                       && this.matchAttribute( this.getLevelSelectors(), 'selectedIndex' )
+               return this.matchAttribute( this.getLevelSelectors(), 'selectedIndex' )
                        && this.matchAttribute( this.getExpirySelectors(), 'selectedIndex' )
                        && this.matchAttribute( this.getExpiryInputs(), 'value' );
        },
@@ -217,7 +165,7 @@ var ProtectionForm = window.ProtectionForm = {
        /**
         * Is protection chaining off?
         *
-        * @return bool
+        * @return {boolean}
         */
        isUnchained: function () {
                var element = document.getElementById( 'mwProtectUnchained' );
@@ -228,160 +176,65 @@ var ProtectionForm = window.ProtectionForm = {
 
        /**
         * Find the highest protection level in any selector
+        * @return {number}
         */
        getMaxLevel: function () {
-               var maxIndex = -1;
-               this.forEachLevelSelector( function ( element ) {
-                       if ( element.selectedIndex > maxIndex ) {
-                               maxIndex = element.selectedIndex;
-                       }
-               } );
-               return maxIndex;
+               return Math.max.apply( Math, this.getLevelSelectors().map( function () {
+                       return this.selectedIndex;
+               } ) );
        },
 
        /**
         * Protect all actions at the specified level
         *
-        * @param index int Protection level
+        * @param {number} index Protection level
         */
        setAllSelectors: function ( index ) {
-               this.forEachLevelSelector( function ( element ) {
-                       if ( element.selectedIndex !== index ) {
-                               element.selectedIndex = index;
-                       }
+               this.getLevelSelectors().each( function () {
+                       this.selectedIndex = index;
                } );
        },
 
-       /**
-        * Apply a callback to each protection selector
-        *
-        * @param func callable Callback function
-        */
-       forEachLevelSelector: function ( func ) {
-               var i, selectors;
-
-               selectors = this.getLevelSelectors();
-               for ( i = 0; i < selectors.length; i++ ) {
-                       func( selectors[i] );
-               }
-       },
-
        /**
         * Get a list of all protection selectors on the page
         *
-        * @return Array
+        * @return {jQuery}
         */
        getLevelSelectors: function () {
-               var i, ours, all, element;
-
-               all = document.getElementsByTagName( 'select' );
-               ours = [];
-               for ( i = 0; i < all.length; i++ ) {
-                       element = all[i];
-                       if ( element.id.match( /^mwProtect-level-/ ) ) {
-                               ours[ours.length] = element;
-                       }
-               }
-               return ours;
-       },
-
-       /**
-        * Apply a callback to each expiry input
-        *
-        * @param func callable Callback function
-        */
-       forEachExpiryInput: function ( func ) {
-               var i, inputs;
-
-               inputs = this.getExpiryInputs();
-               for ( i = 0; i < inputs.length; i++ ) {
-                       func( inputs[i] );
-               }
+               return $( 'select[id ^= mwProtect-level-]' );
        },
 
        /**
         * Get a list of all expiry inputs on the page
         *
-        * @return Array
+        * @return {jQuery}
         */
        getExpiryInputs: function () {
-               var i, all, element, ours;
-
-               all = document.getElementsByTagName( 'input' );
-               ours = [];
-               for ( i = 0; i < all.length; i++ ) {
-                       element = all[i];
-                       if ( element.name.match( /^mwProtect-expiry-/ ) ) {
-                               ours[ours.length] = element;
-                       }
-               }
-               return ours;
-       },
-
-       /**
-        * Apply a callback to each expiry selector list
-        * @param func callable Callback function
-        */
-       forEachExpirySelector: function ( func ) {
-               var i, inputs;
-
-               inputs = this.getExpirySelectors();
-               for ( i = 0; i < inputs.length; i++ ) {
-                       func( inputs[i] );
-               }
+               return $( 'input[id ^= mwProtect-][id $= -expires]' );
        },
 
        /**
         * Get a list of all expiry selector lists on the page
         *
-        * @return Array
+        * @return {jQuery}
         */
        getExpirySelectors: function () {
-               var i, all, ours, element;
-
-               all = document.getElementsByTagName( 'select' );
-               ours = [];
-               for ( i = 0; i < all.length; i++ ) {
-                       element = all[i];
-                       if ( element.id.match( /^mwProtectExpirySelection-/ ) ) {
-                               ours[ours.length] = element;
-                       }
-               }
-               return ours;
+               return $( 'select[id ^= mwProtectExpirySelection-]' );
        },
 
        /**
         * Enable/disable protection selectors and expiry inputs
         *
-        * @param val boolean Enable?
+        * @param {boolean} val Enable?
         */
-       enableUnchainedInputs: function ( val ) {
-               var first = true;
-
-               this.forEachLevelSelector( function ( element ) {
-                       if ( first ) {
-                               first = false;
-                       } else {
-                               element.disabled = !val;
-                       }
-               } );
-               first = true;
-               this.forEachExpiryInput( function ( element ) {
-                       if ( first ) {
-                               first = false;
-                       } else {
-                               element.disabled = !val;
-                       }
-               } );
-               first = true;
-               this.forEachExpirySelector( function ( element ) {
-                       if ( first ) {
-                               first = false;
-                       } else {
-                               element.disabled = !val;
-                       }
-               } );
+       toggleUnchainedInputs: function ( val ) {
+               var setDisabled = function () { this.disabled = !val; };
+               this.getLevelSelectors().slice( 1 ).each( setDisabled );
+               this.getExpiryInputs().slice( 1 ).each( setDisabled );
+               this.getExpirySelectors().slice( 1 ).each( setDisabled );
        }
 };
 
+$( ProtectionForm.init.bind( ProtectionForm ) );
+
 }( mediaWiki, jQuery ) );
index 7896e97..0604773 100644 (file)
@@ -139,10 +139,6 @@ span.texhtml {
        clear: both;
 }
 
-#toolbar img {
-       cursor: pointer;
-}
-
 /**
  * File description page
  */
index 5c6e63b..a403996 100644 (file)
@@ -144,15 +144,18 @@ mw.log.deprecate( win, 'jsMsg', function ( message ) {
 /**
  * Misc. utilities
  *
- * @deprecated since 1.17 Use mediawiki.util instead
+ * @deprecated since 1.17 Use mediawiki.util or jquery.accessKeyLabel instead
  */
 msg = 'Use mediawiki.util instead.';
-mw.log.deprecate( win, 'updateTooltipAccessKeys', mw.util.updateTooltipAccessKeys, msg );
 mw.log.deprecate( win, 'addPortletLink', mw.util.addPortletLink, msg );
 mw.log.deprecate( win, 'appendCSS', mw.util.addCSS, msg );
 msg = 'Use jquery.accessKeyLabel instead.';
 mw.log.deprecate( win, 'tooltipAccessKeyPrefix', 'alt-', msg );
 mw.log.deprecate( win, 'tooltipAccessKeyRegexp', /\[(alt-)?(.)\]$/, msg );
+// mw.util.updateTooltipAccessKeys already generates a deprecation message.
+win.updateTooltipAccessKeys = function () {
+       return mw.util.updateTooltipAccessKeys.apply( null, arguments );
+};
 
 /**
  * Wikipage import methods
index 8c28884..c360e1f 100644 (file)
  * See <http://lesscss.org/#-mixins> for more information about how to write mixins.
  */
 
-.background-image(@url) when (embeddable(@url)) {
-       background-image: embed(@url);
-       background-image: url(@url)!ie;
-}
-
-.background-image(@url) when not (embeddable(@url)) {
-       background-image: url(@url);
+.background-image(@url) {
+       background-image: e('/* @embed */') url(@url);
 }
 
 .vertical-gradient(@startColor: gray, @endColor: white, @startPos: 0, @endPos: 100%) {
  * We do not embed the fallback image on the assumption that the gain for old browsers
  * is not worth the harm done to modern ones.
  */
-.background-image-svg(@svg, @fallback) when (embeddable(@svg)) {
+.background-image-svg(@svg, @fallback) {
        background-image: url(@fallback);
-       /* We don't need the !ie hack because this old IE uses the fallback already */
-       background-image: -webkit-linear-gradient(transparent, transparent), embed(@svg);
-       background-image: linear-gradient(transparent, transparent), embed(@svg);
-}
-
-.background-image-svg(@svg, @fallback) when not (embeddable(@svg)) {
-       background-image: url(@fallback);
-       background-image: -webkit-linear-gradient(transparent, transparent), url(@svg);
-       background-image: linear-gradient(transparent, transparent), url(@svg);
-}
-
-/* Caution: Does not support localisable images */
-.list-style-image(@url) when (embeddable(@url)) {
-       list-style-image: embed(@url);
-       list-style-image: url(@url)!ie;
+       background-image: -webkit-linear-gradient(transparent, transparent), e('/* @embed */') url(@svg);
+       background-image: linear-gradient(transparent, transparent), e('/* @embed */') url(@svg);
 }
 
-.list-style-image(@url) when not (embeddable(@url)) {
-       list-style-image: url(@url);
+.list-style-image(@url) {
+       list-style-image: e('/* @embed */') url(@url);
 }
 
 .transition(@value) {
index 17bf683..e91302b 100644 (file)
@@ -57,3 +57,6 @@
 @colorGrayLight: #ccc;
 @colorGrayLighter: #ddd;
 @colorGrayLightest: #eee;
+
+// Global border radius to be used to buttons and inputs
+@borderRadius: 2px;
index a05a054..246cc81 100644 (file)
@@ -36,6 +36,7 @@
 
        // Things outside the wikipage content
        $( function () {
+               var $nodes;
 
                if ( !supportsPlaceholder ) {
                        // Exclude content to avoid hitting it twice for the (first) wikipage content
                }
 
                // Add accesskey hints to the tooltips
-               mw.util.updateTooltipAccessKeys();
+               if ( document.querySelectorAll ) {
+                       // If we're running on a browser where we can do this efficiently,
+                       // just find all elements that have accesskeys. We can't use jQuery's
+                       // polyfill for the selector since looping over all elements on page
+                       // load might be too slow.
+                       $nodes = $( document.querySelectorAll( '[accesskey]' ) );
+               } else {
+                       // Otherwise go through some elements likely to have accesskeys rather
+                       // than looping over all of them. Unfortunately this will not fully
+                       // work for custom skins with different HTML structures. Input, label
+                       // and button should be rare enough that no optimizations are needed.
+                       $nodes = $( '#column-one a, #mw-head a, #mw-panel a, #p-logo a, input, label, button' );
+               }
+               $nodes.updateTooltipAccessKeys();
 
        } );
 
index 622afe6..7a41708 100644 (file)
@@ -174,11 +174,6 @@ div.magnify a {
        user-select: none;
 }
 
-/* Temporary WMF deployment hack, to be removed before 1.24 release */
-div.magnify img {
-       display: none;
-}
-
 img.thumbborder {
        border: 1px solid #dddddd;
 }
index 3211dea..a6515d2 100644 (file)
@@ -31,7 +31,7 @@
  * Styleguide 1.1.
  */
 span.reference {
-       font-size: smaller;
+       font-size: 80%;
        line-height: 1;
        vertical-align: super;
        unicode-bidi: -moz-isolate;
index e553f44..1f6429b 100644 (file)
@@ -5,7 +5,7 @@ jQuery( function ( $ ) {
        var $preftoc, $preferences, $fieldsets, $legends,
                hash, labelFunc,
                $tzSelect, $tzTextbox, $localtimeHolder, servertime,
-               $checkBoxes;
+               $checkBoxes, savedWindowOnBeforeUnload;
 
        labelFunc = function () {
                return this.id.replace( /^mw-prefsection/g, 'preftab' );
@@ -263,4 +263,43 @@ jQuery( function ( $ ) {
        $( '#mw-input-wpsearcheverything' ).change( function () {
                $checkBoxes.prop( 'disabled', $( this ).prop( 'checked' ) );
        } );
+
+       // Set up a message to notify users if they try to leave the page without
+       // saving.
+       $( '#mw-prefs-form' ).data( 'origdata', $( '#mw-prefs-form' ).serialize() );
+       $( window )
+               .on( 'beforeunload.prefswarning', function () {
+                       var retval;
+
+                       // Check if anything changed
+                       if ( $( '#mw-prefs-form' ).serialize() !== $( '#mw-prefs-form' ).data( 'origdata' ) ) {
+                               // Return our message
+                               retval = mediaWiki.msg( 'prefswarning-warning', mediaWiki.msg( 'saveprefs' ) );
+                       }
+
+                       // Unset the onbeforeunload handler so we don't break page caching in Firefox
+                       savedWindowOnBeforeUnload = window.onbeforeunload;
+                       window.onbeforeunload = null;
+                       if ( retval !== undefined ) {
+                               // ...but if the user chooses not to leave the page, we need to rebind it
+                               setTimeout( function () {
+                                       window.onbeforeunload = savedWindowOnBeforeUnload;
+                               }, 1 );
+                               return retval;
+                       }
+               } )
+               .on( 'pageshow.prefswarning', function () {
+                       // Re-add onbeforeunload handler
+                       if ( !window.onbeforeunload ) {
+                               window.onbeforeunload = savedWindowOnBeforeUnload;
+                       }
+               } );
+       $( '#mw-prefs-form' ).submit( function () {
+               // Unbind our beforeunload handler
+               $( window ).off( '.prefswarning' );
+       } );
+       $( '#mw-prefs-restoreprefs' ).click( function () {
+               // Unbind our beforeunload handler
+               $( window ).off( '.prefswarning' );
+       } );
 } );
index b66f20e..28b1446 100644 (file)
@@ -43,6 +43,7 @@ section.mw-form-header {
        border: 1px solid #c9c9c9;
        padding: 10px;
        text-align: center;
+       margin-bottom: 15px;
 }
 
 .mw-createacct-captcha-assisted {
index 7142d4d..3d60b7a 100644 (file)
 //
 // Styleguide 2.
 
-@buttonBorderRadius: 3px;
 @transitionDuration: .1s;
 @transitionFunction: ease-in-out;
 
 // Neutral button styling
 //
 // Markup:
-// <button class="mw-ui-button">.mw-ui-button</button>
-// <button class="mw-ui-button" disabled>.mw-ui-button</button>
+// <div>
+//   <button class="mw-ui-button">.mw-ui-button</button>
+// </div>
+// <div>
+//   <button class="mw-ui-button" disabled>.mw-ui-button</button>
+// </div>
 //
 // Styleguide 2.1.
 .mw-ui-button {
@@ -43,7 +46,8 @@
 
        // Container styling
        .button-colors(#FFF);
-       border-radius: @buttonBorderRadius;
+       border-radius: @borderRadius;
+       min-width: 70px;
 
        // Ensure that buttons and inputs are nicely aligned when they have differing heights
        vertical-align: middle;
        // using the mw-ui-big class.
        //
        // Markup:
-       // <button class="mw-ui-button mw-ui-big">.mw-ui-button</button>
-       // <button class="mw-ui-button mw-ui-progressive mw-ui-big">.mw-ui-progressive</button>
-       // <button class="mw-ui-button mw-ui-constructive mw-ui-big">.mw-ui-constructive</button>
-       // <button class="mw-ui-button mw-ui-destructive mw-ui-big">.mw-ui-destructive</button>
+       // <div>
+       //   <button class="mw-ui-button mw-ui-big">.mw-ui-button</button>
+       // </div>
+       // <div>
+       //   <button class="mw-ui-button mw-ui-progressive mw-ui-big">.mw-ui-progressive</button>
+       // </div>
+       // <div>
+       //   <button class="mw-ui-button mw-ui-constructive mw-ui-big">.mw-ui-constructive</button>
+       // </div>
+       // <div>
+       //   <button class="mw-ui-button mw-ui-destructive mw-ui-big">.mw-ui-destructive</button>
+       // </div>
        //
        // Styleguide 2.1.6.
        &.mw-ui-big {
        // Some buttons might need to be stacked.
        //
        // Markup:
-       // <button class="mw-ui-button mw-ui-block">.mw-ui-button</button>
-       // <button class="mw-ui-button mw-ui-progressive mw-ui-block">.mw-ui-progressive</button>
-       // <button class="mw-ui-button mw-ui-constructive mw-ui-block">.mw-ui-constructive</button>
-       // <button class="mw-ui-button mw-ui-destructive mw-ui-block">.mw-ui-destructive</button>
+       // <div>
+       //   <button class="mw-ui-button mw-ui-block">.mw-ui-button</button>
+       // </div>
+       // <div>
+       //   <button class="mw-ui-button mw-ui-progressive mw-ui-block">.mw-ui-progressive</button>
+       // </div>
+       // <div>
+       //   <button class="mw-ui-button mw-ui-constructive mw-ui-block">.mw-ui-constructive</button>
+       // </div>
+       // <div>
+       //   <button class="mw-ui-button mw-ui-destructive mw-ui-block">.mw-ui-destructive</button>
+       // </div>
        //
        // Styleguide 2.1.5.
        &.mw-ui-block {
        // .mw-ui-primary is deprecated, kept for compatibility.
        //
        // Markup:
-       // <button class="mw-ui-button mw-ui-progressive">.mw-ui-progressive</button>
-       // <button class="mw-ui-button mw-ui-progressive" disabled>.mw-ui-progressive</button>
+       // <div>
+       //   <button class="mw-ui-button mw-ui-progressive">.mw-ui-progressive</button>
+       // </div>
+       // <div>
+       //   <button class="mw-ui-button mw-ui-progressive" disabled>.mw-ui-progressive</button>
+       // </div>
        //
        // Styleguide 2.1.1.
        &.mw-ui-progressive,
        // e.g. save changes button
        //
        // Markup:
-       // <button class="mw-ui-button mw-ui-constructive">.mw-ui-constructive</button>
-       // <button class="mw-ui-button mw-ui-constructive" disabled>.mw-ui-constructive</button>
+       // <div>
+       //   <button class="mw-ui-button mw-ui-constructive">.mw-ui-constructive</button>
+       // </div>
+       // <div>
+       //   <button class="mw-ui-button mw-ui-constructive" disabled>.mw-ui-constructive</button>
+       // </div>
        //
        // Styleguide 2.1.2.
        &.mw-ui-constructive {
        // This should not be used for cancel buttons.
        //
        // Markup:
-       // <button class="mw-ui-button mw-ui-destructive">.mw-ui-destructive</button>
-       // <button class="mw-ui-button mw-ui-destructive" disabled>.mw-ui-destructive</button>
+       // <div>
+       //   <button class="mw-ui-button mw-ui-destructive">.mw-ui-destructive</button>
+       // </div>
+       // <div>
+       //   <button class="mw-ui-button mw-ui-destructive" disabled>.mw-ui-destructive</button>
+       // </div>
        //
        // Styleguide 2.1.3.
        &.mw-ui-destructive {
        // Use quiet buttons when they are less important and alongisde other progressive/destructive/progressive buttons.
        //
        // Markup:
-       // <button class="mw-ui-button mw-ui-quiet">.mw-ui-button</button>
-       // <button class="mw-ui-button mw-ui-constructive mw-ui-quiet">.mw-ui-constructive</button>
-       // <button class="mw-ui-button mw-ui-constructive mw-ui-quiet" disabled>.mw-ui-constructive</button>
-       // <button class="mw-ui-button mw-ui-destructive mw-ui-quiet">.mw-ui-destructive</button>
-       // <button class="mw-ui-button mw-ui-destructive mw-ui-quiet" disabled>.mw-ui-destructive</button>
-       // <button class="mw-ui-button mw-ui-progressive mw-ui-quiet">.mw-ui-progressive</button>
-       // <button class="mw-ui-button mw-ui-progressive mw-ui-quiet" disabled>.mw-ui-progressive</button>
+       // <div>
+       //   <button class="mw-ui-button mw-ui-quiet">.mw-ui-button</button>
+       // </div>
+       // <div>
+       //   <button class="mw-ui-button mw-ui-constructive mw-ui-quiet">.mw-ui-constructive</button>
+       // </div>
+       // <div>
+       //   <button class="mw-ui-button mw-ui-constructive mw-ui-quiet" disabled>.mw-ui-constructive</button>
+       // </div>
+       // <div>
+       //   <button class="mw-ui-button mw-ui-destructive mw-ui-quiet">.mw-ui-destructive</button>
+       // </div>
+       // <div>
+       //   <button class="mw-ui-button mw-ui-destructive mw-ui-quiet" disabled>.mw-ui-destructive</button>
+       // </div>
+       // <div>
+       //   <button class="mw-ui-button mw-ui-progressive mw-ui-quiet">.mw-ui-progressive</button>
+       // </div>
+       // <div>
+       //   <button class="mw-ui-button mw-ui-progressive mw-ui-quiet" disabled>.mw-ui-progressive</button>
+       // </div>
        //
        // Styleguide 2.1.4.
        &.mw-ui-quiet {
@@ -215,8 +261,8 @@ a.mw-ui-button {
        float: left;
 
        &:first-child {
-               border-top-left-radius: @buttonBorderRadius;
-               border-bottom-left-radius: @buttonBorderRadius;
+               border-top-left-radius: @borderRadius;
+               border-bottom-left-radius: @borderRadius;
        }
 
        &:not(:first-child) {
@@ -224,7 +270,7 @@ a.mw-ui-button {
        }
 
        &:last-child{
-               border-top-right-radius: @buttonBorderRadius;
-               border-bottom-right-radius: @buttonBorderRadius;
+               border-top-right-radius: @borderRadius;
+               border-bottom-right-radius: @borderRadius;
        }
 }
index 6d6fdde..e39646b 100644 (file)
@@ -1,4 +1,5 @@
 @import "mediawiki.mixins";
+@import "mediawiki.ui/variables";
 
 // Checkbox
 //
 
                // the pseudo before element of the label after the checkbox now looks like a checkbox
                & + label {
+                       cursor: pointer;
+
                        &::before {
                                                content: '';
                                                position: absolute;
                                                left: 0;
                                                display: inline-block;
-                                               border-radius: 2px;
+                                               border-radius: @borderRadius;
                                                margin-right: 18px;
                                                width: @checkboxSize;
                                                height: @checkboxSize;
                                                background-color: #fff;
-                                               cursor: pointer;
                                                border: 1px solid grey;
                                        }
                }
                }
 
                // disabled checked boxes have a gray background
-               &:disabled + label::before {
-                       background-color: lightgrey;
+               &:disabled + label {
+                       cursor: default;
+
+                       &::before {
+                               background-color: lightgrey;
+                       }
                }
        }
 }
index 7108fae..1da42a4 100644 (file)
        border: 1px solid @colorFieldBorder;
        .box-sizing(border-box);
        width: 100%;
-       padding: .3em .3em .3em .6em;
+       padding: .4em .3em .2em .6em;
        display: block;
        vertical-align: middle;
+       border-radius: @borderRadius;
        // Override user agent stylesheet properties. Instead use parent element.
        color: inherit;
        font-family: inherit;
@@ -85,6 +86,7 @@ textarea.mw-ui-input {
 // <button class="mw-ui-button mw-ui-constructive">go</button>
 //
 // Styleguide 1.2.
+input[type="number"],
 .mw-ui-input-inline {
        display: inline-block;
        width: auto;
index 4516e20..e29c734 100644 (file)
                                 *
                                 * @param {string} id Short string representing a source wiki, used internally for
                                 *  registered modules to indicate where they should be loaded from (usually lowercase a-z).
-                                * @param {Object|string} loadUrl load.php url, may be an object for backwards-compatability
+                                * @param {Object|string} loadUrl load.php url, may be an object for backwards-compatibility
                                 * @return {boolean}
                                 */
                                addSource: function ( id, loadUrl ) {
index 887885e..2662913 100644 (file)
                        return null;
                },
 
-               /**
-                * Add the appropriate prefix to the accesskey shown in the tooltip.
-                *
-                * If the `$nodes` parameter is given, only those nodes are updated;
-                * otherwise, depending on browser support, we update either all elements
-                * with accesskeys on the page or a bunch of elements which are likely to
-                * have them on core skins.
-                *
-                * @param {Array|jQuery} [$nodes] A jQuery object, or array of nodes to update.
-                */
-               updateTooltipAccessKeys: function ( $nodes ) {
-                       if ( !$nodes ) {
-                               if ( document.querySelectorAll ) {
-                                       // If we're running on a browser where we can do this efficiently,
-                                       // just find all elements that have accesskeys. We can't use jQuery's
-                                       // polyfill for the selector since looping over all elements on page
-                                       // load might be too slow.
-                                       $nodes = $( document.querySelectorAll( '[accesskey]' ) );
-                               } else {
-                                       // Otherwise go through some elements likely to have accesskeys rather
-                                       // than looping over all of them. Unfortunately this will not fully
-                                       // work for custom skins with different HTML structures. Input, label
-                                       // and button should be rare enough that no optimizations are needed.
-                                       $nodes = $( '#column-one a, #mw-head a, #mw-panel a, #p-logo a, input, label, button' );
-                               }
-                       } else if ( !( $nodes instanceof $ ) ) {
-                               $nodes = $( $nodes );
-                       }
-
-                       $nodes.updateTooltipAccessKeys();
-               },
-
                /**
                 * The content wrapper of the skin (e.g. `.mw-body`).
                 *
         */
        mw.log.deprecate( util, 'tooltipAccessKeyRegexp', /\[(ctrl-)?(option-)?(alt-)?(shift-)?(esc-)?(.)\]$/, 'Use jquery.accessKeyLabel instead.' );
 
+       /**
+        * Add the appropriate prefix to the accesskey shown in the tooltip.
+        *
+        * If the `$nodes` parameter is given, only those nodes are updated;
+        * otherwise, depending on browser support, we update either all elements
+        * with accesskeys on the page or a bunch of elements which are likely to
+        * have them on core skins.
+        *
+        * @method updateTooltipAccessKeys
+        * @param {Array|jQuery} [$nodes] A jQuery object, or array of nodes to update.
+        * @deprecated since 1.24 Use the module jquery.accessKeyLabel instead.
+        */
+       mw.log.deprecate( util, 'updateTooltipAccessKeys', function ( $nodes ) {
+               if ( !$nodes ) {
+                       if ( document.querySelectorAll ) {
+                               // If we're running on a browser where we can do this efficiently,
+                               // just find all elements that have accesskeys. We can't use jQuery's
+                               // polyfill for the selector since looping over all elements on page
+                               // load might be too slow.
+                               $nodes = $( document.querySelectorAll( '[accesskey]' ) );
+                       } else {
+                               // Otherwise go through some elements likely to have accesskeys rather
+                               // than looping over all of them. Unfortunately this will not fully
+                               // work for custom skins with different HTML structures. Input, label
+                               // and button should be rare enough that no optimizations are needed.
+                               $nodes = $( '#column-one a, #mw-head a, #mw-panel a, #p-logo a, input, label, button' );
+                       }
+               } else if ( !( $nodes instanceof $ ) ) {
+                       $nodes = $( $nodes );
+               }
+
+               $nodes.updateTooltipAccessKeys();
+       }, 'Use jquery.accessKeyLabel instead.' );
+
        /**
         * Add a little box at the top of the screen to inform the user of
         * something, replacing any previous message.
index 56bb3d3..a62cc9d 100644 (file)
@@ -25,8 +25,8 @@ function isCompatible( ua ) {
 
        // Browsers with outdated or limited JavaScript engines get the no-JS experience
        return !(
-               // Internet Explorer < 7
-               ( ua.indexOf( 'MSIE' ) !== -1 && parseFloat( ua.split( 'MSIE' )[1] ) < 7 ) ||
+               // Internet Explorer < 8
+               ( ua.indexOf( 'MSIE' ) !== -1 && parseFloat( ua.split( 'MSIE' )[1] ) < 8 ) ||
                // Firefox < 3
                ( ua.indexOf( 'Firefox/' ) !== -1 && parseFloat( ua.split( 'Firefox/' )[1] ) < 3 ) ||
                // Opera < 12
diff --git a/skins/common/images/ar/button_bold.png b/skins/common/images/ar/button_bold.png
deleted file mode 100644 (file)
index e524f6c..0000000
Binary files a/skins/common/images/ar/button_bold.png and /dev/null differ
diff --git a/skins/common/images/ar/button_headline.png b/skins/common/images/ar/button_headline.png
deleted file mode 100644 (file)
index 398e561..0000000
Binary files a/skins/common/images/ar/button_headline.png and /dev/null differ
diff --git a/skins/common/images/ar/button_italic.png b/skins/common/images/ar/button_italic.png
deleted file mode 100644 (file)
index 6ec73e9..0000000
Binary files a/skins/common/images/ar/button_italic.png and /dev/null differ
diff --git a/skins/common/images/ar/button_link.png b/skins/common/images/ar/button_link.png
deleted file mode 100644 (file)
index c9c63f6..0000000
Binary files a/skins/common/images/ar/button_link.png and /dev/null differ
diff --git a/skins/common/images/ar/button_nowiki.png b/skins/common/images/ar/button_nowiki.png
deleted file mode 100644 (file)
index 743ea61..0000000
Binary files a/skins/common/images/ar/button_nowiki.png and /dev/null differ
diff --git a/skins/common/images/be-tarask/button_bold.png b/skins/common/images/be-tarask/button_bold.png
deleted file mode 100644 (file)
index 5c10cfe..0000000
Binary files a/skins/common/images/be-tarask/button_bold.png and /dev/null differ
diff --git a/skins/common/images/be-tarask/button_italic.png b/skins/common/images/be-tarask/button_italic.png
deleted file mode 100644 (file)
index 72209d7..0000000
Binary files a/skins/common/images/be-tarask/button_italic.png and /dev/null differ
diff --git a/skins/common/images/be-tarask/button_link.png b/skins/common/images/be-tarask/button_link.png
deleted file mode 100644 (file)
index 09c86fb..0000000
Binary files a/skins/common/images/be-tarask/button_link.png and /dev/null differ
diff --git a/skins/common/images/button_bold.png b/skins/common/images/button_bold.png
deleted file mode 100644 (file)
index 75c3f10..0000000
Binary files a/skins/common/images/button_bold.png and /dev/null differ
diff --git a/skins/common/images/button_extlink.png b/skins/common/images/button_extlink.png
deleted file mode 100644 (file)
index 458943c..0000000
Binary files a/skins/common/images/button_extlink.png and /dev/null differ
diff --git a/skins/common/images/button_headline.png b/skins/common/images/button_headline.png
deleted file mode 100644 (file)
index 9cf751d..0000000
Binary files a/skins/common/images/button_headline.png and /dev/null differ
diff --git a/skins/common/images/button_hr.png b/skins/common/images/button_hr.png
deleted file mode 100644 (file)
index 47e1ca4..0000000
Binary files a/skins/common/images/button_hr.png and /dev/null differ
diff --git a/skins/common/images/button_image.png b/skins/common/images/button_image.png
deleted file mode 100644 (file)
index 6919296..0000000
Binary files a/skins/common/images/button_image.png and /dev/null differ
diff --git a/skins/common/images/button_italic.png b/skins/common/images/button_italic.png
deleted file mode 100644 (file)
index 527fbd1..0000000
Binary files a/skins/common/images/button_italic.png and /dev/null differ
diff --git a/skins/common/images/button_link.png b/skins/common/images/button_link.png
deleted file mode 100644 (file)
index eb5634b..0000000
Binary files a/skins/common/images/button_link.png and /dev/null differ
diff --git a/skins/common/images/button_media.png b/skins/common/images/button_media.png
deleted file mode 100644 (file)
index 4194ec1..0000000
Binary files a/skins/common/images/button_media.png and /dev/null differ
diff --git a/skins/common/images/button_nowiki.png b/skins/common/images/button_nowiki.png
deleted file mode 100644 (file)
index 2ba818d..0000000
Binary files a/skins/common/images/button_nowiki.png and /dev/null differ
diff --git a/skins/common/images/button_sig.png b/skins/common/images/button_sig.png
deleted file mode 100644 (file)
index fe34b3f..0000000
Binary files a/skins/common/images/button_sig.png and /dev/null differ
diff --git a/skins/common/images/cc-0.png b/skins/common/images/cc-0.png
deleted file mode 100644 (file)
index 9d3fe5f..0000000
Binary files a/skins/common/images/cc-0.png and /dev/null differ
diff --git a/skins/common/images/cc-by-nc-sa.png b/skins/common/images/cc-by-nc-sa.png
deleted file mode 100644 (file)
index 0d24a71..0000000
Binary files a/skins/common/images/cc-by-nc-sa.png and /dev/null differ
diff --git a/skins/common/images/cc-by-sa.png b/skins/common/images/cc-by-sa.png
deleted file mode 100644 (file)
index 518fb64..0000000
Binary files a/skins/common/images/cc-by-sa.png and /dev/null differ
diff --git a/skins/common/images/cc-by.png b/skins/common/images/cc-by.png
deleted file mode 100644 (file)
index 9cca2f9..0000000
Binary files a/skins/common/images/cc-by.png and /dev/null differ
diff --git a/skins/common/images/cyrl/LICENSE b/skins/common/images/cyrl/LICENSE
deleted file mode 100644 (file)
index bedcec6..0000000
+++ /dev/null
@@ -1,17 +0,0 @@
-button_bold.png
----------------
-Source : http://commons.wikimedia.org/wiki/Image:Button_bold_ukr.png
-License: Public domain
-Author : Alexey Belomoev
-
-button_italic.png
-------------------------
-Source : http://commons.wikimedia.org/wiki/Image:Button_italic_ukr.png
-License: Public domain
-Author : Alexey Belomoev
-
-button_link.png
------------------
-Source : http://commons.wikimedia.org/wiki/Image:Button_internal_link_ukr.png
-License: GPL
-Author : Saproj, Erik Möller
diff --git a/skins/common/images/cyrl/button_bold.png b/skins/common/images/cyrl/button_bold.png
deleted file mode 100644 (file)
index eae30d9..0000000
Binary files a/skins/common/images/cyrl/button_bold.png and /dev/null differ
diff --git a/skins/common/images/cyrl/button_italic.png b/skins/common/images/cyrl/button_italic.png
deleted file mode 100644 (file)
index b958d22..0000000
Binary files a/skins/common/images/cyrl/button_italic.png and /dev/null differ
diff --git a/skins/common/images/cyrl/button_link.png b/skins/common/images/cyrl/button_link.png
deleted file mode 100644 (file)
index 12ad373..0000000
Binary files a/skins/common/images/cyrl/button_link.png and /dev/null differ
diff --git a/skins/common/images/de/button_bold.png b/skins/common/images/de/button_bold.png
deleted file mode 100644 (file)
index 367d5bc..0000000
Binary files a/skins/common/images/de/button_bold.png and /dev/null differ
diff --git a/skins/common/images/de/button_italic.png b/skins/common/images/de/button_italic.png
deleted file mode 100644 (file)
index fdd8c9f..0000000
Binary files a/skins/common/images/de/button_italic.png and /dev/null differ
diff --git a/skins/common/images/fa/button_bold.png b/skins/common/images/fa/button_bold.png
deleted file mode 100644 (file)
index c54d094..0000000
Binary files a/skins/common/images/fa/button_bold.png and /dev/null differ
diff --git a/skins/common/images/fa/button_headline.png b/skins/common/images/fa/button_headline.png
deleted file mode 100644 (file)
index 9890d15..0000000
Binary files a/skins/common/images/fa/button_headline.png and /dev/null differ
diff --git a/skins/common/images/fa/button_italic.png b/skins/common/images/fa/button_italic.png
deleted file mode 100644 (file)
index 33f91ed..0000000
Binary files a/skins/common/images/fa/button_italic.png and /dev/null differ
diff --git a/skins/common/images/fa/button_link.png b/skins/common/images/fa/button_link.png
deleted file mode 100644 (file)
index 76b939e..0000000
Binary files a/skins/common/images/fa/button_link.png and /dev/null differ
diff --git a/skins/common/images/fa/button_nowiki.png b/skins/common/images/fa/button_nowiki.png
deleted file mode 100644 (file)
index 743ea61..0000000
Binary files a/skins/common/images/fa/button_nowiki.png and /dev/null differ
diff --git a/skins/common/images/gnu-fdl.png b/skins/common/images/gnu-fdl.png
deleted file mode 100644 (file)
index 3feaf57..0000000
Binary files a/skins/common/images/gnu-fdl.png and /dev/null differ
diff --git a/skins/common/images/ksh/LICENSE b/skins/common/images/ksh/LICENSE
deleted file mode 100644 (file)
index ba56f97..0000000
+++ /dev/null
@@ -1,7 +0,0 @@
-
-button_S_italic.png
--------------------
-Source : http://commons.wikimedia.org/wiki/Image:Button_S_italic.png
-License: Public domain
-Author : Purodha Blissenbach, http://ksh.wikipedia.org/wiki/User:Purodha
-
diff --git a/skins/common/images/ksh/button_S_italic.png b/skins/common/images/ksh/button_S_italic.png
deleted file mode 100644 (file)
index 15496c0..0000000
Binary files a/skins/common/images/ksh/button_S_italic.png and /dev/null differ
diff --git a/skins/common/images/poweredby_mediawiki_88x31.png b/skins/common/images/poweredby_mediawiki_88x31.png
deleted file mode 100644 (file)
index 30e1d2e..0000000
Binary files a/skins/common/images/poweredby_mediawiki_88x31.png and /dev/null differ
diff --git a/skins/common/images/public-domain.png b/skins/common/images/public-domain.png
deleted file mode 100644 (file)
index ebf0107..0000000
Binary files a/skins/common/images/public-domain.png and /dev/null differ
index 62157d2..71e0f4b 100644 (file)
@@ -6,7 +6,7 @@
  * @see https://github.com/sebastianbergmann/phpunit/blob/master/src/Extensions/PhptTestCase.php
  * @author Sam Smith <samsmith@wikimedia.org>
  */
-class LessFileCompilationTest extends MediaWikiTestCase {
+class LessFileCompilationTest extends ResourceLoaderTestCase {
 
        /**
         * @var string $file
@@ -38,7 +38,13 @@ class LessFileCompilationTest extends MediaWikiTestCase {
                        "$thisString must refer to a readable file"
                );
 
-               $compiler = ResourceLoader::getLessCompiler( RequestContext::getMain()->getConfig() );
+               $rlContext = static::getResourceLoaderContext();
+
+               // Bleh
+               $method = new ReflectionMethod( $this->module, 'getLessCompiler' );
+               $method->setAccessible( true );
+               $compiler = $method->invoke( $this->module, $rlContext );
+
                $this->assertNotNull( $compiler->compileFile( $this->file ) );
        }
 
index 1166817..995853e 100644 (file)
@@ -88,6 +88,14 @@ abstract class MediaWikiTestCase extends PHPUnit_Framework_TestCase {
                $this->backupStaticAttributes = false;
        }
 
+       public function __destruct() {
+               // Complain if self::setUp() was called, but not self::tearDown()
+               // $this->called['setUp'] will be checked by self::testMediaWikiTestCaseParentSetupCalled()
+               if ( isset( $this->called['setUp'] ) && !isset( $this->called['tearDown'] ) ) {
+                       throw new MWException( get_called_class() . "::tearDown() must call parent::tearDown()" );
+               }
+       }
+
        public function run( PHPUnit_Framework_TestResult $result = null ) {
                /* Some functions require some kind of caching, and will end up using the db,
                 * which we can't allow, as that would open a new connection for mysql.
@@ -192,7 +200,7 @@ abstract class MediaWikiTestCase extends PHPUnit_Framework_TestCase {
        protected function setUp() {
                wfProfileIn( __METHOD__ );
                parent::setUp();
-               $this->called['setUp'] = 1;
+               $this->called['setUp'] = true;
 
                $this->phpErrorLevel = intval( ini_get( 'error_reporting' ) );
 
@@ -221,6 +229,7 @@ abstract class MediaWikiTestCase extends PHPUnit_Framework_TestCase {
        protected function tearDown() {
                wfProfileIn( __METHOD__ );
 
+               $this->called['tearDown'] = true;
                // Cleaning up temporary files
                foreach ( $this->tmpFiles as $fileName ) {
                        if ( is_file( $fileName ) || ( is_link( $fileName ) ) ) {
index dc5549b..f5f302e 100644 (file)
@@ -46,6 +46,7 @@ class ResourceLoaderTestModule extends ResourceLoaderModule {
        protected $script = '';
        protected $styles = '';
        protected $skipFunction = null;
+       protected $isRaw = false;
        protected $targets = array( 'test' );
 
        public function __construct( $options = array() ) {
@@ -77,6 +78,10 @@ class ResourceLoaderTestModule extends ResourceLoaderModule {
        public function getSkipFunction() {
                return $this->skipFunction;
        }
+
+       public function isRaw() {
+               return $this->isRaw;
+       }
 }
 
 class ResourceLoaderFileModuleTestModule extends ResourceLoaderFileModule {
index 185ffa4..702fce4 100644 (file)
@@ -180,7 +180,7 @@ class EditPageTest extends MediaWikiLangTestCase {
                return $page;
        }
 
-       public function provideCreatePages() {
+       public static function provideCreatePages() {
                return array(
                        array( 'expected article being created',
                                'EditPageTest_testCreatePage',
index 72114e9..7b84107 100644 (file)
@@ -1,5 +1,9 @@
 <?php
 
+/**
+ * @group Database
+ */
+
 class LinkerTest extends MediaWikiLangTestCase {
 
        /**
index c82dc42..dcb9856 100644 (file)
@@ -29,7 +29,7 @@ class MWTimestampTest extends MediaWikiLangTestCase {
                $this->assertEquals( '1406833268', $timestamp->__toString() );
        }
 
-       public function provideValidTimestampDifferences() {
+       public static function provideValidTimestampDifferences() {
                return array(
                        array( '1406833268', '1406833269', '00 00 00 01' ),
                        array( '1406833268', '1406833329', '00 00 01 01' ),
index c2acec0..f3d2a84 100644 (file)
@@ -34,7 +34,7 @@ class MessageTest extends MediaWikiLangTestCase {
                $this->assertEquals( $expectedLang, $langProperty->getValue( $message ) );
        }
 
-       public function provideConstructor() {
+       public static function provideConstructor() {
                $langDe = Language::factory( 'de' );
                $langEn = Language::factory( 'en' );
 
@@ -45,7 +45,7 @@ class MessageTest extends MediaWikiLangTestCase {
                );
        }
 
-       public function provideTestParams() {
+       public static function provideTestParams() {
                return array(
                        array( array() ),
                        array( array( 'foo' ), 'foo' ),
index 97fa85c..d7e8cd3 100644 (file)
@@ -141,7 +141,15 @@ class OutputPageTest extends MediaWikiTestCase {
                        // Load module script only
                        array(
                                array( 'test.foo', ResourceLoaderModule::TYPE_SCRIPTS ),
-                               '<script src="http://127.0.0.1:8080/w/load.php?debug=false&amp;lang=en&amp;modules=test.foo&amp;only=scripts&amp;skin=fallback&amp;*"></script>
+                               '<script>if(window.mw){
+document.write("\u003Cscript src=\"http://127.0.0.1:8080/w/load.php?debug=false\u0026amp;lang=en\u0026amp;modules=test.foo\u0026amp;only=scripts\u0026amp;skin=fallback\u0026amp;*\"\u003E\u003C/script\u003E");
+}</script>
+'
+                       ),
+                       array(
+                               // Don't condition wrap raw modules (like the startup module)
+                               array( 'test.raw', ResourceLoaderModule::TYPE_SCRIPTS ),
+                               '<script src="http://127.0.0.1:8080/w/load.php?debug=false&amp;lang=en&amp;modules=test.raw&amp;only=scripts&amp;skin=fallback&amp;*"></script>
 '
                        ),
                        // Load module styles only
@@ -152,14 +160,10 @@ class OutputPageTest extends MediaWikiTestCase {
 '
                        ),
                        // Load private module (only=scripts)
-                       // This is asserted for completion (would get two condition wrappers),
-                       // though in practice we'd never embed a module with only=scripts,
-                       // that mode is reserved for hardcoded requests. Embedded modules
-                       // would always be combined.
                        array(
                                array( 'test.quux', ResourceLoaderModule::TYPE_SCRIPTS ),
                                '<script>if(window.mw){
-if(window.mw){mw.test.baz({token:123});mw.loader.state({"test.quux":"ready"});}
+mw.test.baz({token:123});mw.loader.state({"test.quux":"ready"});
 
 }</script>
 '
@@ -244,17 +248,21 @@ mw.loader.implement("test.quux",function($,jQuery){mw.test.baz({token:123});},{"
                                'styles' => '/* pref-animate=off */ .mw-icon { transition: none; }',
                                'group' => 'private',
                        )),
+                       'test.raw' => new ResourceLoaderTestModule( array(
+                               'script' => 'mw.test.baz( { token: 123 } );',
+                               'isRaw' => true,
+                       )),
                        'test.noscript' => new ResourceLoaderTestModule( array(
                                'styles' => '.mw-test-noscript { content: "style"; }',
                                'group' => 'noscript',
                        )),
                        'test.group.bar' => new ResourceLoaderTestModule( array(
-                                       'styles' => '.mw-group-bar { content: "style"; }',
-                                       'group' => 'bar',
+                               'styles' => '.mw-group-bar { content: "style"; }',
+                               'group' => 'bar',
                        )),
                        'test.group.foo' => new ResourceLoaderTestModule( array(
-                                       'styles' => '.mw-group-foo { content: "style"; }',
-                                       'group' => 'foo',
+                               'styles' => '.mw-group-foo { content: "style"; }',
+                               'group' => 'foo',
                        )),
                ) );
                $links = $method->invokeArgs( $out, $args );
index 86e8e8b..2585811 100644 (file)
@@ -47,7 +47,7 @@ class TestSample extends MediaWikiLangTestCase {
         * If you want to run a the same test with a variety of data, use a data provider.
         * see: http://www.phpunit.de/manual/3.4/en/writing-tests-for-phpunit.html
         */
-       public function provideTitles() {
+       public static function provideTitles() {
                return array(
                        array( 'Text', NS_MEDIA, 'Media:Text' ),
                        array( 'Text', null, 'Text' ),
index e4c7623..0f7069a 100644 (file)
@@ -64,7 +64,7 @@ class TitleArrayFromResultTest extends MediaWikiTestCase {
                $this->assertEquals( $title, $object->current->mTextform );
        }
 
-       public function provideNumberOfRows() {
+       public static function provideNumberOfRows() {
                return array(
                        array( 0 ),
                        array( 1 ),
index b2b0d34..fb58381 100644 (file)
@@ -39,84 +39,61 @@ class TitleTest extends MediaWikiTestCase {
                }
        }
 
-       /**
-        * See also mediawiki.Title.test.js
-        * @covers Title::secureAndSplit
-        * @todo This method should be split into 2 separate tests each with a provider
-        * @note This mainly tests MediaWikiTitleCodec::parseTitle().
-        */
-       public function testSecureAndSplit() {
-               $this->setMwGlobals( array(
-                       'wgLocalInterwikis' => array( 'localtestiw' ),
-                       'wgHooks' => array(
-                               'InterwikiLoadPrefix' => array(
-                                       function ( $prefix, &$data ) {
-                                               if ( $prefix === 'localtestiw' ) {
-                                                       $data = array( 'iw_url' => 'localtestiw' );
-                                               } elseif ( $prefix === 'remotetestiw' ) {
-                                                       $data = array( 'iw_url' => 'remotetestiw' );
-                                               }
-                                               return false;
-                                       }
-                               )
-                       )
-               ));
-               // Valid
-               foreach ( array(
-                       'Sandbox',
-                       'A "B"',
-                       'A \'B\'',
-                       '.com',
-                       '~',
-                       '#',
-                       '"',
-                       '\'',
-                       'Talk:Sandbox',
-                       'Talk:Foo:Sandbox',
-                       'File:Example.svg',
-                       'File_talk:Example.svg',
-                       'Foo/.../Sandbox',
-                       'Sandbox/...',
-                       'A~~',
-                       ':A',
+       public static function provideValidSecureAndSplit() {
+               return array(
+                       array( 'Sandbox' ),
+                       array( 'A "B"' ),
+                       array( 'A \'B\'' ),
+                       array( '.com' ),
+                       array( '~' ),
+                       array( '#' ),
+                       array( '"' ),
+                       array( '\'' ),
+                       array( 'Talk:Sandbox' ),
+                       array( 'Talk:Foo:Sandbox' ),
+                       array( 'File:Example.svg' ),
+                       array( 'File_talk:Example.svg' ),
+                       array( 'Foo/.../Sandbox' ),
+                       array( 'Sandbox/...' ),
+                       array( 'A~~' ),
+                       array( ':A' ),
                        // Length is 256 total, but only title part matters
-                       'Category:' . str_repeat( 'x', 248 ),
-                       str_repeat( 'x', 252 ),
+                       array( 'Category:' . str_repeat( 'x', 248 ) ),
+                       array( str_repeat( 'x', 252 ) ),
                        // interwiki prefix
-                       'localtestiw: #anchor',
-                       'localtestiw:',
-                       'localtestiw:foo',
-                       'localtestiw: foo # anchor',
-                       'localtestiw: Talk: Sandbox # anchor',
-                       'remotetestiw:',
-                       'remotetestiw: Talk: # anchor',
-                       'remotetestiw: #bar',
-                       'remotetestiw: Talk:',
-                       'remotetestiw: Talk: Foo',
-                       'localtestiw:remotetestiw:',
-                       'localtestiw:remotetestiw:foo'
-               ) as $text ) {
-                       $this->assertInstanceOf( 'Title', Title::newFromText( $text ), "Valid: $text" );
-               }
+                       array( 'localtestiw: #anchor' ),
+                       array( 'localtestiw:' ),
+                       array( 'localtestiw:foo' ),
+                       array( 'localtestiw: foo # anchor' ),
+                       array( 'localtestiw: Talk: Sandbox # anchor' ),
+                       array( 'remotetestiw:' ),
+                       array( 'remotetestiw: Talk: # anchor' ),
+                       array( 'remotetestiw: #bar' ),
+                       array( 'remotetestiw: Talk:' ),
+                       array( 'remotetestiw: Talk: Foo' ),
+                       array( 'localtestiw:remotetestiw:' ),
+                       array( 'localtestiw:remotetestiw:foo' )
+               );
+       }
 
-               // Invalid
-               foreach ( array(
-                       '',
-                       ':',
-                       '__  __',
-                       '  __  ',
+       public static function provideInvalidSecureAndSplit() {
+               return array(
+                       array( '' ),
+                       array( ':' ),
+                       array( '__  __' ),
+                       array( '  __  ' ),
                        // Bad characters forbidden regardless of wgLegalTitleChars
-                       'A [ B',
-                       'A ] B',
-                       'A { B',
-                       'A } B',
-                       'A < B',
-                       'A > B',
-                       'A | B',
+                       array( 'A [ B' ),
+                       array( 'A ] B' ),
+                       array( 'A { B' ),
+                       array( 'A } B' ),
+                       array( 'A < B' ),
+                       array( 'A > B' ),
+                       array( 'A | B' ),
                        // URL encoding
-                       'A%20B',
-                       'A%23B',
-                       'A%2523B',
+                       array( 'A%20B' ),
+                       array( 'A%23B' ),
+                       array( 'A%2523B' ),
                        // XML/HTML character entity references
                        // Note: Commented out because they are not marked invalid by the PHP test as
                        // Title::newFromText runs Sanitizer::decodeCharReferencesAndNormalize first.
@@ -124,32 +101,70 @@ class TitleTest extends MediaWikiTestCase {
                        //'A &#233; B',
                        //'A &#x00E9; B',
                        // Subject of NS_TALK does not roundtrip to NS_MAIN
-                       'Talk:File:Example.svg',
+                       array( 'Talk:File:Example.svg' ),
                        // Directory navigation
-                       '.',
-                       '..',
-                       './Sandbox',
-                       '../Sandbox',
-                       'Foo/./Sandbox',
-                       'Foo/../Sandbox',
-                       'Sandbox/.',
-                       'Sandbox/..',
+                       array( '.' ),
+                       array( '..' ),
+                       array( './Sandbox' ),
+                       array( '../Sandbox' ),
+                       array( 'Foo/./Sandbox' ),
+                       array( 'Foo/../Sandbox' ),
+                       array( 'Sandbox/.' ),
+                       array( 'Sandbox/..' ),
                        // Tilde
-                       'A ~~~ Name',
-                       'A ~~~~ Signature',
-                       'A ~~~~~ Timestamp',
-                       str_repeat( 'x', 256 ),
+                       array( 'A ~~~ Name' ),
+                       array( 'A ~~~~ Signature' ),
+                       array( 'A ~~~~~ Timestamp' ),
+                       array( str_repeat( 'x', 256 ) ),
                        // Namespace prefix without actual title
-                       'Talk:',
-                       'Talk:#',
-                       'Category: ',
-                       'Category: #bar',
+                       array( 'Talk:' ),
+                       array( 'Talk:#' ),
+                       array( 'Category: ' ),
+                       array( 'Category: #bar' ),
                        // interwiki prefix
-                       'localtestiw: Talk: # anchor',
-                       'localtestiw: Talk:'
-               ) as $text ) {
-                       $this->assertNull( Title::newFromText( $text ), "Invalid: $text" );
-               }
+                       array( 'localtestiw: Talk: # anchor' ),
+                       array( 'localtestiw: Talk:' )
+               );
+       }
+
+       private function secureAndSplitGlobals() {
+               $this->setMwGlobals( array(
+                       'wgLocalInterwikis' => array( 'localtestiw' ),
+                       'wgHooks' => array(
+                               'InterwikiLoadPrefix' => array(
+                                       function ( $prefix, &$data ) {
+                                               if ( $prefix === 'localtestiw' ) {
+                                                       $data = array( 'iw_url' => 'localtestiw' );
+                                               } elseif ( $prefix === 'remotetestiw' ) {
+                                                       $data = array( 'iw_url' => 'remotetestiw' );
+                                               }
+                                               return false;
+                                       }
+                               )
+                       )
+               ));
+       }
+
+       /**
+        * See also mediawiki.Title.test.js
+        * @covers Title::secureAndSplit
+        * @dataProvider provideValidSecureAndSplit
+        * @note This mainly tests MediaWikiTitleCodec::parseTitle().
+        */
+       public function testSecureAndSplitValid( $text ) {
+               $this->secureAndSplitGlobals();
+               $this->assertInstanceOf( 'Title', Title::newFromText( $text ), "Valid: $text" );
+       }
+
+       /**
+        * See also mediawiki.Title.test.js
+        * @covers Title::secureAndSplit
+        * @dataProvider provideInvalidSecureAndSplit
+        * @note This mainly tests MediaWikiTitleCodec::parseTitle().
+        */
+       public function testSecureAndSplitInvalid( $text ) {
+               $this->secureAndSplitGlobals();
+               $this->assertNull( Title::newFromText( $text ), "Invalid: $text" );
        }
 
        public static function provideConvertByteClassToUnicodeClass() {
@@ -258,8 +273,10 @@ class TitleTest extends MediaWikiTestCase {
         * @param array|string|bool $expected Required error
         * @dataProvider provideTestIsValidMoveOperation
         * @covers Title::isValidMoveOperation
+        * @covers Title::validateFileMoveOperation
         */
        public function testIsValidMoveOperation( $source, $target, $expected ) {
+               $this->setMwGlobals( 'wgContentHandlerUseDB', false );
                $title = Title::newFromText( $source );
                $nt = Title::newFromText( $target );
                $errors = $title->isValidMoveOperation( $nt, false );
@@ -273,13 +290,17 @@ class TitleTest extends MediaWikiTestCase {
                }
        }
 
-       /**
-        * Provides test parameter values for testIsValidMoveOperation()
-        */
-       public function dataTestIsValidMoveOperation() {
+       public static function provideTestIsValidMoveOperation() {
                return array(
+                       // for Title::isValidMoveOperation
+                       array( 'Some page', '', 'badtitletext' ),
                        array( 'Test', 'Test', 'selfmove' ),
-                       array( 'File:Test.jpg', 'Page', 'imagenocrossnamespace' )
+                       array( 'Special:FooBar', 'Test', 'immobile-source-namespace' ),
+                       array( 'Test', 'Special:FooBar', 'immobile-target-namespace' ),
+                       array( 'MediaWiki:Common.js', 'Help:Some wikitext page', 'bad-target-model' ),
+                       array( 'Page', 'File:Test.jpg', 'nonfile-cannot-move-to-file' ),
+                       // for Title::validateFileMoveOperation
+                       array( 'File:Test.jpg', 'Page', 'imagenocrossnamespace' ),
                );
        }
 
@@ -400,13 +421,6 @@ class TitleTest extends MediaWikiTestCase {
                return $result;
        }
 
-       public static function provideTestIsValidMoveOperation() {
-               return array(
-                       array( 'Test', 'Test', 'selfmove' ),
-                       array( 'File:Test.jpg', 'Page', 'imagenocrossnamespace' )
-               );
-       }
-
        /**
         * @dataProvider provideGetPageViewLanguage
         * @covers Title::getPageViewLanguage
@@ -533,7 +547,7 @@ class TitleTest extends MediaWikiTestCase {
                );
        }
 
-       public function provideNewFromTitleValue() {
+       public static function provideNewFromTitleValue() {
                return array(
                        array( new TitleValue( NS_MAIN, 'Foo' ) ),
                        array( new TitleValue( NS_MAIN, 'Foo', 'bar' ) ),
@@ -553,7 +567,7 @@ class TitleTest extends MediaWikiTestCase {
                $this->assertEquals( $value->getFragment(), $title->getFragment() );
        }
 
-       public function provideGetTitleValue() {
+       public static function provideGetTitleValue() {
                return array(
                        array( 'Foo' ),
                        array( 'Foo#bar' ),
@@ -574,7 +588,7 @@ class TitleTest extends MediaWikiTestCase {
                $this->assertEquals( $title->getFragment(), $value->getFragment() );
        }
 
-       public function provideGetFragment() {
+       public static function provideGetFragment() {
                return array(
                        array( 'Foo', '' ),
                        array( 'Foo#bar', 'bar' ),
@@ -614,7 +628,7 @@ class TitleTest extends MediaWikiTestCase {
                $this->assertEquals( $isKnown, $title->isAlwaysKnown() );
        }
 
-       public function provideIsAlwaysKnown() {
+       public static function provideIsAlwaysKnown() {
                return array(
                        array( 'Some nonexistent page', false ),
                        array( 'UTPage', false ),
index ea44f36..62989fa 100644 (file)
@@ -61,7 +61,7 @@ class UserArrayFromResultTest extends MediaWikiTestCase {
                $this->assertEquals( $username, $object->current->mName );
        }
 
-       public function provideNumberOfRows() {
+       public static function provideNumberOfRows() {
                return array(
                        array( 0 ),
                        array( 1 ),
diff --git a/tests/phpunit/includes/UserMailerTest.php b/tests/phpunit/includes/UserMailerTest.php
deleted file mode 100644 (file)
index dca8aeb..0000000
+++ /dev/null
@@ -1,14 +0,0 @@
-<?php
-
-class UserMailerTest extends MediaWikiLangTestCase {
-
-       /**
-        * @covers UserMailer::quotedPrintable
-        */
-       public function testQuotedPrintable() {
-               $this->assertEquals(
-                       "=?UTF-8?Q?=C4=88u=20legebla=3F?=",
-                       UserMailer::quotedPrintable( "\xc4\x88u legebla?", "UTF-8" ) );
-       }
-
-}
index cabbf10..a0c20bb 100644 (file)
@@ -214,8 +214,10 @@ class UserTest extends MediaWikiTestCase {
         */
        public function testEditCount() {
                $user = User::newFromName( 'UnitTestUser' );
-               $user->loadDefaults();
-               $user->addToDatabase();
+
+               if ( !$user->getId() ) {
+                       $user->addToDatabase();
+               }
 
                // let the user have a few (3) edits
                $page = WikiPage::factory( Title::newFromText( 'Help:UserTest_EditCount' ) );
@@ -248,14 +250,17 @@ class UserTest extends MediaWikiTestCase {
         */
        public function testOptions() {
                $user = User::newFromName( 'UnitTestUser' );
-               $user->addToDatabase();
 
-               $user->setOption( 'someoption', 'test' );
+               if ( !$user->getId() ) {
+                       $user->addToDatabase();
+               }
+
+               $user->setOption( 'userjs-someoption', 'test' );
                $user->setOption( 'cols', 200 );
                $user->saveSettings();
 
                $user = User::newFromName( 'UnitTestUser' );
-               $this->assertEquals( 'test', $user->getOption( 'someoption' ) );
+               $this->assertEquals( 'test', $user->getOption( 'userjs-someoption' ) );
                $this->assertEquals( 200, $user->getOption( 'cols' ) );
        }
 
@@ -266,9 +271,9 @@ class UserTest extends MediaWikiTestCase {
         */
        public function testAnonOptions() {
                global $wgDefaultUserOptions;
-               $this->user->setOption( 'someoption', 'test' );
+               $this->user->setOption( 'userjs-someoption', 'test' );
                $this->assertEquals( $wgDefaultUserOptions['cols'], $this->user->getOption( 'cols' ) );
-               $this->assertEquals( 'test', $this->user->getOption( 'someoption' ) );
+               $this->assertEquals( 'test', $this->user->getOption( 'userjs-someoption' ) );
        }
 
        /**
@@ -281,7 +286,7 @@ class UserTest extends MediaWikiTestCase {
                $wgPasswordExpireGrace = 3600 * 24 * 7; // 7 days
 
                $user = User::newFromName( 'UnitTestUser' );
-               $user->loadDefaults();
+               $user->loadDefaults( 'UnitTestUser' );
                $this->assertEquals( false, $user->getPasswordExpired() );
 
                $ts = time() - ( 3600 * 24 * 1 ); // 1 day ago
@@ -338,7 +343,7 @@ class UserTest extends MediaWikiTestCase {
                }
        }
 
-       public function provideGetCanonicalName() {
+       public static function provideGetCanonicalName() {
                return array(
                        array( ' trailing space ', array( 'creatable' => 'Trailing space' ), 'Trailing spaces' ),
                        // @todo FIXME: Maybe the createable name should be 'Talk:Username' or false to reject?
index 907ce79..0dbb010 100644 (file)
@@ -14,7 +14,7 @@ class XmlJs extends MediaWikiTestCase {
                $this->assertEquals( $value, $obj->value );
        }
 
-       public function provideConstruction() {
+       public static function provideConstruction() {
                return array(
                        array( null ),
                        array( '' ),
index eb370d9..cc6fb11 100644 (file)
@@ -7,6 +7,7 @@
  * @author Thiemo Mättig
  *
  * @group Action
+ * @group Database
  */
 class ActionTest extends MediaWikiTestCase {
 
index 3a36b9f..2ea9f33 100644 (file)
@@ -29,7 +29,8 @@ class OldChangesListTest extends MediaWikiLangTestCase {
                parent::setUp();
 
                $this->setMwGlobals( array(
-                       'wgArticlePath' => '/wiki/$1'
+                       'wgArticlePath' => '/wiki/$1',
+                       'wgLang' => Language::factory( 'qqx' )
                ) );
        }
 
@@ -76,12 +77,9 @@ class OldChangesListTest extends MediaWikiLangTestCase {
 
                $line = $oldChangesList->recentChangesLine( $recentChange, false, 1 );
 
-               $message = new Message( 'dellogpage' );
-               $expectedLinkText = $message->inLanguage( 'en' )->text();
-
                $this->assertRegExp( '/href="\/wiki\/Special:Log\/delete/', $line, 'link has href attribute' );
                $this->assertRegExp( '/title="Special:Log\/delete/', $line, 'link has title attribute' );
-               $this->assertRegExp( "/$expectedLinkText/", $line, 'link text' );
+               $this->assertRegExp( "/dellogpage/", $line, 'link text' );
        }
 
        public function testRecentChangesLine_DiffHistLinks() {
@@ -110,14 +108,14 @@ class OldChangesListTest extends MediaWikiLangTestCase {
 
                $line = $oldChangesList->recentChangesLine( $recentChange, false, 1 );
 
-               $this->assertRegExp(
-                       "/<abbr class='newpage' title='This edit created a new page'>N<\/abbr>/",
+               $this->assertContains(
+                       "<abbr class='newpage' title='(recentchanges-label-newpage)'>(newpageletter)</abbr>",
                        $line,
                        'new page flag'
                );
 
-               $this->assertRegExp(
-                       "/<abbr class='botedit' title='This edit was performed by a bot'>b<\/abbr>/",
+               $this->assertContains(
+                       "<abbr class='botedit' title='(recentchanges-label-bot)'>(boteditletter)</abbr>",
                        $line,
                        'bot flag'
                );
@@ -181,9 +179,7 @@ class OldChangesListTest extends MediaWikiLangTestCase {
        private function getContext() {
                $user = $this->getTestUser();
                $context = $this->testRecentChangesHelper->getTestContext( $user );
-
-               $title = Title::newFromText( 'RecentChanges', NS_SPECIAL );
-               $context->setTitle( $title );
+               $context->setLanguage( Language::factory( 'qqx' ) );
 
                return $context;
        }
index 0da0775..ad64327 100644 (file)
@@ -129,6 +129,9 @@ class TestRecentChangesHelper {
 
                $context->setUser( $user );
 
+               $title = Title::newFromText( 'RecentChanges', NS_SPECIAL );
+               $context->setTitle( $title );
+
                return $context;
        }
 }
index a999081..70b9e68 100644 (file)
@@ -38,7 +38,19 @@ class GlobalVarConfigTest extends MediaWikiTestCase {
                );
        }
 
-       public function provideGet() {
+       /**
+        * @covers GlobalVarConfig::has
+        */
+       public function testHas() {
+               $this->maybeStashGlobal( 'wgGlobalVarConfigTestHas' );
+               $GLOBALS['wgGlobalVarConfigTestHas'] = wfRandomString();
+               $this->maybeStashGlobal( 'wgGlobalVarConfigTestNotHas' );
+               $config = new GlobalVarConfig();
+               $this->assertTrue( $config->has( 'GlobalVarConfigTestHas' ) );
+               $this->assertFalse( $config->has( 'GlobalVarConfigTestNotHas' ) );
+       }
+
+       public static function provideGet() {
                $set = array(
                        'wgSomething' => 'default1',
                        'wgFoo' => 'default2',
@@ -70,7 +82,7 @@ class GlobalVarConfigTest extends MediaWikiTestCase {
        public function testGet( $name, $prefix, $expected ) {
                $config = new GlobalVarConfig( $prefix );
                if ( $expected === false ) {
-                       $this->setExpectedException( 'ConfigException', 'GlobalVarConfig::getWithPrefix: undefined variable:' );
+                       $this->setExpectedException( 'ConfigException', 'GlobalVarConfig::get: undefined option:' );
                }
                $this->assertEquals( $config->get( $name ), $expected );
        }
@@ -97,6 +109,7 @@ class GlobalVarConfigTest extends MediaWikiTestCase {
         * @covers GlobalVarConfig::setWithPrefix
         */
        public function testSet( $name, $prefix, $var ) {
+               $this->hideDeprecated( 'GlobalVarConfig::set' );
                $this->maybeStashGlobal( $var );
                $config = new GlobalVarConfig( $prefix );
                $random = wfRandomString();
diff --git a/tests/phpunit/includes/config/HashConfigTest.php b/tests/phpunit/includes/config/HashConfigTest.php
new file mode 100644 (file)
index 0000000..3ad3bfb
--- /dev/null
@@ -0,0 +1,63 @@
+<?php
+
+class HashConfigTest extends MediaWikiTestCase {
+
+       /**
+        * @covers HashConfig::newInstance
+        */
+       public function testNewInstance() {
+               $conf = HashConfig::newInstance();
+               $this->assertInstanceOf( 'HashConfig', $conf );
+       }
+
+       /**
+        * @covers HashConfig::__construct
+        */
+       public function testConstructor() {
+               $conf = new HashConfig();
+               $this->assertInstanceOf( 'HashConfig', $conf );
+
+               // Test passing arguments to the constructor
+               $conf2 = new HashConfig( array(
+                       'one' => '1',
+               ) );
+               $this->assertEquals( '1', $conf2->get( 'one' ) );
+       }
+
+       /**
+        * @covers HashConfig::get
+        */
+       public function testGet() {
+               $conf = new HashConfig( array(
+                       'one' => '1',
+               ));
+               $this->assertEquals( '1', $conf->get( 'one' ) );
+               $this->setExpectedException( 'ConfigException', 'HashConfig::get: undefined option' );
+               $conf->get( 'two' );
+       }
+
+       /**
+        * @covers HashConfig::has
+        */
+       public function testHas() {
+               $conf = new HashConfig( array(
+                       'one' => '1',
+               ) );
+               $this->assertTrue( $conf->has( 'one' ) );
+               $this->assertFalse( $conf->has( 'two' ) );
+       }
+
+       /**
+        * @covers HashConfig::set
+        */
+       public function testSet() {
+               $conf = new HashConfig( array(
+                       'one' => '1',
+               ) );
+               $conf->set( 'two', '2' );
+               $this->assertEquals( '2', $conf->get( 'two' ) );
+               // Check that set overwrites
+               $conf->set( 'one', '3' );
+               $this->assertEquals( '3', $conf->get( 'one' ) );
+       }
+}
\ No newline at end of file
diff --git a/tests/phpunit/includes/config/MultiConfigTest.php b/tests/phpunit/includes/config/MultiConfigTest.php
new file mode 100644 (file)
index 0000000..158da46
--- /dev/null
@@ -0,0 +1,38 @@
+<?php
+
+class MultiConfigTest extends MediaWikiTestCase {
+
+       /**
+        * Tests that settings are fetched in the right order
+        *
+        * @covers MultiConfig::get
+        */
+       public function testGet() {
+               $multi = new MultiConfig( array(
+                       new HashConfig( array( 'foo' => 'bar' ) ),
+                       new HashConfig( array( 'foo' => 'baz', 'bar' => 'foo' ) ),
+                       new HashConfig( array( 'bar' => 'baz' ) ),
+               ) );
+
+               $this->assertEquals( 'bar', $multi->get( 'foo' ) );
+               $this->assertEquals( 'foo', $multi->get( 'bar' ) );
+               $this->setExpectedException( 'ConfigException', 'MultiConfig::get: undefined option:' );
+               $multi->get( 'notset' );
+       }
+
+       /**
+        * @covers MultiConfig::has
+        */
+       public function testHas() {
+               $conf = new MultiConfig( array(
+                       new HashConfig( array( 'foo' => 'foo' ) ),
+                       new HashConfig( array( 'something' => 'bleh' ) ),
+                       new HashConfig( array( 'meh' => 'eh' ) ),
+               ) );
+
+               $this->assertTrue( $conf->has( 'foo' ) );
+               $this->assertTrue( $conf->has( 'something' ) );
+               $this->assertTrue( $conf->has( 'meh' ) );
+               $this->assertFalse( $conf->has( 'what' ) );
+       }
+}
diff --git a/tests/phpunit/includes/content/JSONContentTest.php b/tests/phpunit/includes/content/JSONContentTest.php
deleted file mode 100644 (file)
index acfdc0e..0000000
+++ /dev/null
@@ -1,115 +0,0 @@
-<?php
-
-/**
- * @author Adam Shorland
- * @covers JSONContent
- */
-class JSONContentTest extends MediaWikiLangTestCase {
-
-       /**
-        * @dataProvider provideValidConstruction
-        */
-       public function testValidConstruct( $text, $modelId, $isValid, $expected ) {
-               $obj = new JSONContent( $text, $modelId );
-               $this->assertEquals( $isValid, $obj->isValid() );
-               $this->assertEquals( $expected, $obj->getJsonData() );
-       }
-
-       public function provideValidConstruction() {
-               return array(
-                       array( 'foo', CONTENT_MODEL_JSON, false, null ),
-                       array( FormatJson::encode( array() ), CONTENT_MODEL_JSON, true, array() ),
-                       array( FormatJson::encode( array( 'foo' ) ), CONTENT_MODEL_JSON, true, array( 'foo' ) ),
-               );
-       }
-
-       /**
-        * @dataProvider provideDataToEncode
-        */
-       public function testBeautifyUsesFormatJson( $data ) {
-               $obj = new JSONContent( FormatJson::encode( $data ) );
-               $this->assertEquals( FormatJson::encode( $data, true ), $obj->beautifyJSON() );
-       }
-
-       public function provideDataToEncode() {
-               return array(
-                       array( array() ),
-                       array( array( 'foo' ) ),
-                       array( array( 'foo', 'bar' ) ),
-                       array( array( 'baz' => 'foo', 'bar' ) ),
-                       array( array( 'baz' => 1000, 'bar' ) ),
-               );
-       }
-
-       /**
-        * @dataProvider provideDataToEncode
-        */
-       public function testPreSaveTransform( $data ) {
-               $obj = new JSONContent( FormatJson::encode( $data ) );
-               $newObj = $obj->preSaveTransform( $this->getMockTitle(), $this->getMockUser(), $this->getMockParserOptions() );
-               $this->assertTrue( $newObj->equals( new JSONContent( FormatJson::encode( $data, true ) ) ) );
-       }
-
-       private function getMockTitle() {
-               return $this->getMockBuilder( 'Title' )
-                       ->disableOriginalConstructor()
-                       ->getMock();
-       }
-
-       private function getMockUser() {
-               return $this->getMockBuilder( 'User' )
-                       ->disableOriginalConstructor()
-                       ->getMock();
-       }
-       private function getMockParserOptions() {
-               return $this->getMockBuilder( 'ParserOptions' )
-                       ->disableOriginalConstructor()
-                       ->getMock();
-       }
-
-       /**
-        * @dataProvider provideDataAndParserText
-        */
-       public function testFillParserOutput( $data, $expected ) {
-               $obj = new JSONContent( FormatJson::encode( $data ) );
-               $parserOutput = $obj->getParserOutput( $this->getMockTitle(), null, null, true );
-               $this->assertInstanceOf( 'ParserOutput', $parserOutput );
-//             var_dump( $parserOutput->getText(), "\n" );
-               $this->assertEquals( $expected, $parserOutput->getText() );
-       }
-
-       public function provideDataAndParserText() {
-               return array(
-                       array(
-                               array(),
-                               '<table class="mw-json"><tbody></tbody></table>'
-                       ),
-                       array(
-                               array( 'foo' ),
-                               '<table class="mw-json"><tbody><tr><th>0</th><td class="value">&quot;foo&quot;</td></tr></tbody></table>'
-                       ),
-                       array(
-                               array( 'foo', 'bar' ),
-                               '<table class="mw-json"><tbody><tr><th>0</th><td class="value">&quot;foo&quot;</td></tr>' .
-                               "\n" .
-                               '<tr><th>1</th><td class="value">&quot;bar&quot;</td></tr></tbody></table>'
-                       ),
-                       array(
-                               array( 'baz' => 'foo', 'bar' ),
-                               '<table class="mw-json"><tbody><tr><th>baz</th><td class="value">&quot;foo&quot;</td></tr>' .
-                               "\n" .
-                               '<tr><th>0</th><td class="value">&quot;bar&quot;</td></tr></tbody></table>'
-                       ),
-                       array(
-                               array( 'baz' => 1000, 'bar' ),
-                               '<table class="mw-json"><tbody><tr><th>baz</th><td class="value">1000</td></tr>' .
-                               "\n" .
-                               '<tr><th>0</th><td class="value">&quot;bar&quot;</td></tr></tbody></table>'
-                       ),
-                       array(
-                               array( '<script>alert("evil!")</script>'),
-                               '<table class="mw-json"><tbody><tr><th>0</th><td class="value">&quot;&lt;script&gt;alert(&quot;evil!&quot;)&lt;/script&gt;&quot;</td></tr></tbody></table>',
-                       ),
-               );
-       }
-}
diff --git a/tests/phpunit/includes/content/JsonContentTest.php b/tests/phpunit/includes/content/JsonContentTest.php
new file mode 100644 (file)
index 0000000..77b542f
--- /dev/null
@@ -0,0 +1,114 @@
+<?php
+
+/**
+ * @author Adam Shorland
+ * @covers JsonContent
+ */
+class JsonContentTest extends MediaWikiLangTestCase {
+
+       /**
+        * @dataProvider provideValidConstruction
+        */
+       public function testValidConstruct( $text, $modelId, $isValid, $expected ) {
+               $obj = new JsonContent( $text, $modelId );
+               $this->assertEquals( $isValid, $obj->isValid() );
+               $this->assertEquals( $expected, $obj->getJsonData() );
+       }
+
+       public static function provideValidConstruction() {
+               return array(
+                       array( 'foo', CONTENT_MODEL_JSON, false, null ),
+                       array( FormatJson::encode( array() ), CONTENT_MODEL_JSON, true, array() ),
+                       array( FormatJson::encode( array( 'foo' ) ), CONTENT_MODEL_JSON, true, array( 'foo' ) ),
+               );
+       }
+
+       /**
+        * @dataProvider provideDataToEncode
+        */
+       public function testBeautifyUsesFormatJson( $data ) {
+               $obj = new JsonContent( FormatJson::encode( $data ) );
+               $this->assertEquals( FormatJson::encode( $data, true ), $obj->beautifyJSON() );
+       }
+
+       public static function provideDataToEncode() {
+               return array(
+                       array( array() ),
+                       array( array( 'foo' ) ),
+                       array( array( 'foo', 'bar' ) ),
+                       array( array( 'baz' => 'foo', 'bar' ) ),
+                       array( array( 'baz' => 1000, 'bar' ) ),
+               );
+       }
+
+       /**
+        * @dataProvider provideDataToEncode
+        */
+       public function testPreSaveTransform( $data ) {
+               $obj = new JsonContent( FormatJson::encode( $data ) );
+               $newObj = $obj->preSaveTransform( $this->getMockTitle(), $this->getMockUser(), $this->getMockParserOptions() );
+               $this->assertTrue( $newObj->equals( new JsonContent( FormatJson::encode( $data, true ) ) ) );
+       }
+
+       private function getMockTitle() {
+               return $this->getMockBuilder( 'Title' )
+                       ->disableOriginalConstructor()
+                       ->getMock();
+       }
+
+       private function getMockUser() {
+               return $this->getMockBuilder( 'User' )
+                       ->disableOriginalConstructor()
+                       ->getMock();
+       }
+       private function getMockParserOptions() {
+               return $this->getMockBuilder( 'ParserOptions' )
+                       ->disableOriginalConstructor()
+                       ->getMock();
+       }
+
+       /**
+        * @dataProvider provideDataAndParserText
+        */
+       public function testFillParserOutput( $data, $expected ) {
+               $obj = new JsonContent( FormatJson::encode( $data ) );
+               $parserOutput = $obj->getParserOutput( $this->getMockTitle(), null, null, true );
+               $this->assertInstanceOf( 'ParserOutput', $parserOutput );
+               $this->assertEquals( $expected, $parserOutput->getText() );
+       }
+
+       public static function provideDataAndParserText() {
+               return array(
+                       array(
+                               array(),
+                               '<table class="mw-json"><tbody></tbody></table>'
+                       ),
+                       array(
+                               array( 'foo' ),
+                               '<table class="mw-json"><tbody><tr><th>0</th><td class="value">&quot;foo&quot;</td></tr></tbody></table>'
+                       ),
+                       array(
+                               array( 'foo', 'bar' ),
+                               '<table class="mw-json"><tbody><tr><th>0</th><td class="value">&quot;foo&quot;</td></tr>' .
+                               "\n" .
+                               '<tr><th>1</th><td class="value">&quot;bar&quot;</td></tr></tbody></table>'
+                       ),
+                       array(
+                               array( 'baz' => 'foo', 'bar' ),
+                               '<table class="mw-json"><tbody><tr><th>baz</th><td class="value">&quot;foo&quot;</td></tr>' .
+                               "\n" .
+                               '<tr><th>0</th><td class="value">&quot;bar&quot;</td></tr></tbody></table>'
+                       ),
+                       array(
+                               array( 'baz' => 1000, 'bar' ),
+                               '<table class="mw-json"><tbody><tr><th>baz</th><td class="value">1000</td></tr>' .
+                               "\n" .
+                               '<tr><th>0</th><td class="value">&quot;bar&quot;</td></tr></tbody></table>'
+                       ),
+                       array(
+                               array( '<script>alert("evil!")</script>'),
+                               '<table class="mw-json"><tbody><tr><th>0</th><td class="value">&quot;&lt;script&gt;alert(&quot;evil!&quot;)&lt;/script&gt;&quot;</td></tr></tbody></table>',
+                       ),
+               );
+       }
+}
index bd4ae35..7becd6f 100644 (file)
@@ -361,6 +361,52 @@ just a test"
                $this->assertEquals( CONTENT_MODEL_WIKITEXT, $content->getContentHandler()->getModelID() );
        }
 
+       public function testRedirectParserOption() {
+               $title = Title::newFromText( 'testRedirectParserOption' );
+
+               // Set up hook and its reporting variables
+               $wikitext = null;
+               $redirectTarget = null;
+               $this->mergeMwGlobalArrayValue( 'wgHooks', array(
+                       'InternalParseBeforeLinks' => array(
+                               function ( &$parser, &$text, &$stripState ) use ( &$wikitext, &$redirectTarget ) {
+                                       $wikitext = $text;
+                                       $redirectTarget = $parser->getOptions()->getRedirectTarget();
+                               }
+                       )
+               ) );
+
+               // Test with non-redirect page
+               $wikitext = false;
+               $redirectTarget = false;
+               $content = $this->newContent( 'hello world.' );
+               $options = $content->getContentHandler()->makeParserOptions( 'canonical' );
+               $options->setRedirectTarget( $title );
+               $content->getParserOutput( $title, null, $options );
+               $this->assertEquals( 'hello world.', $wikitext,
+                       'Wikitext passed to hook was not as expected'
+               );
+               $this->assertEquals( null, $redirectTarget, 'Redirect seen in hook was not null' );
+               $this->assertEquals( $title, $options->getRedirectTarget(),
+                       'ParserOptions\' redirectTarget was changed'
+               );
+
+               // Test with a redirect page
+               $wikitext = false;
+               $redirectTarget = false;
+               $content = $this->newContent( "#REDIRECT [[TestRedirectParserOption/redir]]\nhello redirect." );
+               $options = $content->getContentHandler()->makeParserOptions( 'canonical' );
+               $content->getParserOutput( $title, null, $options );
+               $this->assertEquals( 'hello redirect.', $wikitext, 'Wikitext passed to hook was not as expected' );
+               $this->assertNotEquals( null, $redirectTarget, 'Redirect seen in hook was null' );
+               $this->assertEquals( 'TestRedirectParserOption/redir', $redirectTarget->getFullText(),
+                       'Redirect seen in hook was not the expected title'
+               );
+               $this->assertEquals( null, $options->getRedirectTarget(),
+                       'ParserOptions\' redirectTarget was changed'
+               );
+       }
+
        public static function dataEquals() {
                return array(
                        array( new WikitextContent( "hallo" ), null, false ),
index c45de36..ef0f2a9 100644 (file)
@@ -87,7 +87,7 @@ class MWExceptionTest extends MediaWikiTestCase {
                $this->assertEquals( $expectedReturn, $e->runHooks( $name, $args ) );
        }
 
-       public function provideRunHooks() {
+       public static function provideRunHooks() {
                return array(
                        array( null, null, null, null ),
                        array( array(), 'name', array(), null ),
@@ -134,7 +134,7 @@ class MWExceptionTest extends MediaWikiTestCase {
                $this->assertEquals( $expected, $e->isCommandLine() );
        }
 
-       public function provideIsCommandLine() {
+       public static function provideIsCommandLine() {
                return array(
                        array( false, null ),
                        array( true, true ),
@@ -155,7 +155,7 @@ class MWExceptionTest extends MediaWikiTestCase {
                        "The $exception_class exception should be JSON serializable, got false." );
        }
 
-       public function provideExceptionClasses() {
+       public static function provideExceptionClasses() {
                return array(
                        array( 'Exception' ),
                        array( 'MWException' ),
@@ -192,7 +192,7 @@ class MWExceptionTest extends MediaWikiTestCase {
        /**
         * Returns test cases: exception class, key name, gettype()
         */
-       public function provideJsonSerializedKeys() {
+       public static function provideJsonSerializedKeys() {
                $testCases = array();
                foreach ( array( 'Exception', 'MWException' ) as $exClass ) {
                        $exTests = array(
index aaee512..d4e5214 100644 (file)
@@ -12,7 +12,7 @@ class IPSetTest extends MediaWikiTestCase {
         * config is an array constructor argument for IPSet, and the tests are
         * an array of IP => expected (boolean) result against the config dataset.
         */
-       public function provider() {
+       public static function provideIPSets() {
                return array(
                        array(
                                'old_list_subset',
@@ -240,7 +240,7 @@ class IPSetTest extends MediaWikiTestCase {
         * Validates IPSet loading and matching code
         *
         * @covers IPSet
-        * @dataProvider provider
+        * @dataProvider provideIPSets
         */
        public function testIPSet( $desc, array $cfg, array $tests ) {
                $ipset = new IPSet( $cfg );
index 334d5b5..f80f78d 100644 (file)
@@ -13,7 +13,7 @@ class MWMessagePackTest extends MediaWikiTestCase {
         * using <https://github.com/msgpack/msgpack-php>, which includes a
         * serialization function.
         */
-       public function provider() {
+       public static function providePacks() {
                $tests = array(
                        array( 'nil', null, 'c0' ),
                        array( 'bool', true, 'c3' ),
@@ -66,7 +66,7 @@ class MWMessagePackTest extends MediaWikiTestCase {
        /**
         * Verify that values are serialized correctly.
         * @covers MWMessagePack::pack
-        * @dataProvider provider
+        * @dataProvider providePacks
         */
        public function testPack( $type, $value, $expected ) {
                $actual = bin2hex( MWMessagePack::pack( $value ) );
diff --git a/tests/phpunit/includes/mail/MailAddressTest.php b/tests/phpunit/includes/mail/MailAddressTest.php
new file mode 100644 (file)
index 0000000..2d07812
--- /dev/null
@@ -0,0 +1,63 @@
+<?php
+
+class MailAddressTest extends MediaWikiTestCase {
+
+       /**
+        * @covers MailAddress::__construct
+        */
+       public function testConstructor() {
+               $ma = new MailAddress( 'foo@bar.baz', 'UserName', 'Real name' );
+               $this->assertInstanceOf( 'MailAddress', $ma );
+       }
+
+       /**
+        * @covers MailAddress::newFromUser
+        */
+       public function testNewFromUser() {
+               $user = $this->getMock( 'User' );
+               $user->expects( $this->any() )->method( 'getName' )->will( $this->returnValue( 'UserName' ) );
+               $user->expects( $this->any() )->method( 'getEmail' )->will( $this->returnValue( 'foo@bar.baz' ) );
+               $user->expects( $this->any() )->method( 'getRealName' )->will( $this->returnValue( 'Real name' ) );
+
+               $ma = MailAddress::newFromUser( $user );
+               $this->assertInstanceOf( 'MailAddress', $ma );
+               $this->setMwGlobals( 'wgEnotifUseRealName', true );
+               $this->assertEquals( 'Real name <foo@bar.baz>', $ma->toString() );
+               $this->setMwGlobals( 'wgEnotifUseRealName', false );
+               $this->assertEquals( 'UserName <foo@bar.baz>', $ma->toString() );
+       }
+
+       /**
+        * @covers MailAddress::toString
+        * @dataProvider provideToString
+        */
+       public function testToString( $useRealName, $address, $name, $realName, $expected ) {
+               if ( wfIsWindows() ) {
+                       $this->markTestSkipped( 'This test only works on non-Windows platforms' );
+               }
+               $this->setMwGlobals( 'wgEnotifUseRealName', $useRealName );
+               $ma = new MailAddress( $address, $name, $realName );
+               $this->assertEquals( $expected, $ma->toString() );
+       }
+
+       public static function provideToString() {
+               return array(
+                       array( true, 'foo@bar.baz', 'FooBar', 'Foo Bar', 'Foo Bar <foo@bar.baz>' ),
+                       array( true, 'foo@bar.baz', 'UserName', null, 'UserName <foo@bar.baz>' ),
+                       array( true, 'foo@bar.baz', 'AUser', 'My real name', 'My real name <foo@bar.baz>' ),
+                       array( true, 'foo@bar.baz', 'A.user.name', 'my@real.name', '"my@real.name" <foo@bar.baz>' ),
+                       array( false, 'foo@bar.baz', 'AUserName', 'Some real name', 'AUserName <foo@bar.baz>' ),
+                       array( false, 'foo@bar.baz', '', '', 'foo@bar.baz' ),
+                       array( true, 'foo@bar.baz', '', '', 'foo@bar.baz' ),
+               );
+       }
+
+       /**
+        * @covers MailAddress::__toString
+        */
+       public function test__ToString() {
+               $ma = new MailAddress( 'some@email.com', 'UserName', 'A real name' );
+               $this->assertEquals( $ma->toString(), (string)$ma );
+       }
+
+}
\ No newline at end of file
diff --git a/tests/phpunit/includes/mail/UserMailerTest.php b/tests/phpunit/includes/mail/UserMailerTest.php
new file mode 100644 (file)
index 0000000..dca8aeb
--- /dev/null
@@ -0,0 +1,14 @@
+<?php
+
+class UserMailerTest extends MediaWikiLangTestCase {
+
+       /**
+        * @covers UserMailer::quotedPrintable
+        */
+       public function testQuotedPrintable() {
+               $this->assertEquals(
+                       "=?UTF-8?Q?=C4=88u=20legebla=3F?=",
+                       UserMailer::quotedPrintable( "\xc4\x88u legebla?", "UTF-8" ) );
+       }
+
+}
index 247e352..f0bd42a 100644 (file)
@@ -32,7 +32,7 @@ class ExifRotationTest extends MediaWikiMediaTestCase {
         * @dataProvider provideFiles
         */
        public function testMetadata( $name, $type, $info ) {
-               if ( !BitmapHandler::canRotate() ) {
+               if ( !$this->handler->canRotate() ) {
                        $this->markTestSkipped( "This test needs a rasterizer that can auto-rotate." );
                }
                $file = $this->dataFile( $name, $type );
@@ -40,12 +40,29 @@ class ExifRotationTest extends MediaWikiMediaTestCase {
                $this->assertEquals( $info['height'], $file->getHeight(), "$name: height check" );
        }
 
+       /**
+        * Same as before, but with auto-rotation set to auto.
+        *
+        * This sets scaler to image magick, which we should detect as
+        * supporting rotation.
+        * @dataProvider provideFiles
+        */
+       public function testMetadataAutoRotate( $name, $type, $info ) {
+               $this->setMwGlobals( 'wgEnableAutoRotation', null );
+               $this->setMwGlobals( 'wgUseImageMagick', true );
+               $this->setMwGlobals( 'wgUseImageResize', true );
+
+               $file = $this->dataFile( $name, $type );
+               $this->assertEquals( $info['width'], $file->getWidth(), "$name: width check" );
+               $this->assertEquals( $info['height'], $file->getHeight(), "$name: height check" );
+       }
+
        /**
         *
         * @dataProvider provideFiles
         */
        public function testRotationRendering( $name, $type, $info, $thumbs ) {
-               if ( !BitmapHandler::canRotate() ) {
+               if ( !$this->handler->canRotate() ) {
                        $this->markTestSkipped( "This test needs a rasterizer that can auto-rotate." );
                }
                foreach ( $thumbs as $size => $out ) {
@@ -133,6 +150,19 @@ class ExifRotationTest extends MediaWikiMediaTestCase {
                $this->assertEquals( $info['height'], $file->getHeight(), "$name: height check" );
        }
 
+       /**
+        * Same as before, but with auto-rotation set to auto and an image scaler that doesn't support it.
+        * @dataProvider provideFilesNoAutoRotate
+        */
+       public function testMetadataAutoRotateUnsupported( $name, $type, $info ) {
+               $this->setMwGlobals( 'wgEnableAutoRotation', null );
+               $this->setMwGlobals( 'wgUseImageResize', false );
+
+               $file = $this->dataFile( $name, $type );
+               $this->assertEquals( $info['width'], $file->getWidth(), "$name: width check" );
+               $this->assertEquals( $info['height'], $file->getHeight(), "$name: height check" );
+       }
+
        /**
         *
         * @dataProvider provideFilesNoAutoRotate
index 52a51cc..87ffd99 100644 (file)
@@ -116,7 +116,7 @@ class GIFHandlerTest extends MediaWikiMediaTestCase {
                $this->assertEquals( $expected, $actual );
        }
 
-       public function provideGetIndependentMetaArray() {
+       public static function provideGetIndependentMetaArray() {
                return array(
                        array( 'nonanimated.gif', array(
                                'GIFFileComment' => array(
index 092be89..36872a7 100644 (file)
@@ -118,7 +118,7 @@ class PNGHandlerTest extends MediaWikiMediaTestCase {
                $this->assertEquals( $expected, $actual );
        }
 
-       public function provideGetIndependentMetaArray() {
+       public static function provideGetIndependentMetaArray() {
                return array(
                        array( 'rgb-na-png.png', array() ),
                        array( 'xmp.png',
index 1361a92..8f7a0d6 100644 (file)
@@ -28,7 +28,7 @@ class SvgTest extends MediaWikiMediaTestCase {
                $this->assertEquals( $res, $expected );
        }
 
-       public function providerGetIndependentMetaArray() {
+       public static function providerGetIndependentMetaArray() {
                return array(
                        array( 'Tux.svg', array(
                                'ObjectName' => 'Tux',
index 97b76fe..f4b469b 100644 (file)
@@ -110,7 +110,7 @@ class CleanUpTest extends MediaWikiTestCase {
        }
 
        /** @todo document */
-       public function provideAllBytes() {
+       public static function provideAllBytes() {
                return array(
                        array( '', '' ),
                        array( 'x', '' ),
index 160ddad..987b6e6 100644 (file)
@@ -23,9 +23,6 @@ class BagOStuffTest extends MediaWikiTestCase {
                $this->cache->delete( wfMemcKey( 'test' ) );
        }
 
-       protected function tearDown() {
-       }
-
        public function testMerge() {
                $key = wfMemcKey( 'test' );
 
index a450972..df891f5 100644 (file)
@@ -83,14 +83,28 @@ class MediaWikiParserTest {
                        . implode( ' ', $filesToTest ) );
 
                $suite = new PHPUnit_Framework_TestSuite;
+               $testList = array();
+               $counter = 0;
                foreach ( $filesToTest as $fileName ) {
-                       $testsName = basename( $fileName, '.txt' );
+                       // Call the highest level directory the extension name.
+                       // It may or may not actually be, but it should be close
+                       // enough to cause there to be separate names for different
+                       // things, which is good enough for our purposes.
+                       $extensionName = basename( dirname( $fileName ) );
+                       $testsName = $extensionName . '⁄' . basename( $fileName, '.txt' );
                        $escapedFileName = strtr( $fileName, array( "'" => "\\'", '\\' => '\\\\' ) );
-                       /* This used to be ucfirst( basename( dirname( $filename ) ) )
-                        * and then was ucfirst( basename( $filename, '.txt' )
-                        * but that didn't work with names like foo.tests.txt
-                        */
-                       $parserTestClassName = str_replace( '.', '_', ucfirst( $testsName ) );
+                       $parserTestClassName = ucfirst( $testsName );
+                       // Official spec for class names: http://php.net/manual/en/language.oop5.basic.php
+                       // Prepend 'ParserTest_' to be paranoid about it not starting with a number
+                       $parserTestClassName = 'ParserTest_' . preg_replace( '/[^a-zA-Z0-9_\x7f-\xff]/', '_', $parserTestClassName );
+                       if ( isset( $testList[$parserTestClassName] ) ) {
+                               // If a conflict happens, gives a very unclear fatal.
+                               // So as a last ditch effort to prevent that eventuality, if there
+                               // is a conflict, append a number.
+                               $counter++;
+                               $parserTestClassName .= $counter;
+                       }
+                       $testList[$parserTestClassName] = true;
                        $parserTestClassDefinition = <<<EOT
 /**
  * @group Database
index cbf4803..1790086 100644 (file)
@@ -147,6 +147,41 @@ class ParserMethodsTest extends MediaWikiLangTestCase {
                        ),
                ), $out->getSections(), 'getSections() with proper value when <h2> is used' );
        }
+
+       /**
+        * @dataProvider provideNormalizeLinkUrl
+        * @covers Parser::normalizeLinkUrl
+        * @covers Parser::normalizeUrlComponent
+        */
+       public function testNormalizeLinkUrl( $explanation, $url, $expected ) {
+               $this->assertEquals( $expected, Parser::normalizeLinkUrl( $url ), $explanation );
+       }
+
+       public static function provideNormalizeLinkUrl() {
+               return array(
+                       array(
+                               'Escaping of unsafe characters',
+                               'http://example.org/foo bar?param[]="value"&param[]=valüe',
+                               'http://example.org/foo%20bar?param%5B%5D=%22value%22&param%5B%5D=val%C3%BCe',
+                       ),
+                       array(
+                               'Case normalization of percent-encoded characters',
+                               'http://example.org/%ab%cD%Ef%FF',
+                               'http://example.org/%AB%CD%EF%FF',
+                       ),
+                       array(
+                               'Unescaping of safe characters',
+                               'http://example.org/%3C%66%6f%6F%3E?%3C%66%6f%6F%3E#%3C%66%6f%6F%3E',
+                               'http://example.org/%3Cfoo%3E?%3Cfoo%3E#%3Cfoo%3E',
+                       ),
+                       array(
+                               'Context-sensitive replacement of sometimes-safe characters',
+                               'http://example.org/%23%2F%3F%26%3D%2B%3B?%23%2F%3F%26%3D%2B%3B#%23%2F%3F%26%3D%2B%3B',
+                               'http://example.org/%23%2F%3F&=+;?%23/?%26%3D%2B%3B#%23/?&=+;',
+                       ),
+               );
+       }
+
        // @todo Add tests for cleanSig() / cleanSigInSig(), getSection(),
        // replaceSection(), getPreloadText()
 }
index c869258..f656a74 100644 (file)
@@ -25,7 +25,7 @@ class TidyTest extends MediaWikiTestCase {
                $this->assertEquals( $expected, $text, $msg );
        }
 
-       public function provideTestWrapping() {
+       public static function provideTestWrapping() {
                $testMathML = <<<'MathML'
 <math xmlns="http://www.w3.org/1998/Math/MathML">
     <mrow>
index 4d5c78a..8ac419f 100644 (file)
@@ -11,7 +11,7 @@ class BcryptPasswordTestCase extends PasswordTestCase {
                ) );
        }
 
-       public function providePasswordTests() {
+       public static function providePasswordTests() {
                /** @codingStandardsIgnoreStart Generic.Files.LineLength.TooLong */
                return array(
                        // Tests from glibc bcrypt implementation
index 03a742b..86e8270 100644 (file)
@@ -26,7 +26,7 @@ class LayeredParameterizedPasswordTest extends PasswordTestCase {
                );
        }
 
-       public function providePasswordTests() {
+       public static function providePasswordTests() {
                /** @codingStandardsIgnoreStart Generic.Files.LineLength.TooLong */
                return array(
                        array( true, ':testLargeLayeredTop:sha512:1024:512!sha512:1024:512!sha512:1024:512!sha512:1024:512!5!vnRy+2SrSA0fHt3dwhTP5g==!AVnwfZsAQjn+gULv7FSGjA==!xvHUX3WcpkeSn1lvjWcvBg==!It+OC/N9tu+d3ByHhuB0BQ==!Tb.gqUOiD.aWktVwHM.Q/O!7CcyMfXUPky5ptyATJsR2nq3vUqtnBC', 'testPassword123' ),
index 7820d53..78fc3ed 100644 (file)
@@ -51,8 +51,11 @@ abstract class PasswordTestCase extends MediaWikiTestCase {
         * parameter (a password) should match.
         *
         * @return array
+        * @abstract
         */
-       abstract public function providePasswordTests();
+       public static function providePasswordTests() {
+               throw new MWException( "Not implemented" );
+       }
 
        /**
         * @dataProvider providePasswordTests
index ae47120..091853e 100644 (file)
@@ -13,7 +13,7 @@ class Pbkdf2PasswordTest extends PasswordTestCase {
                ) );
        }
 
-       public function providePasswordTests() {
+       public static function providePasswordTests() {
                return array(
                        array( true, ":pbkdf2:sha1:1:20:c2FsdA==:DGDID5YfDnHzqbUkr2ASBi/gN6Y=", 'password' ),
                        array( true, ":pbkdf2:sha1:2:20:c2FsdA==:6mwBTcctb4zNHtkqzh1B8NjeiVc=", 'password' ),
diff --git a/tests/phpunit/includes/resourceloader/ResourceLoaderLESSTest.php b/tests/phpunit/includes/resourceloader/ResourceLoaderLESSTest.php
deleted file mode 100644 (file)
index a3d73e5..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-<?php
-
-class ResourceLoaderLESSTest extends MediaWikiTestCase {
-       public static function lessProvider() {
-               $result = array();
-               foreach ( glob( __DIR__ . '/fixtures/*.less' ) as $file ) {
-                       $result[] = array( $file );
-               }
-
-               return $result;
-       }
-
-       /**
-        * @dataProvider lessProvider
-        */
-       public function testLessFile( $lessFile ) {
-               $cssFile = substr( $lessFile, 0, -4 ) . 'css';
-               if ( !file_exists( $cssFile ) ) {
-                       $this->fail( "No css file found to assert equal to $lessFile" );
-                       return;
-               }
-
-               $expect = file_get_contents( $cssFile );
-               $content = file_get_contents( $lessFile );
-               $result = ResourceLoader::getLessCompiler( RequestContext::getMain()->getConfig() )
-                       ->compile( $content, $lessFile );
-               $this->assertEquals( $expect, $result );
-       }
-}
index 50f88c8..9dc1805 100644 (file)
@@ -22,7 +22,7 @@ class ResourceLoaderWikiModuleTest extends ResourceLoaderTestCase {
                $this->assertEquals( $expected, $module->isKnownEmpty( $context ) );
        }
 
-       public function provideIsKnownEmpty() {
+       public static function provideIsKnownEmpty() {
                return array(
                        // No valid pages
                        array( array(), 'test1', true ),
diff --git a/tests/phpunit/includes/resourceloader/fixtures/001-embeddable.css b/tests/phpunit/includes/resourceloader/fixtures/001-embeddable.css
deleted file mode 100644 (file)
index b291c5e..0000000
+++ /dev/null
@@ -1,9 +0,0 @@
-.box {
-  content: not-embeddable;
-}
-.box {
-  content: embeddable;
-}
-.box {
-  content: embeddable;
-}
diff --git a/tests/phpunit/includes/resourceloader/fixtures/001-embeddable.less b/tests/phpunit/includes/resourceloader/fixtures/001-embeddable.less
deleted file mode 100644 (file)
index 7018aa2..0000000
+++ /dev/null
@@ -1,20 +0,0 @@
-@base: '../fixtures/';
-
-.helper(@url) when (embeddable(@url)) {
-       content: embeddable;
-}
-.helper(@url) when not (embeddable(@url)) {
-       content: not-embeddable;
-}
-
-.box {
-       .helper('path/to/nonexistent/file');
-}
-
-.box {
-       .helper('001-embeddable.css');
-}
-
-.box {
-       .helper("@{base}001-embeddable.css");
-}
diff --git a/tests/phpunit/includes/specialpage/SpecialPageFactoryTest.php b/tests/phpunit/includes/specialpage/SpecialPageFactoryTest.php
new file mode 100644 (file)
index 0000000..b1d4257
--- /dev/null
@@ -0,0 +1,101 @@
+<?php
+/**
+ * Factory for handling the special page list and generating SpecialPage objects.
+ *
+ * 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
+ *
+ * @covers SpecialPageFactory
+ * @group SpecialPage
+ */
+class SpecialPageFactoryTest extends MediaWikiTestCase {
+
+       public function newSpecialAllPages() {
+               return new SpecialAllPages();
+       }
+
+       public function specialPageProvider() {
+               return array(
+                       'class name' => array( 'SpecialAllPages', false ),
+                       'closure' => array( function() {
+                               return new SpecialAllPages();
+                       }, false ),
+                       'function' => array( array( $this, 'newSpecialAllPages' ), false  ),
+               );
+       }
+
+       /**
+        * @dataProvider specialPageProvider
+        */
+       public function testGetPage( $spec, $shouldReuseInstance ) {
+               $this->mergeMwGlobalArrayValue( 'wgSpecialPages', array( 'testdummy' => $spec ) );
+
+               SpecialPageFactory::resetList();
+
+               $page = SpecialPageFactory::getPage( 'testdummy' );
+               $this->assertInstanceOf( 'SpecialPage', $page );
+
+               $page2 = SpecialPageFactory::getPage( 'testdummy' );
+               $this->assertEquals( $shouldReuseInstance, $page2 === $page, "Should re-use instance:" );
+
+               SpecialPageFactory::resetList();
+       }
+
+       public function testGetNames() {
+               $this->mergeMwGlobalArrayValue( 'wgSpecialPages', array( 'testdummy' => 'SpecialAllPages' ) );
+
+               SpecialPageFactory::resetList();
+               $names = SpecialPageFactory::getNames();
+               $this->assertInternalType( 'array', $names );
+               $this->assertContains( 'testdummy', $names );
+               SpecialPageFactory::resetList();
+       }
+
+       public function testResolveAlias() {
+               $this->setMwGlobals( 'wgContLang', Language::factory( 'de' ) );
+
+               SpecialPageFactory::resetList();
+
+               list( $name, $param ) = SpecialPageFactory::resolveAlias( 'Spezialseiten/Foo' );
+               $this->assertEquals( 'Specialpages', $name );
+               $this->assertEquals( 'Foo', $param );
+
+               SpecialPageFactory::resetList();
+       }
+
+       public function testGetLocalNameFor() {
+               $this->setMwGlobals( 'wgContLang', Language::factory( 'de' ) );
+
+               SpecialPageFactory::resetList();
+
+               $name = SpecialPageFactory::getLocalNameFor( 'Specialpages', 'Foo' );
+               $this->assertEquals( 'Spezialseiten/Foo', $name );
+
+               SpecialPageFactory::resetList();
+       }
+
+       public function testGetTitleForAlias() {
+               $this->setMwGlobals( 'wgContLang', Language::factory( 'de' ) );
+
+               SpecialPageFactory::resetList();
+
+               $title = SpecialPageFactory::getTitleForAlias( 'Specialpages/Foo' );
+               $this->assertEquals( 'Spezialseiten/Foo', $title->getText() );
+               $this->assertEquals( NS_SPECIAL, $title->getNamespace() );
+
+               SpecialPageFactory::resetList();
+       }
+
+}
index 8a0ac97..22bdefd 100644 (file)
@@ -6,6 +6,7 @@
  * Copyright © 2013, Siebrand Mazeland
  * Copyright © 2013, Wikimedia Foundation Inc.
  *
+ * @group Database
  */
 
 class ImageListPagerTest extends MediaWikiTestCase {
index bd95281..14d1968 100644 (file)
@@ -1,4 +1,8 @@
 <?php
+/**
+ * @group Database
+ */
+
 class SpecialMIMESearchTest extends MediaWikiTestCase {
 
        /** @var MIMESearchPage */
index fd09043..4dbfc41 100644 (file)
@@ -53,7 +53,7 @@ class SpecialMyLanguageTest extends MediaWikiTestCase {
                $this->assertEquals( $expected, $title );
        }
 
-       public function provideFindTitle() {
+       public static function provideFindTitle() {
                return array(
                        array( null, '::Fail', 'en', 'en' ),
                        array( 'Page/Another', 'Page/Another/en', 'en', 'en' ),
index b13df89..4171c10 100644 (file)
@@ -24,6 +24,7 @@
  * @covers MediaWikiPageLinkRenderer
  *
  * @group Title
+ * @group Database
  */
 class MediaWikiPageLinkRendererTest extends MediaWikiTestCase {
 
@@ -52,7 +53,7 @@ class MediaWikiPageLinkRendererTest extends MediaWikiTestCase {
                return $genderCache;
        }
 
-       public function provideGetPageUrl() {
+       public static function provideGetPageUrl() {
                return array(
                        array(
                                new TitleValue( NS_MAIN, 'Foo_Bar' ),
@@ -85,7 +86,7 @@ class MediaWikiPageLinkRendererTest extends MediaWikiTestCase {
                $this->assertEquals( $url, $actual );
        }
 
-       public function provideRenderHtmlLink() {
+       public static function provideRenderHtmlLink() {
                return array(
                        array(
                                new TitleValue( NS_MAIN, 'Foo_Bar' ),
@@ -127,7 +128,7 @@ class MediaWikiPageLinkRendererTest extends MediaWikiTestCase {
                $this->assertRegExp( $pattern, $actual );
        }
 
-       public function provideRenderWikitextLink() {
+       public static function provideRenderWikitextLink() {
                return array(
                        array(
                                new TitleValue( NS_MAIN, 'Foo_Bar' ),
index bf06e3b..f95b305 100644 (file)
@@ -85,7 +85,7 @@ class MediaWikiTitleCodecTest extends MediaWikiTestCase {
                return new MediaWikiTitleCodec( $lang, $gender );
        }
 
-       public function provideFormat() {
+       public static function provideFormat() {
                return array(
                        array( NS_MAIN, 'Foo_Bar', '', 'en', 'Foo Bar' ),
                        array( NS_USER, 'Hansi_Maier', 'stuff_and_so_on', 'en', 'User:Hansi Maier#stuff and so on' ),
@@ -129,7 +129,7 @@ class MediaWikiTitleCodecTest extends MediaWikiTestCase {
                $this->assertEquals( $normalized, $actual2, 'normalized after round trip' );
        }
 
-       public function provideGetText() {
+       public static function provideGetText() {
                return array(
                        array( NS_MAIN, 'Foo_Bar', '', 'en', 'Foo Bar' ),
                        array( NS_USER, 'Hansi_Maier', 'stuff_and_so_on', 'en', 'Hansi Maier' ),
@@ -148,7 +148,7 @@ class MediaWikiTitleCodecTest extends MediaWikiTestCase {
                $this->assertEquals( $expected, $actual );
        }
 
-       public function provideGetPrefixedText() {
+       public static function provideGetPrefixedText() {
                return array(
                        array( NS_MAIN, 'Foo_Bar', '', 'en', 'Foo Bar' ),
                        array( NS_USER, 'Hansi_Maier', 'stuff_and_so_on', 'en', 'User:Hansi Maier' ),
@@ -174,7 +174,7 @@ class MediaWikiTitleCodecTest extends MediaWikiTestCase {
                $this->assertEquals( $expected, $actual );
        }
 
-       public function provideGetFullText() {
+       public static function provideGetFullText() {
                return array(
                        array( NS_MAIN, 'Foo_Bar', '', 'en', 'Foo Bar' ),
                        array( NS_USER, 'Hansi_Maier', 'stuff_and_so_on', 'en', 'User:Hansi Maier#stuff and so on' ),
@@ -196,7 +196,7 @@ class MediaWikiTitleCodecTest extends MediaWikiTestCase {
                $this->assertEquals( $expected, $actual );
        }
 
-       public function provideParseTitle() {
+       public static function provideParseTitle() {
                //TODO: test capitalization and trimming
                //TODO: test unicode normalization
 
@@ -281,7 +281,7 @@ class MediaWikiTitleCodecTest extends MediaWikiTestCase {
                $this->assertEquals( $title, $actual );
        }
 
-       public function provideParseTitle_invalid() {
+       public static function provideParseTitle_invalid() {
                //TODO: test unicode errors
 
                return array(
@@ -353,7 +353,7 @@ class MediaWikiTitleCodecTest extends MediaWikiTestCase {
                $codec->parseTitle( $text, NS_MAIN );
        }
 
-       public function provideGetNamespaceName() {
+       public static function provideGetNamespaceName() {
                return array(
                        array( NS_MAIN, 'Foo', 'en', '' ),
                        array( NS_USER, 'Foo', 'en', 'User' ),
index fdd40b2..d5d1188 100644 (file)
@@ -68,7 +68,7 @@ class UploadStashTest extends MediaWikiTestCase {
                $stash->removeFile( $file->getFileKey() );
        }
 
-       public function provideInvalidRequests() {
+       public static function provideInvalidRequests() {
                return array(
                        'Check failure on bad wpFileKey' =>
                                array( new FauxRequest( array( 'wpFileKey' => 'foo' ) ) ),
@@ -84,7 +84,7 @@ class UploadStashTest extends MediaWikiTestCase {
                $this->assertFalse( UploadFromStash::isValidRequest( $request ) );
        }
 
-       public function provideValidRequests() {
+       public static function provideValidRequests() {
                return array(
                        'Check good wpFileKey' =>
                                array( new FauxRequest( array( 'wpFileKey' => 'testkey-test.test' ) ) ),
index 7dec626..ed03418 100644 (file)
@@ -21,8 +21,7 @@
                        'Mozilla/5.0 (Windows NT 6.0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/28.0.1500.95 Safari/537.36 OPR/15.0.1147.153',
                        'Mozilla/5.0 (Windows NT 5.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/29.0.1547.57 Safari/537.36 OPR/16.0.1196.62',
                        'Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/36.0.1985.125 Safari/537.36 OPR/23.0.1522.75',
-                       // Internet Explorer 7+
-                       'Mozilla/5.0 (compatible; MSIE 7.0; Windows NT 6.0; en-US)',
+                       // Internet Explorer 8+
                        'Mozilla/5.0 (compatible; MSIE 8.0; Windows NT 5.2; Trident/4.0; Media Center PC 4.0; SLCC1; .NET CLR 3.0.04320)',
                        'Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 7.1; Trident/5.0)',
                        'Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.1; WOW64; Trident/6.0)',
                        'Mozilla/5.0 (Linux; U; Android 2.1; en-us; Nexus One Build/ERD62) AppleWebKit/530.17 (KHTML, like Gecko) Version/4.0 Mobile Safari/530.17'
                ],
                gradeC: [
-                       // Internet Explorer < 7
+                       // Internet Explorer < 8
                        'Mozilla/2.0 (compatible; MSIE 3.03; Windows 3.1)',
                        'Mozilla/4.0 (compatible; MSIE 4.01; Windows 95)',
                        'Mozilla/4.0 (compatible; MSIE 5.0; Windows 98;)',
                        'Mozilla/4.0 (compatible; MSIE 5.5; Windows NT)',
                        'Mozilla/5.0 (compatible; MSIE 6.0; Windows NT 5.1)',
+                       'Mozilla/5.0 (compatible; MSIE 7.0; Windows NT 6.0; en-US)',
                        // Firefox < 3
                        'Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.0.2) Gecko/20060308 Firefox/1.5.0.2',
                        'Mozilla/5.0 (X11; U; Linux i686; nl; rv:1.8.1.1) Gecko/20070311 Firefox/2.0.0.1',